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.

CC1350STK: The LBT example gets into a hung state if not always transmitting

Part Number: CC1350STK
Other Parts Discussed in Thread: CC1350

Hello,

I am using the latest SDK for the CC1350 launchpad Listen Before Talk (LBT) example as my base code.   Instead of printing random numbers and transmitting all the time I only want to read sensor data and transmit that data if it passes a certain threshold.  It appears that if I am not transmitting all the time, within a 5 minute window the program hangs and nothing will transmit.  Is there something I am misunderstanding about the radio code?   Here is my code snippet:

While(true)

{

Sensor code that detects whether to transmit or not

if (transmit)
{
/* Set absolute TX time to utilize automatic power management */
time += (PACKET_INTERVAL_US * 4);
RF_cmdNop.startTime = time;

/* Send packet */
RF_runCmd(rfHandle, (RF_Op*)&RF_cmdNop, RF_PriorityNormal, &callback, 0);

RF_cmdNop.status = IDLE;
RF_cmdPropCs.status = IDLE;
RF_cmdCountBranch.status = IDLE;
RF_cmdPropTx.status = IDLE;
RF_cmdCountBranch.counter = CS_RETRIES_WHEN_BUSY;
}

  • Hello Rob,

    Is there any transmission at all? I ask because it is not clear from the code snippet where the "transmit" variable is set. Is it a global variable? As you may already know the compiler optimizations may be causing this if the transmit variable is not declared as volatile.

    Also you may want to use a Semaphore instead of polling on this variable. You can post the semaphore when your sensor data exceeds your threshold. This is a better way as it will block the Tx task function and thus not always running the while(true) loop forever.

    Regards,
    Prashanth
  • Thanks Prashanth. Yes it will transmit but will suddenly stop transmitting usually within 5 minutes. The transmit variable is static to the file but I did not declare it volatile which I will. Thank you on the semaphore approach, that seems like it will work. I will try it out and let you know.

    Regards,
    Rob
  • Hi Prashanth. I used the semaphore approach and code wise that is the better way to go however, even if I transmit a radio packet just once. The radio stops working after a while. Is there a way to reset the radio in the application code (M3). I have two tasks now. One task to read the sensors and the other task is the main TX LBT task. I set both priorities to 2. Here is the code. I may modify the LBT original example to see if exhibits the same behavior when not always transmitting.

    static void mmcTaskFunction(UArg arg0, UArg arg1)
    {
    while (true)
    {
    Watchdog_clear(watchdogHandle);
    memset(packet, 0, PAYLOAD_LENGTH);
    ReadSensor(&packet[10], Board_I2C1);
    AddSensorOffset((uint16_t *)&packet[10], Board_I2C1);
    if (TransmitSensorPacket((uint16_t *)&packet[10]))
    {
    Semaphore_post(txDoneSem);
    }
    Task_sleep(200000/Clock_tickPeriod);
    }
    }

    /*
    * ======== txTaskFunction ========
    */
    static void txTaskFunction(UArg arg0, UArg arg1)
    {
    RF_Params rfParams;
    RF_Params_init(&rfParams);

    /* Create and enable a Watchdog with resets enabled */
    Watchdog_Params_init(&watchdogParams);
    watchdogParams.resetMode = Watchdog_RESET_ON;
    watchdogHandle = Watchdog_open(Board_WATCHDOG0, &watchdogParams);
    if (watchdogHandle == NULL) {
    /* Error opening watchdog */
    while (1);
    }

    Semaphore_Params params;
    Error_Block eb;

    /* Init params */
    Semaphore_Params_init(&params);
    Error_init(&eb);

    /* Create semaphore instance */
    txDoneSem = Semaphore_create(0, &params, &eb);

    /* Customize the CMD_PROP_TX command for this application */
    RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
    RF_cmdPropTx.pPkt = packet;
    RF_cmdNop.startTrigger.triggerType = TRIG_ABSTIME;
    RF_cmdNop.startTrigger.pastTrig = 1;

    /* Set up the next pointers for the command chain */
    RF_cmdNop.pNextOp = (rfc_radioOp_t*)&RF_cmdPropCs;
    RF_cmdPropCs.pNextOp = (rfc_radioOp_t*)&RF_cmdCountBranch;
    RF_cmdCountBranch.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
    RF_cmdCountBranch.pNextOpIfOk = (rfc_radioOp_t*)&RF_cmdPropCs;

    /* Customize the API commands with application specific defines */
    RF_cmdPropCs.rssiThr = RSSI_THRESHOLD_DBM;
    RF_cmdPropCs.csEndTime = (IDLE_TIME_US + 150) * 4; /* Add some margin */
    RF_cmdCountBranch.counter = CS_RETRIES_WHEN_BUSY;

    /* Request access to the radio */
    rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);

    /* Set the frequency */
    RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);

    /* Get current time */
    time = RF_getCurrentTime();

    /* Run forever */
    while(true)
    {
    Watchdog_clear(watchdogHandle);

    Semaphore_pend(txDoneSem, BIOS_WAIT_FOREVER);

    GetIeeeAddr(&packet[0]);

    /* Create packet with incrementing sequence number and random payload */
    packet[8] = (uint8_t)(seqNumber);
    packet[9] = (uint8_t)(seqNumber >> 8);

    /* Set absolute TX time to utilize automatic power management */
    time += (PACKET_INTERVAL_US * 4);
    RF_cmdNop.startTime = time;

    /* Send packet */
    RF_runCmd(rfHandle, (RF_Op*)&RF_cmdNop, RF_PriorityNormal, &callback, 0);

    RF_cmdNop.status = IDLE;
    RF_cmdPropCs.status = IDLE;
    RF_cmdCountBranch.status = IDLE;
    RF_cmdPropTx.status = IDLE;
    RF_cmdCountBranch.counter = CS_RETRIES_WHEN_BUSY;
    }
    }
  • Hello Rob, 

    The below lines look suspicous in the while loop.

        time += (PACKET_INTERVAL_US * 4);

        RF_cmdNop.startTime = time;

    Since now the tansmission of the packets is not at regular intervals, the .startTime needs to be adjusted by using "time = RF_getCurrentTime()" every time there is new  packet transmission. 

    You can also try playing with the startTriggers to see what best suits you. TRIG_NOW may suit better in this scenario as this will execute the command immediately. TRIG_ABSTIME is used to execute the command at a future time. The time vlaue in your current setup is most likely running behind and causing unexpected behavior.

    Regards,

    Prashanth

  • Hi Prashanth,

    Thank you for the information as this resolved my issue. I greatly appreciate it.

    Thanks,
    Rob