1 2 3 Previous Next 30 Replies Latest reply on Jun 21, 2018 9:08 AM by e.pratt_1639216

    Stop after 5 times for(;;) loop

    andrewjoecollins100_2736831

      Hi All,

       

      I am using a Long Deep Sleep program for PSoC 4 BLE using this link's program: PSoC 4200M WDT Long Deep Sleep .

       

      I am wondering how to make the program stop after 5 blinks from the LED. For the for(;;) loop, I tried using:  for (count=1; count<=N1; count++), but this did not work.

       

      Does anyone know how to accomplish this?

       

      Thanks,

      Andrew Collins

        • 1. Re: Stop after 5 times for(;;) loop
          bob.marlowe

          Use a static or global variable which is tested in the interrupt handler for being >= 10.

          If not, toggle the led and increment the variable.

           

          void wdtCallback()
          {

          static uint8 Counter = 0;

               if(Counter >= 10) return;

               Counter++;
               RED_Write(~RED_Read());
          }

          Happy coding

          Bob

          1 of 1 people found this helpful
          • 2. Re: Stop after 5 times for(;;) loop
            andrewjoecollins100_2736831

            Hi Bob,

             

            That works. Now I want separate on time (0.5s) and off-time (1s) for the LED. I tried to do as below but the deep sleep does not work.

             

            void wdtCallback()

            {

                static uint8 Counter = 0;

                LED_Write(1);

                CyDelay(500);

                LED_Write(0);

                if(Counter >= 10) return;

                Counter++;

            }

            1 of 1 people found this helpful
            • 3. Re: Stop after 5 times for(;;) loop
              bob.marlowe

              As a general rule of thumb: NEVER use a delay in an interrupt handler. This can make the system non-responsive.

              Instead I would suggest you to set the WDT to 100ms and use that as a timebase. This will allow you to have a time resolution of 100ms.

               

              Bob

              1 of 1 people found this helpful
              • 4. Re: Stop after 5 times for(;;) loop
                andrewjoecollins100_2736831

                Bob

                 

                We want to use two WDTs for long delay. We have totally 3 WDTs in PSOC4 BLE. What if we want to use more WDTs for other delay requirements?

                1 of 1 people found this helpful
                • 5. Re: Stop after 5 times for(;;) loop
                  e.pratt_1639216

                  You will either want to change the watchdog timer count for each time period you measure dynamically, or have the two cascaded timers used for a larger period and use the third WDT for a smaller period with counts keeping track of timing for each timed operation individually.

                  Something akin to "systick" timer, but using the WDT period as the base "systick". This also allows timing while in deep sleep mode as well.

                  In my own project, to get more functionality, I ended up dedicating one timer to a large timed period (18h~) and the other two to individual 1ms and second/quarter-second timing individually. (Not fun to get setup and figure out, but works well considering the low-power, multiple timed operations, and no remote interaction requirements of the project.)

                  1 of 1 people found this helpful
                  • 6. Re: Stop after 5 times for(;;) loop
                    andrewjoecollins100_2736831

                    That's exactly what I want to do. Presently I'm cascading two WDTs. How do I use a single timer for 18hrs period? Could you point me to an example?

                     

                    Thanks,

                    Andrew Collins

                    1 of 1 people found this helpful
                    • 7. Re: Stop after 5 times for(;;) loop
                      e.pratt_1639216

                      The WDT2 has a longer period (maximum of 18h~) with resolution of doubles starting from ms up to hours.

                      The basic WDT examples should work: http://www.cypress.com/file/193966/download

                      Since the WDT2 uses a 32-bit timer, it behaves as a single WDT with double the count, but only allows resolution of a single bit for detecting periods/interrupts. The cascade will give better resolution, but the WDT2 is nice for using as a "long resolution" or approximate timer.

                      Let me know if you can't get it working

                      1 of 1 people found this helpful
                      • 8. Re: Stop after 5 times for(;;) loop
                        andrewjoecollins100_2736831

                        I ran the Project #2 from your link to wake the system from deep sleep. It works well for CY_SYS_WDT_COUNTER1 and CY_SYS_WDT_COUNTER0; but does not wake up for CY_SYS_WDT_COUNTER2. In all these cases SLEEP_INTERVAL_250MS is 250. Please let me know if I need to take care of something for COUNTER2 (32bit).

                        1 of 1 people found this helpful
                        • 9. Re: Stop after 5 times for(;;) loop
                          e.pratt_1639216

                          This is the initialization code I use to start the WDT2 interrupt:

                                  CySysWdtDisable(CY_SYS_WDT_COUNTER2_MASK);//enable wdt2 resetting system on 3rd failed interrupt

                                  CySysWdtWriteMode(CY_SYS_WDT_COUNTER2, CY_SYS_WDT_MODE_INT);//set wdtcounter2 to interrupt mode

                                  CySysWdtSetToggleBit(WDT2_COUNT);//set period/interval to 18H 12M 16S

                                  //(WDT2_COUNT is 31, which triggers an interrupt on bit 31 being set)

                                  //CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER2, 1u);//clear counter on match event

                                  CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER2_MASK);

                                  CySysWdtEnable(CY_SYS_WDT_COUNTER2_MASK);//enable wdt2 resetting system on 3rd failed interrupt

                                  CySysWdtEnableCounterIsr(CY_SYS_WDT_COUNTER2);//enable wdt2 ISR

                          And this is the code I put in the ISR when the interrupt for WDT fires:

                              if(WDT_IF & CY_SYS_WDT_COUNTER2_INT) {

                                  CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER2_INT);

                              }

                          1 of 1 people found this helpful
                          • 10. Re: Stop after 5 times for(;;) loop
                            andrewjoecollins100_2736831

                            Thank you for the code. It works very well. Now I want to stop the loop after 10 times execution

                             

                            Can I use the code previously mentioned by Bob? Where should I insert?

                             

                            static uint8 Counter = 0;

                                 if(Counter >= 10) return;

                                 Counter++;

                            1 of 1 people found this helpful
                            • 11. Re: Stop after 5 times for(;;) loop
                              e.pratt_1639216

                              You should be able to reuse it, yes. Just call the wdtCallback() function from the ISR when the WDT fires:

                              if(WDT_IF & CY_SYS_WDT_COUNTER2_INT) {

                                      CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER2_INT);

                                      wdtCallback(); //You can add other functions to call inside the ISR here for the WDT2 interrupt as well, but try to minimze code in ISRs to prevent timing issues.

                                  }

                              1 of 1 people found this helpful
                              • 12. Re: Stop after 5 times for(;;) loop
                                andrewjoecollins100_2736831

                                Thanks for your  suggestion. I will add the wdtCallback() function in the CY_ISR(isr_WDT) function.

                                 

                                The for (;;) loop has the LED_on, deepsleep and LED_off.

                                 

                                For 10 times execution should the WdtCallback function look like the following?

                                 

                                void wdtCallback()

                                {

                                    static uint8 Counter = 0;

                                     if(Counter >= 10) return;

                                     Counter++;

                                }

                                1 of 1 people found this helpful
                                • 13. Re: Stop after 5 times for(;;) loop
                                  e.pratt_1639216

                                  The code bob.marlowe posted will work fine. I didn't mention it as I figured you would go ahead and use it as he posted it.

                                  1 of 1 people found this helpful
                                  • 14. Re: Stop after 5 times for(;;) loop
                                    andrewjoecollins100_2736831

                                    I did that; but the loop is not breaking after 10 times.

                                     

                                    My code is below. Please let me know if I have placed the codes correctly. (I also need to fix deep sleep mode next).

                                     

                                    Thanks

                                     

                                     

                                    #include <project.h>

                                     

                                     

                                    /******************************************************************************

                                    * Macro definition

                                    * ----------------------------------------------------------------------------

                                    * These Macro are only used in this module for button pressing event

                                    * detection. These Macro should not be populated to other modules.

                                    ******************************************************************************/

                                    #define LED_ON                      (uint8)0x00

                                    #define LED_OFF                     (uint8)0x01

                                    #define SLEEP_INTERVAL_250MS        15                    /* millisecond */

                                    #define ILO_FREQ                    32000                       /* Hz */

                                    #define LOG_ROW_INDEX               (CY_FLASH_NUMBER_ROWS - 1)  /* last row */

                                    #define DoSomething(void)           CyDelay(500)                /* just delay 500ms */

                                     

                                     

                                    /******************************************************************************

                                    * Global variables definition

                                    * ----------------------------------------------------------------------------

                                    * These varialbes should be populated to other modules. Header file contain

                                    * the extern statement for these variables.

                                    ******************************************************************************/        

                                    void InitWatchdog(uint16 sleep_interval);

                                    CY_ISR(isr_WDT);

                                     

                                     

                                    void wdtCallback()

                                    {

                                        static uint8 Counter = 0;

                                         if(Counter >= 10) return;

                                         Counter++;

                                    }

                                     

                                     

                                    int main()

                                    {

                                        /*===========================================================================================

                                         * this code piece turns on Green LED for normally system working

                                         *==========================================================================================*/

                                        /* turn on Green LED to indicate system is powered up */

                                        LED_Green_Write(LED_ON);

                                        LED_Red_Write(LED_OFF);

                                        LED_Blue_Write(LED_OFF);   

                                        /* delay for a while to give enough time for Green LED display */

                                        CyDelay(100);

                                       

                                        /*===========================================================================================

                                         * this code piece initializes the watchdog function

                                         *==========================================================================================*/

                                        /* initialize watchdog */

                                        InitWatchdog(SLEEP_INTERVAL_250MS);

                                        /* connect ISR routine to Watchdog interrupt */

                                        ISR_WDT_StartEx(isr_WDT);

                                        /* set the highest priority to make ISR is executed in all condition */

                                        ISR_WDT_SetPriority(0);

                                            CySysClkEcoStart(24);

                                        /* enable global interrupt */

                                        CyGlobalIntEnable;

                                     

                                     

                                            /*==========================================================================================*/

                                        for(;;)

                                        {

                                            /* turn on Green LED to indicate system is in active mode */

                                            LED_Green_Write(LED_ON);

                                            LED_Red_Write(LED_OFF);

                                            LED_Blue_Write(LED_OFF);  

                                           

                                            /* clear watchdog counter before deep sleep */

                                            CySysWdtResetCounters(CY_SYS_WDT_COUNTER2_RESET);

                                            /* reset watchdog counter requires several LFCLK cycles to take effect */

                                        //    CyDelayUs(150);

                                            /* go to deep sleep mode */

                                                        CySysClkEcoStop();

                                            CySysPmDeepSleep();

                                           

                                            /* turn on Red LED after wakeup by Watchdog interrupt */

                                            LED_Green_Write(LED_OFF);

                                            LED_Blue_Write(LED_OFF);

                                            LED_Red_Write(LED_ON);       

                                           

                                            /* do something here after wakeup from deep sleep*/

                                            DoSomething(); 

                                        }

                                    }

                                     

                                     

                                    void InitWatchdog(uint16 sleep_interval)

                                    {

                                            CySysWdtDisable(CY_SYS_WDT_COUNTER2_MASK);//enable wdt2 resetting system on 3rd failed interrupt

                                            CySysWdtWriteMode(CY_SYS_WDT_COUNTER2, CY_SYS_WDT_MODE_INT);//set wdtcounter2 to interrupt mode

                                            CySysWdtSetToggleBit(sleep_interval);//set 31 sleep_interval for 18H 12M 16S

                                            CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER2_MASK);

                                            CySysWdtEnable(CY_SYS_WDT_COUNTER2_MASK);//enable wdt2 resetting system on 3rd failed interrupt

                                            CySysWdtEnableCounterIsr(CY_SYS_WDT_COUNTER2);//enable wdt2 ISR

                                    }

                                     

                                     

                                    CY_ISR(isr_WDT)

                                    {

                                        if(CY_SYS_WDT_COUNTER2_INT) {

                                            CySysWdtClearInterrupt(CY_SYS_WDT_COUNTER2_INT);

                                            wdtCallback();

                                        }

                                    }

                                    1 of 1 people found this helpful
                                    1 2 3 Previous Next