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 81 #define NRF_CCA_BUSY 0 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 96 #define ED_RSSISCALE 4 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) 119 static int8_t last_rssi;
120 static uint8_t last_lqi;
122 PROCESS(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 160 typedef struct timestamps_s {
162 rtimer_clock_t framestart;
164 rtimer_clock_t mpdu_duration;
168 static timestamps_t timestamps;
170 typedef struct tx_buf_s {
172 uint8_t mpdu[MAX_PAYLOAD_LEN];
175 static tx_buf_t tx_buf;
177 typedef struct rx_buf_s {
179 uint8_t mpdu[MPDU_LEN];
183 static rx_buf_t rx_buf;
185 typedef 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;
196 static 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,
207 static bool radio_power =
false;
211 phr_is_valid(uint8_t phr)
213 if(phr < ACK_MPDU_MIN_LEN || phr > MPDU_LEN) {
220 radio_is_powered(
void)
222 if(nrf53_errata_16()) {
225 return NRF_RADIO->POWER == 0 ? false :
true;
230 radio_set_power(
bool power)
232 if(nrf53_errata_16()) {
235 nrf_radio_power_set(NRF_RADIO, power);
240 radio_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);
270 cca_reconfigure(
void)
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);
311 setup_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);
345 setup_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);
360 set_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);
414 power_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%08lx (rx_buf @ 0x%08lx)\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);
493 lqi_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%08lx\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);
586 prepare(
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);
605 transmit(
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);
691 send(
const void *payload,
unsigned short payload_len)
693 prepare(payload, payload_len);
694 return transmit(payload_len);
698 read_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,
744 receiving_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()) {
970 get_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) {
996 set_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=%lu (Derived)\n", timestamps.sfd);
1038 LOG_DBG(
" PHY=%lu (PPI)\n", timestamps.framestart);
1039 LOG_DBG(
" MPDU=%lu (Duration)\n", timestamps.mpdu_duration);
1040 LOG_DBG(
" END=%lu (PPI)\n", timestamps.end);
1041 LOG_DBG(
" Expected=%lu + %u + %lu = %lu\n", timestamps.sfd,
1042 BYTE_DURATION_RTIMER, timestamps.mpdu_duration,
1043 timestamps.sfd + BYTE_DURATION_RTIMER + timestamps.mpdu_duration);
1052 RADIO_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);
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
The delay in usec between turning on the radio and it being actually listening (able to hear a preamb...
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
#define PROCESS(name, strname)
Declare a process.
The parameter is not supported.
void packetbuf_clear(void)
Clear and reset the packetbuf.
Header file for the energy estimation mechanism
TX failed due to a collision.
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Header file for the radio API
#define PROCESS_BEGIN()
Define the beginning of a process.
The delay in usec between a call to the radio API's transmit function and the end of SFD transmission...
The maximum transmission power in dBm.
static void critical_exit(int_master_status_t status)
Exit a critical section and restore the master interrupt.
#define PROCESS_END()
Define the end of a process.
Received signal strength indicator in dBm.
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
The short address (16 bits) for the radio, which is used by the h/w filter.
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver's buffers.
The structure of a Contiki-NG radio device driver.
static void set_channel(uint8_t channel)
Set the current operating channel.
Channel used for radio communication.
For enabling and disabling the SHR search.
The value argument was incorrect.
The parameter was set/read successfully.
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...
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
static int_master_status_t critical_enter()
Enter a critical section.
The RSSI value of the last received packet.
The physical layer header (PHR) + MAC layer footer (MFR) overhead in bytes.
Clear channel assessment threshold in dBm.
INT_MASTER_STATUS_DATATYPE int_master_status_t
Master interrupt state representation data type.
void(* input)(void)
Callback for getting notified of incoming packet.
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.
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
The lowest radio channel number.
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
The highest radio channel number.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
The air time of one byte in usec, e.g.
Main API declarations for TSCH.
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
#define RADIO_TX_MODE_SEND_ON_CCA
Radio TX mode control / retrieval.
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
int(* init)(void)
Initialise the radio hardware.
The delay in usec between the end of SFD reception for an incoming frame and the radio API starting t...
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
Link quality indicator of the last received packet.
The minimum transmission power in dBm.
Radio powered on and able to receive frames.
Transmission power in dBm.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
void watchdog_periodic(void)
Writes the WDT clear sequence.
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Last packet timestamp, of type rtimer_clock_t.
An error occurred during transmission.
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.
Radio powered off and in the lowest possible power consumption state.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
TX was successful and where an ACK was requested one was received.
const tsch_timeslot_timing_usec tsch_timeslot_timing_us_10000
TSCH timing attributes and description.
int(* on)(void)
Turn the radio on.
#define RTIMER_BUSYWAIT(duration)
Busy-wait for a fixed duration.
void process_start(struct process *p, process_data_t data)
Start a process.
static uint8_t get_channel()
Get the current operating channel.