19#if defined(ARDUINO_ARCH_SAMD)
24callfunction_t IntervalTimer::_TC5_callfunc = NULL;
25callfunction_t IntervalTimer::_TC4_callfunc = NULL;
27bool IntervalTimer::counter_active[INTERVALTIMER_MAX_TIMERS] = {};
30bool IntervalTimer::begin(callfunction_t callback, uint32_t usec)
volatile {
31 if (usec < 1431655765U) last_period = usec;
38 if (counter_id >= INTERVALTIMER_MAX_TIMERS){
41 while (counter_id < INTERVALTIMER_MAX_TIMERS && counter_active[counter_id]){
44 if (counter_id >= INTERVALTIMER_MAX_TIMERS){
48 counter_active[counter_id] =
true;
52 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |
53 GCLK_CLKCTRL_ID_TC4_TC5 |
54 GCLK_CLKCTRL_GEN_GCLK0;
57 while (GCLK->STATUS.bit.SYNCBUSY);
59 uint32_t period = last_period*3;
62 TC4->COUNT32.CC[0].reg = period;
63 while (TC4->COUNT32.STATUS.bit.SYNCBUSY);
65 _TC4_callfunc = callback;
66 NVIC_DisableIRQ(TC4_IRQn);
67 NVIC_ClearPendingIRQ(TC4_IRQn);
68 NVIC_SetPriority(TC4_IRQn, last_priority);
69 NVIC_EnableIRQ(TC4_IRQn);
70 TC4->COUNT32.INTENSET.bit.OVF = 1;
72 TC4->COUNT32.CTRLA.reg |= TC_CTRLA_PRESCSYNC_PRESC |
73 TC_CTRLA_WAVEGEN_MFRQ |
74 TC_CTRLA_PRESCALER_DIV16 |
75 TC_CTRLA_MODE_COUNT32;
77 while (TC4->COUNT32.STATUS.bit.SYNCBUSY);
79 TC4->COUNT32.CTRLA.bit.ENABLE = 1;
80 while (TC4->COUNT32.STATUS.bit.SYNCBUSY);
83 TC5->COUNT32.CC[0].reg = period;
85 while (TC5->COUNT32.STATUS.bit.SYNCBUSY);
87 _TC5_callfunc = callback;
88 NVIC_DisableIRQ(TC5_IRQn);
89 NVIC_ClearPendingIRQ(TC5_IRQn);
90 NVIC_SetPriority(TC5_IRQn, last_priority);
91 NVIC_EnableIRQ(TC5_IRQn);
93 TC5->COUNT32.INTENSET.bit.OVF = 1;
95 TC5->COUNT32.CTRLA.reg |= TC_CTRLA_PRESCSYNC_PRESC |
96 TC_CTRLA_WAVEGEN_MFRQ |
97 TC_CTRLA_PRESCALER_DIV16 |
98 TC_CTRLA_MODE_COUNT32;
100 while (TC5->COUNT32.STATUS.bit.SYNCBUSY);
102 TC5->COUNT32.CTRLA.bit.ENABLE = 1;
103 while (TC5->COUNT32.STATUS.bit.SYNCBUSY);
109void IntervalTimer::update(uint32_t usec)
volatile{
110 if (usec < 21845U) last_period = usec;
119 begin(_TC4_callfunc,last_period);
122 begin(_TC5_callfunc,last_period);
128void IntervalTimer::end()
volatile {
129 if (counter_id < INTERVALTIMER_MAX_TIMERS){
132 TC4->COUNT32.CTRLA.bit.ENABLE = 0;
133 while (TC4->COUNT32.STATUS.bit.SYNCBUSY);
134 counter_id=INTERVALTIMER_MAX_TIMERS;
137 TC5->COUNT32.CTRLA.bit.ENABLE = 0;
138 while (TC5->COUNT32.STATUS.bit.SYNCBUSY);
139 counter_id=INTERVALTIMER_MAX_TIMERS;
145void IntervalTimer::priority(uint8_t priority)
volatile {
147 last_priority = priority;
150 else last_priority = priority;
156 TC4->COUNT32.INTFLAG.bit.OVF = 1;
157 if (IntervalTimer::_TC4_callfunc != NULL) IntervalTimer::_TC4_callfunc();
165 TC5->COUNT32.INTFLAG.bit.OVF = 1;
166 if (IntervalTimer::_TC5_callfunc != NULL) IntervalTimer::_TC5_callfunc();
void error_message(uint8_t error_header, uint8_t source_header, uint32_t value, uint8_t sub_source_header)
@ OUT_ERROR_CONFIGURATION_OUT_OF_BOUNDS