drivers/watchdog: window-watchdog stm32: Fix timeout computing
Fix the timeout computation to provide more accurate timeouts versus requested timeout. Additionally, the error margin is reworked in order to: - be relative to the application requested timeout (10% tolerance) - exclude timeouts inferior to application request Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
parent
30634334a8
commit
1c9041c3aa
1 changed files with 13 additions and 9 deletions
|
@ -59,10 +59,10 @@ LOG_MODULE_REGISTER(wdt_wwdg_stm32);
|
|||
*/
|
||||
|
||||
#define ABS_DIFF_UINT(a, b) ((a) > (b) ? (a) - (b) : (b) - (a))
|
||||
#define WWDG_TIMEOUT_ERROR_MARGIN (100 * USEC_PER_MSEC)
|
||||
#define WWDG_TIMEOUT_ERROR_MARGIN(__TIMEOUT__) (__TIMEOUT__ / 10)
|
||||
#define IS_WWDG_TIMEOUT(__TIMEOUT_GOLDEN__, __TIMEOUT__) \
|
||||
(ABS_DIFF_UINT(__TIMEOUT_GOLDEN__, __TIMEOUT__) < \
|
||||
WWDG_TIMEOUT_ERROR_MARGIN)
|
||||
(__TIMEOUT__ - __TIMEOUT_GOLDEN__) < \
|
||||
WWDG_TIMEOUT_ERROR_MARGIN(__TIMEOUT_GOLDEN__)
|
||||
|
||||
static void wwdg_stm32_irq_config(const struct device *dev);
|
||||
|
||||
|
@ -116,7 +116,7 @@ static void wwdg_stm32_convert_timeout(const struct device *dev,
|
|||
{
|
||||
uint32_t clock_freq = wwdg_stm32_get_pclk(dev);
|
||||
uint8_t divider = 0U;
|
||||
uint8_t shift = 3U;
|
||||
uint8_t shift = 0U;
|
||||
|
||||
/* Convert timeout to seconds. */
|
||||
float timeout_s = (float)timeout / USEC_PER_SEC;
|
||||
|
@ -125,18 +125,19 @@ static void wwdg_stm32_convert_timeout(const struct device *dev,
|
|||
*prescaler = 0;
|
||||
*counter = 0;
|
||||
|
||||
for (divider = 8; divider >= 1; divider >>= 1) {
|
||||
wwdg_freq = ((float)clock_freq) / WWDG_INTERNAL_DIVIDER / divider;
|
||||
for (divider = 0; divider <= 3; divider++) {
|
||||
wwdg_freq = ((float)clock_freq) / WWDG_INTERNAL_DIVIDER / (1 << divider);
|
||||
/* +1 to ceil the result, which may lose from truncation */
|
||||
*counter = (uint32_t)(timeout_s * wwdg_freq + 1) - 1;
|
||||
*counter |= WWDG_RESET_LIMIT;
|
||||
*counter += WWDG_RESET_LIMIT;
|
||||
*prescaler = shift << 7;
|
||||
|
||||
if (*counter <= WWDG_COUNTER_MAX) {
|
||||
break;
|
||||
}
|
||||
|
||||
shift--;
|
||||
shift++;
|
||||
*counter = WWDG_COUNTER_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,8 +191,11 @@ static int wwdg_stm32_install_timeout(const struct device *dev,
|
|||
}
|
||||
|
||||
wwdg_stm32_convert_timeout(dev, timeout, &prescaler, &counter);
|
||||
|
||||
calculated_timeout = wwdg_stm32_get_timeout(dev, prescaler, counter);
|
||||
|
||||
LOG_DBG("Desired WDT: %d us", timeout);
|
||||
LOG_DBG("Set WDT: %d us", calculated_timeout);
|
||||
|
||||
if (!(IS_WWDG_PRESCALER(prescaler) && IS_WWDG_COUNTER(counter) &&
|
||||
IS_WWDG_TIMEOUT(timeout, calculated_timeout))) {
|
||||
/* One of the parameters provided is invalid */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue