49 #include "sys/clock.h" 55 #include <ti/devices/DeviceFamily.h> 56 #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h) 57 #include DeviceFamily_constructPath(driverlib/rf_data_entry.h) 58 #include DeviceFamily_constructPath(driverlib/rf_mailbox.h) 65 #if defined(DeviceFamily_CC13X0) 66 #include "driverlib/rf_ieee_mailbox.h" 68 #include DeviceFamily_constructPath(driverlib/rf_ieee_mailbox.h) 71 #include <ti/drivers/rf/RF.h> 89 #define LOG_MODULE "Radio" 90 #define LOG_LEVEL LOG_LEVEL_NONE 93 #define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK 94 #define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS 95 #define IEEE_MODE_CCA_RSSI_THRESHOLD IEEE_MODE_CONF_CCA_RSSI_THRESHOLD 100 #define TIMEOUT_DATA_ENTRY_BUSY (RTIMER_SECOND / 250) 103 #define TIMEOUT_ENTER_RX_WAIT (RTIMER_SECOND >> 10) 105 #define RAT_RANGE (~(uint32_t)0) 106 #define RAT_ONE_QUARTER (RAT_RANGE / (uint32_t)4) 107 #define RAT_THREE_QUARTERS ((RAT_RANGE * (uint32_t)3) / (uint32_t)4) 110 #define RAT_TIMESTAMP_OFFSET -(USEC_TO_RAT(32 * 3) - 1) 112 #define STATUS_CORRELATION 0x3f 113 #define STATUS_REJECT_FRAME 0x40 114 #define STATUS_CRC_FAIL 0x80 120 #define CHECKSUM_LEN 2 127 #define MAX_PAYLOAD_LEN (127 - CHECKSUM_LEN) 129 #define FRAME_FCF_OFFSET 0 130 #define FRAME_SEQNUM_OFFSET 2 132 #define FRAME_ACK_REQUEST 0x20 135 #define TX_BUF_SIZE 180 138 typedef uint8_t lensz_t;
140 #define FRAME_OFFSET sizeof(lensz_t) 141 #define FRAME_SHAVE 8 147 CCA_STATE_INVALID = 2
151 typedef rfc_ieeeRxOutput_t rx_output_t;
152 typedef rfc_CMD_IEEE_MOD_FILT_t cmd_mod_filt_t;
153 typedef rfc_CMD_IEEE_CCA_REQ_t cmd_cca_req_t;
157 uint8_t tx_buf[TX_BUF_SIZE] CC_ALIGN(4);
160 rx_output_t rx_stats;
178 struct ctimer overflow_timer;
179 rtimer_clock_t last_overflow;
180 volatile uint32_t overflow_count;
187 static ieee_radio_t ieee_radio;
190 static cmd_mod_filt_t cmd_mod_filt;
193 #define cmd_radio_setup rf_cmd_ieee_radio_setup 194 #define cmd_fs rf_cmd_ieee_fs 195 #define cmd_tx rf_cmd_ieee_tx 196 #define cmd_rx rf_cmd_ieee_rx 197 #define cmd_rx_ack rf_cmd_ieee_rx_ack 200 #define v_cmd_radio_setup CC_ACCESS_NOW(rfc_CMD_RADIO_SETUP_t, rf_cmd_ieee_radio_setup) 201 #define v_cmd_fs CC_ACCESS_NOW(rfc_CMD_FS_t, rf_cmd_ieee_fs) 202 #define v_cmd_tx CC_ACCESS_NOW(rfc_CMD_IEEE_TX_t, rf_cmd_ieee_tx) 203 #define v_cmd_rx CC_ACCESS_NOW(rfc_CMD_IEEE_RX_t, rf_cmd_ieee_rx) 204 #define v_cmd_rx_ack CC_ACCESS_NOW(rfc_CMD_IEEE_RX_ACK_t, rf_cmd_ieee_rx_ack) 209 return v_cmd_rx.status == ACTIVE;
213 static void check_rat_overflow(
void);
214 static uint32_t rat_to_timestamp(
const uint32_t);
217 static int init(
void);
218 static int prepare(
const void *,
unsigned short);
219 static int transmit(
unsigned short);
220 static int send(
const void *,
unsigned short);
221 static int read(
void *,
unsigned short);
226 static int off(
void);
229 static radio_result_t
get_object(radio_param_t,
void *,
size_t);
230 static radio_result_t
set_object(radio_param_t,
const void *,
size_t);
233 rat_overflow_cb(
void *arg)
235 check_rat_overflow();
237 const clock_time_t two_quarters = (2 * RAT_ONE_QUARTER *
CLOCK_SECOND) / RAT_SECOND;
238 ctimer_set(&ieee_radio.rat.overflow_timer, two_quarters, rat_overflow_cb, NULL);
244 cmd_radio_setup.config.frontEndMode = RF_2_4_GHZ_FRONT_END_MODE;
245 cmd_radio_setup.config.biasMode = RF_2_4_GHZ_BIAS_MODE;
247 cmd_rx.pRxQ = data_queue_init(
sizeof(lensz_t));
248 cmd_rx.pOutput = &ieee_radio.rx_stats;
250 #if IEEE_MODE_PROMISCOUS 251 cmd_rx.frameFiltOpt.frameFiltEn = 0;
253 cmd_rx.frameFiltOpt.frameFiltEn = 1;
256 #if IEEE_MODE_AUTOACK 257 cmd_rx.frameFiltOpt.autoAckEn = 1;
259 cmd_rx.frameFiltOpt.autoAckEn = 0;
262 cmd_rx.ccaRssiThr = IEEE_MODE_CCA_RSSI_THRESHOLD;
264 cmd_tx.pNextOp = (RF_Op *)&cmd_rx_ack;
265 cmd_tx.condition.rule = COND_NEVER;
275 cmd_rx_ack.startTrigger.triggerType = TRIG_NOW;
276 cmd_rx_ack.endTrigger.triggerType = TRIG_REL_START;
277 cmd_rx_ack.endTime = RF_convertUsToRatTicks(700);
280 cmd_mod_filt.commandNo = CMD_IEEE_MOD_FILT;
281 memcpy(&(cmd_mod_filt.newFrameFiltOpt), &(cmd_rx.frameFiltOpt),
sizeof(cmd_rx.frameFiltOpt));
282 memcpy(&(cmd_mod_filt.newFrameTypes), &(cmd_rx.frameTypes),
sizeof(cmd_rx.frameTypes));
288 if(!dot_15_4g_chan_in_range(channel)) {
289 LOG_WARN(
"Supplied hannel %d is illegal, defaults to %d\n",
290 (
int)channel, DOT_15_4G_DEFAULT_CHAN);
291 channel = DOT_15_4G_DEFAULT_CHAN;
299 if(channel == v_cmd_rx.channel) {
304 v_cmd_rx.channel = channel;
306 const uint32_t new_freq = dot_15_4g_freq(channel);
307 const uint16_t freq = (uint16_t)(new_freq / 1000);
308 const uint16_t frac = (uint16_t)(((new_freq - (freq * 1000)) * 0x10000) / 1000);
310 LOG_DBG(
"Set channel to %d, frequency 0x%04X.0x%04X (%lu)\n",
311 (
int)channel, freq, frac, new_freq);
313 v_cmd_fs.frequency = freq;
314 v_cmd_fs.fractFreq = frac;
316 return netstack_sched_fs();
320 set_send_on_cca(
bool enable)
322 ieee_radio.send_on_cca = enable;
326 check_rat_overflow(
void)
328 const bool was_off = !rx_is_active();
331 RF_runDirectCmd(ieee_radio.rf_handle, CMD_NOP);
334 const uint32_t current_value = RF_getCurrentTime();
336 static bool initial_iteration =
true;
337 static uint32_t last_value;
339 if(initial_iteration) {
341 initial_iteration =
false;
344 if((current_value + RAT_ONE_QUARTER) < last_value) {
347 ieee_radio.rat.overflow_count += 1;
351 last_value = current_value;
354 RF_yield(ieee_radio.rf_handle);
359 rat_to_timestamp(
const uint32_t rat_ticks)
361 check_rat_overflow();
363 uint64_t adjusted_overflow_count = ieee_radio.rat.overflow_count;
367 if(rat_ticks > RAT_THREE_QUARTERS) {
368 const rtimer_clock_t one_quarter = (RAT_ONE_QUARTER *
RTIMER_SECOND) / RAT_SECOND;
369 if(RTIMER_CLOCK_LT(
RTIMER_NOW(), ieee_radio.rat.last_overflow + one_quarter)) {
370 adjusted_overflow_count -= 1;
375 const uint64_t rat_ticks_adjusted = (uint64_t)rat_ticks + (uint64_t)RAT_RANGE * adjusted_overflow_count;
378 return RAT_TO_RTIMER(rat_ticks_adjusted + RAT_TIMESTAMP_OFFSET);
385 RF_TxPowerTable_Value tx_power_value;
388 if(ieee_radio.rf_handle) {
389 LOG_WARN(
"Radio already initialized\n");
394 ieee_radio.rf_is_on =
false;
399 RF_Params_init(&rf_params);
402 ieee_radio.rf_handle = netstack_open(&rf_params);
404 if(ieee_radio.rf_handle == NULL) {
405 LOG_ERR(
"Unable to open RF driver\n");
406 return RF_RESULT_ERROR;
411 tx_power_value = RF_TxPowerTable_findValue(rf_tx_power_table, RF_TXPOWER_DBM);
412 if(tx_power_value.rawValue != RF_TxPowerTable_INVALID_VALUE) {
413 rf_stat = RF_setTxPower(ieee_radio.rf_handle, tx_power_value);
414 if(rf_stat == RF_StatSuccess) {
415 LOG_INFO(
"TX power configured to %d dBm\n", RF_TXPOWER_DBM);
417 LOG_WARN(
"Setting TX power to %d dBm failed, stat=0x%02X", RF_TXPOWER_DBM, rf_stat);
420 LOG_WARN(
"Unable to find TX power %d dBm in the TX power table\n", RF_TXPOWER_DBM);
423 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
426 check_rat_overflow();
427 clock_time_t two_quarters = (2 * RAT_ONE_QUARTER *
CLOCK_SECOND) / RAT_SECOND;
428 ctimer_set(&ieee_radio.rat.overflow_timer, two_quarters, rat_overflow_cb, NULL);
437 prepare(
const void *payload,
unsigned short payload_len)
439 if(payload_len > TX_BUF_SIZE || payload_len > MAX_PAYLOAD_LEN) {
442 memcpy(ieee_radio.tx_buf, payload, payload_len);
447 transmit(
unsigned short transmit_len)
451 if(transmit_len > MAX_PAYLOAD_LEN) {
452 LOG_ERR(
"Too long\n");
457 LOG_WARN(
"Channel is not clear for transmission\n");
458 return RADIO_TX_COLLISION;
465 const bool ack_request = (bool)(ieee_radio.tx_buf[FRAME_FCF_OFFSET] & FRAME_ACK_REQUEST);
468 v_cmd_tx.condition.rule = COND_STOP_ON_FALSE;
471 v_cmd_rx_ack.status = IDLE;
473 v_cmd_rx_ack.seqNo = ieee_radio.tx_buf[FRAME_SEQNUM_OFFSET];
476 v_cmd_tx.condition.rule = COND_NEVER;
480 v_cmd_tx.payloadLen = (uint8_t)transmit_len;
481 v_cmd_tx.pPayload = ieee_radio.tx_buf;
483 res = netstack_sched_ieee_tx(ack_request);
485 if(res != RF_RESULT_OK) {
490 switch(v_cmd_rx_ack.status) {
492 case IEEE_DONE_TIMEOUT:
return RADIO_TX_NOACK;
495 case IEEE_DONE_ACKPEND:
return RADIO_TX_OK;
497 default:
return RADIO_TX_ERR;
506 send(
const void *payload,
unsigned short payload_len)
513 read(
void *buf,
unsigned short buf_len)
515 volatile data_entry_t *data_entry = data_queue_current_entry();
519 while((data_entry->status == DATA_ENTRY_BUSY) &&
520 RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + TIMEOUT_DATA_ENTRY_BUSY)) ;
522 if(data_entry->status != DATA_ENTRY_FINISHED) {
547 uint8_t *
const frame_ptr = (uint8_t *)&data_entry->data;
548 const lensz_t frame_len = *(lensz_t *)frame_ptr;
552 LOG_ERR(
"Received frame too short, len=%d\n", frame_len);
554 data_queue_release_entry();
558 const uint8_t *payload_ptr = frame_ptr +
sizeof(lensz_t);
559 const unsigned short payload_len = (
unsigned short)(frame_len -
FRAME_SHAVE);
562 if(payload_len > buf_len) {
563 LOG_ERR(
"MAC payload too large for buffer, len=%d buf_len=%d\n",
564 payload_len, buf_len);
566 data_queue_release_entry();
570 memcpy(buf, payload_ptr, payload_len);
573 ieee_radio.last.rssi = (int8_t)payload_ptr[payload_len + 2];
575 ieee_radio.last.corr_lqi = (uint8_t)(payload_ptr[payload_len + 3] & STATUS_CORRELATION);
577 const uint32_t rat_ticks = *(uint32_t *)(payload_ptr + payload_len + 4);
578 ieee_radio.last.timestamp = rat_to_timestamp(rat_ticks);
580 if(!ieee_radio.poll_mode) {
584 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (packetbuf_attr_t)ieee_radio.last.rssi);
585 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, (packetbuf_attr_t)ieee_radio.last.corr_lqi);
588 data_queue_release_entry();
589 return (
int)payload_len;
593 cca_request(cmd_cca_req_t *cmd_cca_req)
595 RF_Stat stat = RF_StatRadioInactiveError;
597 bool stop_rx =
false;
600 if(!rx_is_active()) {
602 if(v_cmd_rx.status != PENDING) {
603 res = netstack_sched_rx(
false);
604 if(res != RF_RESULT_OK) {
605 LOG_ERR(
"CCA request failed to schedule RX\n");
616 if(!rx_is_active()) {
617 LOG_ERR(
"CCA request failed to turn on RX, RX status=0x%04X\n", v_cmd_rx.status);
618 return RF_RESULT_ERROR;
623 stat = RF_runImmediateCmd(ieee_radio.rf_handle, (uint32_t *)cmd_cca_req);
629 if(stat != RF_StatCmdDoneSuccess) {
630 LOG_ERR(
"CCA request command failed, stat=0x%02X\n", stat);
631 return RF_RESULT_ERROR;
640 cmd_cca_req_t cmd_cca_req;
641 memset(&cmd_cca_req, 0x0,
sizeof(cmd_cca_req_t));
642 cmd_cca_req.commandNo = CMD_IEEE_CCA_REQ;
644 if(cca_request(&cmd_cca_req) != RF_RESULT_OK) {
649 return cmd_cca_req.ccaInfo.ccaState == CCA_STATE_IDLE;
655 cmd_cca_req_t cmd_cca_req;
656 memset(&cmd_cca_req, 0x0,
sizeof(cmd_cca_req_t));
657 cmd_cca_req.commandNo = CMD_IEEE_CCA_REQ;
659 if(cca_request(&cmd_cca_req) != RF_RESULT_OK) {
664 if((cmd_cca_req.ccaInfo.ccaEnergy == CCA_STATE_BUSY) &&
665 (cmd_cca_req.ccaInfo.ccaCorr == CCA_STATE_BUSY) &&
666 (cmd_cca_req.ccaInfo.ccaSync == CCA_STATE_BUSY)) {
667 LOG_WARN(
"We are TXing ACK, therefore not receiving packets\n");
672 return cmd_cca_req.ccaInfo.ccaSync == CCA_STATE_BUSY;
678 const data_entry_t *
const read_entry = data_queue_current_entry();
679 volatile const data_entry_t *curr_entry = read_entry;
685 const uint8_t status = curr_entry->status;
686 if((status == DATA_ENTRY_FINISHED) ||
687 (status == DATA_ENTRY_BUSY)) {
692 curr_entry = (data_entry_t *)curr_entry->pNextEntry;
693 }
while(curr_entry != read_entry);
695 if((num_pending > 0) && !ieee_radio.poll_mode) {
708 if(ieee_radio.rf_is_on) {
709 LOG_WARN(
"Radio is already on\n");
715 res = netstack_sched_rx(
true);
717 if(res != RF_RESULT_OK) {
718 return RF_RESULT_ERROR;
721 ieee_radio.rf_is_on =
true;
728 if(!ieee_radio.rf_is_on) {
729 LOG_WARN(
"Radio is already off\n");
735 ieee_radio.rf_is_on =
false;
739 static radio_result_t
745 return RADIO_RESULT_INVALID_VALUE;
751 case RADIO_PARAM_POWER_MODE:
752 *value = (ieee_radio.rf_is_on)
753 ? RADIO_POWER_MODE_ON
754 : RADIO_POWER_MODE_OFF;
755 return RADIO_RESULT_OK;
758 case RADIO_PARAM_CHANNEL:
760 return RADIO_RESULT_OK;
763 case RADIO_PARAM_PAN_ID:
765 return RADIO_RESULT_OK;
768 case RADIO_PARAM_16BIT_ADDR:
770 return RADIO_RESULT_OK;
773 case RADIO_PARAM_RX_MODE:
775 if(v_cmd_rx.frameFiltOpt.frameFiltEn) {
778 if(v_cmd_rx.frameFiltOpt.autoAckEn) {
781 if(ieee_radio.poll_mode) {
784 return RADIO_RESULT_OK;
787 case RADIO_PARAM_TX_MODE:
789 return RADIO_RESULT_OK;
792 case RADIO_PARAM_TXPOWER:
793 res = rf_get_tx_power(ieee_radio.rf_handle, rf_tx_power_table, (int8_t *)&value);
794 return ((res == RF_RESULT_OK) &&
795 (*value != RF_TxPowerTable_INVALID_DBM))
797 : RADIO_RESULT_ERROR;
800 case RADIO_PARAM_CCA_THRESHOLD:
801 *value = v_cmd_rx.ccaRssiThr;
802 return RADIO_RESULT_OK;
805 case RADIO_PARAM_RSSI:
806 *value = RF_getRssi(ieee_radio.rf_handle);
807 return (*value == RF_GET_RSSI_ERROR_VAL)
812 case RADIO_CONST_CHANNEL_MIN:
814 return RADIO_RESULT_OK;
817 case RADIO_CONST_CHANNEL_MAX:
819 return RADIO_RESULT_OK;
821 case RADIO_CONST_TXPOWER_MIN:
823 return RADIO_RESULT_OK;
826 case RADIO_CONST_TXPOWER_MAX:
827 *value = (
radio_value_t)tx_power_max(rf_tx_power_table, rf_tx_power_table_size);
828 return RADIO_RESULT_OK;
831 case RADIO_PARAM_LAST_RSSI:
833 return RADIO_RESULT_OK;
836 case RADIO_PARAM_LAST_LINK_QUALITY:
838 return RADIO_RESULT_OK;
840 case RADIO_CONST_MAX_PAYLOAD_LEN:
842 return RADIO_RESULT_OK;
845 return RADIO_RESULT_NOT_SUPPORTED;
849 static radio_result_t
857 case RADIO_PARAM_POWER_MODE:
859 if(value == RADIO_POWER_MODE_ON) {
860 return (
on() == RF_RESULT_OK)
862 : RADIO_RESULT_ERROR;
863 }
else if(value == RADIO_POWER_MODE_OFF) {
865 return RADIO_RESULT_OK;
868 return RADIO_RESULT_INVALID_VALUE;
871 case RADIO_PARAM_CHANNEL:
872 if(!dot_15_4g_chan_in_range(value)) {
873 return RADIO_RESULT_INVALID_VALUE;
876 return RADIO_RESULT_OK;
879 case RADIO_PARAM_PAN_ID:
880 v_cmd_rx.localPanID = (uint16_t)value;
881 if(!ieee_radio.rf_is_on) {
882 return RADIO_RESULT_OK;
886 res = netstack_sched_rx(
false);
887 return (res == RF_RESULT_OK)
889 : RADIO_RESULT_ERROR;
892 case RADIO_PARAM_16BIT_ADDR:
893 v_cmd_rx.localShortAddr = (uint16_t)value;
894 if(!ieee_radio.rf_is_on) {
895 return RADIO_RESULT_OK;
899 res = netstack_sched_rx(
false);
900 return (res == RF_RESULT_OK)
902 : RADIO_RESULT_ERROR;
905 case RADIO_PARAM_RX_MODE: {
907 RADIO_RX_MODE_AUTOACK |
908 RADIO_RX_MODE_POLL_MODE)) {
909 return RADIO_RESULT_INVALID_VALUE;
913 v_cmd_rx.frameFiltOpt.frameFiltStop = 1;
914 v_cmd_rx.frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
915 v_cmd_rx.frameFiltOpt.slottedAckEn = 0;
916 v_cmd_rx.frameFiltOpt.autoPendEn = 0;
917 v_cmd_rx.frameFiltOpt.defaultPend = 0;
918 v_cmd_rx.frameFiltOpt.bPendDataReqOnly = 0;
919 v_cmd_rx.frameFiltOpt.bPanCoord = 0;
920 v_cmd_rx.frameFiltOpt.bStrictLenFilter = 0;
922 const bool old_poll_mode = ieee_radio.poll_mode;
923 ieee_radio.poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
924 if(old_poll_mode == ieee_radio.poll_mode) {
926 memcpy(&cmd_mod_filt.newFrameFiltOpt, &(cmd_rx.frameFiltOpt),
sizeof(cmd_rx.frameFiltOpt));
927 const RF_Stat stat = RF_runImmediateCmd(ieee_radio.rf_handle, (uint32_t *)&cmd_mod_filt);
928 if(stat != RF_StatCmdDoneSuccess) {
929 LOG_ERR(
"Setting address filter failed, stat=0x%02X\n", stat);
930 return RADIO_RESULT_ERROR;
932 return RADIO_RESULT_OK;
934 if(!ieee_radio.rf_is_on) {
935 return RADIO_RESULT_OK;
939 res = netstack_sched_rx(
false);
940 return (res == RF_RESULT_OK)
942 : RADIO_RESULT_ERROR;
946 case RADIO_PARAM_TX_MODE:
948 return RADIO_RESULT_INVALID_VALUE;
951 return RADIO_RESULT_OK;
954 case RADIO_PARAM_TXPOWER:
955 if(!tx_power_in_range((int8_t)value, rf_tx_power_table, rf_tx_power_table_size)) {
956 return RADIO_RESULT_INVALID_VALUE;
958 res = rf_set_tx_power(ieee_radio.rf_handle, rf_tx_power_table, (int8_t)value);
959 return (res == RF_RESULT_OK)
961 : RADIO_RESULT_ERROR;
964 case RADIO_PARAM_CCA_THRESHOLD:
965 v_cmd_rx.ccaRssiThr = (int8_t)value;
966 if(!ieee_radio.rf_is_on) {
967 return RADIO_RESULT_OK;
971 res = netstack_sched_rx(
false);
972 return (res == RF_RESULT_OK)
974 : RADIO_RESULT_ERROR;
977 return RADIO_RESULT_NOT_SUPPORTED;
981 static radio_result_t
982 get_object(radio_param_t param,
void *dest,
size_t size)
985 return RADIO_RESULT_INVALID_VALUE;
990 case RADIO_PARAM_64BIT_ADDR: {
991 const size_t srcSize =
sizeof(v_cmd_rx.localExtAddr);
992 if(size != srcSize) {
993 return RADIO_RESULT_INVALID_VALUE;
996 const uint8_t *pSrc = (uint8_t *)&(v_cmd_rx.localExtAddr);
997 uint8_t *pDest = dest;
998 for(
size_t i = 0; i < srcSize; ++i) {
999 pDest[i] = pSrc[srcSize - 1 - i];
1002 return RADIO_RESULT_OK;
1005 case RADIO_PARAM_LAST_PACKET_TIMESTAMP:
1006 if(size !=
sizeof(rtimer_clock_t)) {
1007 return RADIO_RESULT_INVALID_VALUE;
1010 *(rtimer_clock_t *)dest = ieee_radio.last.timestamp;
1012 return RADIO_RESULT_OK;
1015 return RADIO_RESULT_NOT_SUPPORTED;
1019 static radio_result_t
1020 set_object(radio_param_t param,
const void *src,
size_t size)
1025 return RADIO_RESULT_INVALID_VALUE;
1030 case RADIO_PARAM_64BIT_ADDR: {
1031 const size_t destSize =
sizeof(v_cmd_rx.localExtAddr);
1032 if(size != destSize) {
1033 return RADIO_RESULT_INVALID_VALUE;
1036 const uint8_t *pSrc = (
const uint8_t *)src;
1037 volatile uint8_t *pDest = (uint8_t *)&(v_cmd_rx.localExtAddr);
1038 for(
size_t i = 0; i < destSize; ++i) {
1039 pDest[i] = pSrc[destSize - 1 - i];
1042 if(!rx_is_active()) {
1043 return RADIO_RESULT_OK;
1047 res = netstack_sched_rx(
false);
1048 return (res == RF_RESULT_OK)
1050 : RADIO_RESULT_ERROR;
1053 return RADIO_RESULT_NOT_SUPPORTED;
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Header file with descriptors for the various modes of operation defined in IEEE 802.15.4g.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Header file of TX power functionality of CC13xx/CC26xx.
static uint8_t rf_is_on(void)
Checks whether the RFC domain is accessible and the RFC is in IEEE RX.
#define FRAME_SHAVE
RSSI (1) + Status (1)
Header file for the energy estimation mechanism
Header file for the link-layer address representation
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.
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.
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
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 RTIMER_NOW()
Get the current clock time.
#define CLOCK_SECOND
A second, measured in system clock time.
Header file of the CC13xx/CC26xx RF scheduler.
Header file for the callback timer
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
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.
#define RF_CONF_INACTIVITY_TIMEOUT
2 ms
Header file for the real-time timer module.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
Header file of the CC13xx/CC26xx RF data queue.
#define RADIO_TX_MODE_SEND_ON_CCA
The radio transmission mode controls whether transmissions should be done using clear channel assessm...
Header file of RF settings for CC13xx/CC26xx.
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
Header file of common CC13xx/CC26xx RF functionality.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
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.
Header file for the logging system
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.
void process_start(struct process *p, process_data_t data)
Start a process.