/** * * Run a self-test on the timebase. This test verifies that the timebase is * incrementing. The watchdog timer is not tested due to the time required * to wait for the watchdog timer to expire. The time consumed by this test * is dependant on the system clock and the configuration of the dividers in * for the input clock of the timebase. * * @param InstancePtr is a pointer to the XWdtTb instance to be worked on. * * @return * - XST_SUCCESS if self-test was successful * - XST_WDTTB_TIMER_FAILED if the timebase is not incrementing * * @note None. * ******************************************************************************/ int XWdtTb_SelfTest(XWdtTb *InstancePtr) { int LoopCount; u32 TbrValue1; u32 TbrValue2; /* * Assert to ensure the inputs are valid and the instance has been * initialized */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the timebase register twice to start the test */ TbrValue1 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TBR_OFFSET); TbrValue2 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TBR_OFFSET); /* * Read the timebase register for a number of iterations or until it * increments, which ever occurs first */ for (LoopCount = 0; ((LoopCount <= XWT_MAX_SELFTEST_LOOP_COUNT) && (TbrValue2 == TbrValue1)); LoopCount++) { TbrValue2 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TBR_OFFSET); } /* * If the timebase register changed the test is successful, otherwise it * failed */ if (TbrValue2 != TbrValue1) { return XST_SUCCESS; } else { return XST_WDTTB_TIMER_FAILED; } }
/** * * Returns the current contents of the timebase. * * @param InstancePtr is a pointer to the XWdtTb instance to be worked on. * * @return The contents of the timebase. * * @note None. * ******************************************************************************/ u32 XWdtTb_GetTbValue(XWdtTb *InstancePtr) { u32 CurrentTBR; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Return the contents of the timebase register */ CurrentTBR = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TBR_OFFSET); return CurrentTBR; }
/** * * Disable the watchdog timer. * * It is the caller's responsibility to disconnect the interrupt handler * of the watchdog timer from the interrupt source, typically an interrupt * controller, and disable the interrupt in the interrupt controller. * * @param InstancePtr is a pointer to the XWdtTb instance to be worked on. * * @return * - XST_SUCCESS if the watchdog was stopped successfully * - XST_NO_FEATURE if the watchdog cannot be stopped * * @note * * The hardware configuration controls this functionality. If it is not * allowed by the hardware the failure will be returned and the timer * will continue without interruption. * ******************************************************************************/ int XWdtTb_Stop(XWdtTb *InstancePtr) { u32 ControlStatusRegister0; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Check if the disable of the watchdog timer is possible by writing a 0 * to TCSR1 to clear the 2nd enable. If the Enable does not clear in * TCSR0, the watchdog cannot be disabled. Return a NO_FEATURE to * indicate this. */ XWdtTb_WriteReg(InstancePtr->RegBaseAddress, XWT_TWCSR1_OFFSET, 0); /* * Read the contents of TCSR0 so that the writes to the register * that follow are not destructive to other bits and to check if * the second enable was set to zero */ ControlStatusRegister0 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET); /* * If the second enable was not set to zero, the feature is not * allowed in the hardware. Return with NO_FEATURE status */ if ((ControlStatusRegister0 & XWT_CSRX_EWDT2_MASK) != 0) { return XST_NO_FEATURE; } /* * Disable the watchdog timer by performing 2 writes, 1st to * TCSR0 to clear the enable 1 and then to TCSR1 to clear the 2nd enable */ XWdtTb_WriteReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET, (ControlStatusRegister0 & ~XWT_CSR0_EWDT1_MASK)); XWdtTb_WriteReg(InstancePtr->RegBaseAddress, XWT_TWCSR1_OFFSET, 0); InstancePtr->IsStarted = 0; return XST_SUCCESS; }
/** * * Check if the watchdog timer has expired. This function is used for polled * mode and it is also used to check if the last reset was caused by the * watchdog timer. * * @param InstancePtr is a pointer to the XWdtTb instance to be worked on. * * @return TRUE if the watchdog has expired, and FALSE otherwise. * * @note None. * ******************************************************************************/ int XWdtTb_IsWdtExpired(XWdtTb *InstancePtr) { u32 ControlStatusRegister0; u32 Mask; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the current contents */ ControlStatusRegister0 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET); /* * The watchdog has expired if either of the bits are set */ Mask = XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK; return ((ControlStatusRegister0 & Mask) != 0); }
/** * * Restart the watchdog timer. An application needs to call this function * periodically to keep the timer from asserting the reset output. * * @param InstancePtr is a pointer to the XWdtTb instance to be worked on. * * @return None. * * @note None. * ******************************************************************************/ void XWdtTb_RestartWdt(XWdtTb *InstancePtr) { u32 ControlStatusRegister0; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the current contents of TCSR0 so that subsequent writes won't * destroy any other bits */ ControlStatusRegister0 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET); /* * Clear the bit that indicates the reason for the last * system reset, WRS and the WDS bit, if set, by writing * 1's to TCSR0 */ ControlStatusRegister0 |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); XWdtTb_WriteReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET, ControlStatusRegister0); }
/** * * Start the watchdog timer of the device. * * @param InstancePtr is a pointer to the XWdtTb instance to be worked on. * * @return None. * * @note The Timebase is reset to 0 when the Watchdog Timer is started. * The Timebase is always incrementing * ******************************************************************************/ void XWdtTb_Start(XWdtTb *InstancePtr) { u32 ControlStatusRegister0; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the current contents of TCSR0 so that subsequent writes to the * register won't destroy any other bits */ ControlStatusRegister0 = XWdtTb_ReadReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET); /* * Clear the bit that indicates the reason for the last * system reset, WRS and the WDS bit, if set, by writing * 1's to TCSR0 */ ControlStatusRegister0 |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); /* * Indicate that the device is started before we enable it */ InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED; /* * Set the registers to enable the watchdog timer, both enable bits * in TCSR0 and TCSR1 need to be set to enable it */ XWdtTb_WriteReg(InstancePtr->RegBaseAddress, XWT_TWCSR0_OFFSET, (ControlStatusRegister0 | XWT_CSR0_EWDT1_MASK)); XWdtTb_WriteReg(InstancePtr->RegBaseAddress, XWT_TWCSR1_OFFSET, XWT_CSRX_EWDT2_MASK); }
/** * This function tests the functioning of the TimeBase WatchDog Timer module * in the polled mode. * * After one expiration of the WDT timeout interval, the WDT state bit is set to * one in the status register. If the state bit is not cleared (by writing a 1 to * the state bit) before the next expiration of the timeout interval, a WDT reset * is generated. * * This function checks for Watchdog timer reset condition in two timer expiry * state. * * This function may require some time (seconds or even minutes) to execute * because it waits for the watchdog timer to expire. * * @param DeviceId is the XPAR_<WDTB_instance>_DEVICE_ID value from * xparameters.h. * * @return XST_SUCCESS if WRS bit is not set in next two subsequent timer * expiry state, otherwise XST_FAILURE. * * @note None. * ****************************************************************************/ int WdtTbExample(u16 DeviceId) { int Status; int Count = 0; /* * Initialize the watchdog timer and timebase driver so that * it is ready to use. */ Status = XWdtTb_Initialize(&WatchdogTimebase, DeviceId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built correctly. */ Status = XWdtTb_SelfTest(&WatchdogTimebase); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the watchdog timer, the timebase is automatically reset * when this occurs. */ XWdtTb_Start(&WatchdogTimebase); /* * Verify Whether the WatchDog Reset Status has been set in the next two * expiry state. */ while (1) { /* * If the watchdog timer expired, then restart it. */ if (XWdtTb_IsWdtExpired(&WatchdogTimebase)) { /* * Restart the watchdog timer as a normal application * would */ XWdtTb_RestartWdt(&WatchdogTimebase); Count++; } /* * Check whether the WatchDog Reset Status has been set. * If this is set means then the test has failed */ if (XWdtTb_ReadReg(WatchdogTimebase.RegBaseAddress, XWT_TWCSR0_OFFSET) & XWT_CSR0_WRS_MASK) { /* * Stop the watchdog timer */ XWdtTb_Stop(&WatchdogTimebase); return XST_FAILURE; } /* * Check whether the WatchDog timer expires two times. * If the timer expires two times then the test is passed. */ if(Count == 2) { break; } } return XST_SUCCESS; }