53#include "sys/int-master.h"
54#include "sys/critical.h"
58#include "helpers/nrfx_gppi.h"
69#include "hal/nrf_radio.h"
70#include "hal/nrf_timer.h"
71#include "hal/nrf_clock.h"
72#include "hal/nrf_temp.h"
73#include "nrf_erratas.h"
78#define LOG_MODULE "nRF IEEE"
79#define LOG_LEVEL LOG_LEVEL_NONE
82#define NRF_CCA_CLEAR 1
84#define NRF_RECEIVING_NO 0
85#define NRF_RECEIVING_YES 1
87#define NRF_PENDING_NO 0
88#define NRF_PENDING_YES 1
90#define NRF_COMMAND_ERR 0
91#define NRF_COMMAND_OK 1
93#define NRF_CHANNEL_MIN 11
94#define NRF_CHANNEL_MAX 26
105#define MAX_PAYLOAD_LEN (MPDU_LEN - FCS_LEN)
107#define ACK_MPDU_MIN_LEN 5
108#define ACK_PAYLOAD_MIN_LEN (ACK_MPDU_MIN_LEN - FCS_LEN)
119static int8_t last_rssi;
120static uint8_t last_lqi;
122PROCESS(nrf_ieee_rf_process,
"nRF IEEE RF driver");
125#define NRF_CCA_MODE RADIO_CCACTRL_CCAMODE_CarrierAndEdMode
128#ifndef NRF_CCA_ED_THRESHOLD
129#define NRF_CCA_ED_THRESHOLD 0x14
132#ifndef NRF_CCA_CORR_THRESHOLD
133#define NRF_CCA_CORR_THRESHOLD 0x14
136#ifndef NRF_CCA_CORR_COUNT
137#define NRF_CCA_CORR_COUNT 0x02
148#define CRC_IEEE802154_LEN 2
149#define CRC_IEEE802154_POLY 0x11021
150#define CRC_IEEE802154_INIT 0
152#define SYMBOL_DURATION_USEC 16
153#define SYMBOL_DURATION_RTIMER 1
154#define BYTE_DURATION_RTIMER (SYMBOL_DURATION_RTIMER * 2)
155#define TXRU_DURATION_TIMER 3
157#define NRF_PPI_FRAMESTART_CHANNEL 1
158#define NRF_PPI_END_CHANNEL 2
160typedef struct timestamps_s {
162 rtimer_clock_t framestart;
164 rtimer_clock_t mpdu_duration;
168static timestamps_t timestamps;
170typedef struct tx_buf_s {
172 uint8_t mpdu[MAX_PAYLOAD_LEN];
175static tx_buf_t tx_buf;
177typedef struct rx_buf_s {
179 uint8_t mpdu[MPDU_LEN];
183static rx_buf_t rx_buf;
185typedef struct rf_cfg_s {
187 nrf_radio_txpower_t txpower;
191 uint8_t cca_corr_threshold;
192 uint8_t cca_corr_count;
193 uint8_t ed_threshold;
196static rf_cfg_t rf_config = {
198 .txpower = NRF_RADIO_TXPOWER_0DBM,
201 .cca_mode = NRF_CCA_MODE,
202 .cca_corr_threshold = NRF_CCA_CORR_THRESHOLD,
203 .cca_corr_count = NRF_CCA_CORR_COUNT,
204 .ed_threshold = NRF_CCA_ED_THRESHOLD,
207static bool radio_power =
false;
211phr_is_valid(uint8_t phr)
213 if(phr < ACK_MPDU_MIN_LEN || phr > MPDU_LEN) {
220radio_is_powered(
void)
222 if(nrf53_errata_16()) {
225 return NRF_RADIO->POWER == 0 ? false :
true;
230radio_set_power(
bool power)
232 if(nrf53_errata_16()) {
235 nrf_radio_power_set(NRF_RADIO, power);
240radio_rssi_sample_get(
void)
245 rssi_sample = nrf_radio_rssi_sample_get(NRF_RADIO);
247 if(nrf53_errata_87()) {
248 temp = nrf_temp_result_get(NRF_TEMP);
249 return (uint8_t)round(
250 (
float)((
float)(1.56f * rssi_sample) + (
float)(4.9e-5 * pow(rssi_sample, 3)) -
251 (
float)(9.9e-3 * pow(rssi_sample, 2)) - (0.05f * ((
float)(temp) * 0.25f)) - 7.2f));
260 return NRF_RADIO->FREQUENCY / 5 + 10;
266 NRF_RADIO->FREQUENCY = 5 * (channel - 10);
272 nrf_radio_cca_configure(NRF_RADIO, rf_config.cca_mode, rf_config.ed_threshold,
273 rf_config.cca_corr_threshold, rf_config.cca_corr_count);
285 nrf_radio_crc_configure(NRF_RADIO, CRC_IEEE802154_LEN, NRF_RADIO_CRC_ADDR_IEEE802154,
286 CRC_IEEE802154_POLY);
288 nrf_radio_crcinit_set(NRF_RADIO, CRC_IEEE802154_INIT);
295 nrf_radio_packet_conf_t conf;
297 memset(&conf, 0,
sizeof(conf));
301 conf.plen = NRF_RADIO_PREAMBLE_LENGTH_32BIT_ZERO;
303 conf.big_endian =
false;
304 conf.whiteen =
false;
305 conf.maxlen = MPDU_LEN;
307 nrf_radio_packet_configure(NRF_RADIO, &conf);
311setup_interrupts(
void)
314 nrf_radio_int_mask_t interrupts = 0;
318 if(!rf_config.poll_mode) {
319 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
320 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR);
321 interrupts |= NRF_RADIO_INT_CRCOK_MASK | NRF_RADIO_INT_CRCERROR_MASK;
325 nrf_radio_int_disable(NRF_RADIO, 0xFFFFFFFF);
326 NVIC_ClearPendingIRQ(RADIO_IRQn);
329 nrf_radio_int_enable(NRF_RADIO, interrupts);
330 NVIC_EnableIRQ(RADIO_IRQn);
333 NVIC_DisableIRQ(RADIO_IRQn);
345setup_ppi_timestamping(
void)
347 nrfx_gppi_channel_endpoints_setup(
348 NRF_PPI_FRAMESTART_CHANNEL,
349 nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_FRAMESTART),
350 nrf_timer_task_address_get(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3));
351 nrfx_gppi_channel_endpoints_setup(
353 nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END),
354 nrf_timer_task_address_get(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE2));
355 nrfx_gppi_channels_enable(1uL << NRF_PPI_FRAMESTART_CHANNEL
356 | 1uL << NRF_PPI_END_CHANNEL);
360set_poll_mode(
bool enable)
362 rf_config.poll_mode = enable;
369 memset(&rx_buf, 0,
sizeof(rx_buf));
375 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_FRAMESTART);
376 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
377 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
378 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR);
379 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
390 nrf_radio_mode_set(NRF_RADIO, NRF_RADIO_MODE_IEEE802154_250KBIT);
392 if(nrf53_errata_117()) {
393 *((
volatile uint32_t *)0x41008588) = *((
volatile uint32_t *)0x01FF0084);
410 nrf_radio_modecnf0_set(NRF_RADIO,
true, RADIO_MODECNF0_DTX_Center);
414power_on_and_configure(
void)
416 radio_set_power(
true);
434 nrf_radio_state_t curr_state = nrf_radio_state_get(NRF_RADIO);
436 LOG_DBG(
"Enter RX, state=%u", curr_state);
439 if(curr_state == NRF_RADIO_STATE_RX) {
440 LOG_DBG_(
". Was in RX");
446 nrf_radio_packetptr_set(NRF_RADIO, &rx_buf);
449 setup_ppi_timestamping();
454 nrf_radio_shorts_enable(NRF_RADIO, NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK);
455 nrf_radio_shorts_enable(NRF_RADIO, NRF_RADIO_SHORT_RXREADY_START_MASK);
457 if(curr_state != NRF_RADIO_STATE_RXIDLE) {
459 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RXREADY);
460 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN);
463 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_START);
466 LOG_DBG_(
"--->%u\n", nrf_radio_state_get(NRF_RADIO));
468 LOG_DBG(
"PACKETPTR=0x%08" PRIx32
" (rx_buf @ 0x%08" PRIx32
")\n",
469 (uint32_t)nrf_radio_packetptr_get(NRF_RADIO), (uint32_t)&rx_buf);
478 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RSSISTART);
480 while(nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND) ==
false);
481 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND);
483 rssi_sample = radio_rssi_sample_get();
485 return -((int8_t)rssi_sample);
493lqi_convert_to_802154_scale(uint8_t lqi_hw)
495 return (uint8_t)lqi_hw > 63 ? 255 : lqi_hw *ED_RSSISCALE;
505 if(radio_is_powered() ==
false) {
506 LOG_DBG(
"Not powered\n");
507 power_on_and_configure();
512 ENERGEST_ON(ENERGEST_TYPE_LISTEN);
513 return NRF_COMMAND_OK;
521 LOG_DBG(
"channel_clear\n");
526 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY);
527 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE);
528 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCASTOPPED);
530 LOG_DBG(
"channel_clear: CCACTRL=0x%08" PRIx32
"\n", NRF_RADIO->CCACTRL);
533 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_CCASTART);
535 while((nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY) ==
false) &&
536 (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE) ==
false));
538 busy = nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY);
539 idle = nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE);
541 LOG_DBG(
"channel_clear: I=%u, B=%u\n", idle, busy);
547 return NRF_CCA_CLEAR;
559 timestamps.framestart = 0;
561 timestamps.mpdu_duration = 0;
565 nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
566 nrf_clock_task_trigger(NRF_CLOCK, NRF_CLOCK_TASK_HFCLKSTART);
567 while(!nrf_clock_event_check(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED));
568 nrf_clock_event_clear(NRF_CLOCK, NRF_CLOCK_EVENT_HFCLKSTARTED);
577 power_on_and_configure();
580 set_poll_mode(rf_config.poll_mode);
586prepare(
const void *payload,
unsigned short payload_len)
588 LOG_DBG(
"Prepare %u bytes\n", payload_len);
590 if(payload_len > MAX_PAYLOAD_LEN) {
591 LOG_ERR(
"Too long: %u bytes, max %u\n", payload_len, MAX_PAYLOAD_LEN);
596 tx_buf.phr = (uint8_t)payload_len + FCS_LEN;
599 memcpy(tx_buf.mpdu, payload, payload_len);
605transmit(
unsigned short transmit_len)
609 LOG_DBG(
"TX %u bytes + FCS, channel=%u\n", transmit_len,
get_channel());
611 if(transmit_len > MAX_PAYLOAD_LEN) {
612 LOG_ERR(
"TX: too long (%u bytes)\n", transmit_len);
618 if(rf_config.send_on_cca) {
619 if(channel_clear() == NRF_CCA_BUSY) {
620 LOG_DBG(
"TX: Busy\n");
625 nrf_radio_txpower_set(NRF_RADIO, rf_config.txpower);
628 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_STOP);
629 while(nrf_radio_state_get(NRF_RADIO) != NRF_RADIO_STATE_RXIDLE);
631 LOG_DBG(
"Transmit: %u bytes=000000", tx_buf.phr);
632 for(i = 0; i < tx_buf.phr - 2; i++) {
633 LOG_DBG_(
" %02x", tx_buf.mpdu[i]);
637 LOG_DBG(
"TX Start. State %u", nrf_radio_state_get(NRF_RADIO));
640 nrf_radio_packetptr_set(NRF_RADIO, &tx_buf);
643 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
644 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
645 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_TXREADY);
648 ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
651 nrf_radio_shorts_enable(NRF_RADIO, NRF_RADIO_SHORT_TXREADY_START_MASK);
652 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
665 if(nrf53_errata_91()) {
669 LOG_DBG_(
"--->%u\n", nrf_radio_state_get(NRF_RADIO));
672 while(nrf_radio_state_get(NRF_RADIO) == NRF_RADIO_STATE_TX);
674 LOG_DBG(
"TX: Done\n");
685 ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
691send(
const void *payload,
unsigned short payload_len)
693 prepare(payload, payload_len);
694 return transmit(payload_len);
698read_frame(
void *buf,
unsigned short bufsize)
705 payload_len = rx_buf.phr - FCS_LEN;
707 if(phr_is_valid(rx_buf.phr) ==
false) {
708 LOG_DBG(
"Incorrect length: %d\n", payload_len);
714 memcpy(buf, rx_buf.mpdu, payload_len);
715 last_lqi = lqi_convert_to_802154_scale(rx_buf.mpdu[payload_len]);
716 last_rssi = -(radio_rssi_sample_get());
718 packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi);
719 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi);
722 timestamps.phr = rx_buf.phr;
723 timestamps.framestart = nrf_timer_cc_get(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3);
724 timestamps.end = nrf_timer_cc_get(NRF_TIMER0, NRF_TIMER_CC_CHANNEL2);
725 timestamps.mpdu_duration = rx_buf.phr * BYTE_DURATION_RTIMER;
732 timestamps.sfd = timestamps.framestart - BYTE_DURATION_RTIMER;
734 LOG_DBG(
"Read frame: len=%d, RSSI=%d, LQI=0x%02x\n", payload_len, last_rssi,
744receiving_packet(
void)
747 if(radio_is_powered() ==
false) {
748 return NRF_RECEIVING_NO;
752 if(nrf_radio_state_get(NRF_RADIO) != NRF_RADIO_STATE_RX) {
753 return NRF_RECEIVING_NO;
756 if(rf_config.poll_mode) {
758 if(phr_is_valid(rx_buf.phr) ==
false) {
759 return NRF_RECEIVING_NO;
766 if((nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK) ==
false) &&
767 (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR) ==
false)) {
768 return NRF_RECEIVING_YES;
771 return NRF_RECEIVING_NO;
778 if(phr_is_valid(rx_buf.phr) ==
true && rx_buf.full ==
false) {
779 return NRF_RECEIVING_YES;
781 return NRF_RECEIVING_NO;
791 if(phr_is_valid(rx_buf.phr) ==
false) {
792 return NRF_PENDING_NO;
802 if((nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK) ==
true) ||
803 (rx_buf.full ==
true)) {
804 return NRF_PENDING_YES;
807 return NRF_PENDING_NO;
813 radio_set_power(
false);
815 ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
817 return NRF_COMMAND_OK;
835 if(rf_config.poll_mode) {
841 if(rf_config.send_on_cca) {
870#if defined(RADIO_TXPOWER_TXPOWER_Pos8dBm)
891 case RADIO_CONST_MAX_PAYLOAD_LEN:
916 if(value < NRF_CHANNEL_MIN ||
917 value > NRF_CHANNEL_MAX) {
920 rf_config.channel = value;
923 if(radio_is_powered()) {
947 rf_config.txpower = value;
949 if(radio_is_powered()) {
950 nrf_radio_txpower_set(NRF_RADIO, value);
954 rf_config.cca_corr_threshold = value;
956 if(radio_is_powered()) {
970get_object(radio_param_t param,
void *dest,
size_t size)
973 if(size !=
sizeof(rtimer_clock_t) || !dest) {
976 *(rtimer_clock_t *)dest = timestamps.sfd;
980#if MAC_CONF_WITH_TSCH
981 if(param == RADIO_CONST_TSCH_TIMING) {
982 if(size !=
sizeof(uint16_t *) || !dest) {
996set_object(radio_param_t param,
const void *src,
size_t size)
1027 LOG_DBG(
"Polled\n");
1035 NETSTACK_MAC.
input();
1036 LOG_DBG(
"last frame (%u bytes) timestamps:\n", timestamps.phr);
1037 LOG_DBG(
" SFD=%" PRIu32
" (Derived)\n", timestamps.sfd);
1038 LOG_DBG(
" PHY=%" PRIu32
" (PPI)\n", timestamps.framestart);
1039 LOG_DBG(
" MPDU=%" PRIu32
" (Duration)\n", timestamps.mpdu_duration);
1040 LOG_DBG(
" END=%" PRIu32
" (PPI)\n", timestamps.end);
1041 LOG_DBG(
" Expected=%" PRIu32
" + %u + %" PRIu32
" = %" PRIu32
"\n",
1042 timestamps.sfd, BYTE_DURATION_RTIMER, timestamps.mpdu_duration,
1043 timestamps.sfd + BYTE_DURATION_RTIMER + timestamps.mpdu_duration);
1052RADIO_IRQHandler(
void)
1054 if(!rf_config.poll_mode) {
1055 if(nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK)) {
1056 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK);
1059 }
else if(nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR)) {
1060 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR);
Header file for the energy estimation mechanism.
static uint8_t get_channel()
Get the current operating channel.
static void set_channel(uint8_t channel)
Set the current operating channel.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
void watchdog_periodic(void)
Writes the WDT clear sequence.
static void critical_exit(int_master_status_t status)
Exit a critical section and restore the master interrupt.
static int_master_status_t critical_enter()
Enter a critical section.
INT_MASTER_STATUS_DATATYPE int_master_status_t
Master interrupt state representation data type.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void packetbuf_clear(void)
Clear and reset the packetbuf.
#define PROCESS(name, strname)
Declare a process.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
void process_start(struct process *p, process_data_t data)
Start a process.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
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_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_SHR_SEARCH
For enabling and disabling the SHR search.
@ 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_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.
#define RTIMER_BUSYWAIT(duration)
Busy-wait for a fixed duration.
const tsch_timeslot_timing_usec tsch_timeslot_timing_us_10000
TSCH timing attributes and description.
Header file for the logging system.
#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 Packet buffer (packetbuf) management.
Header file for the radio API.
void(* input)(void)
Callback for getting notified of incoming packet.
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.
Main API declarations for TSCH.