51 #include "sys/clock.h" 62 #include "hw_rfc_dbell.h" 63 #include "hw_rfc_pwr.h" 66 #include "rf-core/api/ieee_cmd.h" 67 #include "rf-core/api/ieee_mailbox.h" 68 #include "driverlib/rf_mailbox.h" 69 #include "driverlib/rf_common_cmd.h" 70 #include "driverlib/rf_data_entry.h" 72 #include "smartrf-settings.h" 81 #define PRINTF(...) printf(__VA_ARGS__) 87 #ifdef IEEE_MODE_CONF_AUTOACK 88 #define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK 90 #define IEEE_MODE_AUTOACK 1 94 #ifdef IEEE_MODE_CONF_PROMISCOUS 95 #define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS 97 #define IEEE_MODE_PROMISCOUS 0 100 #ifdef IEEE_MODE_CONF_RSSI_THRESHOLD 101 #define IEEE_MODE_RSSI_THRESHOLD IEEE_MODE_CONF_RSSI_THRESHOLD 103 #define IEEE_MODE_RSSI_THRESHOLD 0xA6 106 #define STATUS_CRC_FAIL 0x80 107 #define STATUS_REJECT_FRAME 0x40 108 #define STATUS_CORRELATION 0x3f 111 #define DATA_ENTRY_STATUS_PENDING 0x00 112 #define DATA_ENTRY_STATUS_ACTIVE 0x01 113 #define DATA_ENTRY_STATUS_BUSY 0x02 114 #define DATA_ENTRY_STATUS_FINISHED 0x03 115 #define DATA_ENTRY_STATUS_UNFINISHED 0x04 118 static uint8_t rf_stats[16] = { 0 };
121 #define RF_CMD_BUFFER_SIZE 128 123 #define RAT_TIMESTAMP_OFFSET_2_4_GHZ 0 133 #define RF_RADIO_OP_GET_STATUS(a) (((rfc_radioOp_t *)a)->status) 135 #define IEEE_MODE_CHANNEL_MIN 11 136 #define IEEE_MODE_CHANNEL_MAX 26 139 typedef struct output_config {
144 static const output_config_t output_power[] = {
160 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) 163 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) 164 #define OUTPUT_POWER_MAX (output_power[0].dbm) 165 #define OUTPUT_POWER_UNKNOWN 0xFFFF 168 static const output_config_t *tx_power_current = &output_power[0];
170 static rfc_CMD_IEEE_MOD_FILT_t filter_cmd;
182 static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN(4);
188 #define CHECKSUM_LEN 2 195 #define MAX_PAYLOAD_LEN (127 - CHECKSUM_LEN) 197 #define DATA_ENTRY_LENSZ_NONE 0 198 #define DATA_ENTRY_LENSZ_BYTE 1 199 #define DATA_ENTRY_LENSZ_WORD 2 202 #define RX_BUF_METADATA_SIZE \ 203 (2 * RF_CORE_RX_BUF_INCLUDE_CRC \ 204 + RF_CORE_RX_BUF_INCLUDE_RSSI \ 205 + RF_CORE_RX_BUF_INCLUDE_CORR \ 206 + 4 * RF_CORE_RX_BUF_INCLUDE_TIMESTAMP) 209 #define RX_BUF_LENGTH_OFFSET sizeof(rfc_dataEntry_t) 211 #define RX_BUF_DATA_OFFSET (RX_BUF_LENGTH_OFFSET + 1) 213 #define RX_BUF_SIZE (RX_BUF_DATA_OFFSET \ 215 + RX_BUF_METADATA_SIZE) 218 static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4);
219 static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
220 static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4);
221 static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4);
224 static dataQueue_t rx_data_queue = { 0 };
227 volatile static uint8_t *rx_read_entry;
230 #define TX_BUF_PAYLOAD_LEN 180 231 #define TX_BUF_HDR_LEN 2 233 static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
235 #ifdef IEEE_MODE_CONF_BOARD_OVERRIDES 236 #define IEEE_MODE_BOARD_OVERRIDES IEEE_MODE_CONF_BOARD_OVERRIDES 238 #define IEEE_MODE_BOARD_OVERRIDES 242 static uint32_t ieee_overrides[] = {
255 IEEE_MODE_BOARD_OVERRIDES
260 static int off(
void);
288 rfc_CMD_IEEE_CCA_REQ_t cmd;
295 memset(&cmd, 0x00,
sizeof(cmd));
297 cmd.commandNo = CMD_IEEE_CCA_REQ;
300 PRINTF(
"transmitting: CMDSTA=0x%08lx\n", cmd_status);
304 if((cmd.currentRssi == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) &&
305 (cmd.ccaInfo.ccaEnergy == RF_CORE_CMD_CCA_REQ_CCA_STATE_BUSY)) {
327 rfc_CMD_IEEE_CCA_REQ_t cmd;
330 PRINTF(
"get_cca_info: Not on\n");
331 return RF_CORE_GET_CCA_INFO_ERROR;
334 memset(&cmd, 0x00,
sizeof(cmd));
335 cmd.ccaInfo.ccaState = RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID;
337 while(cmd.ccaInfo.ccaState == RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID) {
338 memset(&cmd, 0x00,
sizeof(cmd));
339 cmd.commandNo = CMD_IEEE_CCA_REQ;
342 PRINTF(
"get_cca_info: CMDSTA=0x%08lx\n", cmd_status);
344 return RF_CORE_GET_CCA_INFO_ERROR;
349 return *((uint8_t *)&cmd.ccaInfo);
364 rfc_CMD_IEEE_CCA_REQ_t cmd;
369 if(on() != RF_CORE_CMD_OK) {
370 PRINTF(
"get_rssi: on() failed\n");
371 return RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
375 memset(&cmd, 0x00,
sizeof(cmd));
376 cmd.ccaInfo.ccaEnergy = RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID;
378 while(cmd.ccaInfo.ccaEnergy == RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID) {
379 memset(&cmd, 0x00,
sizeof(cmd));
380 cmd.commandNo = CMD_IEEE_CCA_REQ;
383 PRINTF(
"get_rssi: CMDSTA=0x%08lx\n", cmd_status);
386 cmd.currentRssi = RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
396 return cmd.currentRssi;
403 return tx_power_current->dbm;
417 rfc_CMD_SET_TX_POWER_t cmd;
420 for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
421 if(power <= output_power[i].dbm) {
422 tx_power_current = &output_power[i];
437 memset(&cmd, 0x00,
sizeof(cmd));
438 cmd.commandNo = CMD_SET_TX_POWER;
439 cmd.txPower = output_power[i].tx_power;
442 PRINTF(
"set_tx_power: CMDSTA=0x%08lx\n", cmd_status);
450 rfc_CMD_RADIO_SETUP_t cmd;
452 rf_switch_select_path(RF_SWITCH_PATH_2_4GHZ);
457 cmd.txPower = tx_power_current->tx_power;
458 cmd.pRegOverride = ieee_overrides;
459 cmd.config.frontEndMode = RF_CORE_RADIO_SETUP_FRONT_END_MODE;
460 cmd.config.biasMode = RF_CORE_RADIO_SETUP_BIAS_MODE;
465 PRINTF(
"rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n",
466 cmd_status, cmd.status);
467 return RF_CORE_CMD_ERROR;
472 PRINTF(
"rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n",
473 cmd_status, cmd.status);
474 return RF_CORE_CMD_ERROR;
477 return RF_CORE_CMD_OK;
498 if(ret != RF_CORE_CMD_OK) {
499 PRINTF(
"rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
501 return RF_CORE_CMD_ERROR;
505 RF_CORE_ENTER_RX_TIMEOUT);
509 PRINTF(
"rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n",
511 return RF_CORE_CMD_ERROR;
518 init_rx_buffers(
void)
520 rfc_dataEntry_t *entry;
522 entry = (rfc_dataEntry_t *)rx_buf_0;
523 entry->pNextEntry = rx_buf_1;
524 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
525 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
527 entry = (rfc_dataEntry_t *)rx_buf_1;
528 entry->pNextEntry = rx_buf_2;
529 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
530 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
532 entry = (rfc_dataEntry_t *)rx_buf_2;
533 entry->pNextEntry = rx_buf_3;
534 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
535 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
537 entry = (rfc_dataEntry_t *)rx_buf_3;
538 entry->pNextEntry = rx_buf_0;
539 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
540 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
546 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
548 memset(cmd_ieee_rx_buf, 0x00, RF_CMD_BUFFER_SIZE);
550 cmd->commandNo = CMD_IEEE_RX;
551 cmd->status = RF_CORE_RADIO_OP_STATUS_IDLE;
553 cmd->startTime = 0x00000000;
554 cmd->startTrigger.triggerType = TRIG_NOW;
555 cmd->condition.rule = COND_NEVER;
558 cmd->rxConfig.bAutoFlushCrc = 1;
559 cmd->rxConfig.bAutoFlushIgn = 0;
560 cmd->rxConfig.bIncludePhyHdr = 0;
561 cmd->rxConfig.bIncludeCrc = RF_CORE_RX_BUF_INCLUDE_CRC;
562 cmd->rxConfig.bAppendRssi = RF_CORE_RX_BUF_INCLUDE_RSSI;
563 cmd->rxConfig.bAppendCorrCrc = RF_CORE_RX_BUF_INCLUDE_CORR;
564 cmd->rxConfig.bAppendSrcInd = 0;
565 cmd->rxConfig.bAppendTimestamp = RF_CORE_RX_BUF_INCLUDE_TIMESTAMP;
567 cmd->pRxQ = &rx_data_queue;
568 cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats;
570 #if IEEE_MODE_PROMISCOUS 571 cmd->frameFiltOpt.frameFiltEn = 0;
573 cmd->frameFiltOpt.frameFiltEn = 1;
576 cmd->frameFiltOpt.frameFiltStop = 1;
578 #if IEEE_MODE_AUTOACK 579 cmd->frameFiltOpt.autoAckEn = 1;
581 cmd->frameFiltOpt.autoAckEn = 0;
584 cmd->frameFiltOpt.slottedAckEn = 0;
585 cmd->frameFiltOpt.autoPendEn = 0;
586 cmd->frameFiltOpt.defaultPend = 0;
587 cmd->frameFiltOpt.bPendDataReqOnly = 0;
588 cmd->frameFiltOpt.bPanCoord = 0;
589 cmd->frameFiltOpt.maxFrameVersion = 2;
590 cmd->frameFiltOpt.bStrictLenFilter = 0;
593 cmd->frameTypes.bAcceptFt0Beacon = 1;
594 cmd->frameTypes.bAcceptFt1Data = 1;
595 cmd->frameTypes.bAcceptFt2Ack = 1;
596 cmd->frameTypes.bAcceptFt3MacCmd = 1;
597 cmd->frameTypes.bAcceptFt4Reserved = 1;
598 cmd->frameTypes.bAcceptFt5Reserved = 1;
599 cmd->frameTypes.bAcceptFt6Reserved = 1;
600 cmd->frameTypes.bAcceptFt7Reserved = 1;
603 cmd->ccaOpt.ccaEnEnergy = 1;
604 cmd->ccaOpt.ccaEnCorr = 1;
605 cmd->ccaOpt.ccaEnSync = 1;
606 cmd->ccaOpt.ccaCorrOp = 1;
607 cmd->ccaOpt.ccaSyncOp = 0;
608 cmd->ccaOpt.ccaCorrThr = 3;
610 cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD;
612 cmd->numExtEntries = 0x00;
613 cmd->numShortEntries = 0x00;
614 cmd->pExtEntryList = 0;
615 cmd->pShortEntryList = 0;
617 cmd->endTrigger.triggerType = TRIG_NEVER;
618 cmd->endTime = 0x00000000;
621 filter_cmd.commandNo = CMD_IEEE_MOD_FILT;
622 memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt,
sizeof(cmd->frameFiltOpt));
623 memcpy(&filter_cmd.newFrameTypes, &cmd->frameTypes,
sizeof(cmd->frameTypes));
635 return RF_CORE_CMD_OK;
642 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
656 return RF_CORE_CMD_OK;
663 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
664 PRINTF(
"RX off: CMD_ABORT status=0x%08lx\n", cmd_status);
673 ret = RF_CORE_CMD_OK;
676 ret = RF_CORE_CMD_ERROR;
679 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
692 return LPM_MODE_SLEEP;
695 return LPM_MODE_MAX_SUPPORTED;
698 LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
710 PRINTF(
"soft_off: Aborting 0x%04x, Status=0x%04x\n", cmd->commandNo,
714 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
715 PRINTF(
"soft_off: CMD_ABORT status=0x%08lx\n", cmd_status);
720 RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING, RF_CORE_TURN_OFF_TIMEOUT);
726 if(rf_radio_setup() != RF_CORE_CMD_OK) {
727 PRINTF(
"on: radio_setup() failed\n");
728 return RF_CORE_CMD_ERROR;
738 RAT_TIMESTAMP_OFFSET_2_4_GHZ
749 memset(rx_buf_0, 0, RX_BUF_SIZE);
750 memset(rx_buf_1, 0, RX_BUF_SIZE);
751 memset(rx_buf_2, 0, RX_BUF_SIZE);
752 memset(rx_buf_3, 0, RX_BUF_SIZE);
755 rx_data_queue.pCurrEntry = rx_buf_0;
757 rx_data_queue.pLastEntry = NULL;
760 rx_read_entry = rx_buf_0;
765 if(on() != RF_CORE_CMD_OK) {
766 PRINTF(
"init: on() failed\n");
767 return RF_CORE_CMD_ERROR;
770 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
781 prepare(
const void *payload,
unsigned short payload_len)
783 if(payload_len > TX_BUF_PAYLOAD_LEN || payload_len > MAX_PAYLOAD_LEN) {
787 memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, payload_len);
792 transmit(
unsigned short transmit_len)
798 uint8_t tx_active = 0;
800 volatile rfc_CMD_IEEE_TX_t cmd;
802 if(transmit_len > MAX_PAYLOAD_LEN) {
803 PRINTF(
"transmit: too long\n");
809 if(on() != RF_CORE_CMD_OK) {
810 PRINTF(
"transmit: on() failed\n");
824 }
while(tx_active == 1 &&
825 (RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + RF_CORE_TX_TIMEOUT)));
828 PRINTF(
"transmit: Already TXing and wait timed out\n");
834 return RADIO_TX_COLLISION;
840 cmd.payloadLen = transmit_len;
841 cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
844 cmd.startTrigger.triggerType = TRIG_NOW;
853 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
856 while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS)
857 == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
863 if(!rf_core_poll_mode) {
870 if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) {
875 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret,
881 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
882 ret, cmd_status, cmd.status);
891 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
907 send(
const void *payload,
unsigned short payload_len)
909 prepare(payload, payload_len);
910 return transmit(payload_len);
914 release_data_entry(
void)
916 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
919 rx_read_entry[8] = 0;
922 entry->status = DATA_ENTRY_STATUS_PENDING;
923 rx_read_entry = entry->pNextEntry;
927 read_frame(
void *buf,
unsigned short buf_len)
930 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
931 uint32_t rat_timestamp;
935 while(entry->status == DATA_ENTRY_STATUS_BUSY
938 if(entry->status != DATA_ENTRY_STATUS_FINISHED) {
943 len = rx_read_entry[RX_BUF_LENGTH_OFFSET];
944 if(len <= RX_BUF_METADATA_SIZE) {
945 PRINTF(
"RF: too short!");
947 release_data_entry();
951 len -= RX_BUF_METADATA_SIZE;
953 PRINTF(
"RF: too long\n");
955 release_data_entry();
959 memcpy(buf, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET, len);
961 rf_core_last_rssi = (int8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len];
962 rf_core_last_corr_lqi = (uint8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 1] & STATUS_CORRELATION;
965 memcpy(&rat_timestamp, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET + len + 2, 4);
969 if(!rf_core_poll_mode) {
973 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf_core_last_rssi);
974 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf_core_last_corr_lqi);
977 release_data_entry();
987 int ret = RF_CORE_CCA_CLEAR;
994 PRINTF(
"channel_clear: Interrupt context but BLE in progress\n");
995 return RF_CORE_CCA_CLEAR;
1010 if(on() != RF_CORE_CMD_OK) {
1011 PRINTF(
"channel_clear: on() failed\n");
1015 return RF_CORE_CCA_CLEAR;
1021 if(cca_info == RF_CORE_GET_CCA_INFO_ERROR) {
1022 PRINTF(
"channel_clear: CCA error\n");
1023 ret = RF_CORE_CCA_CLEAR;
1029 ret = (cca_info & 0x03) != RF_CORE_CMD_CCA_REQ_CCA_STATE_BUSY;
1040 receiving_packet(
void)
1049 PRINTF(
"receiving_packet: Interrupt context but BLE in progress\n");
1055 PRINTF(
"receiving_packet: We were off\n");
1061 PRINTF(
"receiving_packet: We were TXing\n");
1068 if(cca_info == RF_CORE_GET_CCA_INFO_ERROR) {
1073 if(cca_info & RF_CORE_CMD_CCA_REQ_CCA_SYNC_BUSY) {
1081 pending_packet(
void)
1083 volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
1088 if(entry->status == DATA_ENTRY_STATUS_FINISHED
1089 || entry->status == DATA_ENTRY_STATUS_BUSY) {
1091 if(!rf_core_poll_mode) {
1096 entry = (rfc_dataEntry_t *)entry->pNextEntry;
1097 }
while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
1111 PRINTF(
"on: Interrupt context but BLE in progress\n");
1112 return RF_CORE_CMD_OK;
1124 return RF_CORE_CMD_OK;
1138 PRINTF(
"on: rf_core_boot() failed\n");
1139 return RF_CORE_CMD_ERROR;
1144 if(rf_radio_setup() != RF_CORE_CMD_OK) {
1145 PRINTF(
"on: radio_setup() failed\n");
1146 return RF_CORE_CMD_ERROR;
1160 PRINTF(
"off: Interrupt context but BLE in progress\n");
1161 return RF_CORE_CMD_OK;
1170 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
1172 #if !CC2650_FAST_RADIO_STARTUP 1180 ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
1186 if(((rfc_dataEntry_t *)rx_buf_0)->status == DATA_ENTRY_STATUS_BUSY) {
1187 ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING;
1189 if(((rfc_dataEntry_t *)rx_buf_1)->status == DATA_ENTRY_STATUS_BUSY) {
1190 ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING;
1192 if(((rfc_dataEntry_t *)rx_buf_2)->status == DATA_ENTRY_STATUS_BUSY) {
1193 ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING;
1195 if(((rfc_dataEntry_t *)rx_buf_3)->status == DATA_ENTRY_STATUS_BUSY) {
1196 ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING;
1199 return RF_CORE_CMD_OK;
1203 static radio_result_t
1204 set_send_on_cca(uint8_t enable)
1208 return RADIO_RESULT_NOT_SUPPORTED;
1210 return RADIO_RESULT_OK;
1213 static radio_result_t
1216 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1219 return RADIO_RESULT_INVALID_VALUE;
1223 case RADIO_PARAM_POWER_MODE:
1225 *value =
rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1226 return RADIO_RESULT_OK;
1227 case RADIO_PARAM_CHANNEL:
1229 return RADIO_RESULT_OK;
1230 case RADIO_PARAM_PAN_ID:
1232 return RADIO_RESULT_OK;
1233 case RADIO_PARAM_16BIT_ADDR:
1235 return RADIO_RESULT_OK;
1236 case RADIO_PARAM_RX_MODE:
1238 if(cmd->frameFiltOpt.frameFiltEn) {
1241 if(cmd->frameFiltOpt.autoAckEn) {
1242 *value |= RADIO_RX_MODE_AUTOACK;
1244 if(rf_core_poll_mode) {
1245 *value |= RADIO_RX_MODE_POLL_MODE;
1248 return RADIO_RESULT_OK;
1249 case RADIO_PARAM_TX_MODE:
1251 return RADIO_RESULT_OK;
1252 case RADIO_PARAM_TXPOWER:
1253 *value = get_tx_power();
1254 return RADIO_RESULT_OK;
1255 case RADIO_PARAM_CCA_THRESHOLD:
1256 *value = cmd->ccaRssiThr;
1257 return RADIO_RESULT_OK;
1258 case RADIO_PARAM_RSSI:
1261 if(*value == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) {
1262 return RADIO_RESULT_ERROR;
1264 return RADIO_RESULT_OK;
1266 case RADIO_CONST_CHANNEL_MIN:
1267 *value = IEEE_MODE_CHANNEL_MIN;
1268 return RADIO_RESULT_OK;
1269 case RADIO_CONST_CHANNEL_MAX:
1270 *value = IEEE_MODE_CHANNEL_MAX;
1271 return RADIO_RESULT_OK;
1272 case RADIO_CONST_TXPOWER_MIN:
1273 *value = OUTPUT_POWER_MIN;
1274 return RADIO_RESULT_OK;
1275 case RADIO_CONST_TXPOWER_MAX:
1276 *value = OUTPUT_POWER_MAX;
1277 return RADIO_RESULT_OK;
1278 case RADIO_PARAM_LAST_RSSI:
1279 *value = rf_core_last_rssi;
1280 return RADIO_RESULT_OK;
1281 case RADIO_PARAM_LAST_LINK_QUALITY:
1282 *value = rf_core_last_corr_lqi;
1283 return RADIO_RESULT_OK;
1284 case RADIO_CONST_PHY_OVERHEAD:
1286 return RADIO_RESULT_OK;
1287 case RADIO_CONST_BYTE_AIR_TIME:
1289 return RADIO_RESULT_OK;
1290 case RADIO_CONST_DELAY_BEFORE_TX:
1292 return RADIO_RESULT_OK;
1293 case RADIO_CONST_DELAY_BEFORE_RX:
1295 return RADIO_RESULT_OK;
1296 case RADIO_CONST_DELAY_BEFORE_DETECT:
1298 return RADIO_RESULT_OK;
1299 case RADIO_CONST_MAX_PAYLOAD_LEN:
1301 return RADIO_RESULT_OK;
1303 return RADIO_RESULT_NOT_SUPPORTED;
1307 static radio_result_t
1310 radio_result_t rv = RADIO_RESULT_OK;
1311 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1312 uint8_t old_poll_mode;
1315 case RADIO_PARAM_POWER_MODE:
1316 if(value == RADIO_POWER_MODE_ON) {
1317 if(on() != RF_CORE_CMD_OK) {
1318 PRINTF(
"set_value: on() failed (1)\n");
1319 return RADIO_RESULT_ERROR;
1321 return RADIO_RESULT_OK;
1323 if(value == RADIO_POWER_MODE_OFF) {
1325 return RADIO_RESULT_OK;
1327 return RADIO_RESULT_INVALID_VALUE;
1328 case RADIO_PARAM_CHANNEL:
1329 if(value < IEEE_MODE_CHANNEL_MIN ||
1330 value > IEEE_MODE_CHANNEL_MAX) {
1331 return RADIO_RESULT_INVALID_VALUE;
1335 if(cmd->channel == (uint8_t)value) {
1338 return RADIO_RESULT_OK;
1341 cmd->channel = (uint8_t)value;
1343 case RADIO_PARAM_PAN_ID:
1344 cmd->localPanID = (uint16_t)value;
1346 case RADIO_PARAM_16BIT_ADDR:
1347 cmd->localShortAddr = (uint16_t)value;
1349 case RADIO_PARAM_RX_MODE:
1352 RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) {
1353 return RADIO_RESULT_INVALID_VALUE;
1357 cmd->frameFiltOpt.frameFiltStop = 1;
1358 cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
1359 cmd->frameFiltOpt.slottedAckEn = 0;
1360 cmd->frameFiltOpt.autoPendEn = 0;
1361 cmd->frameFiltOpt.defaultPend = 0;
1362 cmd->frameFiltOpt.bPendDataReqOnly = 0;
1363 cmd->frameFiltOpt.bPanCoord = 0;
1364 cmd->frameFiltOpt.bStrictLenFilter = 0;
1366 old_poll_mode = rf_core_poll_mode;
1367 rf_core_poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
1368 if(rf_core_poll_mode == old_poll_mode) {
1369 uint32_t cmd_status;
1372 memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt,
sizeof(cmd->frameFiltOpt));
1374 if(
rf_core_send_cmd((uint32_t)&filter_cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
1375 PRINTF(
"setting address filter failed: CMDSTA=0x%08lx\n", cmd_status);
1376 return RADIO_RESULT_ERROR;
1378 return RADIO_RESULT_OK;
1383 case RADIO_PARAM_TX_MODE:
1385 return RADIO_RESULT_INVALID_VALUE;
1389 case RADIO_PARAM_TXPOWER:
1390 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1391 return RADIO_RESULT_INVALID_VALUE;
1394 set_tx_power(value);
1396 return RADIO_RESULT_OK;
1398 case RADIO_PARAM_CCA_THRESHOLD:
1399 cmd->ccaRssiThr = (int8_t)value;
1403 return RADIO_RESULT_NOT_SUPPORTED;
1408 return RADIO_RESULT_OK;
1412 if(rx_off() != RF_CORE_CMD_OK) {
1413 PRINTF(
"set_value: rx_off() failed\n");
1414 rv = RADIO_RESULT_ERROR;
1423 if(rx_on() != RF_CORE_CMD_OK) {
1424 PRINTF(
"set_value: rx_on() failed\n");
1425 rv = RADIO_RESULT_ERROR;
1431 static radio_result_t
1432 get_object(radio_param_t param,
void *dest,
size_t size)
1437 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1439 if(param == RADIO_PARAM_64BIT_ADDR) {
1440 if(size != 8 || !dest) {
1441 return RADIO_RESULT_INVALID_VALUE;
1445 src = (uint8_t *)(&cmd->localExtAddr);
1447 for(i = 0; i < 8; i++) {
1448 target[i] = src[7 - i];
1451 return RADIO_RESULT_OK;
1454 if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
1455 if(size !=
sizeof(rtimer_clock_t) || !dest) {
1456 return RADIO_RESULT_INVALID_VALUE;
1458 *(rtimer_clock_t *)dest = rf_core_last_packet_timestamp;
1460 return RADIO_RESULT_OK;
1463 return RADIO_RESULT_NOT_SUPPORTED;
1466 static radio_result_t
1467 set_object(radio_param_t param,
const void *src,
size_t size)
1469 radio_result_t rv = RADIO_RESULT_OK;
1472 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1474 if(param == RADIO_PARAM_64BIT_ADDR) {
1475 if(size != 8 || !src) {
1476 return RADIO_RESULT_INVALID_VALUE;
1479 dst = (uint8_t *)(&cmd->localExtAddr);
1481 for(i = 0; i < 8; i++) {
1482 dst[i] = ((uint8_t *)src)[7 - i];
1487 return RADIO_RESULT_OK;
1490 if(rx_off() != RF_CORE_CMD_OK) {
1491 PRINTF(
"set_object: rx_off() failed\n");
1492 rv = RADIO_RESULT_ERROR;
1495 if(rx_on() != RF_CORE_CMD_OK) {
1496 PRINTF(
"set_object: rx_on() failed\n");
1497 rv = RADIO_RESULT_ERROR;
1502 return RADIO_RESULT_NOT_SUPPORTED;
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch...
static uint8_t transmitting(void)
Check the RF's TX status.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
static uint8_t rf_cmd_ieee_rx()
Set up radio in IEEE802.15.4 RX mode.
Header file with macros which rename TI CC26xxware functions.
static uint8_t rf_is_on(void)
Checks whether the RFC domain is accessible and the RFC is in IEEE RX.
Header file for the energy estimation mechanism
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
Header file for the radio API
Header file for the link-layer address representation
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
The structure of a device driver for a radio in Contiki.
#define RTIMER_BUSYWAIT_UNTIL(cond, max_time)
Busy-wait until a condition for at most max_time.
void lpm_sleep(void)
Enter sleep mode.
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
Header file for the CC13xx/CC26xx RF core driver.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
#define RTIMER_SECOND
Number of rtimer ticks for 1 second.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
#define RTIMER_NOW()
Get the current clock time.
Header file for the CC13xx/CC26xx oscillator control.
uint32_t rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
Convert from RAT timestamp to rtimer ticks.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
Header file for the callback timer
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
A data strcuture representing the radio's primary mode of operation.
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
void process_poll(struct process *p)
Request a process to be polled.
int(* off)(void)
Turn the radio off.
Header file for the real-time timer module.
uint8_t rf_core_rat_init(void)
Initialize the RAT to RTC conversion machinery.
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
void rf_core_cmd_done_dis(void)
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
void rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
Prepare a buffer to host a Radio Op.
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
Header file for the CC13xx/CC26xx BLE driver.
Header file with definitions related to RF switch support.
#define RADIO_TX_MODE_SEND_ON_CCA
The radio transmission mode controls whether transmissions should be done using clear channel assessm...
static uint8_t get_cca_info(void)
Returns CCA information.
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
Header file for the CC13xx/CC26xx UART driver.
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Header file for the Packet buffer (packetbuf) management
#define LPM_MODULE(n, m, s, w, l)
Declare a variable to be used in order to get notifications from LPM.
void rf_core_setup_interrupts(void)
Setup RF core interrupts.
Include file for the Contiki low-layer network stack (NETSTACK)
uint8_t rf_core_restart_rat(void)
Restart the CM0 RAT.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Default definitions of C compiler quirk work-arounds.
uint8_t rf_core_boot()
Boot the RF Core.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
uint8_t rf_core_check_rat_overflow(void)
Check if RAT overflow has occured and increment the overflow counter if so.
int(* on)(void)
Turn the radio on.
void process_start(struct process *p, process_data_t data)
Start a process.
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
#define RF_RADIO_OP_GET_STATUS(a)
Returns the current status of a running Radio Op command.