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.

CC2340R5-Q1: how to put Basic_BLE project in sleep mode

Part Number: CC2340R5-Q1
Other Parts Discussed in Thread: SYSCONFIG, CC2340R5

Tool/software:

I am using CC2340-R5 launchpad and running Basic_BLE project in broadcaster mode only with limited advertising. My device advertises 3 packets at interval of 1000ms and disable the advertising, after that i turn on the advertisement again for after 30 sec using a timer clock as shown in the training module. but my power consumption during the non-transmission period is 3.8 mA (checked using power analyser). Below is the code (app_broadcaster.c) with some changes that i have made . i have disabled the LED GPIO's in sysconfig. still the current is high how do i reduce this current to uAmps or nAmps as stated in datasheet

#include "ti_ble_config.h"
#include <ti/bleapp/ble_app_util/inc/bleapputil_api.h>
#include <ti/bleapp/menu_module/menu_module.h>
#include <app_main.h>
#include <ti/drivers/dpl/ClockP.h>
#include <ti/bleapp/ble_app_util/inc/bleapputil_internal.h>


  static ClockP_Struct clkPeriodic;
  ClockP_Params clockpParams;
  ClockP_Handle clockHandle;


//*****************************************************************************
//! constants
//*****************************************************************************
#define ADV_MAX_LEN                                     18
#define ADVDATA_MANUF_DATA_IDX                          5
#define ADVDATA_SENSOR_DATA_IDX                         (ADVDATA_MANUF_DATA_IDX+B_ADDR_LEN)
#define SP_PERIODIC_EVT_PERIOD                          30000
#define CLOCK_MS                                        1000
#define KEY                                             0xAA

//*****************************************************************************
//! Prototypes
//*****************************************************************************
void Broadcaster_AdvEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData);
void Broadcaster_AppEventHandler();
//*****************************************************************************
//! Globals
//*****************************************************************************
uint8_t MACaddress[B_ADDR_LEN];

int8_t u8Temperature = 0;
uint8_t fPressure = 0;
uint8_t  fAcc=0;
uint8_t fVolt=100;
uint8_t Vehicle_status=0x02;
uint8_t Sensor_status=0x03;
uint8_t BLE_FW_VER=0x01;
uint8_t TPMS_FW_VER=0x01;
uint8_t incr_temp_flg=1;
uint8_t incr_pres_flg=1;
uint8_t rep_flg=0;
uint8_t rep_cntr=0;

BLEAppUtil_EventHandler_t broadcasterAdvHandler =
{
    .handlerType    = BLEAPPUTIL_GAP_ADV_TYPE,
    .pEventHandler  = Broadcaster_AdvEventHandler,
    .eventMask      = BLEAPPUTIL_ADV_START_AFTER_ENABLE |
                      BLEAPPUTIL_ADV_END_AFTER_DISABLE|
                      BLEAPPUTIL_ADV_END
};

//! Store handle needed for each advertise set
uint8 broadcasterAdvHandle_1;

const BLEAppUtil_AdvInit_t broadcasterInitAdvSet1 =
{
    /* Advertise data and length */
    .advDataLen        = sizeof(advData1),
    .advData           = advData1,

    /* Scan respond data and length */
    .scanRespDataLen   = 0,
    .scanRespData      = NULL,

    .advParam        = &advParams1
};


const BLEAppUtil_AdvStart_t broadcasterStartAdvSet1 =
{

  .enableOptions         =GAP_ADV_ENABLE_OPTIONS_USE_MAX_EVENTS, 
  .durationOrMaxEvents   = 3 
};

/*const BLEAppUtil_AdvStart_t broadcasterStartAdvSet1 =
{

  .enableOptions         = GAP_ADV_ENABLE_OPTIONS_USE_MAX,
  .durationOrMaxEvents   = 0
};
*/

//*****************************************************************************
//! Functions
//*****************************************************************************

/*********************************************************************
 * @fn      Broadcaster_AdvEventHandler
 *
 * @brief   The purpose of this function is to handle advertise events
 *          that rise from the GAP and were registered in
 *          @ref BLEAppUtil_RegisterGAPEvent
 *
 * @param   event - message event.
 * @param   pMsgData - pointer to message data.
 *
 * @return  none
 */
void Broadcaster_AdvEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData)
{
    switch(event)
    {
        case BLEAPPUTIL_ADV_START_AFTER_ENABLE:
        {
            MenuModule_printf(APP_MENU_ADV_EVENT, 0, "Adv status: Started - handle: "
                              MENU_MODULE_COLOR_YELLOW "%d" MENU_MODULE_COLOR_RESET,
                              ((BLEAppUtil_AdvEventData_t *)pMsgData)->pBuf->advHandle);

            /** New Code **/
            BLEAppUtil_AdvEventData_t * pkt = (BLEAppUtil_AdvEventData_t *)pMsgData;

            if (pkt->pBuf->advHandle == broadcasterAdvHandle_1)
            {
                bStatus_t status = FAILURE;

                status = GapAdv_prepareLoadByHandle(broadcasterAdvHandle_1, GAP_ADV_FREE_OPTION_DONT_FREE);

                if (status != SUCCESS)
                    for(;;); // Loop

                uint8_t ADV_DATA1_LEN = 11;
                uint8_t i=0;
                uint8_t  *devAddr = NULL;
                uint8_t pressure =0;
                // get MAC address of BLE
                devAddr = GAP_GetDevAddress(TRUE);
                memcpy( &MACaddress[0], &devAddr[0], 6 );

                advData1[i++] = 0x02;
                advData1[i++] = GAP_ADTYPE_FLAGS;
                advData1[i++] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED | GAP_ADTYPE_FLAGS_GENERAL;

                advData1[i++] = ADV_MAX_LEN - i - 1; // length of this data
                advData1[i++] = GAP_ADTYPE_MANUFACTURER_SPECIFIC;

                i=ADVDATA_MANUF_DATA_IDX;

                advData1[i++] = MACaddress[5];
                advData1[i++] = MACaddress[4];
                advData1[i++] = MACaddress[3];
                advData1[i++] = MACaddress[2];
                advData1[i++] = MACaddress[1];
                advData1[i++] = MACaddress[0];

                i = ADVDATA_SENSOR_DATA_IDX;

                advData1[i++] = Vehicle_status;
                advData1[i++] = (u8Temperature+40);

                pressure=(fPressure*2.5);
                advData1[i++] =pressure;
                advData1[i++] = fVolt ;
                advData1[i++] = Sensor_status;
                advData1[i++] = BLE_FW_VER ;
                advData1[i++] = TPMS_FW_VER;

                broadcasterAdvHandler.eventMask = BLEAPPUTIL_ADV_END_AFTER_DISABLE;
                                              

                status = GapAdv_loadByHandle(broadcasterAdvHandle_1,
                                                    GAP_ADV_DATA_TYPE_ADV,
                                                    ADV_MAX_LEN,
                                                    advData1);

                if (status != SUCCESS)
                    for(;;);


                ClockP_start(clockHandle);


                /** End New Code **/
            }
            break;
        }

        case BLEAPPUTIL_ADV_END_AFTER_DISABLE:
        {
            MenuModule_printf(APP_MENU_ADV_EVENT, 0, "Adv status: Ended - handle: "
                         MENU_MODULE_COLOR_YELLOW "%d" MENU_MODULE_COLOR_RESET,
           //                   ((BLEAppUtil_AdvEventData_t *)pMsgData)->pBuf->advHandle);


            break;
        }

        default:
        {
            break;
        }
    }
}

/*********************************************************************
 * @fn      Broadcaster_start
 *
 * @brief   This function is called after stack initialization,
 *          the purpose of this function is to initialize and
 *          register the specific events handlers of the broadcaster
 *          application module
 *
 * @return  SUCCESS, errorInfo
 */
bStatus_t Broadcaster_start()
{
    bStatus_t status = SUCCESS;


    status = BLEAppUtil_registerEventHandler(&broadcasterAdvHandler);
    if(status != SUCCESS)
    {
        // Return status value
        return(status);
    }

    status = BLEAppUtil_initAdvSet(&broadcasterAdvHandle_1, &broadcasterInitAdvSet1);
    if(status != SUCCESS)
    {
        // Return status value
        return(status);
    }

    // Setup parameters.
    ClockP_Params_init(&clockpParams);

    // Convert clockDuration in milliseconds to ticks.
    uint32_t clockTicks = SP_PERIODIC_EVT_PERIOD * (CLOCK_MS/ 1);
    // If period is 0, this is a one-shot timer. If not 0, the it’s a periodic clock.
    clockpParams.period = 0;  //clockTicks;

    // Starts immediately after construction if true, otherwise wait for a call
    // to start.
    clockpParams.startFlag = false;
    clockpParams.arg = (uintptr_t)Broadcaster_AppEventHandler;

    // Initialize clock instance.
    clockHandle = ClockP_construct(&clkPeriodic, (void *)BLEAppUtil_invokeFunctionNoData, clockTicks, &clockpParams);

    status = BLEAppUtil_advStart(broadcasterAdvHandle_1, &broadcasterStartAdvSet1);
    if(status != SUCCESS)
    {
        // Return status value
        return(status);
    }

    // Return status value
    return(status);
}


void Broadcaster_AppEventHandler()
{
  //add your code here
    bStatus_t status = FAILURE;

                   status = GapAdv_prepareLoadByHandle(broadcasterAdvHandle_1, GAP_ADV_FREE_OPTION_DONT_FREE);

                   if (status != SUCCESS)
                       for(;;); // Loop

                   uint8_t ADV_DATA1_LEN = 11;
                   uint8_t i=0;
                   uint8_t pressure =0;

                   advData1[i++] = 0x02;
                   advData1[i++] = GAP_ADTYPE_FLAGS;
                   advData1[i++] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED | GAP_ADTYPE_FLAGS_GENERAL;

                   advData1[i++] = ADV_MAX_LEN - i - 1; // length of this data
                   advData1[i++] = GAP_ADTYPE_MANUFACTURER_SPECIFIC;

                   i=ADVDATA_MANUF_DATA_IDX;

                   advData1[i++] = MACaddress[5];
                   advData1[i++] = MACaddress[4];
                   advData1[i++] = MACaddress[3];
                   advData1[i++] = MACaddress[2];
                   advData1[i++] = MACaddress[1];
                   advData1[i++] = MACaddress[0];

                   i = ADVDATA_SENSOR_DATA_IDX;

                   if(u8Temperature>=100)
                       incr_temp_flg=0;
                   if(u8Temperature<=0)
                       incr_temp_flg=1;

                   if(incr_temp_flg)
                   u8Temperature++;
                   else
                       u8Temperature--;


                   if(fPressure>=40)
                       incr_pres_flg=0;
                   if(fPressure<=0)
                       incr_pres_flg=1;

                   if(incr_pres_flg)
                       fPressure++;
                   else
                       fPressure--;

                   if((!incr_pres_flg))
                       Vehicle_status=Vehicle_status|0x04;
                   else if((incr_pres_flg))
                       Vehicle_status=Vehicle_status &~ 0x04;

                   advData1[i++] = Vehicle_status;
                   advData1[i++] = (u8Temperature+40);

                   pressure=(fPressure*2.5);
                   advData1[i++] =pressure ;
                   advData1[i++] = fVolt ;
                   advData1[i++] = Sensor_status;
                   advData1[i++] = BLE_FW_VER;
                   advData1[i++] = TPMS_FW_VER;


                   broadcasterAdvHandler.eventMask = BLEAPPUTIL_ADV_END_AFTER_DISABLE;
                              

                   status = GapAdv_loadByHandle(broadcasterAdvHandle_1,
                                                       GAP_ADV_DATA_TYPE_ADV,
                                                       ADV_MAX_LEN,
                                                       advData1);

                   BLEAppUtil_advStart(broadcasterAdvHandle_1, &broadcasterStartAdvSet1);

                   if (status != SUCCESS)
                       for(;;);


                   ClockP_start(clockHandle);
                
                   /** End New Code **/

}

//#endif  //( HOST_CONFIG & ( BROADCASTER_CFG ) )

  • Hi Ankit,

    When you are taking your power measurements, are you connected to the XDS110? 

    How are you powering the board?

    I ask because:

    1. When using the XDS110 connected via the socket to the CC2340R5 launchpad, the power measurements will be off. There are a couple reasons for this, but one that comes to mind is that the TX and RX lines have pulls on them, causing them to draw a lot of power.

    2. If you are connected via the XDS110 via the ARM cable (JTAG) then the power measurements should be better, but they still may be high. 

    3. The best method is to power the board without connecting the XDS110 via the socket. All you need is the 3v3 line, ground, and optionally, the nRST line from the XDS110 to the launchpad.

    Best,

    Nima Behmanesh

  • Do I need to change any jumper settings also, because I tried method 2 and 3 but energy trace window is showing zero current only. below are the screenshots

  • Hi Ankit,

    I see the setup now. Energy trace is through the XDS110 so there will be some more connections added. I'm not sure if you'll get accurate results this way though, so I'll need to ask some members of my team.

    I'll respond tomorrow EOD at the latest.

    Best,

    Nima Behmanesh

  • Hello Nima,

    i want to add one more info that, this issue is coming with my modified Basic BLE project (made changes in app broadcaster.c and disable display module in sysconfig), but i am able to see the current spikes in energy trace with original Basic BLE project.  Also when i checked the current consumption of my modified BLE project on Power analyzer available in our office lab i was able to see the current spikes on power analyzer properly but was not able to see it on energy trace. Below are the pictures of Power analyser, energy Trace and sysconfig settings.

  • Hi Ankit,

    Energy works over the 3v3 line, so you should be able to see it. I discussed with one of my colleagues yesterday and they said they may look into it to see if anything has changed.

    That's interesting that the modified example is not showing, though the out-of-box example is. It makes sense to me that you're seeing the right power spikes on the power analyzer. This seems to be something involving the XDS110. As far as I'm aware, removing the display shouldn't affect energy trace.

    I'll look into this further.

    Best,

    Nima Behmanesh

  • Hello Nima,

    Did you get the solution for this?

  • Hi Ankit,

    I've tested this on my side with the same setup, and I'm able to see an energy trace. 

    Are the wires swapped?

    Best,

    Nima Behmanesh