This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2538: Device resets after wakeup interrupt

Part Number: CC2538
Other Parts Discussed in Thread: Z-STACK

Tool/software:

Hello,

I am trying to configure some pins to wakeup the device. But when two of these three pins (BSP_KEY_1, BOARD_SWITCH_NC_PIN) are triggered, the watchdogs triggers sometimes, not always

Why is this happening? 

Below is the code of the hal_sys_ctrl.c file and their configurations

Filename:       hal_sys_ctrl.c

/**************************************************************************************************
 * @fn          SysCtrlWakeupSetting
 *
 * @brief       Setup which peripherals can/cannot wakeup the processor
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void SysCtrlWakeupSetting(void)
{ 
  /* GPIO A, C and SM Timer can wake up the processor */
  GPIOIntWakeupEnable(GPIO_IWE_PORT_A);
  GPIOIntWakeupEnable(GPIO_IWE_PORT_B);
  GPIOIntWakeupEnable(GPIO_IWE_PORT_C);
  GPIOIntWakeupEnable(GPIO_IWE_PORT_D);
  GPIOIntWakeupDisable(GPIO_IWE_USB);
  GPIOIntWakeupEnable(GPIO_IWE_SM_TIMER);
  
  /* Setup GPIO B as a falling edge  */
  GPIOPowIntTypeSet(BSP_KEY_BASE, BSP_KEY_1, GPIO_POW_FALLING_EDGE);
  GPIOPowIntTypeSet(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN, GPIO_POW_FALLING_EDGE);
  GPIOPowIntTypeSet(I2C_INT_BASE, I2C_GPIO_PIN, GPIO_POW_FALLING_EDGE);
}

/**************************************************************************************************
 * @fn          SysCtrlPowIntEnableSetting
 *
 * @brief       Enable power-up interrupt for the specified port, using 
 *              GPIO_PI_IEN register
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void SysCtrlPowIntEnableSetting(void)
{
  GPIOPowIntEnable(BSP_KEY_BASE, BSP_KEY_1);
  GPIOPowIntEnable(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN);
  GPIOPowIntEnable(I2C_INT_BASE, I2C_GPIO_PIN);
}

/**************************************************************************************************
 * @fn          SysCtrlPowIntDisableSetting
 *
 * @brief       Disable power-up interrupt for the specified port, using 
 *              GPIO_PI_IEN register
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void SysCtrlPowIntDisableSetting(void)
{
  GPIOPowIntDisable(BSP_KEY_BASE, BSP_KEY_1);
  GPIOPowIntDisable(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN);
  GPIOPowIntDisable(I2C_INT_BASE, I2C_GPIO_PIN);
}

/**************************************************************************************************
 * @fn          SysCtrlPowIntDisableSetting
 *
 * @brief       Clear the Power Interrupt registers
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void SysCtrlPowIntClear(void)
{
  GPIOPowIntClear(BSP_KEY_BASE, BSP_KEY_1);
  GPIOPowIntClear(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN);
  GPIOPowIntClear(I2C_INT_BASE, I2C_GPIO_PIN);
}

/**************************************************************************************************
 * @fn          SysCtrlClockStartupSetting
 *
 * @brief       Setup clock startup sequence
 *
 * input parameters
 *
 * @param       None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void SysCtrlClockStartSetting(void)
{
  /* Setup the clock startup sequence to 32 MHz external 
   * osc and 32k sourced from external oscillator
   */
  IOCPadConfigSet(GPIO_D_BASE, 0xC0, IOC_OVERRIDE_ANA);
  SysCtrlClockSet(OSC_32KHZ, false, SYS_CTRL_SYSDIV_32MHZ);
}

#define BSP_KEY_BASE            GPIO_B_BASE     //!< Common key Base
#define BSP_KEY_1               GPIO_PIN_3      //!< PB3 Common key 1

#define PUSH_BTN_1_PIN_INIT()                                     \
{                                                                 \
  /* Configure button  as input */                                \
  GPIOPinTypeGPIOInput(BSP_KEY_BASE, BSP_KEY_1);                  \
  IOCPadConfigSet(BSP_KEY_BASE, BSP_KEY_1, IOC_OVERRIDE_PUE);     \
}

#define PUSH_BTN_1_INITIALIZE_INTERRUPT(_cb)                      \
{                                                                 \
  GPIOPinIntClear(  BSP_KEY_BASE, BSP_KEY_1 );                    \
  GPIOPinIntEnable( BSP_KEY_BASE, BSP_KEY_1 );                    \
  ioPinIntRegister( BSP_KEY_BASE, BSP_KEY_1, _cb );               \
  GPIOIntTypeSet(   BSP_KEY_BASE, BSP_KEY_1, GPIO_FALLING_EDGE);  \
}

#define BOARD_SWITCH_NC_BASE            GPIO_A_BASE
#define BOARD_SWITCH_NC_PIN             GPIO_PIN_7

#define SWITCH_NC_PIN_INIT()                                     \
{                                                                 \
  GPIOPinTypeGPIOInput(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN);                  \
  IOCPadConfigSet(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN, IOC_OVERRIDE_PUE);     \
}

#define SWITCH_NC_PIN_INTERRUPT(_cb)\
{\
  GPIOPinIntClear( BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN );\
  GPIOPinIntEnable( BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN );\
  ioPinIntRegister( BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN, _cb );\
  GPIOIntTypeSet( BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN, GPIO_FALLING_EDGE );\
}

#define I2C_INT_BASE   GPIO_C_BASE
#define I2C_GPIO_PIN   GPIO_PIN_6

#define I2C_PIN_INIT()\
{ \
  GPIOPinTypeGPIOInput(I2C_INT_BASE, I2C_GPIO_PIN);\
    IOCPadConfigSet(I2C_INT_BASE, I2C_GPIO_PIN, IOC_OVERRIDE_PUE); \
}

#define I2C_INITIALIZE_INTERRUPT(_cb)                       \
{                                                                       \
  GPIOPinIntClear( I2C_INT_BASE, I2C_GPIO_PIN );                        \
    GPIOPinIntEnable( I2C_INT_BASE, I2C_GPIO_PIN );                       \
      ioPinIntRegister( I2C_INT_BASE, I2C_GPIO_PIN, _cb );                  \
        GPIOIntTypeSet(   I2C_INT_BASE, I2C_GPIO_PIN, GPIO_FALLING_EDGE);     \
           IntPrioritySet(INT_GPIOC, HAL_INT_PRIOR_KEY);\
}

  • Hello Panagiotis,

    Can you please provide more code, such as the callback and watchdog usage?  Also, what code resource are you using?  It is likely that GPIO interrupt examples already exist which you can use as a reference.  Based on your description it appears that the callback is being entered, but there may be a race condition involving clearing the watchdog in time or clearing the interrupt flag incorrectly.

    Regards,
    Ryan

  • Hello,

    Without setting the interrupts to wake up the device (removing the corresponding code in hal_sys_ctrl.c), I don't have any problems with the watchdog when the interrupts are triggered.

    I am using Zigbee 1.2.2a

    I clear the watchdog at the start of every event loop function. I tried clearing it after the device wakes up but it didn;t work


    Here is an example of a callback

    #define SWITCH_NC_PIN_CLEAR_INT() GPIOPinIntClear( BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN );
    
    void TamperSwitchNCISR(void)
    {
      SWITCH_NC_PIN_CLEAR_INT();
      GPIOPowIntClear(BOARD_SWITCH_NC_BASE, BOARD_SWITCH_NC_PIN);
      
    /* do stuff */
      
      CLEAR_SLEEP_MODE();
      
      return;
    }
    
    #define PUSH_BTN_1_CLEAR_ISR()  GPIOPinIntClear( BSP_KEY_BASE, BSP_KEY_1 ) 
    
    void HandleKey_1_ISR(void)
    {
      // Clear Interrupt status
      PUSH_BTN_1_CLEAR_ISR();
      GPIOPowIntClear(BSP_KEY_BASE, BSP_KEY_1);
    
    /* do stuff */
      
      CLEAR_SLEEP_MODE();
    
    }

  • You should not have to change anything in hal_sys_ctrl.c for the Zigbee HA 1.2.2a resource.  If you want a sleepy ZED then this configuration is made by choosing POWER_SAVING pre-definition as discussed in the Z-Stack Home Developer's User Guide. 

    Sleepy devices will not enter the event loop regularly and this could be causing the watchdog timer to expire.  You could set up a timer which is reliably calling the watchdog.  I also recommend you make your GPIO interrupts thread-safe and do as little as possible so that the application can continue to run as expected.

    I also recommend that you further debug in IAR to determine the exact cause of the device reset.

    Regards,
    Ryan