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.

CC1312R: After aborting RF_cmdRx to send RF_cmdTx the RF_cmdRx cannot re-enabled

Part Number: CC1312R

Hi team,

after processing the RF_cmdPropTx rarely the RF_cmdPropRx cannot be started.

Our use case:

We are using up to 200 custom boards with the CC1312 simultaneously.
The communication in our application operates like a master-slave system so there is one master and all others are slaves. All slaves running RF_cmdPropRx.
To send a response the Rx command is aborted. After send complete the slaves restart RF_cmdPropRx.
when the master requests several slaves the slaves use a individual wait time (up to 1.8seconds) before send a response.

But after processing RF_cmdPropTx rarely the RF_cmdPropRx does not restart (randomly 1 or 2 slaves are affected).
In one case I saw the RF_cmdPropRx.status was set to 0x0405 (DONE_ABORT), but why not 0x0002 (ACTIVE)?

In the file I added the used rfc_CMD_.. with configurations and the function to send data and restart the rx command.

Best Regards,

Martin

rfwrite.txt
rfc_CMD_NOP_t RF_cmdNop =
{
    .commandNo                = CMD_NOP,
    .status                   = 0x0000,
    .pNextOp                  = 0, // Set this to (uint8_t*)&RF_cmdPropCs in the application
    .startTime                = 0x00000000,
    .startTrigger.triggerType = TRIG_REL_SUBMIT, // Trigs at an absolute time
    .startTrigger.bEnaCmd     = 0x0,
    .startTrigger.triggerNo   = 0x0,
    .startTrigger.pastTrig    = 0x1,
    .condition.rule           = COND_ALWAYS, // Always run next command (except in case of Abort)
    .condition.nSkip          = 0x0,
};

// CMD_PROP_CS
rfc_CMD_PROP_CS_t RF_cmdPropCs =
{
    .commandNo                = CMD_PROP_CS,
    .status                   = 0x0000,
    .pNextOp                  = 0, // Set this to (uint8_t*)&RF_cmdCountBranch in the application
    .startTime                = 0x00000000,
    .startTrigger.triggerType = TRIG_NOW,
    .startTrigger.bEnaCmd     = 0x0,
    .startTrigger.triggerNo   = 0x0,
    .startTrigger.pastTrig    = 0x0,
    .condition.rule           = COND_SKIP_ON_FALSE, // Run next command if this command returned TRUE,
                                                    // skip a number of commands (.condition.nSkip - 1) if it returned FALSE
                                                    // End causes for the CMD_PROP_CS command:
                                                    // Observed channel state Busy with csConf.busyOp = 1:                            PROP_DONE_BUSY        TRUE
                                                    // 0bserved channel state Idle with csConf.idleOp = 1:                            PROP_DONE_IDLE        FALSE
                                                    // Timeout trigger observed with channel state Busy:                              PROP_DONE_BUSY        TRUE
                                                    // Timeout trigger observed with channel state Idle:                              PROP_DONE_IDLE        FALSE
                                                    // Timeout trigger observed with channel state Invalid and csConf.timeoutRes = 0: PROP_DONE_BUSYTIMEOUT TRUE
                                                    // Timeout trigger observed with channel state Invalid and csConf.timeoutRes = 1: PROP_DONE_IDLETIMEOUT FALSE
                                                    // Received CMD_STOP after command started:                                       PROP_DONE_STOPPED     FALSE
    .condition.nSkip          = 0x2, // Number of skips + 1 if the rule involves skipping. 0: Same, 1: Next, 2: Skip next
    .csFsConf.bFsOffIdle      = 0x0, // Keep synthesizer running if command ends with channel Idle
    .csFsConf.bFsOffBusy      = 0x0, // Keep synthesizer running if command ends with Busy
    .__dummy0                 = 0x00,
    .csConf.bEnaRssi          = 0x1, // Enable RSSI as a criterion
    .csConf.bEnaCorr          = 0x0, // Disable correlation (PQT) as a criterion
    .csConf.operation         = 0x0, // Busy if either RSSI or correlation indicates Busy
    .csConf.busyOp            = 0x1, // End carrier sense on channel Busy
    .csConf.idleOp            = 0x0, // Continue on channel Idle
    .csConf.timeoutRes        = 0x0, // Timeout with channel state Invalid treated as Busy
    .rssiThr                  = 0x0, // Set the RSSI threshold in the application
    .numRssiIdle              = 0x0, // Number of consecutive RSSI measurements - 1 below the threshold
                                     // needed before the channel is declared Idle
    .numRssiBusy              = 0x0, // Number of consecutive RSSI measurements -1 above the threshold
                                     // needed before the channel is declared Busy
    .corrPeriod               = 0x0000, // N/A since .csConf.bEnaCorr = 0
    .corrConfig.numCorrInv    = 0x0, // N/A since .csConf.bEnaCorr = 0
    .corrConfig.numCorrBusy   = 0x0, // N/A since .csConf.bEnaCorr = 0
    .csEndTrigger.triggerType = TRIG_REL_START, // Trigs at a time relative to the command started
    .csEndTrigger.bEnaCmd     = 0x0,
    .csEndTrigger.triggerNo   = 0x0,
    .csEndTrigger.pastTrig    = 0x0,
    .csEndTime                = 0x00000000, // Set the CS end time in the application
};

// CMD_COUNT_BRANCH
rfc_CMD_COUNT_BRANCH_t RF_cmdCountBranch =
{
    .commandNo                = CMD_COUNT_BRANCH,
    .status                   = 0x0000,
    .pNextOp                  = 0, // Set this to (uint8_t*)&RF_cmdPropTx in the application
    .startTime                = 0x00000000,
    .startTrigger.triggerType = TRIG_NOW, // Triggers immediately
    .startTrigger.bEnaCmd     = 0x0,
    .startTrigger.triggerNo   = 0x0,
    .startTrigger.pastTrig    = 0x0,
    .condition.rule           = COND_SKIP_ON_FALSE, // Run next command if this command returned TRUE, stop if it returned FALSE
                                                    // End causes for the CMD_COUNT_BRANCH command:
                                                    // Finished operation with counter = 0 when being started: DONE_OK         TRUE
                                                    // Finished operation with counter > 0 after decrementing: DONE_OK         TRUE
                                                    // Finished operation with counter = 0 after decrementing: DONE_COUNTDOWN  FALSE
    .condition.nSkip          = 0x1,
    .counter                  = 0, // On start, the radio CPU decrements the value, and the end status of the operation differs if the result is zero
                                   // This number is set in the application (CS_RETRIES_WHEN_BUSY) and determines how many times the CMD_PROP_CS should run
                                   // in the case where the channel i Busy
    .pNextOpIfOk              = 0, // Set this to (uint8_t*)&RF_cmdPropCs in the application
};

rfc_CMD_PROP_TX_t RF_cmdPropTx =
{
    .commandNo = 0x3801,
    .status = 0x0000,
    .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    .startTime = 0x00000000,
    .startTrigger.triggerType = 0x0,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bVarLen = 0x1,
    .pktLen = 0xFF,
    .syncWord = 0xE36B51D9,
    .pPkt = 0 // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};


// CMD_PROP_RX
// Proprietary Mode Receive Command
rfc_CMD_PROP_RX_t RF_cmdPropRx =
{
    .commandNo = 0x3802,
    .status = 0x0000,
    .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    .startTime = 0x00000000,
    .startTrigger.triggerType = 0x0,
    .startTrigger.bEnaCmd = 0x0,
    .startTrigger.triggerNo = 0x0,
    .startTrigger.pastTrig = 0x0,
    .condition.rule = 0x1,
    .condition.nSkip = 0x0,
    .pktConf.bFsOff = 0x0,
    .pktConf.bRepeatOk = 0x1,
    .pktConf.bRepeatNok = 0x1,
    .pktConf.bUseCrc = 0x1,
    .pktConf.bVarLen = 0x1,
    .pktConf.bChkAddress = 0x0,
    .pktConf.endType = 0x0,
    .pktConf.filterOp = 0x0,
    .rxConf.bAutoFlushIgnored = 0x1,
    .rxConf.bAutoFlushCrcErr = 0x1,
    .rxConf.bIncludeHdr = 0x1,
    .rxConf.bIncludeCrc = 0x0,
    .rxConf.bAppendRssi = 0x1,
    .rxConf.bAppendTimestamp = 0x0,
    .rxConf.bAppendStatus = 0x0,
    .syncWord = 0xE36B51D9,
    .maxPktLen = 0xFF,
    .address0 = 0xAA,
    .address1 = 0xBB,
    .endTrigger.triggerType = 0x1,
    .endTrigger.bEnaCmd = 0x0,
    .endTrigger.triggerNo = 0x0,
    .endTrigger.pastTrig = 0x0,
    .endTime = 0x00000000,
    .pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
    .pOutput = 0 // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
};


int rfWrite(uint8_t *data_ptr, uint32_t length, uint32_t delayUs){
    if(data_ptr == NULL || length == 0)
        return ucEINVAL;

    SmartRfModule_t *module_ptr = (SmartRfModule_t*)this_ptr->_private_ptr;

    /* 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 = -100;
    RF_cmdPropCs.csEndTime = 5150 * 4; /* Add some margin */

    const uint8_t ABORT_GRACEFUL = 1;
    RF_flushCmd(rfHandle, rxCmdHandle, ABORT_GRACEFUL);
    RF_pendCmd(rfHandle, rxCmdHandle, RF_RX_QUEUE_EVENT_MSK);

    /* Send packet */
    RF_cmdCountBranch.counter = CS_RETRIES_WHEN_BUSY;
    RF_cmdPropTx.pktLen = length;
    RF_cmdPropTx.pPkt = data_ptr;
    RF_cmdNop.startTime = delayUs * 4;
    RF_postCmd(rfHandle, (RF_Op*)&RF_cmdNop, RF_PriorityHigh, NULL, 0);

    /* restart Rx */
    rxCmdHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal,
                             &rfRxCallback, RF_RX_QUEUE_EVENT_MSK);
    return ucOK;
}