Problems and confusion with watchdog on PSoC 4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

 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 */

   
        
0 Likes
3 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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
 

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes

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.

0 Likes