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();
}
}