请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:CC1310 工具/软件:
我有一个需要在 2 个器件之间进行双向通信的应用。 该代码应在接收到有效数据包之后发送 ACK 数据包、但出于某种原因、未传输 ACK 数据包。 我找不到问题所在、配置对我来说是正确的、我是否遗漏了一些内容?
下面是初始化射频驱动程序及其所用函数的任务。 如果我使用 RF_runCmd 启动命令来启动命令、接收和发送数据包可以正常工作、但 RF_cmdPropTxAck 命令在 RF_cmdPropRxSniff 命令之后不运行
static void rf_init_task(UArg arg0, UArg arg1) {
// Initialize the radio
RF_Params rfParams;
RF_Params_init(&rfParams);
// Create queue and data entries
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);
}
// Get address
rf_generate_addr();
initializeTxAdvCmdFromTxCmd(&RF_cmdPropTxAck, &RF_cmdPropTx);
RF_cmdPropTxAck.commandNo = CMD_PROP_TX_ADV;
RF_cmdPropTxAck.startTrigger.triggerType = TRIG_NOW;
RF_cmdPropTxAck.pPkt = (uint8_t*)&ACK;
RF_cmdPropTxAck.pktLen = PAYLOAD_LENGTH;
ACK.dst_addr = *(uint64_t *)filter_address;
ACK.data.raw = 0;
ACK.cmd = RF_CMD_ACK;
initializeSniffCmdFromRxCmd(&RF_cmdPropRxSniff, &RF_cmdPropRx);
RF_cmdPropRxSniff.condition.rule = COND_STOP_ON_FALSE;
RF_cmdPropRxSniff.pNextOp = (RF_Op*)&RF_cmdPropTxAck; // Run TxAck command after a valid packet received on RxSniff
// Configure RX part of RX_SNIFF command
RF_cmdPropRxSniff.pQueue = &dataQueue;
RF_cmdPropRxSniff.pOutput = (uint8_t*) &rx_statistics;
RF_cmdPropRxSniff.maxPktLen = MAX_LENGTH;
// Discard ignored packets and CRC errors from Rx queue
RF_cmdPropRxSniff.rxConf.bAutoFlushIgnored = 1;
RF_cmdPropRxSniff.rxConf.bAutoFlushCrcErr = 1;
RF_cmdPropRxSniff.pktConf.bRepeatOk = 0; // (default: 1)
RF_cmdPropRxSniff.pktConf.bRepeatNok = 1;
// Calculate datarate from prescaler and rate word
uint32_t datarate = calculateSymbolRate(RF_cmdPropRadioDivSetup.symbolRate.preScale, RF_cmdPropRadioDivSetup.symbolRate.rateWord);
// Configure Sniff-mode part of the RX_SNIFF command
configureSniffCmd(&RF_cmdPropRxSniff, datarate, WOR_WAKEUPS_PER_SECOND(sensor.settings.autotest));
// Configure TX
rf_config_tx();
// Open RF
rf_handle = RF_open(&rf_object, &RF_prop, (RF_RadioSetup*) &RF_cmdPropRadioDivSetup, &rfParams);
// Set the frequency
rf_set_frequency(0);
// Set TX power
if (rf_handle != NULL) {
RF_TxPowerTable_Value tx_power = RF_TxPowerTable_findValue((RF_TxPowerTable_Entry*) RF_PROP_txPowerTable, 14);
if (tx_power.rawValue != RF_TxPowerTable_INVALID_VALUE) {
RF_setTxPower(rf_handle, tx_power);
}
}
// Send callback to inform that radio is ready
ready_callback(true);
// Terminate the task
Task_exit();
}
static void initializeTxAdvCmdFromTxCmd(rfc_CMD_PROP_TX_ADV_t *RF_cmdPropTxAdv, rfc_CMD_PROP_TX_t *RF_cmdPropTx) {
#define RADIO_OP_HEADER_SIZE 14
/* Copy general radio operation header from TX commmand to TX_ADV */
memcpy(RF_cmdPropTxAdv, RF_cmdPropTx, RADIO_OP_HEADER_SIZE);
/* Set command to CMD_PROP_TX_ADV */
RF_cmdPropTxAdv->commandNo = CMD_PROP_TX_ADV;
/* Copy over relevant parameters */
RF_cmdPropTxAdv->pktConf.bFsOff = RF_cmdPropTx->pktConf.bFsOff;
RF_cmdPropTxAdv->pktConf.bUseCrc = RF_cmdPropTx->pktConf.bUseCrc;
RF_cmdPropTxAdv->syncWord = RF_cmdPropTx->syncWord;
}
static void initializeSniffCmdFromRxCmd(rfc_CMD_PROP_RX_SNIFF_t *rxSniffCmd, rfc_CMD_PROP_RX_t *rxCmd) {
/* Copy RX configuration from RX command */
memcpy(rxSniffCmd, rxCmd, sizeof(rfc_CMD_PROP_RX_t));
/* Change to RX_SNIFF command from RX command */
rxSniffCmd->commandNo = CMD_PROP_RX_SNIFF;
}
static uint32_t calculateSymbolRate(uint8_t prescaler, uint32_t rateWord) {
/* Calculate datarate according to TRM Section 23.7.5.2:
* f_baudrate = (R * f_ref)/(p * 2^20)
* - R = rateWord
* - f_ref = 24Mhz
* - p = prescaler */
uint64_t numerator = rateWord * 24000000ULL;
uint64_t denominator = prescaler * 1048576ULL;
uint32_t result = (uint32_t) (numerator / denominator);
return result;
}
static void rf_config_tx(void) {
// Packet length
RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
// Pointer to packet
RF_cmdPropTx.pPkt = (uint8_t*) &tx_payload;
#if ACK_MODE == true
RF_cmdPropTx.pNextOp = (rfc_radioOp_t*) &RF_cmdPropRxAdv;
// Only run the RX command if TX is successful
RF_cmdPropTx.condition.rule = COND_STOP_ON_FALSE;
RF_cmdPropRxAdv = RF_cmdPropRxAdv_preDef;
// RX to wait for ACK
RF_cmdPropRxAdv.pQueue = &dataQueue;
// Discard ignored packets from Rx queue
RF_cmdPropRxAdv.rxConf.bAutoFlushIgnored = 1;
// Discard packets with CRC error from Rx queue
RF_cmdPropRxAdv.rxConf.bAutoFlushCrcErr = 1;
// Implement packet length filtering to avoid PROP_ERROR_RXBUF
RF_cmdPropRxAdv.maxPktLen = MAX_LENGTH;
RF_cmdPropRxAdv.pktConf.bRepeatOk = 0;
RF_cmdPropRxAdv.pktConf.bRepeatNok = 0;
RF_cmdPropRxAdv.pOutput = (uint8_t*) &rx_statistics;
// Receive operation will end RX_TIMEOUT ms after command starts
RF_cmdPropRxAdv.endTrigger.triggerType = TRIG_REL_PREVEND;
RF_cmdPropRxAdv.endTime = RADIO_WAIT_IN_MS(ACK_TIMEOUT_MS);
// Filter address to only MR14
RF_cmdPropRxAdv.pktConf.filterOp = 1;
RF_cmdPropRxAdv.addrConf.addrSize = 8;
RF_cmdPropRxAdv.addrConf.numAddr = 1;
RF_cmdPropRxAdv.pAddr = filter_address;
#endif
// Listen before talk (rfListenBeforeTalk.c)
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;
}
void rf_set_frequency(uint8_t position) {
// Change settings to new frequency
RF_cmdFs.frequency = RF_FREQUENCY[position];
RF_cmdFs.fractFreq = RF_FREQUENCY_FRACT[position];
RF_cmdPropRadioDivSetup.centerFreq = RF_FREQUENCY[position];
// Set the frequency
if (rf_handle != NULL) {
RF_runCmd(rf_handle, (RF_Op*) &RF_cmdFs, RF_PriorityNormal, NULL, 0);
}
}
