Watchdog: Set wdt behaviour correctly#1705
Watchdog: Set wdt behaviour correctly#1705Riksu9000 wants to merge 1 commit intoInfiniTimeOrg:mainfrom Riksu9000:fix-wdt
Conversation
The first removed line shifts a mask, but the mask itself is shifted, so the shift is applied twice. The shift is zero, so effectively this sets the first bit to zero. The second line creates a mask with halt run parameter at sleep position, which is clearly wrong. It sets the first bit to one, making the first line redundant. The third line shifts a mask again, like the first line. This sets the seventh bit to one, which is undefined and probably (hopefully) does nothing. The fourth line does a logical or with HALT_Pause, but HALT_Pause is zero, so it does nothing. Effectively none of the lines are correct. Use NRF hal to explicitly set the behaviour to what it is when the first bit is set.
|
Build size and comparison to main:
|
|
Let's try to understand what's happening there. Here's the code in question: NRF_WDT->CONFIG &= ~(WDT_CONFIG_SLEEP_Msk << WDT_CONFIG_SLEEP_Pos);
NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Run << WDT_CONFIG_SLEEP_Pos);
NRF_WDT->CONFIG &= ~(WDT_CONFIG_HALT_Msk << WDT_CONFIG_HALT_Pos);
NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos);And the definition of the variable from /* Register: WDT_CONFIG */
/* Description: Configuration register */
/* Bit 3 : Configure the watchdog to either be paused, or kept running, while the CPU is halted by the debugger */
#define WDT_CONFIG_HALT_Pos (3UL) /*!< Position of HALT field. */
#define WDT_CONFIG_HALT_Msk (0x1UL << WDT_CONFIG_HALT_Pos) /*!< Bit mask of HALT field. */
#define WDT_CONFIG_HALT_Pause (0UL) /*!< Pause watchdog while the CPU is halted by the debugger */
#define WDT_CONFIG_HALT_Run (1UL) /*!< Keep the watchdog running while the CPU is halted by the debugger */
/* Bit 0 : Configure the watchdog to either be paused, or kept running, while the CPU is sleeping */
#define WDT_CONFIG_SLEEP_Pos (0UL) /*!< Position of SLEEP field. */
#define WDT_CONFIG_SLEEP_Msk (0x1UL << WDT_CONFIG_SLEEP_Pos) /*!< Bit mask of SLEEP field. */
#define WDT_CONFIG_SLEEP_Pause (0UL) /*!< Pause watchdog while the CPU is sleeping */
#define WDT_CONFIG_SLEEP_Run (1UL) /*!< Keep the watchdog running while the CPU is sleeping */I was a bit confused at first, but I think you're right : the code does not exactly what we expect it to do: equals And equals The shift is indeed applied twice. The end result is the correct one : we want to keep the watchdog running while the CPU sleep but not when the CPU is halted by the debugger (NRF52832 reference manual v1.1 p412): However, the way to get that result is mostly bad. Now, I'm afraid I don't agree with the proposed changes :
To fix this issue, I would rather fix the current implementation of the driver instead of replacing it with another driver. I would also take the opportunity to improve the implementation of documentation of the driver to make improve the readability of the code. I'm willing to work on this :) Why do I want to avoid using drivers from the NRF SDK? This is a personal choice I made early in the development of InfiniTime. However, they contain a lot of code we don't use (because we don't need all the functionalities of the chip) which makes the understanding of the code and debugging of the application a bit more tedious. They also heavily rely on concatenated It would have probably been possible to use those drivers anyway, but I eventually decided that it was easier to implement those driver from scratch, using the reference manual of the NRF52832. This made the fine tuning of the implementation for our use-case (memory usage, low power mode,...) a lot easier. As I said, this is a personal choice. Using the NRF drivers would have probably been possible, but I preferred the other option. And I currently see no reason to re-implement all our drivers using the NRF drivers right now. |
|
Closing in favor of #1710 |

The first removed line shifts a mask, but the mask itself is shifted, so
the shift is applied twice. The shift is zero, so effectively this sets
the first bit to zero.
The second line creates a mask with halt run parameter at sleep
position, which is clearly wrong. It sets the first bit to one, making
the first line redundant.
The third line shifts a mask again, like the first line. This sets the
seventh bit to one, which is undefined and probably (hopefully) does
nothing.
The fourth line does a logical or with HALT_Pause, but HALT_Pause is
zero, so it does nothing.
Effectively none of the lines are correct.
Use NRF hal to explicitly set the behaviour to what it is when the first
bit is set.