mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +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 int timer_read(tim_t dev)
|
||||||
{
|
{
|
||||||
|
unsigned a, b;
|
||||||
switch (dev) {
|
switch (dev) {
|
||||||
#if TIMER_0_EN
|
#if TIMER_0_EN
|
||||||
case TIMER_0:
|
case TIMER_0:
|
||||||
return (((unsigned int)(0xffff & TIMER_0_DEV_0->CNT)) | (TIMER_0_DEV_1->CNT<<16));
|
/* do OR'ing two times and only use value if results are equal.
|
||||||
break;
|
* 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
|
#endif
|
||||||
#if TIMER_1_EN
|
#if TIMER_1_EN
|
||||||
case TIMER_1:
|
case TIMER_1:
|
||||||
return (((unsigned int)(0xffff & TIMER_1_DEV_0->CNT)) | (TIMER_1_DEV_1->CNT<<16));
|
/* see above about why loop is needed */
|
||||||
break;
|
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
|
#endif
|
||||||
case TIMER_UNDEFINED:
|
case TIMER_UNDEFINED:
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user