52 #include "sys/clock.h"
61 #include "hw_rfc_dbell.h"
62 #include "hw_rfc_pwr.h"
65 #include "rf-core/api/mailbox.h"
66 #include "rf-core/api/common_cmd.h"
67 #include "rf-core/api/ieee_cmd.h"
68 #include "rf-core/api/data_entry.h"
69 #include "rf-core/api/ieee_mailbox.h"
71 #include "smartrf-settings.h"
80 #define PRINTF(...) printf(__VA_ARGS__)
86 #ifdef IEEE_MODE_CONF_AUTOACK
87 #define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK
89 #define IEEE_MODE_AUTOACK 1
93 #ifdef IEEE_MODE_CONF_PROMISCOUS
94 #define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS
96 #define IEEE_MODE_PROMISCOUS 0
99 #ifdef IEEE_MODE_CONF_RSSI_THRESHOLD
100 #define IEEE_MODE_RSSI_THRESHOLD IEEE_MODE_CONF_RSSI_THRESHOLD
102 #define IEEE_MODE_RSSI_THRESHOLD 0xA6
106 #define DATA_ENTRY_STATUS_PENDING 0x00
107 #define DATA_ENTRY_STATUS_ACTIVE 0x01
108 #define DATA_ENTRY_STATUS_BUSY 0x02
109 #define DATA_ENTRY_STATUS_FINISHED 0x03
110 #define DATA_ENTRY_STATUS_UNFINISHED 0x04
113 static uint8_t rf_stats[16] = { 0 };
116 #define RF_CMD_BUFFER_SIZE 128
126 #define RF_RADIO_OP_GET_STATUS(a) (((rfc_radioOp_t *)a)->status)
129 #define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128
132 #define RF_CCA_CLEAR 1
133 #define RF_CCA_BUSY 0
136 #define RF_GET_CCA_INFO_ERROR 0xFF
142 #define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0
143 #define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1
144 #define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2
146 #define IEEE_MODE_CHANNEL_MIN 11
147 #define IEEE_MODE_CHANNEL_MAX 26
150 #define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11)
153 #define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10)
156 typedef struct output_config {
163 static const output_config_t output_power[] = {
164 { 5, 0x30, 0x00, 0x93 },
165 { 4, 0x24, 0x00, 0x93 },
166 { 3, 0x1c, 0x00, 0x5a },
167 { 2, 0x18, 0x00, 0x4e },
168 { 1, 0x14, 0x00, 0x42 },
169 { 0, 0x21, 0x01, 0x31 },
170 { -3, 0x18, 0x01, 0x25 },
171 { -6, 0x11, 0x01, 0x1d },
172 { -9, 0x0e, 0x01, 0x19 },
173 {-12, 0x0b, 0x01, 0x14 },
174 {-15, 0x0b, 0x03, 0x0c },
175 {-18, 0x09, 0x03, 0x0c },
176 {-21, 0x07, 0x03, 0x0c },
179 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
182 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm)
183 #define OUTPUT_POWER_MAX (output_power[0].dbm)
184 #define OUTPUT_POWER_UNKNOWN 0xFFFF
187 const output_config_t *tx_power_current = &output_power[0];
199 static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN(4);
201 #define DATA_ENTRY_LENSZ_NONE 0
202 #define DATA_ENTRY_LENSZ_BYTE 1
203 #define DATA_ENTRY_LENSZ_WORD 2
205 #define RX_BUF_SIZE 140
207 static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4);
208 static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
209 static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4);
210 static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4);
213 static dataQueue_t rx_data_queue = { 0 };
216 volatile static uint8_t *rx_read_entry;
219 #define TX_BUF_PAYLOAD_LEN 180
220 #define TX_BUF_HDR_LEN 2
222 static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
225 static uint32_t ieee_overrides[] = {
242 static int off(
void);
270 rfc_CMD_IEEE_CCA_REQ_t cmd;
277 memset(&cmd, 0x00,
sizeof(cmd));
279 cmd.commandNo = CMD_IEEE_CCA_REQ;
282 PRINTF(
"transmitting: CMDSTA=0x%08lx\n", cmd_status);
286 if((cmd.currentRssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN) &&
287 (cmd.ccaInfo.ccaEnergy == RF_CMD_CCA_REQ_CCA_STATE_BUSY)) {
310 rfc_CMD_IEEE_CCA_REQ_t cmd;
313 PRINTF(
"get_cca_info: Not on\n");
314 return RF_GET_CCA_INFO_ERROR;
317 rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN;
319 while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) {
320 memset(&cmd, 0x00,
sizeof(cmd));
321 cmd.commandNo = CMD_IEEE_CCA_REQ;
324 PRINTF(
"get_cca_info: CMDSTA=0x%08lx\n", cmd_status);
326 return RF_GET_CCA_INFO_ERROR;
329 rssi = cmd.currentRssi;
333 return *((uint8_t *)&cmd.ccaInfo);
349 rfc_CMD_GET_RSSI_t cmd;
354 if(on() != RF_CORE_CMD_OK) {
355 PRINTF(
"get_rssi: on() failed\n");
356 return RF_CMD_CCA_REQ_RSSI_UNKNOWN;
360 memset(&cmd, 0x00,
sizeof(cmd));
361 cmd.commandNo = CMD_GET_RSSI;
363 rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN;
367 rssi = (cmd_status >> 16) & 0xFF;
382 return tx_power_current->dbm;
396 rfc_CMD_SET_TX_POWER_t cmd;
399 for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
400 if(power <= output_power[i].dbm) {
401 tx_power_current = &output_power[i];
416 memset(&cmd, 0x00,
sizeof(cmd));
417 cmd.commandNo = CMD_SET_TX_POWER;
418 cmd.txPower.IB = output_power[i].register_ib;
419 cmd.txPower.GC = output_power[i].register_gc;
420 cmd.txPower.tempCoeff = output_power[i].temp_coeff;
423 PRINTF(
"set_tx_power: CMDSTA=0x%08lx\n", cmd_status);
431 rfc_CMD_RADIO_SETUP_t cmd;
436 cmd.txPower.IB = tx_power_current->register_ib;
437 cmd.txPower.GC = tx_power_current->register_gc;
438 cmd.txPower.tempCoeff = tx_power_current->temp_coeff;
439 cmd.pRegOverride = ieee_overrides;
444 PRINTF(
"rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n",
445 cmd_status, cmd.status);
446 return RF_CORE_CMD_ERROR;
451 PRINTF(
"rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n",
452 cmd_status, cmd.status);
453 return RF_CORE_CMD_ERROR;
456 return RF_CORE_CMD_OK;
478 if(ret != RF_CORE_CMD_OK) {
479 PRINTF(
"rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
481 return RF_CORE_CMD_ERROR;
487 (RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT)));
491 PRINTF(
"rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n",
493 return RF_CORE_CMD_ERROR;
500 init_rx_buffers(
void)
502 rfc_dataEntry_t *entry;
504 entry = (rfc_dataEntry_t *)rx_buf_0;
505 entry->pNextEntry = rx_buf_1;
506 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
507 entry->length =
sizeof(rx_buf_0) - 8;
509 entry = (rfc_dataEntry_t *)rx_buf_1;
510 entry->pNextEntry = rx_buf_2;
511 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
512 entry->length =
sizeof(rx_buf_0) - 8;
514 entry = (rfc_dataEntry_t *)rx_buf_2;
515 entry->pNextEntry = rx_buf_3;
516 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
517 entry->length =
sizeof(rx_buf_0) - 8;
519 entry = (rfc_dataEntry_t *)rx_buf_3;
520 entry->pNextEntry = rx_buf_0;
521 entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
522 entry->length =
sizeof(rx_buf_0) - 8;
528 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
530 memset(cmd_ieee_rx_buf, 0x00, RF_CMD_BUFFER_SIZE);
532 cmd->commandNo = CMD_IEEE_RX;
533 cmd->status = RF_CORE_RADIO_OP_STATUS_IDLE;
535 cmd->startTime = 0x00000000;
536 cmd->startTrigger.triggerType = TRIG_NOW;
537 cmd->condition.rule = COND_NEVER;
538 cmd->channel = RF_CORE_CHANNEL;
540 cmd->rxConfig.bAutoFlushCrc = 1;
541 cmd->rxConfig.bAutoFlushIgn = 0;
542 cmd->rxConfig.bIncludePhyHdr = 0;
543 cmd->rxConfig.bIncludeCrc = 1;
544 cmd->rxConfig.bAppendRssi = 1;
545 cmd->rxConfig.bAppendCorrCrc = 1;
546 cmd->rxConfig.bAppendSrcInd = 0;
547 cmd->rxConfig.bAppendTimestamp = 0;
549 cmd->pRxQ = &rx_data_queue;
550 cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats;
552 #if IEEE_MODE_PROMISCOUS
553 cmd->frameFiltOpt.frameFiltEn = 0;
555 cmd->frameFiltOpt.frameFiltEn = 1;
558 cmd->frameFiltOpt.frameFiltStop = 1;
560 #if IEEE_MODE_AUTOACK
561 cmd->frameFiltOpt.autoAckEn = 1;
563 cmd->frameFiltOpt.autoAckEn = 0;
566 cmd->frameFiltOpt.slottedAckEn = 0;
567 cmd->frameFiltOpt.autoPendEn = 0;
568 cmd->frameFiltOpt.defaultPend = 0;
569 cmd->frameFiltOpt.bPendDataReqOnly = 0;
570 cmd->frameFiltOpt.bPanCoord = 0;
571 cmd->frameFiltOpt.maxFrameVersion = 1;
572 cmd->frameFiltOpt.bStrictLenFilter = 0;
575 cmd->frameTypes.bAcceptFt0Beacon = 1;
576 cmd->frameTypes.bAcceptFt1Data = 1;
577 cmd->frameTypes.bAcceptFt2Ack = 1;
578 cmd->frameTypes.bAcceptFt3MacCmd = 1;
579 cmd->frameTypes.bAcceptFt4Reserved = 1;
580 cmd->frameTypes.bAcceptFt5Reserved = 1;
581 cmd->frameTypes.bAcceptFt6Reserved = 1;
582 cmd->frameTypes.bAcceptFt7Reserved = 1;
585 cmd->ccaOpt.ccaEnEnergy = 1;
586 cmd->ccaOpt.ccaEnCorr = 1;
587 cmd->ccaOpt.ccaEnSync = 0;
588 cmd->ccaOpt.ccaCorrOp = 1;
589 cmd->ccaOpt.ccaSyncOp = 1;
590 cmd->ccaOpt.ccaCorrThr = 3;
592 cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD;
594 cmd->numExtEntries = 0x00;
595 cmd->numShortEntries = 0x00;
596 cmd->pExtEntryList = 0;
597 cmd->pShortEntryList = 0;
599 cmd->endTrigger.triggerType = TRIG_NEVER;
600 cmd->endTime = 0x00000000;
612 return RF_CORE_CMD_OK;
619 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
633 return RF_CORE_CMD_OK;
640 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
641 PRINTF(
"RX off: CMD_ABORT status=0x%08lx\n", cmd_status);
650 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
651 ret = RF_CORE_CMD_OK;
654 ret = RF_CORE_CMD_ERROR;
668 return LPM_MODE_SLEEP;
671 return LPM_MODE_MAX_SUPPORTED;
686 PRINTF(
"soft_off: Aborting 0x%04x, Status=0x%04x\n", cmd->commandNo,
690 if(
rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
691 PRINTF(
"soft_off: CMD_ABORT status=0x%08lx\n", cmd_status);
695 while((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) ==
696 RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING);
702 if(rf_radio_setup() != RF_CORE_CMD_OK) {
703 PRINTF(
"on: radio_setup() failed\n");
704 return RF_CORE_CMD_ERROR;
723 memset(rx_buf_0, 0, RX_BUF_SIZE);
724 memset(rx_buf_1, 0, RX_BUF_SIZE);
725 memset(rx_buf_2, 0, RX_BUF_SIZE);
726 memset(rx_buf_3, 0, RX_BUF_SIZE);
729 rx_data_queue.pCurrEntry = rx_buf_0;
731 rx_data_queue.pLastEntry =
NULL;
734 rx_read_entry = rx_buf_0;
739 if(on() != RF_CORE_CMD_OK) {
740 PRINTF(
"init: on() failed\n");
741 return RF_CORE_CMD_ERROR;
744 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
753 prepare(
const void *payload,
unsigned short payload_len)
755 int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN);
757 memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len);
758 return RF_CORE_CMD_OK;
762 transmit(
unsigned short transmit_len)
768 uint8_t tx_active = 0;
770 volatile rfc_CMD_IEEE_TX_t cmd;
774 if(on() != RF_CORE_CMD_OK) {
775 PRINTF(
"transmit: on() failed\n");
789 }
while(tx_active == 1 &&
790 (RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + TX_WAIT_TIMEOUT)));
793 PRINTF(
"transmit: Already TXing and wait timed out\n");
799 return RADIO_TX_COLLISION;
805 cmd.payloadLen = transmit_len;
806 cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
815 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
816 ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
819 while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS)
820 == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
826 if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) {
832 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret,
838 PRINTF(
"transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
839 ret, cmd_status, cmd.status);
848 ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
849 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
866 send(
const void *payload,
unsigned short payload_len)
868 prepare(payload, payload_len);
869 return transmit(payload_len);
873 release_data_entry(
void)
875 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
878 rx_read_entry[8] = 0;
881 entry->status = DATA_ENTRY_STATUS_PENDING;
882 rx_read_entry = entry->pNextEntry;
885 read_frame(
void *buf,
unsigned short buf_len)
889 rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
891 if(entry->status != DATA_ENTRY_STATUS_FINISHED) {
896 if(rx_read_entry[8] < 4) {
897 PRINTF(
"RF: too short\n");
898 RIMESTATS_ADD(tooshort);
900 release_data_entry();
904 len = rx_read_entry[8] - 4;
907 PRINTF(
"RF: too long\n");
908 RIMESTATS_ADD(toolong);
910 release_data_entry();
914 memcpy(buf, (
char *)&rx_read_entry[9], len);
916 rssi = (int8_t)rx_read_entry[9 + len + 2];
918 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
921 release_data_entry();
931 int ret = RF_CCA_CLEAR;
938 PRINTF(
"channel_clear: Interrupt context but BLE in progress\n");
954 if(on() != RF_CORE_CMD_OK) {
955 PRINTF(
"channel_clear: on() failed\n");
965 if(cca_info == RF_GET_CCA_INFO_ERROR) {
966 PRINTF(
"channel_clear: CCA error\n");
973 ret = (cca_info & 0x03) != RF_CMD_CCA_REQ_CCA_STATE_BUSY;
984 receiving_packet(
void)
995 PRINTF(
"receiving_packet: Interrupt context but BLE in progress\n");
1001 PRINTF(
"receiving_packet: We were off\n");
1007 PRINTF(
"receiving_packet: We were TXing\n");
1013 if(cca_info == RF_GET_CCA_INFO_ERROR) {
1018 ret = (cca_info & 0x03) == RF_CMD_CCA_REQ_CCA_STATE_BUSY;
1029 pending_packet(
void)
1031 volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
1036 if(entry->status == DATA_ENTRY_STATUS_FINISHED) {
1041 entry = (rfc_dataEntry_t *)entry->pNextEntry;
1042 }
while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
1056 PRINTF(
"on: Interrupt context but BLE in progress\n");
1057 return RF_CORE_CMD_OK;
1069 return RF_CORE_CMD_OK;
1073 PRINTF(
"on: rf_core_boot() failed\n");
1074 return RF_CORE_CMD_ERROR;
1088 if(rf_radio_setup() != RF_CORE_CMD_OK) {
1089 PRINTF(
"on: radio_setup() failed\n");
1090 return RF_CORE_CMD_ERROR;
1104 PRINTF(
"off: Interrupt context but BLE in progress\n");
1105 return RF_CORE_CMD_OK;
1114 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
1120 ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
1126 ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING;
1127 ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING;
1128 ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING;
1129 ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING;
1131 return RF_CORE_CMD_OK;
1134 static radio_result_t
1137 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1140 return RADIO_RESULT_INVALID_VALUE;
1144 case RADIO_PARAM_POWER_MODE:
1146 *value =
rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1147 return RADIO_RESULT_OK;
1148 case RADIO_PARAM_CHANNEL:
1150 return RADIO_RESULT_OK;
1151 case RADIO_PARAM_PAN_ID:
1153 return RADIO_RESULT_OK;
1154 case RADIO_PARAM_16BIT_ADDR:
1156 return RADIO_RESULT_OK;
1157 case RADIO_PARAM_RX_MODE:
1159 if(cmd->frameFiltOpt.frameFiltEn) {
1162 if(cmd->frameFiltOpt.autoAckEn) {
1163 *value |= RADIO_RX_MODE_AUTOACK;
1166 return RADIO_RESULT_OK;
1167 case RADIO_PARAM_TXPOWER:
1168 *value = get_tx_power();
1169 return RADIO_RESULT_OK;
1170 case RADIO_PARAM_CCA_THRESHOLD:
1171 *value = cmd->ccaRssiThr;
1172 return RADIO_RESULT_OK;
1173 case RADIO_PARAM_RSSI:
1176 if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) {
1177 return RADIO_RESULT_ERROR;
1179 return RADIO_RESULT_OK;
1181 case RADIO_CONST_CHANNEL_MIN:
1182 *value = IEEE_MODE_CHANNEL_MIN;
1183 return RADIO_RESULT_OK;
1184 case RADIO_CONST_CHANNEL_MAX:
1185 *value = IEEE_MODE_CHANNEL_MAX;
1186 return RADIO_RESULT_OK;
1187 case RADIO_CONST_TXPOWER_MIN:
1188 *value = OUTPUT_POWER_MIN;
1189 return RADIO_RESULT_OK;
1190 case RADIO_CONST_TXPOWER_MAX:
1191 *value = OUTPUT_POWER_MAX;
1192 return RADIO_RESULT_OK;
1194 return RADIO_RESULT_NOT_SUPPORTED;
1198 static radio_result_t
1201 uint8_t was_off = 0;
1202 radio_result_t rv = RADIO_RESULT_OK;
1203 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1206 case RADIO_PARAM_POWER_MODE:
1207 if(value == RADIO_POWER_MODE_ON) {
1208 if(on() != RF_CORE_CMD_OK) {
1209 PRINTF(
"set_value: on() failed (1)\n");
1210 return RADIO_RESULT_ERROR;
1212 return RADIO_RESULT_OK;
1214 if(value == RADIO_POWER_MODE_OFF) {
1216 return RADIO_RESULT_OK;
1218 return RADIO_RESULT_INVALID_VALUE;
1219 case RADIO_PARAM_CHANNEL:
1220 if(value < IEEE_MODE_CHANNEL_MIN ||
1221 value > IEEE_MODE_CHANNEL_MAX) {
1222 return RADIO_RESULT_INVALID_VALUE;
1225 if(cmd->channel == (uint8_t)value) {
1228 return RADIO_RESULT_OK;
1231 cmd->channel = (uint8_t)value;
1233 case RADIO_PARAM_PAN_ID:
1234 cmd->localPanID = (uint16_t)value;
1236 case RADIO_PARAM_16BIT_ADDR:
1237 cmd->localShortAddr = (uint16_t)value;
1239 case RADIO_PARAM_RX_MODE:
1242 RADIO_RX_MODE_AUTOACK)) {
1243 return RADIO_RESULT_INVALID_VALUE;
1247 cmd->frameFiltOpt.frameFiltStop = 1;
1248 cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
1249 cmd->frameFiltOpt.slottedAckEn = 0;
1250 cmd->frameFiltOpt.autoPendEn = 0;
1251 cmd->frameFiltOpt.defaultPend = 0;
1252 cmd->frameFiltOpt.bPendDataReqOnly = 0;
1253 cmd->frameFiltOpt.bPanCoord = 0;
1254 cmd->frameFiltOpt.bStrictLenFilter = 0;
1257 case RADIO_PARAM_TXPOWER:
1258 if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1259 return RADIO_RESULT_INVALID_VALUE;
1262 set_tx_power(value);
1264 return RADIO_RESULT_OK;
1265 case RADIO_PARAM_CCA_THRESHOLD:
1266 cmd->ccaRssiThr = (int8_t)value;
1269 return RADIO_RESULT_NOT_SUPPORTED;
1275 if(on() != RF_CORE_CMD_OK) {
1276 PRINTF(
"set_value: on() failed (2)\n");
1277 return RADIO_RESULT_ERROR;
1281 if(rx_off() != RF_CORE_CMD_OK) {
1282 PRINTF(
"set_value: rx_off() failed\n");
1283 rv = RADIO_RESULT_ERROR;
1286 if(rx_on() != RF_CORE_CMD_OK) {
1287 PRINTF(
"set_value: rx_on() failed\n");
1288 rv = RADIO_RESULT_ERROR;
1299 static radio_result_t
1300 get_object(radio_param_t param,
void *dest,
size_t size)
1305 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1307 if(param == RADIO_PARAM_64BIT_ADDR) {
1308 if(size != 8 || !dest) {
1309 return RADIO_RESULT_INVALID_VALUE;
1313 src = (uint8_t *)(&cmd->localExtAddr);
1315 for(i = 0; i < 8; i++) {
1316 target[i] = src[7 - i];
1319 return RADIO_RESULT_OK;
1321 return RADIO_RESULT_NOT_SUPPORTED;
1324 static radio_result_t
1325 set_object(radio_param_t param,
const void *src,
size_t size)
1327 uint8_t was_off = 0;
1331 rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1333 if(param == RADIO_PARAM_64BIT_ADDR) {
1334 if(size != 8 || !src) {
1335 return RADIO_RESULT_INVALID_VALUE;
1338 dst = (uint8_t *)(&cmd->localExtAddr);
1340 for(i = 0; i < 8; i++) {
1341 dst[i] = ((uint8_t *)src)[7 - i];
1346 if(on() != RF_CORE_CMD_OK) {
1347 PRINTF(
"set_object: on() failed\n");
1348 return RADIO_RESULT_ERROR;
1352 if(rx_off() != RF_CORE_CMD_OK) {
1353 PRINTF(
"set_object: rx_off() failed\n");
1354 rv = RADIO_RESULT_ERROR;
1357 if(rx_on() != RF_CORE_CMD_OK) {
1358 PRINTF(
"set_object: rx_on() failed\n");
1359 rv = RADIO_RESULT_ERROR;
1369 return RADIO_RESULT_NOT_SUPPORTED;
void process_poll(struct process *p)
Request a process to be polled.
Header file for the real-time timer module.
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
Header file for the radio API
Header file with macros which rename TI CC26xxware functions.
#define RTIMER_NOW()
Get the current clock 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...
Default definitions of C compiler quirk work-arounds.
Header file for the CC13xx/CC26xx BLE driver.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
Header file for the energy estimation mechanism
The structure of a device driver for a radio in Contiki.
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
Header file for the Rime buffer (packetbuf) management
#define LPM_MODULE(n, m, s, w, l)
Declare a variable to be used in order to get notifications from LPM.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
static uint8_t get_cca_info(void)
Returns CCA information.
void rf_core_setup_interrupts()
Setup RF core interrupts.
Header file for the CC13xx/CC26xx RF core driver.
Header file for the Rime address representation
int(* off)(void)
Turn the radio off.
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
#define NULL
The null pointer.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
static uint8_t transmitting(void)
Check the RF's TX status.
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
uint8_t rf_core_boot()
Boot the RF Core.
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
int(* on)(void)
Turn the radio on.
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
static uint8_t rf_is_on(void)
Checks whether the RFC domain is accessible and the RFC is in IEEE RX.
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
void process_start(struct process *p, process_data_t data)
Start a process.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
#define RF_RADIO_OP_GET_STATUS(a)
Returns the current status of a running Radio Op command.
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
Header file for Rime statistics
Header file for the CC13xx/CC26xx UART driver.
static uint8_t rf_cmd_ieee_rx()
Set up radio in IEEE802.15.4 RX mode.
Header file for the CC13xx/CC26xx oscillator control.
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch...
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
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_cmd_done_dis()
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
Include file for the Contiki low-layer network stack (NETSTACK)
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
A data strcuture representing the radio's primary mode of operation.
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.