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.

RTOS/CC1310: HWI while radio TX and RX

Part Number: CC1310


Tool/software: TI-RTOS

Hi,

We are transmitting and receiving data with this pattern below;

FS

TX / RX

Guard

1ms

9ms

3ms

In this scenario, these FS->TX and  FS->RX is chained commands. I send one of these chained commands and waiting for semaphore. After completing last command on chain one semaphore is released. So, after getting semaphore i send another raio command. This lasts forever.

In my problem, I am also getting HWI from I/O pin. When i get HWI, i am getting error of ERROR_PAST_START. But this is arbitrary time, i guess in the error case HWI comes above radio operation. When i disable HWI, radio can send and receive forever. How can i handle HWI while i an sending and receiving data? My code is below;

void RadioInit(uint16_t centerFreq, uint16_t fractFreq)
{
    Semaphore_Params semParams;
    Semaphore_Params_init(&semParams);
    Semaphore_construct(&mutSemStruct, 1, &semParams);
    mutSemHandle = Semaphore_handle(&mutSemStruct);

    Semaphore_construct(&cmdFinishedStruct, 1, &semParams);
    cmdFinishedHandle = Semaphore_handle(&cmdFinishedStruct);

    Mailbox_Params mailboxParams;
    Mailbox_Params_init(&mailboxParams);
    RfTxMailboxHandle = Mailbox_create(sizeof(ts_RfMsgMailBoxElem), 20, &mailboxParams, NULL);

    RfRxMailboxHandle = Mailbox_create(sizeof(ts_RfMsgMailBoxElem), 32, &mailboxParams, NULL);

    Task_Params taskParams;
    Task_Params_init(&taskParams);
    taskParams.stackSize = RF_RX_STACK_SIZE;
    taskParams.stack = &rfRxTaskStack;
    Task_construct(&rfRxTaskStruct, (Task_FuncPtr) RxRfTask, &taskParams, NULL);

    RF_Params rfParams;
    RF_Params_init(&rfParams);
    rfParams.nPowerUpDurationMargin = 400;

    if (RFQueue_defineQueue(&dataQueue, rxDataEntryBuffer, sizeof(rxDataEntryBuffer), NUM_DATA_ENTRIES,
    MAX_LENGTH + NUM_APPENDED_BYTES))
    {
        /* Failed to allocate space for all data entries */
        while (1)
            ;
    }

    /* Modify CMD_PROP_RX command for application needs */
    RF_cmdPropRx.pQueue = &dataQueue; /* Set the Data Entity queue for received data */
    RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1; /* Discard ignored packets from Rx queue */
    RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
    RF_cmdPropRx.rxConf.bAppendRssi = 1;
    RF_cmdPropRx.rxConf.bIncludeHdr = 1;
    RF_cmdPropRx.rxConf.bAppendTimestamp = 1;
    RF_cmdPropRx.maxPktLen = MAX_LENGTH; /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
    RF_cmdPropRx.pktConf.bRepeatOk = 1;
    RF_cmdPropRx.pktConf.bRepeatNok = 1;
    RF_cmdPropRx.pOutput = (uint8_t *) &rxOutput;
    RF_cmdPropRx.startTrigger.triggerType = TRIG_REL_PREVEND;
    RF_cmdPropRx.startTime = CHAINED_RX_START_REL_TIME_MS * RF_TIMER_CLK_ONE_MS;
    RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
    RF_cmdPropRx.endTime = CHAINED_RX_REL_END_TIME_MS * RF_TIMER_CLK_ONE_MS;

    /* Customize the CMD_PROP_TX command for this application */
    RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
    RF_cmdPropTx.pPkt = packet;
    RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_PREVEND;
    RF_cmdPropTx.startTime = CHAINED_TX_START_REL_TIME_MS * RF_TIMER_CLK_ONE_MS;
    RF_cmdPropTx.startTrigger.pastTrig = 0;

    RF_cmdFs.startTrigger.triggerType = TRIG_ABSTIME;
    RF_cmdFs.startTrigger.pastTrig = 0;
    RF_cmdFs.pNextOp = (rfc_radioOp_t*) &RF_cmdPropTx;
    RF_cmdFs.condition.rule = COND_ALWAYS;
    /* Request access to the radio */
    rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*) &RF_cmdPropRadioDivSetup, &rfParams);
}

void freqHopCallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{
//    LedToggleRx();
    if ((e & RF_EventLastCmdDone) /*&& (RF_cmdPropTx.status == DONE_OK)*/)
    {
        Semaphore_post(cmdFinishedHandle);
        if((((volatile RF_Op*)&RF_cmdFs)->status) != DONE_OK)
        {
            NetAppSendUartDebugInfo(100, 0, 0, ((volatile RF_Op*)&RF_cmdFs)->status, 0, 0, 0, 0, buff);//This is for debug purpose normally no uart msg in callback.
        }
    }

    ts_RfMsgMailBoxElem mailbox;
    if (e & RF_EventRxEntryDone)
    {
        //        blinkRx(1);
        //        LedToggleRx();
        /* Get current unhandled data entry */
        currentDataEntry = RFQueue_getDataEntry();

        if (currentDataEntry->status == DATA_ENTRY_FINISHED)
        {
            /* Handle the packet data, located at &currentDataEntry->data:
             * - Element lenght added with config.lenSz  = 0
             * - Length is the first byte with the current configuration
             * - Data starts from the second byte */
            packetLength = *(uint8_t*) (&currentDataEntry->data);
            packetDataPointer = (uint8_t*) (&currentDataEntry->data + 1);
            /* Copy the payload + rssi(1) + timestamp(4) + status(1)  byte to the packet variable */
            memcpy(mailbox.msg, packetDataPointer, packetLength);
            memcpy(&mailbox.rssi, packetDataPointer + packetLength, 1);
            memcpy(&mailbox.timestamp, packetDataPointer + packetLength + 1, 4);

            Mailbox_post(RfRxMailboxHandle, &mailbox, 0);
            RFQueue_nextEntry();
        }
    }
}

void hopFrequency(float freq, uint32_t start_ts, uint32_t rx_duration, uint8_t chainCmd, const uint8_t* p, uint8_t totalPacketLen)
{
    currentFreq = freq;
    uint16_t freqInt, freqFract;
    calc_freq_params(freq, &freqInt, &freqFract);
    RF_cmdFs.frequency = freqInt;
    RF_cmdFs.fractFreq = freqFract;
    RF_cmdFs.startTime = start_ts;

    if (chainCmd == CHAINED_RX)
    {
        RF_cmdPropRx.endTime = rx_duration;
        RFPrepareReceive();
        RF_cmdFs.pNextOp = (rfc_radioOp_t*) &RF_cmdPropRx;
    }
    else
    {
        RF_cmdPropTx.pktLen = totalPacketLen;
        RF_cmdPropTx.pPkt = (uint8_t *) p;
        RFPrepareSend();
        RF_cmdFs.pNextOp = (rfc_radioOp_t*) &RF_cmdPropTx;
    }

    Semaphore_pend(mutSemHandle, BIOS_WAIT_FOREVER);
    rfCmdHandle = RF_postCmd(rfHandle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, &freqHopCallback, (RF_EventLastCmdDone | RF_EventRxEntryDone));
    Semaphore_post(mutSemHandle);
}

This is the way how i send radio commands.

for (i = 0; i < MAX_NETWORK_SIZE; i++) // scan all slots
{
Semaphore_pend(cmdFinishedHandle, BIOS_WAIT_FOREVER);
if (myNetworkID == currentSlotNumber)
hopFrequency(freqTable[currentCycleNumber][currentSlotNumber], start_ts_next_cycle, 0, CHAINED_TX, (uint8_t *) &currentCycleMessages.hello,
sizeof(HelloPayload));
else
hopFrequency(freqTable[currentCycleNumber][currentSlotNumber], start_ts_next_cycle, rx_duration_next_cycle, CHAINED_RX, NULL, NULL);
start_ts_old_cycle = start_ts_next_cycle;
start_ts_next_cycle = CalculateNextTimestamp(start_ts_old_cycle, custom_cycle_count, 1);
DEBUG_PRINT(
(hello_mode, currentSlotNumber, synchronizationFlag, 0, start_ts_next_cycle, rx_duration_next_cycle, 0, freqTable[currentCycleNumber][currentSlotNumber], buffer));

currentSlotNumber++;
}

I am getting status of RF_cmdFs in callback above using UART. So, Why the HWI prevent me to send and receive data?

Best regards.

Ramazan

  • Hi,

    • increase the Hardware Interrupt / Software Interrupt priorities of the RF driver in the board file. 
    • or increase the power-up margin time of the RF driver when calling RF_open().

    For raising the driver's priorities, see this post. Try the SWI priority first as shown, then try to increase the HWI priority if necessary. Default HWI priority is INT_PRI_LEVEL7 (~0 has equal meaning), try INT_PRI_LEVEL6.

    When playing with the margin: The default power-up duration margin until TI-RTOS SDK 2.21 was very tight. In the latest SimpleLink SDK releases, it was relaxed a bit. You may try 350 µs.

  • Hi Richard,

    I tried these solutions but still HWI slows my process and RF operation returns ERROR_PAST_START. I wrote some test code. My code is just sending 32 byte packets with chained CMD_FS->CMD_PROP_TX(first command ts is t0) in 13ms intervals. After completing RF command i post semaphore in callback. In another task, i pend for this semaphore and after receiving it, i post another radio command(its time is t0 + (13*4000)). Thus, command intervals absolutely 13 ms. Here is some log:

    CNT:15833 toffset= 28749 current_time:823595312 ,last_cb_diff:51994<LF>
    CNT:15834 toffset= 28748 current_time:823647311 ,last_cb_diff:51994<LF>
    CNT:15835 toffset= 28749 current_time:823699312 ,last_cb_diff:51996<LF>
    CNT:15836 toffset= 28749 current_time:823751312 ,last_cb_diff:51995<LF>
    CNT:15837 toffset= 28749 current_time:823803312 ,last_cb_diff:51995<LF>
    CNT:15838 toffset= 28749 current_time:823855312 ,last_cb_diff:51994<LF>
    CNT:15839 toffset= 28749 current_time:823907312 ,last_cb_diff:51995<LF>
    CNT:15840 toffset= 28748 current_time:823959311 ,last_cb_diff:51994<LF>
    Pin interrupt received at RF_clock:824002044.<LF>
    CNT:15841 toffset= 28529 current_time:824011092 ,last_cb_diff:51776<LF>
    CNT:15842 toffset= 30220 current_time:824012783 ,last_cb_diff:1686<LF>
    error cnt:6 error_code:2048<LF>
    CNT:15843 toffset= 770 current_time:824087333 ,last_cb_diff:74544<LF>
    error cnt:7 error_code:2048<LF>
    CNT:15844 toffset= 28752 current_time:824167315 ,last_cb_diff:79976<LF>
    CNT:15845 toffset= 28750 current_time:824219313 ,last_cb_diff:51992<LF>
    CNT:15846 toffset= 28749 current_time:824271312 ,last_cb_diff:51993<LF>
    CNT:15847 toffset= 28749 current_time:824323312 ,last_cb_diff:51994<LF>
    CNT:15848 toffset= 28749 current_time:824375312 ,last_cb_diff:51995<LF>
    CNT:15849 toffset= 28749 current_time:824427312 ,last_cb_diff:51995<LF>
    CNT:15850 toffset= 28749 current_time:824479312 ,last_cb_diff:51995<LF>
    CNT:15851 toffset= 28748 current_time:824531311 ,last_cb_diff:51994<LF>

    in here, CNT: packet count
    toffset: Clock difference between command start time and completing time(callback).
    current_time: clock in callback(after command completion)
    last_cb_diff: two command completion clock difference (normally; 13ms*4000 = 52000)

    const RFCC26XX_HWAttrs RFCC26XX_hwAttrs = {
    .hwiCpe0Priority = INT_PRI_LEVEL6,
    .hwiHwPriority = INT_PRI_LEVEL6,
    .swiCpe0Priority = 1,
    .swiHwPriority = 1,
    };
    RF_Params rfParams;
    RF_Params_init(&rfParams);
    rfParams.nPowerUpDurationMargin = 350;


    If you want i can post my test code.

    void intCallbackFxn(PIN_Handle handle, PIN_Id pinId)
    {
    c_time = RF_getCurrentTime();
    Semaphore_post(semIntHandle);
    }
    This is my pin HWI callback function. To sum up, issue is still current. Do you have any suggestions?

    Best regards.
    Ramazan