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
118static 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
139typedef struct output_config {
144static 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
168static const output_config_t *tx_power_current = &output_power[0];
170static rfc_CMD_IEEE_MOD_FILT_t filter_cmd;
182static 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)
218static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4);
219static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
220static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4);
221static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4);
224static dataQueue_t rx_data_queue = { 0 };
227volatile static uint8_t *rx_read_entry;
230#define TX_BUF_PAYLOAD_LEN 180
231#define TX_BUF_HDR_LEN 2
233static 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
242static uint32_t ieee_overrides[] = {
255 IEEE_MODE_BOARD_OVERRIDES
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;
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;
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;
698LPM_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);
781prepare(
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);
792transmit(
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);
907send(
const void *payload,
unsigned short payload_len)
909 prepare(payload, payload_len);
910 return transmit(payload_len);
914release_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;
927read_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;
1040receiving_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) {
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;
1204set_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");
1432get_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;
1467set_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");
Header file for the CC13xx/CC26xx UART driver.
Default definitions of C compiler quirk work-arounds.
Header file for the callback timer.
Header file for the energy estimation mechanism.
#define LPM_MODULE(n, m, s, w, l)
Declare a variable to be used in order to get notifications from LPM.
void lpm_sleep(void)
Enter sleep mode.
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
void process_start(struct process *p, process_data_t data)
Start a process.
void process_poll(struct process *p)
Request a process to be polled.
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
@ RADIO_RESULT_ERROR
An error occurred when getting/setting the parameter, but the arguments were otherwise correct.
@ RADIO_RESULT_NOT_SUPPORTED
The parameter is not supported.
@ RADIO_RESULT_INVALID_VALUE
The value argument was incorrect.
@ RADIO_RESULT_OK
The parameter was set/read successfully.
@ RADIO_PARAM_POWER_MODE
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
@ RADIO_CONST_PHY_OVERHEAD
The physical layer header (PHR) + MAC layer footer (MFR) overhead in bytes.
@ RADIO_PARAM_RSSI
Received signal strength indicator in dBm.
@ RADIO_PARAM_LAST_PACKET_TIMESTAMP
Last packet timestamp, of type rtimer_clock_t.
@ RADIO_PARAM_LAST_RSSI
The RSSI value of the last received packet.
@ RADIO_CONST_BYTE_AIR_TIME
The air time of one byte in usec, e.g.
@ RADIO_PARAM_RX_MODE
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
@ RADIO_PARAM_CHANNEL
Channel used for radio communication.
@ RADIO_PARAM_LAST_LINK_QUALITY
Link quality indicator of the last received packet.
@ RADIO_CONST_DELAY_BEFORE_RX
The delay in usec between turning on the radio and it being actually listening (able to hear a preamb...
@ RADIO_PARAM_TXPOWER
Transmission power in dBm.
@ RADIO_PARAM_64BIT_ADDR
Long (64 bits) address for the radio, which is used by the address filter.
@ RADIO_CONST_DELAY_BEFORE_TX
The delay in usec between a call to the radio API's transmit function and the end of SFD transmission...
@ RADIO_CONST_CHANNEL_MAX
The highest radio channel number.
@ RADIO_PARAM_PAN_ID
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
@ RADIO_PARAM_CCA_THRESHOLD
Clear channel assessment threshold in dBm.
@ RADIO_CONST_TXPOWER_MIN
The minimum transmission power in dBm.
@ RADIO_CONST_CHANNEL_MIN
The lowest radio channel number.
@ RADIO_CONST_TXPOWER_MAX
The maximum transmission power in dBm.
@ RADIO_CONST_DELAY_BEFORE_DETECT
The delay in usec between the end of SFD reception for an incoming frame and the radio API starting t...
@ RADIO_PARAM_16BIT_ADDR
The short address (16 bits) for the radio, which is used by the h/w filter.
@ RADIO_PARAM_TX_MODE
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
@ RADIO_POWER_MODE_OFF
Radio powered off and in the lowest possible power consumption state.
@ RADIO_POWER_MODE_ON
Radio powered on and able to receive frames.
@ RADIO_TX_COLLISION
TX failed due to a collision.
@ RADIO_TX_ERR
An error occurred during transmission.
@ RADIO_TX_OK
TX was successful and where an ACK was requested one was received.
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
#define RF_RADIO_OP_GET_STATUS(a)
Returns the current status of a running Radio Op command.
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
static uint8_t transmitting(void)
Check the RF's TX status.
static uint8_t rf_is_on(void)
Checks whether the RFC domain is accessible and the RFC is in IEEE RX.
static uint8_t rf_cmd_ieee_rx()
Set up radio in IEEE802.15.4 RX mode.
static uint8_t get_cca_info(void)
Returns CCA information.
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.
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
uint8_t rf_core_boot()
Boot the RF Core.
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
uint32_t rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
Convert from RAT timestamp to rtimer ticks.
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
uint8_t rf_core_restart_rat(void)
Restart the CM0 RAT.
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
void rf_core_setup_interrupts(void)
Setup RF core interrupts.
uint8_t rf_core_rat_init(void)
Initialize the RAT to RTC conversion machinery.
uint8_t rf_core_check_rat_overflow(void)
Check if RAT overflow has occured and increment the overflow counter if so.
#define RTIMER_BUSYWAIT_UNTIL(cond, max_time)
Busy-wait until a condition for at most max_time.
#define RTIMER_NOW()
Get the current clock time.
Header file for the link-layer address representation.
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the CC13xx/CC26xx oscillator control.
Header file for the Packet buffer (packetbuf) management.
Header file for the radio API.
Header file for the CC13xx/CC26xx BLE driver.
Header file for the CC13xx/CC26xx RF core driver.
Header file with definitions related to RF switch support.
Header file for the real-time timer module.
The structure of a Contiki-NG radio device driver.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* off)(void)
Turn the radio off.
int(* init)(void)
Initialise the radio hardware.
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
int(* on)(void)
Turn the radio on.
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver's buffers.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not.
A data strcuture representing the radio's primary mode of operation.
Header file with macros which rename TI CC26xxware functions.