43 #include "dev/watchdog.h" 47 #include "sys/clock.h" 48 #include "sys/critical.h" 60 #include "hw_rfc_dbell.h" 61 #include "hw_rfc_pwr.h" 64 #include "driverlib/rf_mailbox.h" 65 #include "driverlib/rf_common_cmd.h" 66 #include "driverlib/rf_data_entry.h" 67 #include "driverlib/rf_prop_mailbox.h" 68 #include "driverlib/rf_prop_cmd.h" 71 #include "rf_patches/rf_patch_cpe_genfsk.h" 72 #include "rf_patches/rf_patch_rfe_genfsk.h" 74 #include "rf-core/smartrf-settings.h" 83 #define PRINTF(...) printf(__VA_ARGS__) 89 #define DATA_ENTRY_STATUS_PENDING 0x00 90 #define DATA_ENTRY_STATUS_ACTIVE 0x01 91 #define DATA_ENTRY_STATUS_BUSY 0x02 92 #define DATA_ENTRY_STATUS_FINISHED 0x03 93 #define DATA_ENTRY_STATUS_UNFINISHED 0x04 96 #ifdef PROP_MODE_CONF_DW 97 #define PROP_MODE_DW PROP_MODE_CONF_DW 99 #define PROP_MODE_DW 0 102 #ifdef PROP_MODE_CONF_USE_CRC16 103 #define PROP_MODE_USE_CRC16 PROP_MODE_CONF_USE_CRC16 105 #define PROP_MODE_USE_CRC16 0 116 #define RF_RADIO_OP_GET_STATUS(a) GET_FIELD_V(a, radioOp, status) 118 #ifdef PROP_MODE_CONF_RSSI_THRESHOLD 119 #define PROP_MODE_RSSI_THRESHOLD PROP_MODE_CONF_RSSI_THRESHOLD 121 #define PROP_MODE_RSSI_THRESHOLD 0xA6 124 static int8_t rssi_threshold = PROP_MODE_RSSI_THRESHOLD;
126 #if MAC_CONF_WITH_TSCH 127 static volatile uint8_t is_receiving_packet;
131 static int off(
void);
133 static rfc_propRxOutput_t rx_stats;
136 #define DOT_4G_MAX_FRAME_LEN 2047 137 #define DOT_4G_PHR_LEN 2 140 #define DOT_4G_PHR_CRC16 0x10 141 #define DOT_4G_PHR_DW 0x08 143 #if PROP_MODE_USE_CRC16 145 #define DOT_4G_PHR_CRC_BIT DOT_4G_PHR_CRC16 149 #define DOT_4G_PHR_CRC_BIT 0 154 #define DOT_4G_PHR_DW_BIT DOT_4G_PHR_DW 156 #define DOT_4G_PHR_DW_BIT 0 175 #define MAX_PAYLOAD_LEN 125 178 #ifdef PROP_MODE_CONF_TX_POWER_431_527 179 #define PROP_MODE_TX_POWER_431_527 PROP_MODE_CONF_TX_POWER_431_527 181 #define PROP_MODE_TX_POWER_431_527 prop_mode_tx_power_431_527 185 #ifdef PROP_MODE_CONF_TX_POWER_779_930 186 #define PROP_MODE_TX_POWER_779_930 PROP_MODE_CONF_TX_POWER_779_930 188 #define PROP_MODE_TX_POWER_779_930 prop_mode_tx_power_779_930 192 #if DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_470 193 #define TX_POWER_DRIVER PROP_MODE_TX_POWER_431_527 195 #define TX_POWER_DRIVER PROP_MODE_TX_POWER_779_930 198 extern const prop_mode_tx_power_config_t TX_POWER_DRIVER[];
201 #define OUTPUT_POWER_MAX (TX_POWER_DRIVER[0].dbm) 202 #define OUTPUT_POWER_UNKNOWN 0xFFFF 205 static const prop_mode_tx_power_config_t *tx_power_current = &TX_POWER_DRIVER[1];
207 #ifdef PROP_MODE_CONF_LO_DIVIDER 208 #define PROP_MODE_LO_DIVIDER PROP_MODE_CONF_LO_DIVIDER 210 #define PROP_MODE_LO_DIVIDER 0x05 213 #ifdef PROP_MODE_CONF_RX_BUF_CNT 214 #define PROP_MODE_RX_BUF_CNT PROP_MODE_CONF_RX_BUF_CNT 216 #define PROP_MODE_RX_BUF_CNT 4 219 #define DATA_ENTRY_LENSZ_NONE 0 220 #define DATA_ENTRY_LENSZ_BYTE 1 221 #define DATA_ENTRY_LENSZ_WORD 2 224 #define RX_BUF_METADATA_SIZE \ 225 (CRC_LEN * RF_CORE_RX_BUF_INCLUDE_CRC \ 226 + RF_CORE_RX_BUF_INCLUDE_RSSI \ 227 + RF_CORE_RX_BUF_INCLUDE_CORR \ 228 + 4 * RF_CORE_RX_BUF_INCLUDE_TIMESTAMP) 231 #define RX_BUF_LENGTH_OFFSET sizeof(rfc_dataEntry_t) 233 #define RX_BUF_DATA_OFFSET (RX_BUF_LENGTH_OFFSET + DOT_4G_PHR_LEN) 235 #define ALIGN_TO_4(size) (((size) + 3) & ~3) 237 #define RX_BUF_SIZE ALIGN_TO_4(RX_BUF_DATA_OFFSET \ 239 + RX_BUF_METADATA_SIZE) 246 static uint8_t rx_buf[PROP_MODE_RX_BUF_CNT][RX_BUF_SIZE] CC_ALIGN(4);
249 static dataQueue_t rx_data_queue = { 0 };
252 volatile static uint8_t *rx_read_entry;
258 #define RAT_TIMESTAMP_OFFSET_SUB_GHZ USEC_TO_RADIO(160 * 6 - 240) 261 #define TX_BUF_PAYLOAD_LEN 180 262 #define TX_BUF_HDR_LEN 2 264 static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
273 return smartrf_settings_cmd_prop_rx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE;
279 return smartrf_settings_cmd_prop_tx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE;
287 uint8_t attempts = 0;
289 rfc_CMD_GET_RSSI_t cmd;
294 if(
on() != RF_CORE_CMD_OK) {
295 PRINTF(
"get_rssi: on() failed\n");
296 return RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
300 rssi = RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
302 while((rssi == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) && ++attempts < 10) {
303 memset(&cmd, 0x00,
sizeof(cmd));
304 cmd.commandNo = CMD_GET_RSSI;
307 PRINTF(
"get_rssi: CMDSTA=0x%08lx\n", cmd_status);
311 rssi = (cmd_status >> 16) & 0xFF;
328 freq_khz = smartrf_settings_cmd_fs.frequency * 1000;
336 freq_khz += (((smartrf_settings_cmd_fs.fractFreq * 1000) + 65535) / 65536);
338 return (freq_khz - DOT_15_4G_CHAN0_FREQUENCY) / DOT_15_4G_CHANNEL_SPACING;
347 new_freq = DOT_15_4G_CHAN0_FREQUENCY + (channel * DOT_15_4G_CHANNEL_SPACING);
349 freq = (uint16_t)(new_freq / 1000);
350 frac = (new_freq - (freq * 1000)) * 65536 / 1000;
352 PRINTF(
"set_channel: %u = 0x%04x.0x%04x (%lu)\n", channel, freq, frac,
355 smartrf_settings_cmd_prop_radio_div_setup.centerFreq = freq;
356 smartrf_settings_cmd_fs.frequency = freq;
357 smartrf_settings_cmd_fs.fractFreq = frac;
361 get_tx_power_array_last_element(
void)
363 const prop_mode_tx_power_config_t *array = TX_POWER_DRIVER;
366 while(array->tx_power != OUTPUT_POWER_UNKNOWN) {
377 return tx_power_current->dbm;
389 for(i = get_tx_power_array_last_element(); i >= 0; --i) {
390 if(power <= TX_POWER_DRIVER[i].dbm) {
396 tx_power_current = &TX_POWER_DRIVER[i];
404 prop_div_radio_setup(
void)
407 rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_prop_radio_div_setup;
409 rf_switch_select_path(RF_SWITCH_PATH_SUBGHZ);
412 smartrf_settings_cmd_prop_radio_div_setup.loDivider = PROP_MODE_LO_DIVIDER;
415 smartrf_settings_cmd_prop_radio_div_setup.txPower = tx_power_current->tx_power;
418 smartrf_settings_cmd_prop_radio_div_setup.config.frontEndMode =
419 RF_CORE_PROP_FRONT_END_MODE;
420 smartrf_settings_cmd_prop_radio_div_setup.config.biasMode =
421 RF_CORE_PROP_BIAS_MODE;
425 PRINTF(
"prop_div_radio_setup: DIV_SETUP, CMDSTA=0x%08lx, status=0x%04x\n",
426 cmd_status, cmd->status);
427 return RF_CORE_CMD_ERROR;
432 PRINTF(
"prop_div_radio_setup: DIV_SETUP wait, CMDSTA=0x%08lx," 433 "status=0x%04x\n", cmd_status, cmd->status);
434 return RF_CORE_CMD_ERROR;
437 return RF_CORE_CMD_OK;
444 volatile rfc_CMD_PROP_RX_ADV_t *cmd_rx_adv;
447 cmd_rx_adv = (rfc_CMD_PROP_RX_ADV_t *)&smartrf_settings_cmd_prop_rx_adv;
448 cmd_rx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE;
450 cmd_rx_adv->rxConf.bIncludeCrc = RF_CORE_RX_BUF_INCLUDE_CRC;
451 cmd_rx_adv->rxConf.bAppendRssi = RF_CORE_RX_BUF_INCLUDE_RSSI;
452 cmd_rx_adv->rxConf.bAppendTimestamp = RF_CORE_RX_BUF_INCLUDE_TIMESTAMP;
453 cmd_rx_adv->rxConf.bAppendStatus = RF_CORE_RX_BUF_INCLUDE_CORR;
459 cmd_rx_adv->maxPktLen = DOT_4G_MAX_FRAME_LEN - cmd_rx_adv->lenOffset;
463 if(ret != RF_CORE_CMD_OK) {
464 PRINTF(
"rf_cmd_prop_rx: send_cmd ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
465 ret, cmd_status, cmd_rx_adv->status);
466 return RF_CORE_CMD_ERROR;
470 RF_CORE_ENTER_RX_TIMEOUT);
473 if(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE) {
474 PRINTF(
"rf_cmd_prop_rx: CMDSTA=0x%08lx, status=0x%04x\n",
475 cmd_status, cmd_rx_adv->status);
476 return RF_CORE_CMD_ERROR;
483 init_rx_buffers(
void)
485 rfc_dataEntry_t *entry;
488 for(i = 0; i < PROP_MODE_RX_BUF_CNT; i++) {
489 entry = (rfc_dataEntry_t *)rx_buf[i];
490 entry->status = DATA_ENTRY_STATUS_PENDING;
491 entry->config.type = DATA_ENTRY_TYPE_GEN;
492 entry->config.lenSz = DATA_ENTRY_LENSZ_WORD;
493 entry->length = RX_BUF_SIZE - 8;
494 entry->pNextEntry = rx_buf[i + 1];
497 ((rfc_dataEntry_t *)rx_buf[PROP_MODE_RX_BUF_CNT - 1])->pNextEntry = rx_buf[0];
506 PRINTF(
"rx_on_prop: We were on. PD=%u, RX=0x%04x\n",
508 return RF_CORE_CMD_OK;
512 ret = rf_cmd_prop_rx();
515 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
529 return RF_CORE_CMD_OK;
536 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
537 PRINTF(
"rx_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status);
543 if(smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_STOPPED ||
544 smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_ABORT) {
546 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
547 ret = RF_CORE_CMD_OK;
549 PRINTF(
"rx_off_prop: status=0x%04x\n",
550 smartrf_settings_cmd_prop_rx_adv.status);
551 ret = RF_CORE_CMD_ERROR;
565 return LPM_MODE_SLEEP;
568 return LPM_MODE_MAX_SUPPORTED;
571 LPM_MODULE(prop_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
577 rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_fs;
581 PRINTF(
"prop_fs: CMD_FS, CMDSTA=0x%08lx, status=0x%04x\n",
582 cmd_status, cmd->status);
583 return RF_CORE_CMD_ERROR;
588 PRINTF(
"prop_fs: CMD_FS wait, CMDSTA=0x%08lx, status=0x%04x\n",
589 cmd_status, cmd->status);
590 return RF_CORE_CMD_ERROR;
593 return RF_CORE_CMD_OK;
607 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
608 PRINTF(
"soft_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status);
613 RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING, RF_CORE_TURN_OFF_TIMEOUT);
619 if(prop_div_radio_setup() != RF_CORE_CMD_OK) {
620 PRINTF(
"soft_on_prop: prop_div_radio_setup() failed\n");
621 return RF_CORE_CMD_ERROR;
624 if(prop_fs() != RF_CORE_CMD_OK) {
625 PRINTF(
"soft_on_prop: prop_fs() failed\n");
626 return RF_CORE_CMD_ERROR;
636 RAT_TIMESTAMP_OFFSET_SUB_GHZ
644 if(ti_lib_chipinfo_chip_family_is_cc13xx() ==
false) {
645 return RF_CORE_CMD_ERROR;
649 memset(rx_buf, 0,
sizeof(rx_buf));
652 rx_data_queue.pCurrEntry = rx_buf[0];
653 rx_data_queue.pLastEntry = NULL;
656 rx_read_entry = rx_buf[0];
658 smartrf_settings_cmd_prop_rx_adv.pQueue = &rx_data_queue;
659 smartrf_settings_cmd_prop_rx_adv.pOutput = (uint8_t *)&rx_stats;
663 if(
on() != RF_CORE_CMD_OK) {
664 PRINTF(
"init: on() failed\n");
665 return RF_CORE_CMD_ERROR;
668 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
680 prepare(
const void *payload,
unsigned short payload_len)
682 if(payload_len > TX_BUF_PAYLOAD_LEN || payload_len > MAX_PAYLOAD_LEN) {
686 memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, payload_len);
691 transmit(
unsigned short transmit_len)
696 volatile rfc_CMD_PROP_TX_ADV_t *cmd_tx_adv;
699 uint16_t total_length;
701 if(transmit_len > MAX_PAYLOAD_LEN) {
702 PRINTF(
"transmit: too long\n");
708 if(
on() != RF_CORE_CMD_OK) {
709 PRINTF(
"transmit: on() failed\n");
722 total_length = transmit_len + CRC_LEN;
724 tx_buf[0] = total_length & 0xFF;
725 tx_buf[1] = (total_length >> 8) + DOT_4G_PHR_DW_BIT + DOT_4G_PHR_CRC_BIT;
728 cmd_tx_adv = (rfc_CMD_PROP_TX_ADV_t *)&smartrf_settings_cmd_prop_tx_adv;
734 cmd_tx_adv->pktLen = transmit_len + DOT_4G_PHR_LEN;
735 cmd_tx_adv->pPkt = tx_buf;
747 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
750 while((cmd_tx_adv->status & RF_CORE_RADIO_OP_MASKED_STATUS)
751 == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
757 if(!rf_core_poll_mode) {
762 if(cmd_tx_adv->status == RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK) {
767 PRINTF(
"transmit: Not Sent OK status=0x%04x\n",
773 PRINTF(
"transmit: PROP_TX_ERR ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
774 ret, cmd_status, cmd_tx_adv->status);
782 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
791 cmd_tx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE;
803 send(
const void *payload,
unsigned short payload_len)
810 release_data_entry(
void)
812 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
813 uint8_t *data_ptr = &entry->data;
821 entry->status = DATA_ENTRY_STATUS_PENDING;
822 rx_read_entry = entry->pNextEntry;
825 if(rf_core_rx_is_full) {
826 rf_core_rx_is_full =
false;
827 PRINTF(
"RXQ was full, re-enabling radio!\n");
835 read_frame(
void *buf,
unsigned short buf_len)
837 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
840 uint32_t rat_timestamp;
845 if(entry->status == DATA_ENTRY_STATUS_FINISHED
846 || entry->status == DATA_ENTRY_STATUS_BUSY) {
851 entry = (rfc_dataEntryGeneral_t *)entry->pNextEntry;
852 }
while(entry != (rfc_dataEntryGeneral_t *)rx_read_entry);
859 rx_read_entry = (
volatile uint8_t *)entry;
863 while(entry->status == DATA_ENTRY_STATUS_BUSY
866 #if MAC_CONF_WITH_TSCH 868 is_receiving_packet = 0;
871 if(entry->status != DATA_ENTRY_STATUS_FINISHED) {
882 data_ptr = &entry->data;
883 len = (*(uint16_t *)data_ptr);
885 if(len <= RX_BUF_METADATA_SIZE) {
886 PRINTF(
"RF: too short!");
888 release_data_entry();
893 len -= RX_BUF_METADATA_SIZE;
896 PRINTF(
"RF: too long\n");
898 release_data_entry();
902 memcpy(buf, data_ptr, len);
905 rf_core_last_rssi = (int8_t)data_ptr[len];
906 rf_core_last_corr_lqi = data_ptr[len + 5];
909 memcpy(&rat_timestamp, data_ptr + len + 1, 4);
913 if(!rf_core_poll_mode) {
917 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rf_core_last_rssi);
918 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, rf_core_last_corr_lqi);
921 release_data_entry();
931 int8_t rssi = RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
938 return RF_CORE_CCA_CLEAR;
943 if(
on() != RF_CORE_CMD_OK) {
944 PRINTF(
"channel_clear: on() failed\n");
948 return RF_CORE_CCA_CLEAR;
952 PRINTF(
"channel_clear: called while in TX\n");
953 return RF_CORE_CCA_CLEAR;
957 while(rssi == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) {
963 rssi = (cmd_status >> 16) & 0xFF;
970 if(rssi >= rssi_threshold) {
971 return RF_CORE_CCA_BUSY;
974 return RF_CORE_CCA_CLEAR;
984 #if MAC_CONF_WITH_TSCH 992 if(!is_receiving_packet) {
996 if(HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFHWIFG) & RFC_DBELL_RFHWIFG_MDMSOFT) {
997 is_receiving_packet = 1;
1001 is_receiving_packet = (
channel_clear() == RF_CORE_CCA_BUSY);
1002 if(!is_receiving_packet) {
1004 ti_lib_rfc_hw_int_clear(RFC_DBELL_RFHWIFG_MDMSOFT);
1008 return is_receiving_packet;
1043 volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
1047 if(entry->status == DATA_ENTRY_STATUS_FINISHED
1048 || entry->status == DATA_ENTRY_STATUS_BUSY) {
1050 if(!rf_core_poll_mode) {
1055 entry = (rfc_dataEntry_t *)entry->pNextEntry;
1056 }
while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
1070 return RF_CORE_CMD_OK;
1075 smartrf_settings_cmd_prop_rx_adv.status);
1076 return RF_CORE_CMD_OK;
1087 PRINTF(
"on: rf_core_power_up() failed\n");
1091 return RF_CORE_CMD_ERROR;
1098 rf_patch_cpe_genfsk();
1099 while(!HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG));
1100 HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG) = 0;
1101 rf_patch_rfe_genfsk();
1104 HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG) = 0;
1105 HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) =
1106 CMDR_DIR_CMD_1BYTE(CMD_BUS_REQUEST, 1);
1109 ti_lib_rfc_adi3vco_ldo_voltage_mode(
true);
1112 ti_lib_rfc_rtrim((rfc_radioOp_t *)&smartrf_settings_cmd_prop_radio_div_setup);
1115 while(!HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG));
1116 HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG) = 0;
1119 PRINTF(
"on: rf_core_start_rat() failed\n");
1123 return RF_CORE_CMD_ERROR;
1138 if(prop_div_radio_setup() != RF_CORE_CMD_OK) {
1139 PRINTF(
"on: prop_div_radio_setup() failed\n");
1140 return RF_CORE_CMD_ERROR;
1143 if(prop_fs() != RF_CORE_CMD_OK) {
1144 PRINTF(
"on: prop_fs() failed\n");
1145 return RF_CORE_CMD_ERROR;
1148 return rx_on_prop();
1155 rfc_dataEntry_t *entry;
1162 return RF_CORE_CMD_OK;
1168 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
1170 #if !CC2650_FAST_RADIO_STARTUP 1176 smartrf_settings_cmd_prop_rx_adv.status = RF_CORE_RADIO_OP_STATUS_IDLE;
1182 for(i = 0; i < PROP_MODE_RX_BUF_CNT; i++) {
1183 entry = (rfc_dataEntry_t *)rx_buf[i];
1184 if(entry->status == DATA_ENTRY_STATUS_BUSY) {
1185 entry->status = DATA_ENTRY_STATUS_PENDING;
1189 return RF_CORE_CMD_OK;
1193 static radio_result_t
1194 set_send_on_cca(uint8_t enable)
1198 return RADIO_RESULT_NOT_SUPPORTED;
1200 return RADIO_RESULT_OK;
1203 static radio_result_t
1207 return RADIO_RESULT_INVALID_VALUE;
1211 case RADIO_PARAM_POWER_MODE:
1213 *value =
rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1214 return RADIO_RESULT_OK;
1215 case RADIO_PARAM_CHANNEL:
1217 return RADIO_RESULT_OK;
1218 case RADIO_PARAM_RX_MODE:
1220 if(rf_core_poll_mode) {
1221 *value |= RADIO_RX_MODE_POLL_MODE;
1223 return RADIO_RESULT_OK;
1224 case RADIO_PARAM_TX_MODE:
1226 return RADIO_RESULT_OK;
1227 case RADIO_PARAM_TXPOWER:
1228 *value = get_tx_power();
1229 return RADIO_RESULT_OK;
1230 case RADIO_PARAM_CCA_THRESHOLD:
1231 *value = rssi_threshold;
1232 return RADIO_RESULT_OK;
1233 case RADIO_PARAM_RSSI:
1234 *value = get_rssi();
1236 if(*value == RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN) {
1237 return RADIO_RESULT_ERROR;
1239 return RADIO_RESULT_OK;
1241 case RADIO_CONST_CHANNEL_MIN:
1243 return RADIO_RESULT_OK;
1244 case RADIO_CONST_CHANNEL_MAX:
1245 *value = DOT_15_4G_CHANNEL_MAX;
1246 return RADIO_RESULT_OK;
1247 case RADIO_CONST_TXPOWER_MIN:
1248 *value = TX_POWER_DRIVER[get_tx_power_array_last_element()].dbm;
1249 return RADIO_RESULT_OK;
1250 case RADIO_CONST_TXPOWER_MAX:
1251 *value = OUTPUT_POWER_MAX;
1252 return RADIO_RESULT_OK;
1253 case RADIO_PARAM_LAST_RSSI:
1254 *value = rf_core_last_rssi;
1255 return RADIO_RESULT_OK;
1256 case RADIO_PARAM_LAST_LINK_QUALITY:
1257 *value = rf_core_last_corr_lqi;
1258 return RADIO_RESULT_OK;
1259 case RADIO_CONST_PHY_OVERHEAD:
1262 return RADIO_RESULT_OK;
1263 case RADIO_CONST_BYTE_AIR_TIME:
1265 return RADIO_RESULT_OK;
1266 case RADIO_CONST_DELAY_BEFORE_TX:
1268 return RADIO_RESULT_OK;
1269 case RADIO_CONST_DELAY_BEFORE_RX:
1271 return RADIO_RESULT_OK;
1272 case RADIO_CONST_DELAY_BEFORE_DETECT:
1274 return RADIO_RESULT_OK;
1275 case RADIO_CONST_MAX_PAYLOAD_LEN:
1277 return RADIO_RESULT_OK;
1279 return RADIO_RESULT_NOT_SUPPORTED;
1283 static radio_result_t
1286 radio_result_t rv = RADIO_RESULT_OK;
1287 uint8_t old_poll_mode;
1290 case RADIO_PARAM_POWER_MODE:
1291 if(value == RADIO_POWER_MODE_ON) {
1292 if(
on() != RF_CORE_CMD_OK) {
1293 PRINTF(
"set_value: on() failed (1)\n");
1294 return RADIO_RESULT_ERROR;
1296 return RADIO_RESULT_OK;
1298 if(value == RADIO_POWER_MODE_OFF) {
1300 return RADIO_RESULT_OK;
1302 return RADIO_RESULT_INVALID_VALUE;
1303 case RADIO_PARAM_CHANNEL:
1305 value > DOT_15_4G_CHANNEL_MAX) {
1306 return RADIO_RESULT_INVALID_VALUE;
1312 return RADIO_RESULT_OK;
1318 case RADIO_PARAM_RX_MODE:
1319 if(value & ~(RADIO_RX_MODE_POLL_MODE)) {
1320 return RADIO_RESULT_INVALID_VALUE;
1323 old_poll_mode = rf_core_poll_mode;
1324 rf_core_poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
1325 if(rf_core_poll_mode == old_poll_mode) {
1326 return RADIO_RESULT_OK;
1330 case RADIO_PARAM_TX_MODE:
1332 return RADIO_RESULT_INVALID_VALUE;
1336 case RADIO_PARAM_TXPOWER:
1337 if(value < TX_POWER_DRIVER[get_tx_power_array_last_element()].dbm ||
1338 value > OUTPUT_POWER_MAX) {
1339 return RADIO_RESULT_INVALID_VALUE;
1344 set_tx_power(value);
1346 if(soft_on_prop() != RF_CORE_CMD_OK) {
1347 PRINTF(
"set_value: soft_on_prop() failed\n");
1348 rv = RADIO_RESULT_ERROR;
1351 return RADIO_RESULT_OK;
1353 case RADIO_PARAM_CCA_THRESHOLD:
1354 rssi_threshold = (int8_t)value;
1357 return RADIO_RESULT_NOT_SUPPORTED;
1362 return RADIO_RESULT_OK;
1366 if(rx_off_prop() != RF_CORE_CMD_OK) {
1367 PRINTF(
"set_value: rx_off_prop() failed\n");
1368 rv = RADIO_RESULT_ERROR;
1374 PRINTF(
"set_value: rf_core_restart_rat() failed\n");
1380 if(soft_on_prop() != RF_CORE_CMD_OK) {
1381 PRINTF(
"set_value: soft_on_prop() failed\n");
1382 rv = RADIO_RESULT_ERROR;
1388 static radio_result_t
1389 get_object(radio_param_t param,
void *dest,
size_t size)
1391 if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
1392 if(size !=
sizeof(rtimer_clock_t) || !dest) {
1393 return RADIO_RESULT_INVALID_VALUE;
1395 *(rtimer_clock_t *)dest = rf_core_last_packet_timestamp;
1397 return RADIO_RESULT_OK;
1400 return RADIO_RESULT_NOT_SUPPORTED;
1403 static radio_result_t
1404 set_object(radio_param_t param,
const void *src,
size_t size)
1406 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.
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
static void critical_exit(int_master_status_t status)
Exit a critical section and restore the master interrupt.
int rf_core_power_up()
Turn on power to the RFC and boot it.
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.
static void set_channel(uint8_t channel)
Set the current operating channel.
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.
static int_master_status_t critical_enter()
Enter a critical section.
#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.
Header file with descriptors for the various modes of operation defined in IEEE 802.15.4g.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
INT_MASTER_STATUS_DATATYPE int_master_status_t
Master interrupt state representation data type.
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
Header file for the CC13xx prop mode NETSTACK_RADIO driver.
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.
void rf_core_cmd_done_dis(void)
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
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...
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_start_rat(void)
Start the CM0 RAT.
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.
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.
static uint8_t get_channel()
Get the current operating channel.