Other Parts Discussed in Thread: CC2530EM
Sir,
I try using timer 2 start/stop synchronization function in power save mode 2. (the hardware is cc2530EM board)
when cpu wake up from sleep mode, I read T2M0, T2M1, T2MOVF0, T2MOVF1, and T2MOVF2 after start timer 2.
The read number always smaller than expected value.
Please help me find why.
Regards,
David Zhang
follow is my code:
/** Test Sleep timer **/
#include <iocc2530.h>
#include "PowerMode.h"
/* --------------------------------------------
* Common
*---------------------------------------------
*/
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed long int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
#ifndef BV
#define BV(n) (1 << (n))
#endif
#define XOSC_STB BV(6)
#define OSC_PD BV(2)
#define OSC_32KHZ 0x00 /* external 32 KHz xosc */
int8_t CurrentST2; //current sleep time register 2 value
int8_t CurrentST1; //current sleep time register 1 value
int8_t CurrentST0; //current sleep time register 0 value
int8_t SyncST2; //value for synchronous car RX and road TX, for ST2
int8_t SyncST1; //value for synchronous car RX and road TX, for ST1
int8_t SyncST0; //value for synchronous car RX and road TX, for ST0
uint16_t j=0;
uint8_t t2m0[20]; //record timer 2 value
uint8_t t2m1[20];
uint8_t t2mov0[20];
uint8_t t2mov1[20];
uint8_t t2mov2[20];
uint8_t temp0;
uint8_t temp1;
uint8_t temp2;
uint8_t temp3;
uint8_t temp4;
uint8_t temp5;
/* one tick of 32.768KHz = 1/32768 = 0.000030517578
300ms ticks is 0.3/0.000030517578 = 9830.4, take 9830(DEG), or 2666(HEX)
*/
#define CONSTANT300MSST2 0x00;
#define CONSTANT300MSST1 0x26;
#define CONSTANT300MSST0 0x66;
/* one tick of 32.768KHz = 1/32768 = 0.000030517578
1s ticks is 32768(DEG), or 8000(HEX)
*/
#define CONSTANT1SST2 0x0;
#define CONSTANT1SST1 0x80;
#define CONSTANT1SST0 0x0;
/*
2s ticks is 2*32768 = 65536(DEG), or 10000(HEX)
*/
#define CONSTANT2SST2 0x1;
#define CONSTANT2SST1 0x0;
#define CONSTANT2SST0 0x0;
/*
16s ticks is 16*32768 = 524288(DEG), or 80000(HEX)
*/
#define CONSTANT16SST2 8;
#define CONSTANT16SST1 0;
#define CONSTANT16SST0 0;
int main( void )
{
uint16_t i;
STIE = 0;
/*-----------------------------------------
* initial record memory
*------------------------------------------
*/
for (j=0; j <20; j++)
{
t2m0[j] = 0; //clear record timer 2 value
t2m1[j] = 0;
t2mov0[j] = 0;
t2mov1[j] = 0;
t2mov2[j] = 0;
}
j = 0;
/* ------------------------------------------------------------------
* Configure clock to use XOSC
* -----------------------------
*/
SLEEPCMD &= ~OSC_PD; /* turn on 16MHz RC and 32MHz XOSC */
while (!(SLEEPSTA & XOSC_STB)); /* wait for 32MHz XOSC stable */
asm("NOP"); /* chip bug workaround */
{
uint16_t i;
/* Require 63us delay for all revs */
for (i=0; i<504; i++)
{
asm("NOP");
}
}
CLKCONCMD &= 0x00; /* 32MHz XOSC */
while (CLKCONSTA != (0x00 | OSC_32KHZ));
SLEEPCMD |= OSC_PD; /* turn off 16MHz RC */
/* ----------------------------------------------------------------
* Set I/O
* -----------------------------------------------------------------
*/
P1DIR |= 0x02;
P1_1 = 0;
/*----------------------------------------------------------------
* Set Timer 2
*-----------------------------------------------------------------
*/
T2CTRL &= ~0x01; //stop timer 2, enter IDLE mode
T2MSEL = 0x88; //Select T2tim and T2ovf
T2M0 = 0; // initial Timer 2 16-bit timer count
T2M1 = 0;
T2MOVF0 = 0; // initial Timer 2 overflow registers
T2MOVF1 = 0;
T2MOVF2 = 0;
T2CTRL &= ~0x02; //Starting timer immediately
T2CTRL |= 0x01; //Run timer 2
T2CTRL |= 0x02; //Starting and stopping of timer happens at the
//first positive edge of the 32khz clock
/* -----------------------------------------------------------------
* Set sleep timer
* ------------------------------------------------------------------
*/
STIE = 0;
STIF = 0;
SLEEPCMD=(SLEEPCMD &~0x02)|0x02;
// Enable sleep timer interrupt
STIF = 0;
STIE = 1;
EA = 1;
CurrentST0 = X_ST0;
CurrentST1 = X_ST1;
CurrentST2 = X_ST2;
/* Set sleep timer compare value */
while (STLOAD == 0);
X_ST2 = CurrentST2 + CONSTANT2SST2;
X_ST1 = CurrentST1 + CONSTANT2SST1;
X_ST0 = CurrentST0 + CONSTANT2SST0;
STIF = 0;
while (1)
{
// SLEEPCMD=(SLEEPCMD &~0x02)|0x02;
// EnterSleepModeProcessInterruptsOnWakeup();
// EnterSleepModeDisableInterruptsOnWakeup();
T2CTRL &= ~0x01 ;//stop timer 2 when 32khz clock rising edge sampled as 1
while (!(SLEEPSTA & 0x01))
asm("NOP");
while ((SLEEPSTA & 0x01)) //wait 32KHz clock rise edge
asm("NOP");
PCON = 1; // enter sleep model
// EnterSleepModeProcessInterruptsOnWakeup();
asm("NOP"); //need two "nop" for interrupt back
asm("NOP"); //
CurrentST0 = X_ST0;
CurrentST1 = X_ST1;
CurrentST2 = X_ST2;
/* Set sleep timer compare value */
while (STLOAD == 0);
X_ST2 = CurrentST2 + CONSTANT2SST2;
X_ST1 = CurrentST1 + CONSTANT2SST1;
X_ST0 = CurrentST0 + CONSTANT2SST0;
STIF = 0;
asm("NOP");
/*------------ wait 0.3ms for 32 MHz osc stable -----------*/
for (i=0; i<320; i++)
{
asm("NOP");
}
T2CTRL |= 0x01; // start timer 2
while (!(SLEEPSTA & 0x01)) //wait 32KHz clock signal low
asm("NOP");
while((SLEEPSTA & 0x01)) //wait sleep timer rise edge
asm("NOP");
// for (i=0; i<10; i++)
for (i=0; i<50; i++)
{
asm("NOP");
}
T2CTRL |= 0x08; // set LATCH_MODE
temp0 = T2M0; //record timer 2 value
temp1 = T2M1;
temp2 = T2MOVF0;
temp3 = T2MOVF1;
temp4 = T2MOVF2;
T2CTRL &= ~0x08; // clear LATCH_MODE
t2m0[j] = temp0; //record timer 2 value
t2m1[j] = temp1;
t2mov0[j] = temp2;
t2mov1[j] = temp3;
t2mov2[j] = temp4;
j++;
for (i=0; i<10; i++)
{
asm("NOP");
}
P1_1 ^=1;
}
}
#pragma vector = ST_VECTOR
static __interrupt void Sleeptimer_ISR(void)
{
uint16_t i;
for (i=0; i<5; i++)
{
asm("NOP");
}
STIF = 0; //clear sleep timer interrupt flag
}
Thanks