YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
timerA_msp432.cpp
1/*
2 * timer_msp432.cpp
3 *
4 * Created on: 09.07.2016
5 * Author: aterstegge
6 */
7
8#include <cassert>
9#include "timerA_msp432.h"
10
11extern uint32_t SubsystemMasterClock;
12
13function<void()> timerA_msp432::_intHandler0 = 0;
14function<void()> timerA_msp432::_intHandler1 = 0;
15function<void()> timerA_msp432::_intHandler2 = 0;
16function<void()> timerA_msp432::_intHandler3 = 0;
17
18timerA_msp432::timerA_msp432(Timer_A_Type * timer)
19 : _timer(timer), _mode(TIMER::ONE_SHOT) {
20 // initialize attributes
21 _period_us = 0;
22 _ccr0 = 0;
23 _divider = 0;
24 // initialize the ctl register
25 _timer->CTL = 0;
26 // enable IRQ in NVIC
27 if (timer == TIMER_A0) NVIC_EnableIRQ(TA0_0_IRQn);
28 else if (timer == TIMER_A1) NVIC_EnableIRQ(TA1_0_IRQn);
29 else if (timer == TIMER_A2) NVIC_EnableIRQ(TA2_0_IRQn);
30 else if (timer == TIMER_A3) NVIC_EnableIRQ(TA3_0_IRQn);
31}
32
33timerA_msp432::~timerA_msp432() {
34 _timer->CTL = 0; // reset control register to default value
35}
36
37void timerA_msp432::setPeriod(uint32_t us, TIMER::timer_mode mode) {
38 _mode = mode;
39 _period_us = us;
40 // Calculate dividers and CCR0
41 uint32_t clock_MHz = SubsystemMasterClock / 1000000;
42 clock_MHz *= us;
43 uint16_t id, ex0;
44 bool found = false;
45 for (id = 0; id < 4; id++) {
46 for (ex0 = 0; ex0 < 8; ex0++) {
47 _divider = (1 << id) * (ex0 + 1);
48 _ccr0 = clock_MHz / _divider;
49 if (_ccr0 < 0x10000) {
50 found = true;
51 break;
52 }
53 }
54 if (found) break;
55 }
56 assert(found);
57 // Set the calculated results
58 _timer->CTL &= ~TIMER_A_CTL_ID_MASK;
59 _timer->CTL |= (id << TIMER_A_CTL_ID_OFS);
60 _timer->EX0 = ex0;
61 _timer->CCR[0] = _ccr0 - 1;
62}
63
64uint32_t timerA_msp432::getPeriod() {
65 return _period_us;
66}
67
68void timerA_msp432::setCallback(function<void()> f) {
69 if (_timer == TIMER_A0) { timerA_msp432::_intHandler0 = f; }
70 else if (_timer == TIMER_A1) { timerA_msp432::_intHandler1 = f; }
71 else if (_timer == TIMER_A2) { timerA_msp432::_intHandler2 = f; }
72 else if (_timer == TIMER_A3) { timerA_msp432::_intHandler3 = f; }
73}
74
75void timerA_msp432::start() {
76 // Initialize control register
77 _timer->CTL |= TIMER_A_CTL_SSEL__SMCLK | // SMCLK clock source
78 TIMER_A_CTL_CLR; // Clear timer
79 _timer->CCTL[0] |= TIMER_A_CCTLN_CCIE;
80
81 // Set the timer mode to start
82 if (_mode == TIMER::ONE_SHOT)
84 else
85 _timer->CTL |= TIMER_A_CTL_MC__UP;
86}
87
88void timerA_msp432::stop() {
89 _timer->CTL = 0;
90}
91
92bool timerA_msp432::isRunning() {
93 return _timer->CTL & TIMER_A_CTL_MC_MASK;
94}
95
96void timerA_msp432::reset() {
97 _timer->CTL |= TIMER_A_CTL_CLR;
98}
99
100// Interrupt handler
102extern "C" {
103
104void TA0_0_IRQHandler(void) {
105 // clear interrupt
106 TIMER_A0->CCTL[0] &= ~TIMER_A_CCTLN_CCIFG;
107 // disable timer if one-shot was selected
108 if ((TIMER_A0->CTL & TIMER_A_CTL_MC_MASK) == TIMER_A_CTL_MC__CONTINUOUS)
109 TIMER_A0->CTL = 0;
110 // call the user handler
111 if (timerA_msp432::_intHandler0) {
112 timerA_msp432::_intHandler0();
113 }
114}
115
116void TA1_0_IRQHandler(void) {
117 // clear interrupt
118 TIMER_A1->CCTL[0] &= ~TIMER_A_CCTLN_CCIFG;
119 // disable timer if one-shot was selected
120 if ((TIMER_A1->CTL & TIMER_A_CTL_MC_MASK) == TIMER_A_CTL_MC__CONTINUOUS)
121 TIMER_A1->CTL = 0;
122 // call the user handler
123 if (timerA_msp432::_intHandler1) {
124 timerA_msp432::_intHandler1();
125 }
126}
127
128void TA2_0_IRQHandler(void) {
129 // clear interrupt
130 TIMER_A2->CCTL[0] &= ~TIMER_A_CCTLN_CCIFG;
131 // disable timer if one-shot was selected
132 if ((TIMER_A2->CTL & TIMER_A_CTL_MC_MASK) == TIMER_A_CTL_MC__CONTINUOUS)
133 TIMER_A2->CTL = 0;
134 // call the user handler
135 if (timerA_msp432::_intHandler2) {
136 timerA_msp432::_intHandler2();
137 }
138}
139
140void TA3_0_IRQHandler(void) {
141 // clear interrupt
142 TIMER_A3->CCTL[0] &= ~TIMER_A_CCTLN_CCIFG;
143 // disable timer if one-shot was selected
144 if ((TIMER_A3->CTL & TIMER_A_CTL_MC_MASK) == TIMER_A_CTL_MC__CONTINUOUS)
145 TIMER_A3->CTL = 0;
146 // call the user handler
147 if (timerA_msp432::_intHandler3) {
148 timerA_msp432::_intHandler3();
149 }
150}
151
152} // extern "C"
#define TIMER_A_CTL_ID_OFS
#define TIMER_A_CTL_MC__CONTINUOUS
__IO uint16_t CCTL[5]
#define TIMER_A_CTL_CLR
__IO uint16_t EX0
__IO uint16_t CTL
#define TIMER_A_CCTLN_CCIE
#define TIMER_A_CTL_SSEL__SMCLK
__IO uint16_t CCR[5]
#define TIMER_A_CTL_MC__UP
#define TIMER_A_CTL_MC_MASK