mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
tmu: fix freeze when using sleep_us_spin() with interrupts on
Because of timing the interrupt handler could run before the flag is checked.
This commit is contained in:
parent
1384c54b5f
commit
caf585b0a1
3 changed files with 14 additions and 6 deletions
|
@ -162,10 +162,11 @@ void timer_stop(int timer);
|
||||||
it may have only paused. If the timer never stops, you're in trouble. */
|
it may have only paused. If the timer never stops, you're in trouble. */
|
||||||
void timer_wait(int timer);
|
void timer_wait(int timer);
|
||||||
|
|
||||||
/* timer_spinwait(): Actively wait for a timer to raise UNF
|
/* timer_spinwait(): Start a timer and actively wait for UNF
|
||||||
Waits until the timer raises UNF, without sleeping. This is useful for
|
Waits until the timer raises UNF, without sleeping. This is useful for
|
||||||
delays in driver code that is run when interrupts are disabled. This relies
|
delays in driver code that is run when interrupts are disabled. UNIE is
|
||||||
neither on the interrupt signal nor on the UNIE flag. */
|
disabled before starting the timer and waiting, so the callback is never
|
||||||
|
called. */
|
||||||
void timer_spinwait(int timer);
|
void timer_spinwait(int timer);
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
|
@ -13,12 +13,14 @@ static void do_sleep(uint64_t delay_us, int spin)
|
||||||
GINT_CALL_SET_STOP(&flag));
|
GINT_CALL_SET_STOP(&flag));
|
||||||
if(timer < 0) return;
|
if(timer < 0) return;
|
||||||
|
|
||||||
timer_start(timer);
|
|
||||||
if(spin) {
|
if(spin) {
|
||||||
timer_spinwait(timer);
|
timer_spinwait(timer);
|
||||||
timer_stop(timer);
|
timer_stop(timer);
|
||||||
}
|
}
|
||||||
else timer_wait(timer);
|
else {
|
||||||
|
timer_start(timer);
|
||||||
|
timer_wait(timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sleep_us(): Sleep for a fixed duration in microseconds */
|
/* sleep_us(): Sleep for a fixed duration in microseconds */
|
||||||
|
|
|
@ -209,6 +209,7 @@ void timer_stop(int id)
|
||||||
if(id < 3)
|
if(id < 3)
|
||||||
{
|
{
|
||||||
TMU[id].TCR.UNIE = 0;
|
TMU[id].TCR.UNIE = 0;
|
||||||
|
TMU[id].TCR.UNF = 0;
|
||||||
TMU[id].TCOR = 0xffffffff;
|
TMU[id].TCOR = 0xffffffff;
|
||||||
TMU[id].TCNT = 0xffffffff;
|
TMU[id].TCNT = 0xffffffff;
|
||||||
}
|
}
|
||||||
|
@ -240,17 +241,21 @@ void timer_wait(int id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* timer_spinwait(): Actively wait for a timer to raise UNF */
|
/* timer_spinwait(): Start a timer and actively wait for UNF */
|
||||||
void timer_spinwait(int id)
|
void timer_spinwait(int id)
|
||||||
{
|
{
|
||||||
if(id < 3)
|
if(id < 3)
|
||||||
{
|
{
|
||||||
tmu_t *T = &TMU[id];
|
tmu_t *T = &TMU[id];
|
||||||
|
T->TCR.UNIE = 0;
|
||||||
|
timer_start(id);
|
||||||
while(!T->TCR.UNF) {}
|
while(!T->TCR.UNF) {}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
etmu_t *T = &ETMU[id-3];
|
etmu_t *T = &ETMU[id-3];
|
||||||
|
set(T->TCR.UNIE, 0);
|
||||||
|
timer_start(id);
|
||||||
while(!T->TCR.UNF) {}
|
while(!T->TCR.UNF) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue