The issue is that I am resetting the application using the function NVIC_System_reset() function whenever Our device does not connect to the Cloud application through the Ethernet then after every 6 iterations I will get a Log saying that Reboot has happened due to the Watchdog reset and I verified it using SYS->RSTSTS register.
Note: The issue does not occur when I perform the WDT_RESET_COUNTER(); before doing NVIC_system_reset();
I have verified all of the registers related to the WDT peripheral as per the User Manual and No clue is found regarding the issue with the relation of multiple NVIC system reset() and Watchdod reboot after booting Up.
Platform : Mbed OS
Compiler: ARM C6
I am using the m487sidae microcontroller and below code is the Initializations of the Watchdog and the WDT_IrqHandler() functions.
void mbed_sdk_init(void)
{
static int inited = 0;
if (inited) {
return;
}
inited = 1;
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable HIRC clock (Internal RC 22.1184MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
/* Enable HXT clock (external XTAL 12MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
/* Enable LIRC for lp_ticker */
CLK_EnableXtalRC(CLK_PWRCTL_LIRCEN_Msk);
/* Enable LXT for RTC */
CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk);
/* Wait for HIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
/* Wait for HXT clock ready */
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
/* Wait for LIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_LIRCSTB_Msk);
/* Wait for LXT clock ready */
CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk);
/* Select HCLK clock source as HIRC and HCLK clock divider as 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
// CLK_EnableModuleClock(WDT_MODULE);
CLK_EnableModuleClock(I2C0_MODULE);
// CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
/* Set core clock as 192000000 from PLL */
CLK_SetCoreClock(192000000);
/* Set PCLK0/PCLK1 to HCLK/2 */
CLK->PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2);
#if DEVICE_ANALOGIN
/* Vref connect to internal */
SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_3_0V;
#endif
/* Set I2C0 multi-function pins */
SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA5MFP_Msk | SYS_GPA_MFPL_PA4MFP_Msk);
SYS->GPA_MFPL |= (SYS_GPA_MFPL_PA5MFP_I2C0_SCL | SYS_GPA_MFPL_PA4MFP_I2C0_SDA);
// I2C clock pin enable schmitt trigger
PA->SMTEN |= GPIO_SMTEN_SMTEN5_Msk;
SystemCoreClockUpdate();
GPIO_SetMode(PA,BIT9,GPIO_MODE_OUTPUT);
GPIO_SetMode(PA,BIT8,GPIO_MODE_OUTPUT);
GPIO_SetMode(PF,BIT7,GPIO_MODE_OUTPUT);
PA8 = 1;
PA9 = 1;
PF6 = 1;
//printf("\n\n hal init Setting WDT \n\n");
/* Lock protected registers */
SYS_LockReg();
/* Get around h/w issue with reset from power-down mode
*
* When UART interrupt enabled and WDT reset from power-down mode, in the next
* cycle, UART interrupt keeps breaking in and cannot block unless via NVIC. To
* get around it, we make up a signal of WDT wake-up from power-down mode in the
* start of boot process on detecting WDT reset.
*/
// printf("reset_status_register_is--->%8x\n\r",SYS->RSTSTS);
if (SYS_IS_WDT_RST()) {
/* Enable IP module clock */
CLK_EnableModuleClock(WDT_MODULE);
/* Select IP clock source */
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
/* The name of symbol WDT_IRQHandler() is mangled in C++ and cannot
* override that in startup file in C. Note the NVIC_SetVector call
* cannot be left out when WDT_IRQHandler() is redefined in C++ file.
*
* NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
*/
NVIC_EnableIRQ(WDT_IRQn);
NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
SYS_UnlockReg();
/* Configure/Enable WDT */
WDT->CTL = WDT_TIMEOUT_2POW4 | // Timeout interval of 2^4 LIRC clocks
WDT_CTL_WDTEN_Msk | // Enable watchdog timer
WDT_CTL_INTEN_Msk | // Enable interrupt
WDT_CTL_WKF_Msk | // Clear wake-up flag
WDT_CTL_WKEN_Msk | // Enable wake-up on timeout
WDT_CTL_IF_Msk | // Clear interrupt flag
WDT_CTL_RSTF_Msk | // Clear reset flag
!WDT_CTL_RSTEN_Msk | // Disable reset
WDT_CTL_RSTCNT_Msk; // Reset up counter
CLK_PowerDown();
/* Clear all flags & Disable WDT/INT/WK/RST */
WDT->CTL = (WDT_CTL_WKF_Msk | WDT_CTL_IF_Msk | WDT_CTL_RSTF_Msk | WDT_CTL_RSTCNT_Msk);
NVIC_DisableIRQ(WDT_IRQn);
SYS_LockReg();
}
SYS_UnlockReg();
NVIC_EnableIRQ(WDT_IRQn);
NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
SYS_UnlockReg();
I2C_Open(I2C0, 100000);
WDT_Open(WDT_TIMEOUT_2POW18, WDT_RESET_DELAY_1026CLK, TRUE, TRUE);
WDT_EnableInt();
}
WDT_IRQHandler function is below
void WDT_IRQHandler(void)
{
SYS_UnlockReg();
WDT_RESET_COUNTER_IN_CTL();
WDT_RESET_COUNTER();
/* Check WDT interrupt flag */
if (WDT_GET_TIMEOUT_INT_FLAG()) {
WDT_CLEAR_TIMEOUT_INT_FLAG();
}
/* Check WDT wake-up flag */
if (WDT_GET_TIMEOUT_WAKEUP_FLAG()) {
WDT_CLEAR_TIMEOUT_WAKEUP_FLAG();
}
}