Skip to content

Commit fcc121a

Browse files
committed
Rework us_ticker.c, work-around for #8656
1 parent 23e9e66 commit fcc121a

File tree

1 file changed

+23
-22
lines changed

1 file changed

+23
-22
lines changed

targets/TARGET_Atmel/TARGET_SAM_CortexM0P/us_ticker.c

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,7 @@ void us_ticker_init(void)
8585

8686
cycles_per_us = system_gclk_gen_get_hz(config_tc.clock_source) / 1000000;
8787
MBED_ASSERT(cycles_per_us > 0);
88-
/*while((cycles_per_us & 1) == 0 && prescaler <= 10) {
89-
cycles_per_us = cycles_per_us >> 1;
90-
prescaler++;
91-
}*/
88+
9289
while((cycles_per_us > 1) && (prescaler <= 10)) {
9390
cycles_per_us = cycles_per_us >> 1;
9491
prescaler++;
@@ -115,6 +112,11 @@ void us_ticker_init(void)
115112

116113
/* Enable the timer module */
117114
tc_enable(&us_ticker_module);
115+
116+
/* Enable the timer interrupt */
117+
tc_disable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
118+
NVIC_SetVector(TICKER_COUNTER_IRQn, (uint32_t)TICKER_COUNTER_Handlr);
119+
NVIC_EnableIRQ(TICKER_COUNTER_IRQn);
118120
}
119121

120122
uint32_t us_ticker_read()
@@ -127,37 +129,33 @@ uint32_t us_ticker_read()
127129

128130
void us_ticker_set_interrupt(timestamp_t timestamp)
129131
{
130-
uint32_t cur_time;
131-
int32_t delta;
132-
133-
cur_time = us_ticker_read();
134-
delta = (int32_t)((uint32_t)timestamp - cur_time);
135-
if (delta < 0) {
136-
/* Event already occurred in past */
137-
us_ticker_irq_handler();
138-
return;
139-
}
140-
141-
NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
142-
NVIC_SetVector(TICKER_COUNTER_IRQn, (uint32_t)TICKER_COUNTER_Handlr);
143-
144132
/* Enable the callback */
145133
tc_enable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
146134
tc_set_compare_value(&us_ticker_module, TC_COMPARE_CAPTURE_CHANNEL_0, (uint32_t)timestamp);
147-
148-
NVIC_EnableIRQ(TICKER_COUNTER_IRQn);
149135
}
150136

151137
void us_ticker_disable_interrupt(void)
152138
{
153139
/* Disable the callback */
154140
tc_disable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
155-
NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
156141
}
157142

158143
void us_ticker_fire_interrupt(void)
159144
{
160-
NVIC_SetPendingIRQ(TICKER_COUNTER_IRQn);
145+
/**
146+
* We should be able to trigger this by just calling:
147+
*
148+
* NVIC_SetPendingIRQ(TICKER_COUNTER_IRQn);
149+
*
150+
* However, tc_interrupt.c -> _tc_interrupt_handler then gets the wrong value from reg.
151+
* It should be 48 (when called via the normal API), but is 32. I've tried setting
152+
* this register before triggering the interrupt, and this fails in the same way.
153+
* I have no clue how to fix this properly... If someone comes along who understands
154+
* Atmel IRQ handling better I'd love to get a better patch
155+
*/
156+
157+
// this gives us a minimum tick of 400 us.
158+
us_ticker_set_interrupt(us_ticker_read() + 400);
161159
}
162160

163161
void us_ticker_clear_interrupt(void)
@@ -175,5 +173,8 @@ void us_ticker_clear_interrupt(void)
175173

176174
void us_ticker_free(void)
177175
{
176+
tc_clear_interrupt(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
177+
NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
178178

179+
us_ticker_inited = 0;
179180
}

0 commit comments

Comments
 (0)