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");
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
936 && RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + RADIO_FRAME_DURATION(MAX_PAYLOAD_LEN)));
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;
1204 set_send_on_cca(uint8_t enable)
1216 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1238 if(cmd->frameFiltOpt.frameFiltEn) {
1241 if(cmd->frameFiltOpt.autoAckEn) {
1244 if(rf_core_poll_mode) {
1253 *value = get_tx_power();
1256 *value = cmd->ccaRssiThr;
1261 if(*value == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) {
1267 *value = IEEE_MODE_CHANNEL_MIN;
1270 *value = IEEE_MODE_CHANNEL_MAX;
1273 *value = OUTPUT_POWER_MIN;
1276 *value = OUTPUT_POWER_MAX;
1279 *value = rf_core_last_rssi;
1282 *value = rf_core_last_corr_lqi;
1299 case RADIO_CONST_MAX_PAYLOAD_LEN:
1311 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1312 uint8_t old_poll_mode;
1317 if(on() != RF_CORE_CMD_OK) {
1318 PRINTF(
"set_value: on() failed (1)\n");
1329 if(value < IEEE_MODE_CHANNEL_MIN ||
1330 value > IEEE_MODE_CHANNEL_MAX) {
1335 if(cmd->channel == (uint8_t)value) {
1341 cmd->channel = (uint8_t)value;
1344 cmd->localPanID = (uint16_t)value;
1347 cmd->localShortAddr = (uint16_t)value;
1357 cmd->frameFiltOpt.frameFiltStop = 1;
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;
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);
1390 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1394 set_tx_power(value);
1399 cmd->ccaRssiThr = (int8_t)value;
1412 if(rx_off() != RF_CORE_CMD_OK) {
1413 PRINTF(
"set_value: rx_off() failed\n");
1423 if(rx_on() != RF_CORE_CMD_OK) {
1424 PRINTF(
"set_value: rx_on() failed\n");
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;
1440 if(size != 8 || !dest) {
1445 src = (uint8_t *)(&cmd->localExtAddr);
1447 for(i = 0; i < 8; i++) {
1448 target[i] = src[7 - i];
1455 if(size !=
sizeof(rtimer_clock_t) || !dest) {
1458 *(rtimer_clock_t *)dest = rf_core_last_packet_timestamp;
1467 set_object(radio_param_t param,
const void *src,
size_t size)
1472 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1475 if(size != 8 || !src) {
1479 dst = (uint8_t *)(&cmd->localExtAddr);
1481 for(i = 0; i < 8; i++) {
1482 dst[i] = ((uint8_t *)src)[7 - i];
1490 if(rx_off() != RF_CORE_CMD_OK) {
1491 PRINTF(
"set_object: rx_off() failed\n");
1495 if(rx_on() != RF_CORE_CMD_OK) {
1496 PRINTF(
"set_object: rx_on() failed\n");
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.
The delay in usec between turning on the radio and it being actually listening (able to hear a preamb...
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.
The parameter is not supported.
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
TX failed due to a collision.
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
The delay in usec between a call to the radio API's transmit function and the end of SFD transmission...
The maximum transmission power in dBm.
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.
Received signal strength indicator in dBm.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
The short address (16 bits) for the radio, which is used by the h/w filter.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver's buffers.
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
The structure of a Contiki-NG radio device driver.
#define RTIMER_BUSYWAIT_UNTIL(cond, max_time)
Busy-wait until a condition for at most max_time.
Channel used for radio communication.
The value argument was incorrect.
The parameter was set/read successfully.
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...
An error occurred when getting/setting the parameter, but the arguments were otherwise correct...
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
#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.
The RSSI value of the last received packet.
The physical layer header (PHR) + MAC layer footer (MFR) overhead in bytes.
uint32_t rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
Convert from RAT timestamp to rtimer ticks.
Clear channel assessment threshold in dBm.
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.
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
The lowest radio channel number.
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
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)
The highest radio channel number.
The air time of one byte in usec, e.g.
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
Enable address-based frame filtering.
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
Header file for the CC13xx/CC26xx BLE driver.
Header file with definitions related to RF switch support.
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
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.
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
int(* init)(void)
Initialise the radio hardware.
The delay in usec between the end of SFD reception for an incoming frame and the radio API starting t...
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
Link quality indicator of the last received packet.
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
Long (64 bits) address for the radio, which is used by the address filter.
The minimum transmission power in dBm.
Radio powered on and able to receive frames.
Transmission power in dBm.
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.
Last packet timestamp, of type rtimer_clock_t.
An error occurred during transmission.
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.
Radio powered off and in the lowest possible power consumption state.
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
TX was successful and where an ACK was requested one was received.
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.