- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
i am struggling a bit with the watchdog on PSoC 4 and Cascading Watchdog. Here is my program:
I have following questions:
1. How long are the intervals from WDT_COUNT0_MATCH and WDT_COUNT1_MATCH respectively? How can i translate the hex values to milliseconds? How can i measure how long my program takes to see if the watchdog interval is long enough?
2. Do i need the cascade for my program? I just want to be sure my program never hangs up, since its in a sealed environment.
3. I tried with only one WDT counter an no cascade and resette the timer in the main while loop with CySysWdtResetCounters(CY_SYS_WDT_COUNTER0_MASK); but it didnt reset the wdt.
When i use the cascade construct, like in the code below and call CySysWdtResetCounters(CY_SYS_WDT_CASCADE_01); in the main loop it works, but i still have no idea how to measure the time my program needs for one run and how big to set the timers...
Please give me some advice on how to implement a simple proper WDT to detect program hang ups.
Thanks in advance,
Patrick
CODE:
/*******************************************************************************
* File Name: main.c
*
* Version: 1.0
*
* Description:
* BLE example project that works as a BLE to UART bridge, using
* Cypress's BLE component APIs and application layer callback.
* This project demostrates a custom service usage for BLE to UART
* bridge in a PERIPHERAL role.
*
* References:
* BLUETOOTH SPECIFICATION Version 4.1
*
* Hardware Dependency:
* (1) CY8CKIT-042 BLE
* (2) An external UART transciever (if flow control is needed)
*
********************************************************************************
* Copyright 2015, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "main.h"
/* WDT counter configuration */
#define WDT_COUNT0_MATCH (0x4FFFu)
#define WDT_COUNT1_MATCH (0x0008u) //0008u
/* Prototype of WDT ISR */
CY_ISR_PROTO(WdtIsrHandler);
uint8 proximityWasActive = 1;
uint16 ms_count = 0;
//Debouncing the CapSense
CY_ISR(MY_ISR) {
ms_count++;
if(ms_count == 500) { // 0.1 seconds
proximityWasActive = 1; //Reset proximity switch
ms_count = 0; // reset ms counter
}
}
int main()
{
#ifdef LOW_POWER_MODE
CYBLE_LP_MODE_T lpMode;
CYBLE_BLESS_STATE_T blessState;
#endif
CYBLE_API_RESULT_T bleApiResult;
/*######################
Start the Watchdog Timer
######################*/
/* Setup ISR for interrupts at WDT counter 0 events. */
WdtIsr_StartEx(WdtIsrHandler);
/* Enable global interrupts. */
CyGlobalIntEnable;
/* Set WDT counter 0 to generate interrupt on match */
CySysWdtWriteMode(CY_SYS_WDT_COUNTER0, CY_SYS_WDT_MODE_INT);
CySysWdtWriteMatch(CY_SYS_WDT_COUNTER0, WDT_COUNT0_MATCH);
CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER0, 1u);
/* Enable WDT counters 0 and 1 cascade */
CySysWdtWriteCascade(CY_SYS_WDT_CASCADE_01);
/* Set WDT counter 1 to generate reset on match */
CySysWdtWriteMatch(CY_SYS_WDT_COUNTER1, WDT_COUNT1_MATCH);
CySysWdtWriteMode(CY_SYS_WDT_COUNTER1, CY_SYS_WDT_MODE_RESET);
CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER1, 1u);
/* Enable WDT counters 0 and 1 */
CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK | CY_SYS_WDT_COUNTER1_MASK);
/* Lock WDT registers and try to disable WDT counters 0 and 1 */
CySysWdtLock();
CySysWdtDisable(CY_SYS_WDT_COUNTER1_MASK | CY_SYS_WDT_COUNTER0_MASK);
CySysWdtUnlock();
/*######################
Start CapSense Component
######################*/
/* 1. Enable Proximity sensor as it is disabled by default */
CapSense_1_EnableWidget(CapSense_1_PROXIMITYSENSOR0__PROX);
/* 2. Start CapSense block - Calibrates the proximity sensor for the set sensitivity setting (in the Scan Order tab of Component Configuration */
CapSense_1_Start();
/* 3. Initialize Proximity baseline */
CapSense_1_InitializeSensorBaseline(PROXIMITY_SENSOR_INDEX);
/* 4. Setup a timer to debounce the CapSense */
Timer_1_Start();
debounce_timer_isr_StartEx(MY_ISR);
/* Start UART and BLE component and display project information */
UART_Start();
bleApiResult = CyBle_Start(AppCallBack);
//Test the UART
UART_UartPutString("\n\r***************** UART TEST OK *****************\n\r");
if(bleApiResult == CYBLE_ERROR_OK)
{
#ifdef PRINT_MESSAGE_LOG
UART_UartPutString("\n\r************************************************************");
UART_UartPutString("\n\r***************** BLE UART example project *****************");
UART_UartPutString("\n\r************************************************************\n\r");
UART_UartPutString("\n\rDevice role \t: PERIPHERAL");
#ifdef LOW_POWER_MODE
UART_UartPutString("\n\rLow Power Mode \t: ENABLED");
#else
UART_UartPutString("\n\rLow Power Mode \t: DISABLED");
#endif
#ifdef FLOW_CONTROL
UART_UartPutString("\n\rFlow Control \t: ENABLED");
#else
UART_UartPutString("\n\rFlow Control \t: DISABLED");
#endif
#endif
}
else
{
#ifdef PRINT_MESSAGE_LOG
UART_UartPutString("\n\r\t\tCyBle stack initilization FAILED!!! \n\r ");
#endif
/* Enter infinite loop */
while(1);
}
CyBle_ProcessEvents();
/***************************************************************************
* Main polling loop
***************************************************************************/
while(1)
{
CySysWdtResetCounters(CY_SYS_WDT_CASCADE_01);
CyDelay(10);
#ifdef LOW_POWER_MODE
if((CyBle_GetState() != CYBLE_STATE_INITIALIZING) && (CyBle_GetState() != CYBLE_STATE_DISCONNECTED))
{
/* Enter DeepSleep mode between connection intervals */
lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);
CyGlobalIntDisable;
blessState = CyBle_GetBleSsState();
if(lpMode == CYBLE_BLESS_DEEPSLEEP)
{
if((blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) && \
(UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u)
{
#ifdef FLOW_CONTROL
EnableUartRxInt();
#endif
CySysPmSleep();
#ifdef FLOW_CONTROL
DisableUartRxInt();
#endif
}
}
else
{
if((blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) && \
(UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u)
{
#ifdef FLOW_CONTROL
EnableUartRxInt();
#endif
CySysPmSleep();
#ifdef FLOW_CONTROL
DisableUartRxInt();
#endif
}
}
CyGlobalIntEnable;
/* Handle advertising led blinking */
HandleLeds();
}
#else
//HandleLeds();
#endif
/*******************************************************************
* Process all pending BLE events in the stack
*******************************************************************/
//HandleBleProcessing();
//CyBle_ProcessEvents();
/*******************************************************************
* Handle the Cap Sense
*******************************************************************/
//HandleCapSense();
}
}
CY_ISR(WdtIsrHandler)
{
/* Clear interrupts state */
CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER0_INT);
WdtIsr_ClearPending();
}
/* [] END OF FILE */
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please do not supply code snippets here, they are just half of the story. There are a lot of settings, component versions etc that may cause a different behave. Even checking your sources without the help of the IDE takes more time and still something might be overlooked. Can you please post your complete project, so that we all can have a look at all of your settings? To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Excerpt from System Reference Guide
Clearing WDT
The LFCLK clock is asynchronous to the SYSCLK. So, generally, it takes 3 LFCLK cycles for the WDT registers changes to come into effect. This is important to remember that WDT should be cleared at least 4 cycles (3 + 1 for sure) before timeout occurs, especially when small match values / low toggle bit numbers are used. The WDT counters should be cleared by calling the CySysWdtResetCounters() function with the parameter corresponding to the counters whose values are going to be cleared.
It is recommended to clear WDT counters from the portion of the code that is not directly associated with the WDT interrupt. It is possible that the main function of the firmware has crashed or is in an endless loop, but that the WDT interrupt vector is still intact and the WDT is getting serviced properly.
Furthermore: The WDT settings have to be made in the clocks-view of .cydwr-file. WDT resets after 3 (three) counter expires and the WDT is fed from the LFCLK whichs frequency you have to set.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Do you get success in implementing cascade with two watchdog timers? If yes & then how you did it ?
Because I have tried it so many times but did not get success.