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
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;
}