I'm using the CC1110 with SIMPLICITI 1.2.0. My main End Device function it's a simple loop that transmit the internal temperature over the radio and then enter PM2 for 5 minutes.
This is the main function:
void main() { /* Initialize Board */ BSP_Init(); /* Send Join request */ SMPL_Init(RxCB); while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) { SPIN_ABOUT_A_SECOND; /* calls nwk_pllBackgrounder for us */ } while (1) { /* If Packets arrived */ while(awake_flag) { if(sSemaphore) /* If there is packets... */ { sSemaphore = 0; SMPL_Receive( sLinkID1, rxmsg, &length ); processMessage(rxmsg, length); } } /* Send Sensor Data */ GetSensorData(SensorData); /*Transmit frame */ SMPL_Send(sLinkID1, SensorData, sizeof(SensorData)); /* Set sleep timer and enter PM2 according to datasheet */ BSP_SleepFor(PM2,1SECOND_RESOLUTION, Sleep_Time); } }
The SleepFor function is form the CC1110 Mini DK Software Example (swrc133)
void BSP_SleepFor(uint8_t mode, uint8_t res, uint16_t steps) { // Set radio to sleep SMPL_Ioctl(IOCTL_OBJ_RADIO,IOCTL_ACT_RADIO_SLEEP,0); IEN2 &= ~0x01; // Disable RF interrupt BSP_DISABLE_INTERRUPTS(); BSP_SET_MAIN_CLOCK_RC(); // Set main clock source to RC oscillator // Update Sleep timer WORCTL = 0x04 + (res&0x03); // Reset timer and set resolution, mask out the 2 LSB's. uint8_t temp = WORTIME0; // Wait one full 32kHz cycle to allow sleep timer to reset while( temp == WORTIME0); temp = WORTIME0; while( temp == WORTIME0); WOREVT1 = (steps>>8); // Set timer high byte WOREVT0 = (uint8_t)steps; // Set timer Low byte STIF = 0; // Clear Sleep Timer flag in IRCON WORIRQ = 0x10; // 0x12 Enable Interupts and clear module flag STIE = 1; // Enable Sleep Timer interrupt. BSP_ENABLE_INTERRUPTS(); bsp_PowerMode(mode); BSP_SET_MAIN_CLOCK_XOSC(); // Set main clock source to External oscillator // Wake up the radio and set it in Idle SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE,0); IEN2 |= 0x01; // Enable RF interrupt }
void bsp_PowerMode(uint8_t mode) { if (mode == POWER_MODE_2 || mode == POWER_MODE_3) { // NOTE! At this point, make sure all interrupts that will not be used to // wake from PM are disabled as described in chapter 13.1.3 of the datasheet. // Store current DMA channel 0 descriptor and abort any ongoing transfers if the channel is in use uint8_t storedDescHigh = DMA0CFGH; uint8_t storedDescLow = DMA0CFGL; uint8_t storedDmaArm = DMAARM; DMAARM |= 0x81; // Update descriptor with correct source if( mode == 2 ) { dmaDesc[0] = (uint8_t) ((uint16_t)&pm2Buf >> 8); dmaDesc[1] = (uint8_t) (uint16_t)&pm2Buf; } else { dmaDesc[0] = (uint8_t) ((uint16_t)&pm3Buf >> 8); dmaDesc[1] = (uint8_t) (uint16_t)&pm3Buf; } // Associate the descriptor with DMA channel 0 and arm the DMA channel DMA0CFGH = (uint16_t)&dmaDesc >> 8; DMA0CFGL = (uint16_t)&dmaDesc; DMAARM = 0x01; // Allign with positive 32 kHz clock edge as described in chapter 13.8.2 // in the datasheet. uint8_t temp = WORTIME0; while( temp == WORTIME0); // Make sure XOSC is powered down when entering PM2/3 and that cache of flash is disabled. MEMCTR |= 0x02; SLEEP = 0x04 | mode; // Enter power mode as described in chapter 13.1.3 in the datasheet. asm("NOP"); asm("NOP"); asm("NOP"); if( SLEEP & 0x03 ) { asm("MOV 0xD7,#0x01"); // DMAREQ = 0x01; asm("NOP"); // Needed to perfectly align the DMA transfer asm("ORL 0x87,#0x01"); // PCON |= 0x01; asm("NOP"); } MEMCTR &= ~0x02; // Update with original DMA descriptor and arm. DMA0CFGH = storedDescHigh; DMA0CFGL = storedDescLow; DMAARM = storedDmaArm; } else if ( mode == POWER_MODE_1 ) { uint8_t temp = WORTIME0; while( temp == WORTIME0); SLEEP |= mode; asm("NOP"); asm("NOP"); asm("NOP"); if ( SLEEP & 0x03 ) { PCON |= 0x01; asm("NOP"); } } else if ( mode == POWER_MODE_0 ) { PCON |= 0x01; asm("NOP"); } else { /* Not valid */ } }
My problem is that the function SleepFor() it's taking too long to enter in PM2 (around 1 second most of the times). I did some debugging and found that the delay is when aligning with the 32KHz clock edge ( while( temp == WORTIME0) ).
I also found that every time the CC1110 wakes up and receives a command (which is not every time it wakes up) there is no delay aligning with the 32KHz clock edge.
My question is: Is there any way to reduce the time aligning with the clock edge?
My application has very limited energy resources. So, 3mA absorption (Active mode current) per 1 second it's too much.
I hope someone can give me a solution.
Thanks,
Abel.