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);
184 #define DATA_ENTRY_LENSZ_NONE 0 185 #define DATA_ENTRY_LENSZ_BYTE 1 186 #define DATA_ENTRY_LENSZ_WORD 2 189 #define RX_BUF_METADATA_SIZE \ 190 (2 * RF_CORE_RX_BUF_INCLUDE_CRC \ 191 + RF_CORE_RX_BUF_INCLUDE_RSSI \ 192 + RF_CORE_RX_BUF_INCLUDE_CORR \ 193 + 4 * RF_CORE_RX_BUF_INCLUDE_TIMESTAMP) 196 #define RX_BUF_LENGTH_OFFSET sizeof(rfc_dataEntry_t) 198 #define RX_BUF_DATA_OFFSET (RX_BUF_LENGTH_OFFSET + 1) 200 #define RX_BUF_SIZE (RX_BUF_DATA_OFFSET \ 201 + NETSTACK_RADIO_MAX_PAYLOAD_LEN \ 202 + RX_BUF_METADATA_SIZE) 205 static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4);
206 static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
207 static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4);
208 static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4);
211 static dataQueue_t rx_data_queue = { 0 };
214 volatile static uint8_t *rx_read_entry;
217 #define TX_BUF_PAYLOAD_LEN 180 218 #define TX_BUF_HDR_LEN 2 220 static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
222 #ifdef IEEE_MODE_CONF_BOARD_OVERRIDES 223 #define IEEE_MODE_BOARD_OVERRIDES IEEE_MODE_CONF_BOARD_OVERRIDES 225 #define IEEE_MODE_BOARD_OVERRIDES 229 static uint32_t ieee_overrides[] = {
242 IEEE_MODE_BOARD_OVERRIDES
247 static int off(
void);
275 rfc_CMD_IEEE_CCA_REQ_t cmd;
282 memset(&cmd, 0x00,
sizeof(cmd));
284 cmd.commandNo = CMD_IEEE_CCA_REQ;
287 PRINTF(
"transmitting: CMDSTA=0x%08lx\n", cmd_status);
291 if((cmd.currentRssi == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) &&
292 (cmd.ccaInfo.ccaEnergy == RF_CORE_CMD_CCA_REQ_CCA_STATE_BUSY)) {
314 rfc_CMD_IEEE_CCA_REQ_t cmd;
317 PRINTF(
"get_cca_info: Not on\n");
318 return RF_CORE_GET_CCA_INFO_ERROR;
321 memset(&cmd, 0x00,
sizeof(cmd));
322 cmd.ccaInfo.ccaState = RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID;
324 while(cmd.ccaInfo.ccaState == RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID) {
325 memset(&cmd, 0x00,
sizeof(cmd));
326 cmd.commandNo = CMD_IEEE_CCA_REQ;
329 PRINTF(
"get_cca_info: CMDSTA=0x%08lx\n", cmd_status);
331 return RF_CORE_GET_CCA_INFO_ERROR;
336 return *((uint8_t *)&cmd.ccaInfo);
351 rfc_CMD_IEEE_CCA_REQ_t cmd;
356 if(on() != RF_CORE_CMD_OK) {
357 PRINTF(
"get_rssi: on() failed\n");
358 return RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
362 memset(&cmd, 0x00,
sizeof(cmd));
363 cmd.ccaInfo.ccaEnergy = RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID;
365 while(cmd.ccaInfo.ccaEnergy == RF_CORE_CMD_CCA_REQ_CCA_STATE_INVALID) {
366 memset(&cmd, 0x00,
sizeof(cmd));
367 cmd.commandNo = CMD_IEEE_CCA_REQ;
370 PRINTF(
"get_rssi: CMDSTA=0x%08lx\n", cmd_status);
373 cmd.currentRssi = RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
383 return cmd.currentRssi;
390 return tx_power_current->dbm;
404 rfc_CMD_SET_TX_POWER_t cmd;
407 for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
408 if(power <= output_power[i].dbm) {
409 tx_power_current = &output_power[i];
424 memset(&cmd, 0x00,
sizeof(cmd));
425 cmd.commandNo = CMD_SET_TX_POWER;
426 cmd.txPower = output_power[i].tx_power;
429 PRINTF(
"set_tx_power: CMDSTA=0x%08lx\n", cmd_status);
437 rfc_CMD_RADIO_SETUP_t cmd;
439 rf_switch_select_path(RF_SWITCH_PATH_2_4GHZ);
444 cmd.txPower = tx_power_current->tx_power;
445 cmd.pRegOverride = ieee_overrides;
446 cmd.config.frontEndMode = RF_CORE_RADIO_SETUP_FRONT_END_MODE;
447 cmd.config.biasMode = RF_CORE_RADIO_SETUP_BIAS_MODE;
452 PRINTF(
"rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n",
453 cmd_status, cmd.status);
454 return RF_CORE_CMD_ERROR;
459 PRINTF(
"rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n",
460 cmd_status, cmd.status);
461 return RF_CORE_CMD_ERROR;
464 return RF_CORE_CMD_OK;
485 if(ret != RF_CORE_CMD_OK) {
486 PRINTF(
"rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
488 return RF_CORE_CMD_ERROR;
492 RF_CORE_ENTER_RX_TIMEOUT);
496 PRINTF(
"rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n",
498 return RF_CORE_CMD_ERROR;
505 init_rx_buffers(
void)
507 rfc_dataEntry_t *entry;
509 entry = (rfc_dataEntry_t *)rx_buf_0;
510 entry->pNextEntry = rx_buf_1;
511 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
512 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
514 entry = (rfc_dataEntry_t *)rx_buf_1;
515 entry->pNextEntry = rx_buf_2;
516 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
517 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
519 entry = (rfc_dataEntry_t *)rx_buf_2;
520 entry->pNextEntry = rx_buf_3;
521 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
522 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
524 entry = (rfc_dataEntry_t *)rx_buf_3;
525 entry->pNextEntry = rx_buf_0;
526 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
527 entry->length =
sizeof(rx_buf_0) -
sizeof(*entry);
533 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
535 memset(cmd_ieee_rx_buf, 0x00, RF_CMD_BUFFER_SIZE);
537 cmd->commandNo = CMD_IEEE_RX;
538 cmd->status = RF_CORE_RADIO_OP_STATUS_IDLE;
540 cmd->startTime = 0x00000000;
541 cmd->startTrigger.triggerType = TRIG_NOW;
542 cmd->condition.rule = COND_NEVER;
545 cmd->rxConfig.bAutoFlushCrc = 1;
546 cmd->rxConfig.bAutoFlushIgn = 0;
547 cmd->rxConfig.bIncludePhyHdr = 0;
548 cmd->rxConfig.bIncludeCrc = RF_CORE_RX_BUF_INCLUDE_CRC;
549 cmd->rxConfig.bAppendRssi = RF_CORE_RX_BUF_INCLUDE_RSSI;
550 cmd->rxConfig.bAppendCorrCrc = RF_CORE_RX_BUF_INCLUDE_CORR;
551 cmd->rxConfig.bAppendSrcInd = 0;
552 cmd->rxConfig.bAppendTimestamp = RF_CORE_RX_BUF_INCLUDE_TIMESTAMP;
554 cmd->pRxQ = &rx_data_queue;
555 cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats;
557 #if IEEE_MODE_PROMISCOUS 558 cmd->frameFiltOpt.frameFiltEn = 0;
560 cmd->frameFiltOpt.frameFiltEn = 1;
563 cmd->frameFiltOpt.frameFiltStop = 1;
565 #if IEEE_MODE_AUTOACK 566 cmd->frameFiltOpt.autoAckEn = 1;
568 cmd->frameFiltOpt.autoAckEn = 0;
571 cmd->frameFiltOpt.slottedAckEn = 0;
572 cmd->frameFiltOpt.autoPendEn = 0;
573 cmd->frameFiltOpt.defaultPend = 0;
574 cmd->frameFiltOpt.bPendDataReqOnly = 0;
575 cmd->frameFiltOpt.bPanCoord = 0;
576 cmd->frameFiltOpt.maxFrameVersion = 2;
577 cmd->frameFiltOpt.bStrictLenFilter = 0;
580 cmd->frameTypes.bAcceptFt0Beacon = 1;
581 cmd->frameTypes.bAcceptFt1Data = 1;
582 cmd->frameTypes.bAcceptFt2Ack = 1;
583 cmd->frameTypes.bAcceptFt3MacCmd = 1;
584 cmd->frameTypes.bAcceptFt4Reserved = 1;
585 cmd->frameTypes.bAcceptFt5Reserved = 1;
586 cmd->frameTypes.bAcceptFt6Reserved = 1;
587 cmd->frameTypes.bAcceptFt7Reserved = 1;
590 cmd->ccaOpt.ccaEnEnergy = 1;
591 cmd->ccaOpt.ccaEnCorr = 1;
592 cmd->ccaOpt.ccaEnSync = 1;
593 cmd->ccaOpt.ccaCorrOp = 1;
594 cmd->ccaOpt.ccaSyncOp = 0;
595 cmd->ccaOpt.ccaCorrThr = 3;
597 cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD;
599 cmd->numExtEntries = 0x00;
600 cmd->numShortEntries = 0x00;
601 cmd->pExtEntryList = 0;
602 cmd->pShortEntryList = 0;
604 cmd->endTrigger.triggerType = TRIG_NEVER;
605 cmd->endTime = 0x00000000;
608 filter_cmd.commandNo = CMD_IEEE_MOD_FILT;
609 memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt,
sizeof(cmd->frameFiltOpt));
610 memcpy(&filter_cmd.newFrameTypes, &cmd->frameTypes,
sizeof(cmd->frameTypes));
622 return RF_CORE_CMD_OK;
629 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
643 return RF_CORE_CMD_OK;
650 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
651 PRINTF(
"RX off: CMD_ABORT status=0x%08lx\n", cmd_status);
660 ret = RF_CORE_CMD_OK;
663 ret = RF_CORE_CMD_ERROR;
666 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
679 return LPM_MODE_SLEEP;
682 return LPM_MODE_MAX_SUPPORTED;
685 LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
697 PRINTF(
"soft_off: Aborting 0x%04x, Status=0x%04x\n", cmd->commandNo,
701 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
702 PRINTF(
"soft_off: CMD_ABORT status=0x%08lx\n", cmd_status);
707 RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING, RF_CORE_TURN_OFF_TIMEOUT);
713 if(rf_radio_setup() != RF_CORE_CMD_OK) {
714 PRINTF(
"on: radio_setup() failed\n");
715 return RF_CORE_CMD_ERROR;
725 RAT_TIMESTAMP_OFFSET_2_4_GHZ
736 memset(rx_buf_0, 0, RX_BUF_SIZE);
737 memset(rx_buf_1, 0, RX_BUF_SIZE);
738 memset(rx_buf_2, 0, RX_BUF_SIZE);
739 memset(rx_buf_3, 0, RX_BUF_SIZE);
742 rx_data_queue.pCurrEntry = rx_buf_0;
744 rx_data_queue.pLastEntry = NULL;
747 rx_read_entry = rx_buf_0;
752 if(on() != RF_CORE_CMD_OK) {
753 PRINTF(
"init: on() failed\n");
754 return RF_CORE_CMD_ERROR;
757 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
768 prepare(
const void *payload,
unsigned short payload_len)
770 int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN);
772 memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len);
777 transmit(
unsigned short transmit_len)
783 uint8_t tx_active = 0;
785 volatile rfc_CMD_IEEE_TX_t cmd;
789 if(on() != RF_CORE_CMD_OK) {
790 PRINTF(
"transmit: on() failed\n");
804 }
while(tx_active == 1 &&
805 (RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + RF_CORE_TX_TIMEOUT)));
808 PRINTF(
"transmit: Already TXing and wait timed out\n");
814 return RADIO_TX_COLLISION;
820 cmd.payloadLen = transmit_len;
821 cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
824 cmd.startTrigger.triggerType = TRIG_NOW;
833 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
836 while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS)
837 == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
843 if(!rf_core_poll_mode) {
850 if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) {
855 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret,
861 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
862 ret, cmd_status, cmd.status);
871 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
887 send(
const void *payload,
unsigned short payload_len)
889 prepare(payload, payload_len);
890 return transmit(payload_len);
894 release_data_entry(
void)
896 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
899 rx_read_entry[8] = 0;
902 entry->status = DATA_ENTRY_STATUS_PENDING;
903 rx_read_entry = entry->pNextEntry;
907 read_frame(
void *buf,
unsigned short buf_len)
910 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
911 uint32_t rat_timestamp;
915 while(entry->status == DATA_ENTRY_STATUS_BUSY
916 && RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + (RTIMER_SECOND / 250)));
918 if(entry->status != DATA_ENTRY_STATUS_FINISHED) {
923 len = rx_read_entry[RX_BUF_LENGTH_OFFSET];
924 if(len <= RX_BUF_METADATA_SIZE) {
925 PRINTF(
"RF: too short!");
927 release_data_entry();
931 len -= RX_BUF_METADATA_SIZE;
933 PRINTF(
"RF: too long\n");
935 release_data_entry();
939 memcpy(buf, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET, len);
941 rf_core_last_rssi = (int8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len];
942 rf_core_last_corr_lqi = (uint8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 1] & STATUS_CORRELATION;
945 memcpy(&rat_timestamp, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET + len + 2, 4);
949 if(!rf_core_poll_mode) {
953 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf_core_last_rssi);
954 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf_core_last_corr_lqi);
957 release_data_entry();
967 int ret = RF_CORE_CCA_CLEAR;
974 PRINTF(
"channel_clear: Interrupt context but BLE in progress\n");
975 return RF_CORE_CCA_CLEAR;
990 if(on() != RF_CORE_CMD_OK) {
991 PRINTF(
"channel_clear: on() failed\n");
995 return RF_CORE_CCA_CLEAR;
1001 if(cca_info == RF_CORE_GET_CCA_INFO_ERROR) {
1002 PRINTF(
"channel_clear: CCA error\n");
1003 ret = RF_CORE_CCA_CLEAR;
1009 ret = (cca_info & 0x03) != RF_CORE_CMD_CCA_REQ_CCA_STATE_BUSY;
1020 receiving_packet(
void)
1029 PRINTF(
"receiving_packet: Interrupt context but BLE in progress\n");
1035 PRINTF(
"receiving_packet: We were off\n");
1041 PRINTF(
"receiving_packet: We were TXing\n");
1048 if(cca_info == RF_CORE_GET_CCA_INFO_ERROR) {
1053 if(cca_info & RF_CORE_CMD_CCA_REQ_CCA_SYNC_BUSY) {
1061 pending_packet(
void)
1063 volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
1068 if(entry->status == DATA_ENTRY_STATUS_FINISHED
1069 || entry->status == DATA_ENTRY_STATUS_BUSY) {
1071 if(!rf_core_poll_mode) {
1076 entry = (rfc_dataEntry_t *)entry->pNextEntry;
1077 }
while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
1091 PRINTF(
"on: Interrupt context but BLE in progress\n");
1092 return RF_CORE_CMD_OK;
1104 return RF_CORE_CMD_OK;
1118 PRINTF(
"on: rf_core_boot() failed\n");
1119 return RF_CORE_CMD_ERROR;
1124 if(rf_radio_setup() != RF_CORE_CMD_OK) {
1125 PRINTF(
"on: radio_setup() failed\n");
1126 return RF_CORE_CMD_ERROR;
1140 PRINTF(
"off: Interrupt context but BLE in progress\n");
1141 return RF_CORE_CMD_OK;
1150 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
1152 #if !CC2650_FAST_RADIO_STARTUP 1160 ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
1166 if(((rfc_dataEntry_t *)rx_buf_0)->status == DATA_ENTRY_STATUS_BUSY) {
1167 ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING;
1169 if(((rfc_dataEntry_t *)rx_buf_1)->status == DATA_ENTRY_STATUS_BUSY) {
1170 ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING;
1172 if(((rfc_dataEntry_t *)rx_buf_2)->status == DATA_ENTRY_STATUS_BUSY) {
1173 ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING;
1175 if(((rfc_dataEntry_t *)rx_buf_3)->status == DATA_ENTRY_STATUS_BUSY) {
1176 ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING;
1179 return RF_CORE_CMD_OK;
1183 static radio_result_t
1184 set_send_on_cca(uint8_t enable)
1188 return RADIO_RESULT_NOT_SUPPORTED;
1190 return RADIO_RESULT_OK;
1193 static radio_result_t
1196 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1199 return RADIO_RESULT_INVALID_VALUE;
1203 case RADIO_PARAM_POWER_MODE:
1205 *value =
rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1206 return RADIO_RESULT_OK;
1207 case RADIO_PARAM_CHANNEL:
1209 return RADIO_RESULT_OK;
1210 case RADIO_PARAM_PAN_ID:
1212 return RADIO_RESULT_OK;
1213 case RADIO_PARAM_16BIT_ADDR:
1215 return RADIO_RESULT_OK;
1216 case RADIO_PARAM_RX_MODE:
1218 if(cmd->frameFiltOpt.frameFiltEn) {
1221 if(cmd->frameFiltOpt.autoAckEn) {
1222 *value |= RADIO_RX_MODE_AUTOACK;
1224 if(rf_core_poll_mode) {
1225 *value |= RADIO_RX_MODE_POLL_MODE;
1228 return RADIO_RESULT_OK;
1229 case RADIO_PARAM_TX_MODE:
1231 return RADIO_RESULT_OK;
1232 case RADIO_PARAM_TXPOWER:
1233 *value = get_tx_power();
1234 return RADIO_RESULT_OK;
1235 case RADIO_PARAM_CCA_THRESHOLD:
1236 *value = cmd->ccaRssiThr;
1237 return RADIO_RESULT_OK;
1238 case RADIO_PARAM_RSSI:
1241 if(*value == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) {
1242 return RADIO_RESULT_ERROR;
1244 return RADIO_RESULT_OK;
1246 case RADIO_CONST_CHANNEL_MIN:
1247 *value = IEEE_MODE_CHANNEL_MIN;
1248 return RADIO_RESULT_OK;
1249 case RADIO_CONST_CHANNEL_MAX:
1250 *value = IEEE_MODE_CHANNEL_MAX;
1251 return RADIO_RESULT_OK;
1252 case RADIO_CONST_TXPOWER_MIN:
1253 *value = OUTPUT_POWER_MIN;
1254 return RADIO_RESULT_OK;
1255 case RADIO_CONST_TXPOWER_MAX:
1256 *value = OUTPUT_POWER_MAX;
1257 return RADIO_RESULT_OK;
1258 case RADIO_PARAM_LAST_RSSI:
1259 *value = rf_core_last_rssi;
1260 return RADIO_RESULT_OK;
1261 case RADIO_PARAM_LAST_LINK_QUALITY:
1262 *value = rf_core_last_corr_lqi;
1263 return RADIO_RESULT_OK;
1264 case RADIO_CONST_PHY_OVERHEAD:
1266 return RADIO_RESULT_OK;
1267 case RADIO_CONST_BYTE_AIR_TIME:
1269 return RADIO_RESULT_OK;
1270 case RADIO_CONST_DELAY_BEFORE_TX:
1272 return RADIO_RESULT_OK;
1273 case RADIO_CONST_DELAY_BEFORE_RX:
1275 return RADIO_RESULT_OK;
1276 case RADIO_CONST_DELAY_BEFORE_DETECT:
1278 return RADIO_RESULT_OK;
1280 return RADIO_RESULT_NOT_SUPPORTED;
1284 static radio_result_t
1287 radio_result_t rv = RADIO_RESULT_OK;
1288 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1289 uint8_t old_poll_mode;
1292 case RADIO_PARAM_POWER_MODE:
1293 if(value == RADIO_POWER_MODE_ON) {
1294 if(on() != RF_CORE_CMD_OK) {
1295 PRINTF(
"set_value: on() failed (1)\n");
1296 return RADIO_RESULT_ERROR;
1298 return RADIO_RESULT_OK;
1300 if(value == RADIO_POWER_MODE_OFF) {
1302 return RADIO_RESULT_OK;
1304 return RADIO_RESULT_INVALID_VALUE;
1305 case RADIO_PARAM_CHANNEL:
1306 if(value < IEEE_MODE_CHANNEL_MIN ||
1307 value > IEEE_MODE_CHANNEL_MAX) {
1308 return RADIO_RESULT_INVALID_VALUE;
1312 if(cmd->channel == (uint8_t)value) {
1315 return RADIO_RESULT_OK;
1318 cmd->channel = (uint8_t)value;
1320 case RADIO_PARAM_PAN_ID:
1321 cmd->localPanID = (uint16_t)value;
1323 case RADIO_PARAM_16BIT_ADDR:
1324 cmd->localShortAddr = (uint16_t)value;
1326 case RADIO_PARAM_RX_MODE:
1329 RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) {
1330 return RADIO_RESULT_INVALID_VALUE;
1334 cmd->frameFiltOpt.frameFiltStop = 1;
1335 cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
1336 cmd->frameFiltOpt.slottedAckEn = 0;
1337 cmd->frameFiltOpt.autoPendEn = 0;
1338 cmd->frameFiltOpt.defaultPend = 0;
1339 cmd->frameFiltOpt.bPendDataReqOnly = 0;
1340 cmd->frameFiltOpt.bPanCoord = 0;
1341 cmd->frameFiltOpt.bStrictLenFilter = 0;
1343 old_poll_mode = rf_core_poll_mode;
1344 rf_core_poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
1345 if(rf_core_poll_mode == old_poll_mode) {
1346 uint32_t cmd_status;
1349 memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt,
sizeof(cmd->frameFiltOpt));
1351 if(
rf_core_send_cmd((uint32_t)&filter_cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
1352 PRINTF(
"setting address filter failed: CMDSTA=0x%08lx\n", cmd_status);
1353 return RADIO_RESULT_ERROR;
1355 return RADIO_RESULT_OK;
1360 case RADIO_PARAM_TX_MODE:
1362 return RADIO_RESULT_INVALID_VALUE;
1366 case RADIO_PARAM_TXPOWER:
1367 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1368 return RADIO_RESULT_INVALID_VALUE;
1371 set_tx_power(value);
1373 return RADIO_RESULT_OK;
1375 case RADIO_PARAM_CCA_THRESHOLD:
1376 cmd->ccaRssiThr = (int8_t)value;
1380 return RADIO_RESULT_NOT_SUPPORTED;
1385 return RADIO_RESULT_OK;
1389 if(rx_off() != RF_CORE_CMD_OK) {
1390 PRINTF(
"set_value: rx_off() failed\n");
1391 rv = RADIO_RESULT_ERROR;
1400 if(rx_on() != RF_CORE_CMD_OK) {
1401 PRINTF(
"set_value: rx_on() failed\n");
1402 rv = RADIO_RESULT_ERROR;
1408 static radio_result_t
1409 get_object(radio_param_t param,
void *dest,
size_t size)
1414 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1416 if(param == RADIO_PARAM_64BIT_ADDR) {
1417 if(size != 8 || !dest) {
1418 return RADIO_RESULT_INVALID_VALUE;
1422 src = (uint8_t *)(&cmd->localExtAddr);
1424 for(i = 0; i < 8; i++) {
1425 target[i] = src[7 - i];
1428 return RADIO_RESULT_OK;
1431 if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
1432 if(size !=
sizeof(rtimer_clock_t) || !dest) {
1433 return RADIO_RESULT_INVALID_VALUE;
1435 *(rtimer_clock_t *)dest = rf_core_last_packet_timestamp;
1437 return RADIO_RESULT_OK;
1440 return RADIO_RESULT_NOT_SUPPORTED;
1443 static radio_result_t
1444 set_object(radio_param_t param,
const void *src,
size_t size)
1446 radio_result_t rv = RADIO_RESULT_OK;
1449 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1451 if(param == RADIO_PARAM_64BIT_ADDR) {
1452 if(size != 8 || !src) {
1453 return RADIO_RESULT_INVALID_VALUE;
1456 dst = (uint8_t *)(&cmd->localExtAddr);
1458 for(i = 0; i < 8; i++) {
1459 dst[i] = ((uint8_t *)src)[7 - i];
1464 return RADIO_RESULT_OK;
1467 if(rx_off() != RF_CORE_CMD_OK) {
1468 PRINTF(
"set_object: rx_off() failed\n");
1469 rv = RADIO_RESULT_ERROR;
1472 if(rx_on() != RF_CORE_CMD_OK) {
1473 PRINTF(
"set_object: rx_on() failed\n");
1474 rv = RADIO_RESULT_ERROR;
1479 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 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.