From a7b699b27e07460a852bc4202311bd278053dffb Mon Sep 17 00:00:00 2001 From: Yann GASCUEL <34003959+lnv42@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:24:58 +0100 Subject: [PATCH] fix infinity loop in SpinDelayUs() and SpinDelayUsPrecision() I don't know why : but AT91C_BASE_PWMC_CH0->PWMC_CCNTR value is never equal to 0, so if start+ticks was equal to 0, it was inifity looping. This fix may produce bit longer wait than expected in some case, depending on if AT91C_BASE_PWMC_CH0->PWMC_CCNTR delay between 0xFFFF and 0x0001 is just 1 step or 2... /!\ Figure out why AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never 0 and fix it there is probably a better way to fix this infinity loop issue /!\ --- armsrc/ticks.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 61089595c..3cf2c54dc 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -35,11 +35,14 @@ void SpinDelayUsPrecision(int us) { AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xFFFF; // Channel Period Register - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t end = AT91C_BASE_PWMC_CH0->PWMC_CCNTR + ticks; + if (end == 0) // AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never == 0 + end++; // so we have to end++ to avoid inivity loop for (;;) { uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now == (uint16_t)(start + ticks)) + + if (now == end) return; WDT_HIT(); @@ -59,13 +62,15 @@ void SpinDelayUs(int us) { AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t end = AT91C_BASE_PWMC_CH0->PWMC_CCNTR + ticks; + if (end == 0) // AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never == 0 + end++; // so we have to end++ to avoid inivity loop for (;;) { uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now == (uint16_t)(start + ticks)) - return; + if (now == end) + return; WDT_HIT(); } }