Other Parts Discussed in Thread: CC1350
Tool/software: TI-RTOS
Hi everybody,
we have a big trouble on our system, we've developed on LAUNCHXL-CC1350.
We're using Power_enablePolicy(), but we never get consumption smaller than 1.6mA.
It seems that CC1350 never goes to idle or smaller power modes.
Here a release of our firmware in which we have cleaned all specific functions of our sensor, but it still consumes 1.6mA.
#include <stdlib.h> /* atoi */
#include <string.h> /* memcpy */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Task.h>
#include <xdc/runtime/Error.h>
#include <inc/hw_ccfg.h>
#include <inc/hw_ccfg_simple_struct.h>
#include "at/AtProcess.h"
#include "at/AtControl.h"
#include "at/platform/inc/AtTerm.h"
#include "at/platform/tirtos/DbgPrint.h"
#include "at/AtParams.h"
#include "easylink/EasyLink.h"
#include "Board.h"
#include <ti/drivers/PIN.h>
#include <ti/drivers/SPI.h>
#include <ti/drivers/UART.h>
#include <driverlib/sys_ctrl.h>
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/PIN.h>
#include <driverlib/trng.h>
#include "seb/SEB.h"
#define NODE_TASK_STACK_SIZE 1024
#define NODE_TASK_PRIORITY 3
#define NODE_EVENT_ALL 0xFFFFFFFF
#define NODE_EVENT_NEW_BLE_MSG (uint32_t)(1 << 0)
#define RADIO_EVENT_ALL 0xFFFFFFFF
#define RADIO_EVENT_SEND_ADC_DATA (uint32_t)(1 << 0)
#define RADIO_EVENT_DATA_ACK_RECEIVED (uint32_t)(1 << 1)
#define RADIO_EVENT_ACK_TIMEOUT (uint32_t)(1 << 2)
#define RADIO_EVENT_SEND_FAIL (uint32_t)(1 << 3)
#define NODERADIO_MAX_RETRIES 2
#define NORERADIO_ACK_TIMEOUT_TIME_MS (160)
#define NODE_0M_TXPOWER -10
static Clock_Params clkParams;
static Clock_Struct clk0Struct;
typedef enum
{
RxStatus_Stop = 0,
RxStatus_Wait = 1,
RxStatus_Success = 2,
RxStatus_Timeout = 3
} RxStatusn;
typedef enum
{
Err_PinOpen = 1,
Err_PinCb = 2,
Err_FlashInfo = 3,
Err_FlashRead = 4,
Err_FlashWrite = 5,
Err_NoHMC5993 = 6,
Err_HMCSetup = 7,
Err_Radio = 8,
Err_UART = 9,
Err_Checkdata = 10,
Err_Generic = 11
} BigErrors;
typedef enum
{
SPI_Closed = 0,
SPI_HMC5993 = 1,
SPI_Flash = 2
} SPI_port;
/****************************
* defines di programma *
****************************/
#define OK 0
#define ERRORE 1
#define BIT7 0x80
#define BIT6 0x40
#define BIT5 0x20
#define BIT4 0x10
#define BIT3 0x08
#define BIT2 0x04
#define BIT1 0x02
#define BIT0 0x01
#define SRETRY_EMB 10
/************************
* Semaphores variables *
************************/
static Semaphore_Handle sema1;
static Semaphore_Params semParams;
static Semaphore_Struct sem1Struct;
static SPI_Params spiparams;
static SPI_Handle spihandle;
static SPI_Transaction spiTransaction;
static int SPI_Port;
static Char txbuf[256];
static Char rxbuf[256];
/****************
* Uart RS232 *
****************/
static UART_Params uartParams;
static UART_Handle uart;
EasyLink_TxPacket txPacket;
static int RxStatus;
static uint8_t BLE_request = 0;
/************************************************
* Application LED pin configuration table: *
************************************************/
PIN_Handle pinHandle;
PIN_State pinState;
PIN_Config pinTable[] = {
Board_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_RLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_DIO1_RFSW | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_DIO30_SWPWR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
PIN_State buttonPinState;
PIN_Handle buttonPinHandle;
PIN_Config buttonPinTable[] = {
Board_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
Board_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
PIN_TERMINATE
};
/***** Defines *****/
#define SensorTaskStackSize 2048
#define SensorTaskStackSize1 2048
#define SensorTaskPriority 2
static Task_Params SensorTaskParams;
Task_Struct SensorpTask;
static uint8_t SensorTaskStack[SensorTaskStackSize];
static Task_Params SensorTaskParams1;
Task_Struct SensorpTask1;
static uint8_t SensorTaskStack1[SensorTaskStackSize1];
typedef struct Sensor_configuration
{
uint32_t NumStallo;
uint32_t gwd;
uint32_t DataCal;
uint32_t SogliaLo;
uint32_t SogliaHi;
uint32_t Nresets;
short sdv[3];
uint8_t Gain;
} Sensor_configuration;
static Sensor_configuration CNF;
static short Status = 0;
static short C_retry;
static short C_kalive;
static short C_misura;
static short Retries;
static short S_retry;
static bool ret;
static uint8_t TxBuffer[40];
#define Wait 0
static uint16_t nodeAddress16;
/* proprietary advertisement packet */
static uint8_t localNameAdvertisement[] = {
0x02, //Length of this Data section
0x01, //<<Flags>>
0x02, //LE General Discoverable Mode
0x11, //Length of this Data section (era 0x18)
0x09, //<<Complete local name>>
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'O', '1',
'2', '3', '4', '5', '6'
};
/* proprietary advertisement packet */
static uint8_t propAdvertisement[] = {
0x02, //Length of this section
0x01, //<<Flags>>
0x02, //LE General Discoverable Mode
0x06, //Length of this section
0xff, //<<Manufacturer Specific Data>>
0x0d,
0x00,
0x03,
0x00,
0x00}; //BTN state
SimpleBeacon_Frame propAdvFrame;
SimpleBeacon_Frame localNameAdvFrame;
static uint8_t bleMacAddr[6];
/***** Prototypes *****/
static void sendBleAdvertisement();
#define EDELAY 20000
static void ShowError(int n)
{
int x;
if (n == 0) n=1;
while (1) {
PIN_setOutputValue(pinHandle, Board_GLED,true);
Task_sleep(EDELAY);
for (x=0; x<n; x++) {
PIN_setOutputValue(pinHandle, Board_RLED,true);
Task_sleep(EDELAY);
PIN_setOutputValue(pinHandle, Board_RLED,false);
Task_sleep(EDELAY);
}
PIN_setOutputValue(pinHandle, Board_GLED,false);
Task_sleep(EDELAY*6);
}
}
int SPI_to_Flash(void)
{
if (SPI_Port != SPI_Flash) {
if (SPI_Port == SPI_HMC5993) {
SPI_close(spihandle);
SPI_Port = SPI_Closed;
}
spihandle = SPI_open(Board_SPI1, &spiparams);
if (!spihandle) return ERRORE;
SPI_Port = SPI_Flash;
}
return OK;
}
int SPI_to_Sensor(void)
{
if (SPI_Port != SPI_HMC5993) {
if (SPI_Port == SPI_Flash) {
SPI_close(spihandle);
SPI_Port = SPI_Closed;
}
spihandle = SPI_open(Board_SPI0, &spiparams);
if (!spihandle) return ERRORE;
SPI_Port = SPI_HMC5993;
}
return OK;
}
int FlashInfotest(void)
{
if (SPI_to_Flash() != OK) return ERRORE;
Task_sleep(100);
txbuf[0] = 0x9f; //get Identification
txbuf[1] = 0;
txbuf[2] = 0;
txbuf[3] = 0;
spiTransaction.count = 4; //1 byte TX, 3 byte RX
spiTransaction.txBuf = &txbuf;
spiTransaction.rxBuf = &rxbuf;
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
if ((rxbuf[1]!=0xC2)||(rxbuf[2]!=0x28)||(rxbuf[3]!=0x14)) return ERRORE;
return OK;
}
int LeggiConfigurazione(void)
{
int x;
uint8_t CRC;
bool FlashOK = false;
if (SPI_to_Flash() != OK) return ERRORE;
Task_sleep(100);
txbuf[0] = 0x03; //read
txbuf[1] = 0x00; //addr msb
txbuf[2] = 0x00; //addr
txbuf[3] = 0x00; //addr lsb (24 bit)
spiTransaction.count = 4+4+sizeof(CNF);
Task_sleep(1000);
ret = SPI_transfer(spihandle, &spiTransaction);
if (ret) {
if ((rxbuf[4]==0x12)&&(rxbuf[5]==0x34)&&(rxbuf[6]==sizeof(CNF))) {
CRC=0;
for (x=0;x<sizeof(CNF);x++) CRC^= rxbuf[8+x];
if (CRC == rxbuf[7]) FlashOK=true;
}
if (FlashOK) {
memcpy(&CNF, &rxbuf[8], sizeof(CNF));
}
}
return OK;
}
int ReadFlashStatus(void)
{
Task_sleep(100);
txbuf[0] = 0x05;
spiTransaction.count = 2; //1 byte TX, 1 byte RX
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
return OK;
}
int ScriviConfigurazione(void)
{
int x;
uint8_t CRC;
if (SPI_to_Flash() != OK) return ERRORE;
Task_sleep(100);
do {
Task_sleep(100);
txbuf[0] = 0x06;
spiTransaction.count = 1;
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return 1;
if (ReadFlashStatus() != 0) return ERRORE;
} while ((rxbuf[1] & 0x02) == 0);
/*********************
* sector erase (4K) *
*********************/
Task_sleep(100);
txbuf[0] = 0x20; //read
txbuf[1] = 0; //block address
txbuf[2] = 0;
txbuf[3] = 0;
spiTransaction.count = 4; //1 byte TX, 3 byte address
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
do {
Task_sleep(1000);
if (ReadFlashStatus() != 0) return ERRORE;
} while ((rxbuf[1] & 0x01) == 0x01);
do {
Task_sleep(100);
txbuf[0] = 0x06;
spiTransaction.count = 1;
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return 2;
if (ReadFlashStatus() != 0) return ERRORE;
} while ((rxbuf[1] & 0x02) == 0);
Task_sleep(100);
txbuf[0] = 0x02;
txbuf[1] = 0x00;
txbuf[2] = 0x00;
txbuf[3] = 0x00;
txbuf[4] = 0x12;
txbuf[5] = 0x34;
txbuf[6] = sizeof(CNF);
memcpy(&txbuf[8], &CNF, sizeof(CNF));
CRC=0;
for (x=0;x<sizeof(CNF);x++) CRC^= txbuf[8+x];
txbuf[7] = CRC;
spiTransaction.count = 4 + 4 + sizeof(CNF);
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
do {
Task_sleep(1000);
if (ReadFlashStatus() != 0) return ERRORE;
} while ((rxbuf[1] & 0x01) == 0x01);
Task_sleep(100);
txbuf[0] = 0x03;
txbuf[1] = 0x00;
txbuf[2] = 0x00;
txbuf[3] = 0x00;
spiTransaction.count = 4 + sizeof(CNF);
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
return memcmp(&txbuf[4], &CNF, sizeof(CNF));
}
static int HMC5983test(void)
{
if (SPI_to_Sensor() != OK) return ERRORE;
Task_sleep(100);
txbuf[0] = BIT7+BIT6+10;
txbuf[1] = 0;
txbuf[2] = 0;
txbuf[3] = 0;
spiTransaction.count = 4;
spiTransaction.txBuf = &txbuf;
spiTransaction.rxBuf = &rxbuf;
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
if ((rxbuf[1]!=0x48)||(rxbuf[2]!=0x34)||(rxbuf[3]!=0x33)) return ERRORE;
return OK;
}
static int HMC5983Setup(void)
{
if (SPI_to_Sensor() != OK) return ERRORE;
Task_sleep(100);
txbuf[0] = BIT6+0;
txbuf[1] = 0x90;
txbuf[2] = CNF.Gain <<5;
spiTransaction.count = 3;
spiTransaction.txBuf = &txbuf;
spiTransaction.rxBuf = &rxbuf;
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
txbuf[0] = BIT7+0;
spiTransaction.count = 2;
spiTransaction.txBuf = &txbuf;
spiTransaction.rxBuf = &rxbuf;
ret = SPI_transfer(spihandle, &spiTransaction);
if (!ret) return ERRORE;
if (rxbuf[1] != 0x90) return ERRORE;
return OK;
}
static void DebugSys(UArg arg0, UArg arg1)
{
uint8_t b;
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.readReturnMode = UART_RETURN_FULL;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.baudRate = 9600;
uartParams.readMode = UART_MODE_BLOCKING;
uartParams.readTimeout = UART_WAIT_FOREVER;
uart = UART_open(Board_UART0, &uartParams);
if (uart == NULL) ShowError(Err_UART);
while (1)
{
UART_read(uart, &b, 1);
}
}
static void cb (EasyLink_RxPacket * rxPacket, EasyLink_Status status)
{
if (status != EasyLink_Status_Success) return;
if (RxStatus != RxStatus_Wait) return;
PIN_setOutputValue(pinHandle, Board_GLED,true);
RxStatus = RxStatus_Success;
Semaphore_post(sema1);
}
void TimerTick(UArg arg0)
{
CNF.gwd++;
if (Status != Wait) C_retry++;
C_kalive++;
C_misura++;
Semaphore_post(sema1);
}
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId) {
CPUdelay(8000*50);
if (!PIN_getInputValue(pinId)) {
switch (pinId) {
case Board_BUTTON0:
break;
case Board_BUTTON1:
break;
default:
break;
}
}
}
static int SendRadioCommand(void)
{
uint8_t *b = &TxBuffer[0];
int i;
C_kalive = 0;
C_retry = 0;
PIN_setOutputValue(pinHandle, Board_RLED, true);
*b++ = 0x80;
i = b - &TxBuffer[0];
TxBuffer[5]=(uint8_t)((i-6)+(Retries << 5));
memcpy(txPacket.dstAddr, AtParams_txAddr, AtParams_addrSize);
txPacket.absTime = 0;
txPacket.len = i;
memcpy(txPacket.payload, TxBuffer, i);
AtParams_easyLinkStatus = EasyLink_transmit(&txPacket);
PIN_setOutputValue(pinHandle, Board_RLED,false);
if (AtParams_easyLinkStatus != EasyLink_Status_Success) return 1;
return 0;
}
static void AttendiRicezione(void)
{
int t;
EasyLink_Status n;
RxStatus = RxStatus_Wait;
Semaphore_reset(sema1, 0);
n = EasyLink_receiveAsync(&cb, 0);
if (n != EasyLink_Status_Success) return;
for (t=0;t <5;t++ ) {
Semaphore_pend(sema1, BIOS_WAIT_FOREVER);
if (RxStatus == RxStatus_Success) {
PIN_setOutputValue(pinHandle, Board_GLED,false);
return;
}
}
n = EasyLink_abort();
}
static void SensorMain(UArg arg0, UArg arg1)
{
S_retry = SRETRY_EMB;
pinHandle = PIN_open(&pinState, pinTable);
/********************
* Open Button pins *
********************/
buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
if (!buttonPinHandle) ShowError(Err_PinOpen);
/********************************
* Setup callback for 2 buttons *
********************************/
if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) ShowError(Err_PinCb);
PIN_setOutputValue(pinHandle, Board_DIO30_SWPWR, 1);
SPI_Params_init(&spiparams);
spiparams.bitRate = 200000;
spiparams.frameFormat = SPI_POL1_PHA1;
SPI_Port = SPI_Closed;
if (FlashInfotest() != OK) ShowError(Err_FlashInfo);
if (LeggiConfigurazione() != OK) ShowError(Err_FlashRead);
CNF.Gain = 1;
if (HMC5983test() != 0) ShowError(Err_NoHMC5993);
if (HMC5983Setup() != 0) ShowError(Err_HMCSetup);
Task_sleep(1000);
Semaphore_Params_init(&semParams);
Semaphore_construct(&sem1Struct, 0, &semParams);
sema1 = Semaphore_handle(&sem1Struct);
RxStatus = RxStatus_Stop;
Clock_Params_init(&clkParams);
clkParams.period = 90000;
clkParams.startFlag = TRUE;
Clock_construct(&clk0Struct, (Clock_FuncPtr)TimerTick, 90000, &clkParams);
EasyLink_setCtrl(EasyLink_Ctrl_MultiClient_Mode, 1);
EasyLink_Status n = EasyLink_init(EasyLink_Phy_625bpsLrm);
if (n != EasyLink_Status_Success) ShowError(Err_Radio);
/* initialise the Simple Beacon module called directly for Prop Adv
* Set multiclient mode to true
*/
SimpleBeacon_init(true);
SimpleBeacon_getIeeeAddr(bleMacAddr);
propAdvFrame.deviceAddress = bleMacAddr;
propAdvFrame.length = sizeof(propAdvertisement);
propAdvFrame.pAdvData = propAdvertisement;
if (CNF.NumStallo <255) nodeAddress16 = (uint16_t)(CNF.NumStallo);
else nodeAddress16 = 255;
localNameAdvertisement[20] = (nodeAddress16)%10 + 0x30;
localNameAdvertisement[19] = ((nodeAddress16)%100)/10 + 0x30;
localNameAdvertisement[18] = (nodeAddress16)/100 + 0x30;
localNameAdvFrame.deviceAddress = bleMacAddr;
localNameAdvFrame.length = sizeof(localNameAdvertisement);
localNameAdvFrame.pAdvData = localNameAdvertisement;
AtParams_rxTimeout = 100;
Task_sleep(1000);
while (1)
{
Semaphore_reset(sema1, 0);
Semaphore_pend(sema1, BIOS_WAIT_FOREVER);
if (BLE_request){
BLE_request = 0;
sendBleAdvertisement();
}
if (C_retry < S_retry) continue;
SendRadioCommand();
AttendiRicezione();
}
}
static void sendBleAdvertisement()
{
uint8_t txCnt, chan;
//Swtich RF switch to 2.4G antenna
PIN_setOutputValue(pinHandle, Board_DIO1_RFSW, 0);
for (txCnt = 0; txCnt < SimpleBeacon_AdvertisementTimes; txCnt++)
{
for (chan = 37; chan < 40; chan++)
{
//set BTN value in Prop advertisement
propAdvertisement[9] = 0x01;
//advertisement advertise local name
SimpleBeacon_sendFrame(localNameAdvFrame, 1, (uint64_t) 1<<chan);
//advertisement advertise button value
SimpleBeacon_sendFrame(propAdvFrame, 1, (uint64_t) 1<<chan);
}
//sleep on all but last advertisement
if(txCnt+1 < SimpleBeacon_AdvertisementTimes)
{
Task_sleep(SimpleBeacon_AdvertisementIntervals[txCnt]);
}
}
//Swtich RF switch to Sub1G antenna
PIN_setOutputValue(pinHandle, Board_DIO1_RFSW, 1);
}
/****************************
* ======== main ======== *
****************************/
int main(void)
{
Board_initGeneral();
Power_enablePolicy();
Board_initSPI();
Board_initUART();
Task_Params_init(&SensorTaskParams);
SensorTaskParams.stackSize = SensorTaskStackSize;
SensorTaskParams.priority = SensorTaskPriority;
SensorTaskParams.stack = &SensorTaskStack;
SensorTaskParams.arg0 = (UInt) 1000000;
Task_construct(&SensorpTask, SensorMain, &SensorTaskParams, NULL);
Task_Params_init(&SensorTaskParams1);
SensorTaskParams1.stackSize = SensorTaskStackSize1;
SensorTaskParams1.priority = SensorTaskPriority;
SensorTaskParams1.stack = &SensorTaskStack1;
SensorTaskParams1.arg0 = (UInt) 1000000;
Task_construct(&SensorpTask1, DebugSys, &SensorTaskParams1, NULL);
System_flush();
BIOS_start();
return (0);
}