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.

cc2541 - Port 0 Interrupt does not work with Timer 3 interrupt

Other Parts Discussed in Thread: CC2541, CC2544

Hi,

I have integrated two projects (one for Power mode3 demo and another for Timer 3 demo of cc2541) provided by TI. I am using SmartRF05EB board for development.

Expected Output:

1. I want the CC2541 core to go to deep sleep using PM3. To achieve this, I am calling the Sleep function from Timer 3 ISR after few seconds. 

2. When CC2541 is in Deep sleep mode and I press the S1 button, It should wakeup.

Current Issue faced:

The CC2541 core goes to sleep. But, on pressing S1 button, it does not wakeup.

Port 0 Interrupt is not triggered when I integrate both projects (PM3 and Timer 3). However, both projects work successfully when compiled and run individually on SmartRF05EB kit.

I have pasted the code which is a single c file. Please go through the file and provide some inputs if I am missing something. If you need more information, do let me know.

Thanks in advance.

//----------------------------------------------------------------------------------------------------------------------------------------------

/***********************************************************************************
  Filename:     powermode3.c

  Description:  This software example shows how to properly enter Power Mode 3
                and then exit upon Port 0 Interrupt. The SRF05EB LED1 is cleared
                before entering Power Mode 3, and then set by the Port 0 ISR.
                Hence, the LED1 is ON in Active Mode and OFF in Power Mode 3.

  Note:         PM2 and PM3 is not supported on the CC2544.

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

/***********************************************************************************
* INCLUDES
*/
#include <power_mode.h>
#include <hal_types.h>
// Include Name definitions of individual bits and bit-fields in the CC254x device registers.
#include <ioCC254x_bitdef.h>
// Include device specific file
#if (chip==2541)
#include "ioCC2541.h"
#elif (chip==2543)
#include "ioCC2543.h"
#elif (chip==2545)
#include "ioCC2545.h"
#else
#error "Chip not supported!"
#endif


/***********************************************************************************
* CONSTANTS
*/
// Wait time in Active mode.
#define ACT_MODE_TIME  50000


/***********************************************************************************
* LOCAL VARIABLES
*/
// Variable for active mode duration.
//static uint32 __xdata activeModeCnt = 0;


/***********************************************************************************
* LOCAL FUNCTIONS
*/

/***********************************************************************************
* @fn          setup_port_interrupt
*
* @brief       Function which sets up the Port 0 Interrupt for Power Mode 3 usage.
*
* @param       void
*
* @return      void
*/
void setup_port_interrupt(void)
{
    // Clear Port 0 Interrupt flags.
    P0IF = 0;
    P0IFG = 0x00;

    // Interrupt enable on all pins on port 0.
    P0IEN = 0xFF;  

    // Enable CPU Interrupt for Port 0 (IEN1.P0IE = 1).
    P0IE = 1;

    // Enable Global Interrupt by setting the (IEN0.EA = 1).
    EA = 1;
}


/***********************************************************************************
* @fn          port0_isr
*
* @brief       Port 0 Interrupt Service Routine, which executes when SRF05EB S1
*              (P0_1) is pressed.
*
* @param       void
*
* @return      void
*/
#pragma vector = P0INT_VECTOR
__interrupt void port0_isr(void)
{
    // Note that the order in which the following flags are cleared is important.

    // Clear Port 0 Interrupt Flags.
    P0IFG = 0x00;

    // Clear CPU Interrupt Flag for P0 (IRCON.P0IF = 0).
    P0IF = 0;

    // Set LED1 to indicate Active Mode.
    P1_0 = 1;
}

/*******************************************************************************
* @fn      t3_isr
*
* @brief   Interrupt handler for Timer 3 overflow interrupts. Toggles LED1.
*          Interrupts from Timer 3 are level triggered, so the module
*          interrupt flag is cleared prior to the CPU interrupt flag.
*
* @param   void
*
* @return  void
*
*******************************************************************************/
uint32 cntx=0, cnty=0;
#pragma vector = T3_VECTOR
__interrupt void t3_isr(void)
{
    // Clears the module interrupt flag.
    T3OVFIF = 0;

    // Toggles LED1 on SmartRF05EB or CC2544Dongle.
#if (chip==2541 || chip==2543 || chip==2545)
    P1_1 ^= 1;  // Toggle SRF05EB LED1.
#elif (chip==2544)
    P0_2 ^= 1;  // Toggle GREEN LED1 on CC2544Dongle.
#endif

    if(cntx++ > 20)
    {
        cntx = 0;
        P1_0 = 0;                 // LED1 on.
        P1_1 = 0;                 // LED1 on.
        // Clears the CPU interrupt flag.
        T3IF = 0;
        EnterSleepModeProcessInterruptsOnWakeup();   
    }
    // Clears the CPU interrupt flag.
    T3IF = 0;
}

/***********************************************************************************
* @fn          main
*
* @brief       Enter Power Mode, exit Power Mode 3 using Port 0 Interrupt.
*
* @param       none
*
* @return      0
*/

void main(void)
{

    /***************************************************************************
     * Setup clock & frequency
     *
     * Configures the Timer tick speed setting, resulting in a Timer tick
     * frequency of 250 kHz.
     */
    CLKCONCMD = (CLKCONCMD & ~CLKCON_TICKSPD) | CLKCON_TICKSPD_250K;
 
 
    /***************************************************************************
     * Setup I/O
     *
     * Select P1_0 direction to output
     */
#if (chip==2541 || chip==2543 || chip==2545)
    // LED1 as GPIO.
    P1SEL &= ~BIT1;           
    // Set LED1 as output.
    P1DIR |= BIT1;
#elif (chip==2544)
    // LED1 (GREEN) as GPIO.
    P0SEL1 &= ~P0SEL1_SELP0_2;
    // Set LED1 (GREEN) as output.
    PDIR |= PDIR_DIRP0_2;
#endif

 
    /***************************************************************************
     * Setup interrupt
     *
     * Enables global interrupts (IEN0.EA = 1) and interrupts from Timer 3
     * (IEN1.T3IE = 1).
     */
    //EA = 1;
    T3IE = 1;
 
 
    /***************************************************************************
     * Timer 3 setup
     *
     * Timer 3 control (T3CTL) configuration:
     * - Prescaler divider value: 128.
     * - Free running mode.
     * - Overflow interrupt enabled.
     * The Timer is also cleared and started.
     */
    T3CTL = T3CTL_DIV_128 | T3CTL_MODE_FREERUN | T3CTL_OVFIM | T3CTL_CLR | T3CTL_START;

    /***************************************************************************
     * Setup I/O
     */
    // Initialize P1_0 for SRF05EB LED1.
    P1SEL &= ~BIT0;           // Function as General Purpose I/O.
    P1_0 = 1;                 // LED1 on.
    P1DIR |= BIT0;            // Output.

    // Initialize P0_1 for SRF05EB S1 button.
    P0SEL &= ~BIT1;           // Function as General Purpose I/O.
    P0DIR &= ~BIT1;           // Input.
    P0INP |= BIT1;            // 3-state input.


    /***************************************************************************
     * Setup interrupt
     *
     * Setup and enable Port 0 Interrupt, which shall wake-up the SoC from
     * Power Mode 3.
     */
    setup_port_interrupt();
   
   
    /***********************************************************************
     * Setup powermode
     */
    // Set [SLEEPCMD.MODE] to PM3.
    SLEEPCMD = (SLEEPCMD & ~SLEEPCMD_MODE) | SLEEPCMD_MODE_PM3;
   
    /* Main Loop, enter/exit Power Mode 3. */
    while(1)
    {
//        // Wait some time in Active Mode, and clear LED1 before
//        // entering Power Mode 3.
//        for(activeModeCnt = 0; activeModeCnt < ACT_MODE_TIME; activeModeCnt++);
//        P1_0 = 0;
//       
//        // Enter powermode
//        // Sets PCON.IDLE with a 2-byte boundary assembly instruction.
//        // NOTE: Cache must be enabled (see CM in FCTL).
//        // This method gives the least current consumption.
//        EnterSleepModeProcessInterruptsOnWakeup();
       
    }
}

 

  • Hi all,

    It looks as if the Sleep mode function does something that does not allow the Port ISR to wake it up. I came to this conclusion by commenting EnterSleepModeProcessInterruptsOnWakeup();  in Timer 3 ISR and just compiling and running it.

    When I pressed S1 button, the related LED was turned ON. This means the issue is not with interrupt initialization as I had thought. Both interrupts work together without issue. The issue is with Sleep mode PM3.

    Did anyone face a similar issue? Is there a resolution?

    Thanks,

    Anup