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 if(payload_len > TX_BUF_PAYLOAD_LEN || payload_len > NETSTACK_RADIO_MAX_PAYLOAD_LEN) {
774 memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, payload_len);
779 transmit(
unsigned short transmit_len)
785 uint8_t tx_active = 0;
787 volatile rfc_CMD_IEEE_TX_t cmd;
789 if(transmit_len > NETSTACK_RADIO_MAX_PAYLOAD_LEN) {
790 PRINTF(
"transmit: too long\n");
796 if(on() != RF_CORE_CMD_OK) {
797 PRINTF(
"transmit: on() failed\n");
811 }
while(tx_active == 1 &&
812 (RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + RF_CORE_TX_TIMEOUT)));
815 PRINTF(
"transmit: Already TXing and wait timed out\n");
821 return RADIO_TX_COLLISION;
827 cmd.payloadLen = transmit_len;
828 cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
831 cmd.startTrigger.triggerType = TRIG_NOW;
840 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
843 while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS)
844 == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
850 if(!rf_core_poll_mode) {
857 if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) {
862 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret,
868 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
869 ret, cmd_status, cmd.status);
878 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
894 send(
const void *payload,
unsigned short payload_len)
896 prepare(payload, payload_len);
897 return transmit(payload_len);
901 release_data_entry(
void)
903 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
906 rx_read_entry[8] = 0;
909 entry->status = DATA_ENTRY_STATUS_PENDING;
910 rx_read_entry = entry->pNextEntry;
914 read_frame(
void *buf,
unsigned short buf_len)
917 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
918 uint32_t rat_timestamp;
922 while(entry->status == DATA_ENTRY_STATUS_BUSY
923 && RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + (RTIMER_SECOND / 250)));
925 if(entry->status != DATA_ENTRY_STATUS_FINISHED) {
930 len = rx_read_entry[RX_BUF_LENGTH_OFFSET];
931 if(len <= RX_BUF_METADATA_SIZE) {
932 PRINTF(
"RF: too short!");
934 release_data_entry();
938 len -= RX_BUF_METADATA_SIZE;
940 PRINTF(
"RF: too long\n");
942 release_data_entry();
946 memcpy(buf, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET, len);
948 rf_core_last_rssi = (int8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len];
949 rf_core_last_corr_lqi = (uint8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 1] & STATUS_CORRELATION;
952 memcpy(&rat_timestamp, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET + len + 2, 4);
956 if(!rf_core_poll_mode) {
960 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf_core_last_rssi);
961 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf_core_last_corr_lqi);
964 release_data_entry();
974 int ret = RF_CORE_CCA_CLEAR;
981 PRINTF(
"channel_clear: Interrupt context but BLE in progress\n");
982 return RF_CORE_CCA_CLEAR;
997 if(on() != RF_CORE_CMD_OK) {
998 PRINTF(
"channel_clear: on() failed\n");
1002 return RF_CORE_CCA_CLEAR;
1008 if(cca_info == RF_CORE_GET_CCA_INFO_ERROR) {
1009 PRINTF(
"channel_clear: CCA error\n");
1010 ret = RF_CORE_CCA_CLEAR;
1016 ret = (cca_info & 0x03) != RF_CORE_CMD_CCA_REQ_CCA_STATE_BUSY;
1027 receiving_packet(
void)
1036 PRINTF(
"receiving_packet: Interrupt context but BLE in progress\n");
1042 PRINTF(
"receiving_packet: We were off\n");
1048 PRINTF(
"receiving_packet: We were TXing\n");
1055 if(cca_info == RF_CORE_GET_CCA_INFO_ERROR) {
1060 if(cca_info & RF_CORE_CMD_CCA_REQ_CCA_SYNC_BUSY) {
1068 pending_packet(
void)
1070 volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
1075 if(entry->status == DATA_ENTRY_STATUS_FINISHED
1076 || entry->status == DATA_ENTRY_STATUS_BUSY) {
1078 if(!rf_core_poll_mode) {
1083 entry = (rfc_dataEntry_t *)entry->pNextEntry;
1084 }
while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
1098 PRINTF(
"on: Interrupt context but BLE in progress\n");
1099 return RF_CORE_CMD_OK;
1111 return RF_CORE_CMD_OK;
1125 PRINTF(
"on: rf_core_boot() failed\n");
1126 return RF_CORE_CMD_ERROR;
1131 if(rf_radio_setup() != RF_CORE_CMD_OK) {
1132 PRINTF(
"on: radio_setup() failed\n");
1133 return RF_CORE_CMD_ERROR;
1147 PRINTF(
"off: Interrupt context but BLE in progress\n");
1148 return RF_CORE_CMD_OK;
1157 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
1159 #if !CC2650_FAST_RADIO_STARTUP 1167 ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
1173 if(((rfc_dataEntry_t *)rx_buf_0)->status == DATA_ENTRY_STATUS_BUSY) {
1174 ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING;
1176 if(((rfc_dataEntry_t *)rx_buf_1)->status == DATA_ENTRY_STATUS_BUSY) {
1177 ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING;
1179 if(((rfc_dataEntry_t *)rx_buf_2)->status == DATA_ENTRY_STATUS_BUSY) {
1180 ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING;
1182 if(((rfc_dataEntry_t *)rx_buf_3)->status == DATA_ENTRY_STATUS_BUSY) {
1183 ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING;
1186 return RF_CORE_CMD_OK;
1190 static radio_result_t
1191 set_send_on_cca(uint8_t enable)
1195 return RADIO_RESULT_NOT_SUPPORTED;
1197 return RADIO_RESULT_OK;
1200 static radio_result_t
1203 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1206 return RADIO_RESULT_INVALID_VALUE;
1210 case RADIO_PARAM_POWER_MODE:
1212 *value =
rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1213 return RADIO_RESULT_OK;
1214 case RADIO_PARAM_CHANNEL:
1216 return RADIO_RESULT_OK;
1217 case RADIO_PARAM_PAN_ID:
1219 return RADIO_RESULT_OK;
1220 case RADIO_PARAM_16BIT_ADDR:
1222 return RADIO_RESULT_OK;
1223 case RADIO_PARAM_RX_MODE:
1225 if(cmd->frameFiltOpt.frameFiltEn) {
1228 if(cmd->frameFiltOpt.autoAckEn) {
1229 *value |= RADIO_RX_MODE_AUTOACK;
1231 if(rf_core_poll_mode) {
1232 *value |= RADIO_RX_MODE_POLL_MODE;
1235 return RADIO_RESULT_OK;
1236 case RADIO_PARAM_TX_MODE:
1238 return RADIO_RESULT_OK;
1239 case RADIO_PARAM_TXPOWER:
1240 *value = get_tx_power();
1241 return RADIO_RESULT_OK;
1242 case RADIO_PARAM_CCA_THRESHOLD:
1243 *value = cmd->ccaRssiThr;
1244 return RADIO_RESULT_OK;
1245 case RADIO_PARAM_RSSI:
1248 if(*value == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) {
1249 return RADIO_RESULT_ERROR;
1251 return RADIO_RESULT_OK;
1253 case RADIO_CONST_CHANNEL_MIN:
1254 *value = IEEE_MODE_CHANNEL_MIN;
1255 return RADIO_RESULT_OK;
1256 case RADIO_CONST_CHANNEL_MAX:
1257 *value = IEEE_MODE_CHANNEL_MAX;
1258 return RADIO_RESULT_OK;
1259 case RADIO_CONST_TXPOWER_MIN:
1260 *value = OUTPUT_POWER_MIN;
1261 return RADIO_RESULT_OK;
1262 case RADIO_CONST_TXPOWER_MAX:
1263 *value = OUTPUT_POWER_MAX;
1264 return RADIO_RESULT_OK;
1265 case RADIO_PARAM_LAST_RSSI:
1266 *value = rf_core_last_rssi;
1267 return RADIO_RESULT_OK;
1268 case RADIO_PARAM_LAST_LINK_QUALITY:
1269 *value = rf_core_last_corr_lqi;
1270 return RADIO_RESULT_OK;
1271 case RADIO_CONST_PHY_OVERHEAD:
1273 return RADIO_RESULT_OK;
1274 case RADIO_CONST_BYTE_AIR_TIME:
1276 return RADIO_RESULT_OK;
1277 case RADIO_CONST_DELAY_BEFORE_TX:
1279 return RADIO_RESULT_OK;
1280 case RADIO_CONST_DELAY_BEFORE_RX:
1282 return RADIO_RESULT_OK;
1283 case RADIO_CONST_DELAY_BEFORE_DETECT:
1285 return RADIO_RESULT_OK;
1287 return RADIO_RESULT_NOT_SUPPORTED;
1291 static radio_result_t
1294 radio_result_t rv = RADIO_RESULT_OK;
1295 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1296 uint8_t old_poll_mode;
1299 case RADIO_PARAM_POWER_MODE:
1300 if(value == RADIO_POWER_MODE_ON) {
1301 if(on() != RF_CORE_CMD_OK) {
1302 PRINTF(
"set_value: on() failed (1)\n");
1303 return RADIO_RESULT_ERROR;
1305 return RADIO_RESULT_OK;
1307 if(value == RADIO_POWER_MODE_OFF) {
1309 return RADIO_RESULT_OK;
1311 return RADIO_RESULT_INVALID_VALUE;
1312 case RADIO_PARAM_CHANNEL:
1313 if(value < IEEE_MODE_CHANNEL_MIN ||
1314 value > IEEE_MODE_CHANNEL_MAX) {
1315 return RADIO_RESULT_INVALID_VALUE;
1319 if(cmd->channel == (uint8_t)value) {
1322 return RADIO_RESULT_OK;
1325 cmd->channel = (uint8_t)value;
1327 case RADIO_PARAM_PAN_ID:
1328 cmd->localPanID = (uint16_t)value;
1330 case RADIO_PARAM_16BIT_ADDR:
1331 cmd->localShortAddr = (uint16_t)value;
1333 case RADIO_PARAM_RX_MODE:
1336 RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) {
1337 return RADIO_RESULT_INVALID_VALUE;
1341 cmd->frameFiltOpt.frameFiltStop = 1;
1342 cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
1343 cmd->frameFiltOpt.slottedAckEn = 0;
1344 cmd->frameFiltOpt.autoPendEn = 0;
1345 cmd->frameFiltOpt.defaultPend = 0;
1346 cmd->frameFiltOpt.bPendDataReqOnly = 0;
1347 cmd->frameFiltOpt.bPanCoord = 0;
1348 cmd->frameFiltOpt.bStrictLenFilter = 0;
1350 old_poll_mode = rf_core_poll_mode;
1351 rf_core_poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
1352 if(rf_core_poll_mode == old_poll_mode) {
1353 uint32_t cmd_status;
1356 memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt,
sizeof(cmd->frameFiltOpt));
1358 if(
rf_core_send_cmd((uint32_t)&filter_cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
1359 PRINTF(
"setting address filter failed: CMDSTA=0x%08lx\n", cmd_status);
1360 return RADIO_RESULT_ERROR;
1362 return RADIO_RESULT_OK;
1367 case RADIO_PARAM_TX_MODE:
1369 return RADIO_RESULT_INVALID_VALUE;
1373 case RADIO_PARAM_TXPOWER:
1374 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1375 return RADIO_RESULT_INVALID_VALUE;
1378 set_tx_power(value);
1380 return RADIO_RESULT_OK;
1382 case RADIO_PARAM_CCA_THRESHOLD:
1383 cmd->ccaRssiThr = (int8_t)value;
1387 return RADIO_RESULT_NOT_SUPPORTED;
1392 return RADIO_RESULT_OK;
1396 if(rx_off() != RF_CORE_CMD_OK) {
1397 PRINTF(
"set_value: rx_off() failed\n");
1398 rv = RADIO_RESULT_ERROR;
1407 if(rx_on() != RF_CORE_CMD_OK) {
1408 PRINTF(
"set_value: rx_on() failed\n");
1409 rv = RADIO_RESULT_ERROR;
1415 static radio_result_t
1416 get_object(radio_param_t param,
void *dest,
size_t size)
1421 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1423 if(param == RADIO_PARAM_64BIT_ADDR) {
1424 if(size != 8 || !dest) {
1425 return RADIO_RESULT_INVALID_VALUE;
1429 src = (uint8_t *)(&cmd->localExtAddr);
1431 for(i = 0; i < 8; i++) {
1432 target[i] = src[7 - i];
1435 return RADIO_RESULT_OK;
1438 if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
1439 if(size !=
sizeof(rtimer_clock_t) || !dest) {
1440 return RADIO_RESULT_INVALID_VALUE;
1442 *(rtimer_clock_t *)dest = rf_core_last_packet_timestamp;
1444 return RADIO_RESULT_OK;
1447 return RADIO_RESULT_NOT_SUPPORTED;
1450 static radio_result_t
1451 set_object(radio_param_t param,
const void *src,
size_t size)
1453 radio_result_t rv = RADIO_RESULT_OK;
1456 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1458 if(param == RADIO_PARAM_64BIT_ADDR) {
1459 if(size != 8 || !src) {
1460 return RADIO_RESULT_INVALID_VALUE;
1463 dst = (uint8_t *)(&cmd->localExtAddr);
1465 for(i = 0; i < 8; i++) {
1466 dst[i] = ((uint8_t *)src)[7 - i];
1471 return RADIO_RESULT_OK;
1474 if(rx_off() != RF_CORE_CMD_OK) {
1475 PRINTF(
"set_object: rx_off() failed\n");
1476 rv = RADIO_RESULT_ERROR;
1479 if(rx_on() != RF_CORE_CMD_OK) {
1480 PRINTF(
"set_object: rx_on() failed\n");
1481 rv = RADIO_RESULT_ERROR;
1486 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.