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.

Abnormal consumption on CC1350

Part Number: LAUNCHXL-CC1350
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);
}

  • Hello Matteo,
    If it is not going into one of the lowpower states, then it is very likely that one of the peripherals may be still active. From just looking at the code it seems (my guess) like the UART may be still active. Can you please set a break point at a location where you think it should enter the low power state and see if SPI/UART/Clock are inactive. You can add PoweCC26xx.c file into your project and monitor PowerCC26XX_module.constraintCounts to see if all the constraints are released. It won't enter low power states if there are any active constraints. Please try to identify any constraints and release those.
    Regards,
    Prashanth
  • Yes, UART is still active, I need it. And also SPI is always active, I need it for the flash chip and for a magnetic chip we use (HMC5983, low consumption), but I need that when they arent' used che consumption would be under 100uA. SPI is closed only for a short time when I pass from SPI for flash chip to SPI for magnetic chip, or vice versa.