mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu: stm32f1: timer: fix race when combining two 16bit timer values
This commit is contained in:
parent
383ada9349
commit
efbd5518f6
@ -220,16 +220,33 @@ int timer_clear(tim_t dev, int channel)
|
||||
|
||||
unsigned int timer_read(tim_t dev)
|
||||
{
|
||||
unsigned a, b;
|
||||
switch (dev) {
|
||||
#if TIMER_0_EN
|
||||
case TIMER_0:
|
||||
return (((unsigned int)(0xffff & TIMER_0_DEV_0->CNT)) | (TIMER_0_DEV_1->CNT<<16));
|
||||
break;
|
||||
/* do OR'ing two times and only use value if results are equal.
|
||||
* otherwise, the lower 16bit counter could overflow while the
|
||||
* upper counter is read, leading to an incorrect result. */
|
||||
do {
|
||||
a = (((unsigned int)(0xffff & TIMER_0_DEV_0->CNT)) |
|
||||
(TIMER_0_DEV_1->CNT<<16));
|
||||
b = (((unsigned int)(0xffff & TIMER_0_DEV_0->CNT)) |
|
||||
(TIMER_0_DEV_1->CNT<<16));
|
||||
} while (a!=b);
|
||||
|
||||
return a;
|
||||
#endif
|
||||
#if TIMER_1_EN
|
||||
case TIMER_1:
|
||||
return (((unsigned int)(0xffff & TIMER_1_DEV_0->CNT)) | (TIMER_1_DEV_1->CNT<<16));
|
||||
break;
|
||||
/* see above about why loop is needed */
|
||||
do {
|
||||
a = (((unsigned int)(0xffff & TIMER_1_DEV_0->CNT)) |
|
||||
(TIMER_1_DEV_1->CNT<<16));
|
||||
b = (((unsigned int)(0xffff & TIMER_1_DEV_0->CNT)) |
|
||||
(TIMER_1_DEV_1->CNT<<16));
|
||||
} while (a!=b);
|
||||
|
||||
return a;
|
||||
#endif
|
||||
case TIMER_UNDEFINED:
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user