Contiki-NG
nrf52840-ieee.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, Toshiba BRIL
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*---------------------------------------------------------------------------*/
31 /**
32  * \addtogroup nrf52840
33  * @{
34  *
35  * \addtogroup nrf52840-dev Device drivers
36  * @{
37  *
38  * \defgroup nrf52840-rf-ieee nRF52840 IEEE mode driver
39  *
40  * @{
41  *
42  * \file
43  * Implementation of the nRF52840 IEEE mode NETSTACK_RADIO driver
44  */
45 /*---------------------------------------------------------------------------*/
46 #include "contiki.h"
47 #include "dev/radio.h"
48 #include "sys/energest.h"
49 #include "sys/int-master.h"
50 #include "sys/critical.h"
51 #include "net/netstack.h"
52 #include "net/packetbuf.h"
53 #include "net/mac/tsch/tsch.h"
54 #include "nrf_radio.h"
55 #include "nrf_ppi.h"
56 #include "nrf_timer.h"
57 #include "nrf_clock.h"
58 
59 #include <stdint.h>
60 #include <stdbool.h>
61 #include <string.h>
62 /*---------------------------------------------------------------------------*/
63 /*
64  * Log configuration
65  *
66  * NB: LOG_LEVEL_DBG should only be used to validate radio driver operation.
67  *
68  * Setting LOG_LEVEL to LOG_LEVEL_DBG will mess-up all MAC-layer ACK-related
69  * timings, including the time we spend waiting for an ACK and the time it
70  * takes us to transmit one. Expect all unicast communications to become
71  * erratic or to break altogether.
72  */
73 #include "sys/log.h"
74 
75 #define LOG_MODULE "nRF52840 IEEE"
76 #define LOG_LEVEL LOG_LEVEL_ERR
77 /*---------------------------------------------------------------------------*/
78 #define NRF52840_CCA_BUSY 0
79 #define NRF52840_CCA_CLEAR 1
80 /*---------------------------------------------------------------------------*/
81 #define NRF52840_RECEIVING_NO 0
82 #define NRF52840_RECEIVING_YES 1
83 /*---------------------------------------------------------------------------*/
84 #define NRF52840_PENDING_NO 0
85 #define NRF52840_PENDING_YES 1
86 /*---------------------------------------------------------------------------*/
87 #define NRF52840_COMMAND_ERR 0
88 #define NRF52840_COMMAND_OK 1
89 /*---------------------------------------------------------------------------*/
90 #define NRF52840_CHANNEL_MIN 11
91 #define NRF52840_CHANNEL_MAX 26
92 /*---------------------------------------------------------------------------*/
93 #define ED_RSSISCALE 4
94 /*---------------------------------------------------------------------------*/
95 #define FCS_LEN 2
96 #define MPDU_LEN 127
97 /*
98  * The maximum number of bytes this driver can accept from the MAC layer for
99  * transmission or will deliver to the MAC layer after reception. Includes
100  * the MAC header and payload, but not the FCS.
101  */
102 #define MAX_PAYLOAD_LEN (MPDU_LEN - FCS_LEN)
103 
104 #define ACK_MPDU_MIN_LEN 5
105 #define ACK_PAYLOAD_MIN_LEN (ACK_MPDU_MIN_LEN - FCS_LEN)
106 /*---------------------------------------------------------------------------*/
107 /*
108  * The last frame's RSSI and LQI
109  *
110  * Unlike other radios that write RSSI and LQI in the FCS, the nrf52840
111  * only writes one value. This is a "hardware-reported" value, which needs
112  * converted to the .15.4 standard LQI scale using an 8-bit saturating
113  * multiplication by 4 (see the Product Spec). This value is based on the
114  * median of three RSSI samples taken during frame reception.
115  */
116 static int8_t last_rssi;
117 static uint8_t last_lqi;
118 /*---------------------------------------------------------------------------*/
119 PROCESS(nrf52840_ieee_rf_process, "nRF52840 IEEE RF driver");
120 /*---------------------------------------------------------------------------*/
121 #ifndef NRF52840_CCA_MODE
122 #define NRF52840_CCA_MODE RADIO_CCACTRL_CCAMODE_CarrierAndEdMode
123 #endif
124 
125 #ifndef NRF52840_CCA_ED_THRESHOLD
126 #define NRF52840_CCA_ED_THRESHOLD 0x14
127 #endif
128 
129 #ifndef NRF52840_CCA_CORR_THRESHOLD
130 #define NRF52840_CCA_CORR_THRESHOLD 0x14
131 #endif
132 
133 #ifndef NRF52840_CCA_CORR_COUNT
134 #define NRF52840_CCA_CORR_COUNT 0x02
135 #endif
136 /*---------------------------------------------------------------------------*/
137 /*
138  * .15.4-compliant CRC:
139  *
140  * Lenght 2, Initial value 0.
141  *
142  * Polynomial x^16 + x^12 + x^5 + 1
143  * CRCPOLY: 1 00010000 00100001
144  */
145 #define CRC_IEEE802154_LEN 2
146 #define CRC_IEEE802154_POLY 0x11021
147 #define CRC_IEEE802154_INIT 0
148 /*---------------------------------------------------------------------------*/
149 #define SYMBOL_DURATION_USEC 16
150 #define SYMBOL_DURATION_RTIMER 1
151 #define BYTE_DURATION_RTIMER (SYMBOL_DURATION_RTIMER * 2)
152 #define TXRU_DURATION_TIMER 3
153 /*---------------------------------------------------------------------------*/
154 typedef struct timestamps_s {
155  rtimer_clock_t sfd; /* Derived: 1 byte = 2 rtimer ticks before FRAMESTART */
156  rtimer_clock_t framestart; /* PPI Channel 0 */
157  rtimer_clock_t end; /* PPI pre-programmed Channel 27 */
158  rtimer_clock_t mpdu_duration; /* Calculated: PHR * 2 rtimer ticks */
159  uint8_t phr; /* PHR: The MPDU length in bytes */
160 } timestamps_t;
161 
162 static volatile timestamps_t timestamps;
163 /*---------------------------------------------------------------------------*/
164 typedef struct tx_buf_s {
165  uint8_t phr;
166  uint8_t mpdu[MAX_PAYLOAD_LEN];
167 } tx_buf_t;
168 
169 static tx_buf_t tx_buf;
170 /*---------------------------------------------------------------------------*/
171 typedef struct rx_buf_s {
172  uint8_t phr;
173  uint8_t mpdu[MPDU_LEN];
174  bool full; /* Used in interrupt / non-poll mode for additional state */
175 } rx_buf_t;
176 
177 static rx_buf_t rx_buf;
178 /*---------------------------------------------------------------------------*/
179 typedef struct rf_cfg_s {
180  bool poll_mode;
181  nrf_radio_txpower_t txpower;
182  uint8_t channel;
183  uint8_t send_on_cca; /* Perform CCA before TX */
184  uint8_t cca_mode;
185  uint8_t cca_corr_threshold;
186  uint8_t cca_corr_count;
187  uint8_t ed_threshold;
188 } rf_cfg_t;
189 
190 static volatile rf_cfg_t rf_config = {
191  .poll_mode = false,
192  .txpower = NRF_RADIO_TXPOWER_0DBM,
193  .send_on_cca = RADIO_TX_MODE_SEND_ON_CCA,
194  .channel = IEEE802154_DEFAULT_CHANNEL,
195  .cca_mode = NRF52840_CCA_MODE,
196  .cca_corr_threshold = NRF52840_CCA_CORR_THRESHOLD,
197  .cca_corr_count = NRF52840_CCA_CORR_COUNT,
198  .ed_threshold = NRF52840_CCA_ED_THRESHOLD,
199 };
200 /*---------------------------------------------------------------------------*/
201 static bool
202 phr_is_valid(uint8_t phr)
203 {
204  if(phr < ACK_MPDU_MIN_LEN || phr > MPDU_LEN) {
205  return false;
206  }
207  return true;
208 }
209 /*---------------------------------------------------------------------------*/
210 static bool
211 radio_is_powered(void)
212 {
213  return NRF_RADIO->POWER == 0 ? false : true;
214 }
215 /*---------------------------------------------------------------------------*/
216 static uint8_t
217 get_channel(void)
218 {
219  return NRF_RADIO->FREQUENCY / 5 + 10;
220 }
221 /*---------------------------------------------------------------------------*/
222 static void
223 set_channel(uint8_t channel)
224 {
225  NRF_RADIO->FREQUENCY = 5 * (channel - 10);
226 }
227 /*---------------------------------------------------------------------------*/
228 static void
229 cca_reconfigure(void)
230 {
231  uint32_t ccactrl;
232 
233  ccactrl = rf_config.cca_mode;
234  ccactrl |= rf_config.ed_threshold << RADIO_CCACTRL_CCAEDTHRES_Pos;
235  ccactrl |= rf_config.cca_corr_count << RADIO_CCACTRL_CCACORRCNT_Pos;
236  ccactrl |= rf_config.cca_corr_threshold << RADIO_CCACTRL_CCACORRTHRES_Pos;
237 
238  NRF_RADIO->CCACTRL = ccactrl;
239 }
240 /*---------------------------------------------------------------------------*/
241 static void
242 crc_init(void)
243 {
244  /*
245  * Initialise the CRC engine in .15.4 mode:
246  * - Length: 2 bytes
247  * - Polynomial:
248  * - Initial value: 0
249  */
250  nrf_radio_crc_configure(CRC_IEEE802154_LEN, NRF_RADIO_CRC_ADDR_IEEE802154,
251  CRC_IEEE802154_POLY);
252 
253  nrf_radio_crcinit_set(CRC_IEEE802154_INIT);
254 }
255 /*---------------------------------------------------------------------------*/
256 static void
257 packet_init(void)
258 {
259  /* Configure packet format for .15.4 */
260  nrf_radio_packet_conf_t conf;
261 
262  memset(&conf, 0, sizeof(conf));
263 
264  conf.lflen = 8; /* Length field, in bits */
265  conf.s1incl = false;
266  conf.plen = NRF_RADIO_PREAMBLE_LENGTH_32BIT_ZERO;
267  conf.crcinc = true;
268  conf.big_endian = false;
269  conf.whiteen = false;
270  conf.maxlen = MPDU_LEN;
271 
272  nrf_radio_packet_configure(&conf);
273 }
274 /*---------------------------------------------------------------------------*/
275 static void
276 setup_interrupts(void)
277 {
278  int_master_status_t stat;
279  nrf_radio_int_mask_t interrupts = 0;
280 
281  stat = critical_enter();
282 
283  if(!rf_config.poll_mode) {
284  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK);
285  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR);
286  interrupts |= NRF_RADIO_INT_CRCOK_MASK | NRF_RADIO_INT_CRCERROR_MASK;
287  }
288 
289  /* Make sure all interrupts are disabled before we enable selectively */
290  nrf_radio_int_disable(0xFFFFFFFF);
291  NVIC_ClearPendingIRQ(RADIO_IRQn);
292 
293  if(interrupts) {
294  nrf_radio_int_enable(interrupts);
295  NVIC_EnableIRQ(RADIO_IRQn);
296  } else {
297  /* No radio interrupts required. Make sure they are all off at the NVIC */
298  NVIC_DisableIRQ(RADIO_IRQn);
299  }
300 
301  critical_exit(stat);
302 }
303 /*---------------------------------------------------------------------------*/
304 /*
305  * Set up timestamping with PPI:
306  * - Enable the pre-programmed Channel 27: RADIO->END--->TIMER0->CAPTURE[2]
307  * - Programme Channel 0 for RADIO->FRAMESTART--->TIMER0->CAPTURE[3]
308  */
309 static void
310 setup_ppi_timestamping(void)
311 {
312  nrf_ppi_channel_endpoint_setup(
313  NRF_PPI_CHANNEL0,
314  (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_FRAMESTART),
315  (uint32_t)nrf_timer_task_address_get(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3));
316  nrf_ppi_channel_enable(NRF_PPI_CHANNEL0);
317  nrf_ppi_channel_enable(NRF_PPI_CHANNEL27);
318 }
319 /*---------------------------------------------------------------------------*/
320 static void
321 set_poll_mode(bool enable)
322 {
323  rf_config.poll_mode = enable;
324  setup_interrupts();
325 }
326 /*---------------------------------------------------------------------------*/
327 static void
328 rx_buf_clear(void)
329 {
330  memset(&rx_buf, 0, sizeof(rx_buf));
331 }
332 /*---------------------------------------------------------------------------*/
333 static void
334 rx_events_clear()
335 {
336  nrf_radio_event_clear(NRF_RADIO_EVENT_FRAMESTART);
337  nrf_radio_event_clear(NRF_RADIO_EVENT_END);
338  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR);
339  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK);
340 }
341 /*---------------------------------------------------------------------------*/
342 /*
343  * Powering off the peripheral will reset all registers to default values
344  * This function here must be called at every power on to set the radio in a
345  * known state
346  */
347 static void
348 configure(void)
349 {
350  nrf_radio_mode_set(NRF_RADIO_MODE_IEEE802154_250KBIT);
351 
352  set_channel(rf_config.channel);
353 
354  cca_reconfigure();
355 
356  /* Initialise the CRC engine in .15.4 mode */
357  crc_init();
358 
359  /* Initialise the packet format */
360  packet_init();
361 
362  /*
363  * MODECNF: Fast ramp up, DTX=center
364  * The Nordic driver is using DTX=0, but this is against the PS (v1.1 p351)
365  */
366  nrf_radio_modecnf0_set(true, RADIO_MODECNF0_DTX_Center);
367 }
368 /*---------------------------------------------------------------------------*/
369 static void
370 power_on_and_configure(void)
371 {
372  nrf_radio_power_set(true);
373  configure();
374 }
375 /*---------------------------------------------------------------------------*/
376 /*
377  * The caller must first make sure the radio is powered and configured.
378  *
379  * When we enter this function we can be in one of the following states:
380  * - STATE_RX: We were already in RX. Do nothing
381  * - STATE_RXIDLE: A reception just finished and we reverted to RXIDLE.
382  * We just need to send the START task.
383  * - STATE_TXIDLE: A TX just finished and we reverted to TXIDLE.
384  * We just need to send the START task.
385  * - STATE_DISABLED: We just turned on. We need to request radio rampup
386  */
387 static void
388 enter_rx(void)
389 {
390  nrf_radio_state_t curr_state = nrf_radio_state_get();
391 
392  LOG_DBG("Enter RX, state=%u", curr_state);
393 
394  /* Do nothing if we are already in RX */
395  if(curr_state == NRF_RADIO_STATE_RX) {
396  LOG_DBG_(". Was in RX");
397  LOG_DBG_("\n");
398  return;
399  }
400 
401  /* Prepare the RX buffer */
402  nrf_radio_packetptr_set(&rx_buf);
403 
404  /* Initiate PPI timestamping */
405  setup_ppi_timestamping();
406 
407  /* Make sure the correct interrupts are enabled */
408  setup_interrupts();
409 
410  nrf_radio_shorts_enable(NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK);
411  nrf_radio_shorts_enable(NRF_RADIO_SHORT_RXREADY_START_MASK);
412 
413  if(curr_state != NRF_RADIO_STATE_RXIDLE) {
414  /* Clear EVENTS_RXREADY and trigger RXEN (which will trigger START) */
415  nrf_radio_event_clear(NRF_RADIO_EVENT_RXREADY);
416  nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
417  } else {
418  /* Trigger the Start task */
419  nrf_radio_task_trigger(NRF_RADIO_TASK_START);
420  }
421 
422  LOG_DBG_("--->%u\n", nrf_radio_state_get());
423 
424  LOG_DBG("PACKETPTR=0x%08lx (rx_buf @ 0x%08lx)\n",
425  (uint32_t)nrf_radio_packetptr_get(), (uint32_t)&rx_buf);
426 }
427 /*---------------------------------------------------------------------------*/
428 /* Retrieve an RSSI sample. The radio must be in RX mode */
429 static int8_t
430 rssi_read(void)
431 {
432  uint8_t rssi_sample;
433 
434  nrf_radio_task_trigger(NRF_RADIO_TASK_RSSISTART);
435 
436  while(nrf_radio_event_check(NRF_RADIO_EVENT_RSSIEND) == false);
437  nrf_radio_event_clear(NRF_RADIO_EVENT_RSSIEND);
438 
439  rssi_sample = nrf_radio_rssi_sample_get();
440 
441  return -((int8_t)rssi_sample);
442 }
443 /*---------------------------------------------------------------------------*/
444 /*
445  * Convert the hardware-reported LQI to 802.15.4 range using an 8-bit
446  * saturating multiplication by 4, as per the Product Spec.
447  */
448 static uint8_t
449 lqi_convert_to_802154_scale(uint8_t lqi_hw)
450 {
451  return (uint8_t)lqi_hw > 63 ? 255 : lqi_hw * ED_RSSISCALE;
452 }
453 /*---------------------------------------------------------------------------*/
454 /* Netstack API functions */
455 /*---------------------------------------------------------------------------*/
456 static int
457 on(void)
458 {
459  LOG_DBG("On\n");
460 
461  if(radio_is_powered() == false) {
462  LOG_DBG("Not powered\n");
463  power_on_and_configure();
464  }
465 
466  enter_rx();
467 
468  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
469  return NRF52840_COMMAND_OK;
470 }
471 /*---------------------------------------------------------------------------*/
472 static int
473 channel_clear(void)
474 {
475  bool busy, idle;
476 
477  LOG_DBG("channel_clear\n");
478 
479  on();
480 
481  /* Clear previous CCA-related events, if any */
482  nrf_radio_event_clear(NRF_RADIO_EVENT_CCABUSY);
483  nrf_radio_event_clear(NRF_RADIO_EVENT_CCAIDLE);
484  nrf_radio_event_clear(NRF_RADIO_EVENT_CCASTOPPED);
485 
486  LOG_DBG("channel_clear: CCACTRL=0x%08lx\n", NRF_RADIO->CCACTRL);
487 
488  /* We are now in RX. Send CCASTART */
489  nrf_radio_task_trigger(NRF_RADIO_TASK_CCASTART);
490 
491  while((nrf_radio_event_check(NRF_RADIO_EVENT_CCABUSY) == false) &&
492  (nrf_radio_event_check(NRF_RADIO_EVENT_CCAIDLE) == false));
493 
494  busy = nrf_radio_event_check(NRF_RADIO_EVENT_CCABUSY);
495  idle = nrf_radio_event_check(NRF_RADIO_EVENT_CCAIDLE);
496 
497  LOG_DBG("channel_clear: I=%u, B=%u\n", idle, busy);
498 
499  if(busy) {
500  return NRF52840_CCA_BUSY;
501  }
502 
503  return NRF52840_CCA_CLEAR;
504 }
505 /*---------------------------------------------------------------------------*/
506 static int
507 init(void)
508 {
509  LOG_DBG("Init\n");
510 
511  last_rssi = 0;
512  last_lqi = 0;
513 
514  timestamps.sfd = 0;
515  timestamps.framestart = 0;
516  timestamps.end = 0;
517  timestamps.mpdu_duration = 0;
518  timestamps.phr = 0;
519 
520  /* Request the HF clock */
521  nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
522  nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART);
523  while(!nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED));
524  nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED);
525 
526  /* Start the RF driver process */
527  process_start(&nrf52840_ieee_rf_process, NULL);
528 
529  /* Prepare the RX buffer */
530  rx_buf_clear();
531 
532  /* Power on the radio */
533  power_on_and_configure();
534 
535  /* Set up initial state of poll mode. This will configure interrupts. */
536  set_poll_mode(rf_config.poll_mode);
537 
538  return RADIO_TX_OK;
539 }
540 /*---------------------------------------------------------------------------*/
541 static int
542 prepare(const void *payload, unsigned short payload_len)
543 {
544  LOG_DBG("Prepare %u bytes\n", payload_len);
545 
546  if(payload_len > MAX_PAYLOAD_LEN) {
547  LOG_ERR("Too long: %u bytes, max %u\n", payload_len, MAX_PAYLOAD_LEN);
548  return RADIO_TX_ERR;
549  }
550 
551  /* Populate the PHR. Packet length, including the FCS */
552  tx_buf.phr = (uint8_t)payload_len + FCS_LEN;
553 
554  /* Copy the payload over */
555  memcpy(tx_buf.mpdu, payload, payload_len);
556 
557  return RADIO_TX_OK;
558 }
559 /*---------------------------------------------------------------------------*/
560 static int
561 transmit(unsigned short transmit_len)
562 {
563  int i;
564 
565  LOG_DBG("TX %u bytes + FCS, channel=%u\n", transmit_len, get_channel());
566 
567  if(transmit_len > MAX_PAYLOAD_LEN) {
568  LOG_ERR("TX: too long (%u bytes)\n", transmit_len);
569  return RADIO_TX_ERR;
570  }
571 
572  on();
573 
574  if(rf_config.send_on_cca) {
575  if(channel_clear() == NRF52840_CCA_BUSY) {
576  LOG_DBG("TX: Busy\n");
577  return RADIO_TX_COLLISION;
578  }
579  }
580 
581  nrf_radio_txpower_set(rf_config.txpower);
582 
583  /* When we reach here we are in state RX. Send a STOP to drop to RXIDLE */
584  nrf_radio_task_trigger(NRF_RADIO_TASK_STOP);
585  while(nrf_radio_state_get() != NRF_RADIO_STATE_RXIDLE);
586 
587  LOG_DBG("Transmit: %u bytes=000000", tx_buf.phr);
588  for(i = 0; i < tx_buf.phr - 2; i++) {
589  LOG_DBG_(" %02x", tx_buf.mpdu[i]);
590  }
591  LOG_DBG_("\n");
592 
593  LOG_DBG("TX Start. State %u", nrf_radio_state_get());
594 
595  /* Pointer to the TX buffer in PACKETPTR before task START */
596  nrf_radio_packetptr_set(&tx_buf);
597 
598  /* Clear TX-related events */
599  nrf_radio_event_clear(NRF_RADIO_EVENT_END);
600  nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND);
601  nrf_radio_event_clear(NRF_RADIO_EVENT_TXREADY);
602 
603  /* Start the transmission */
604  ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
605 
606  /* Enable the SHORT between TXREADY and START before triggering TXRU */
607  nrf_radio_shorts_enable(NRF_RADIO_SHORT_TXREADY_START_MASK);
608  nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN);
609 
610  /*
611  * With fast rampup, the transition between TX and READY (TXRU duration)
612  * takes 40us. This means we will be in TX mode in less than 3 rtimer ticks
613  * (3x16=42 us). After this duration, we can busy wait for TX to finish.
614  */
615  RTIMER_BUSYWAIT(TXRU_DURATION_TIMER);
616 
617  LOG_DBG_("--->%u\n", nrf_radio_state_get());
618 
619  /* Wait for TX to complete */
620  while(nrf_radio_state_get() == NRF_RADIO_STATE_TX);
621 
622  LOG_DBG("TX: Done\n");
623 
624  /*
625  * Enter RX.
626  * TX has finished and we are in state TXIDLE. enter_rx will handle the
627  * transition from any state to RX, so we don't need to do anything further
628  * here.
629  */
630  enter_rx();
631 
632  /* We are now in RX */
633  ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
634 
635  return RADIO_TX_OK;
636 }
637 /*---------------------------------------------------------------------------*/
638 static int
639 send(const void *payload, unsigned short payload_len)
640 {
641  prepare(payload, payload_len);
642  return transmit(payload_len);
643 }
644 /*---------------------------------------------------------------------------*/
645 static int
646 read_frame(void *buf, unsigned short bufsize)
647 {
648  int payload_len;
649 
650  /* Clear all events */
651  rx_events_clear();
652 
653  payload_len = rx_buf.phr - FCS_LEN;
654 
655  if(phr_is_valid(rx_buf.phr) == false) {
656  LOG_DBG("Incorrect length: %d\n", payload_len);
657  rx_buf_clear();
658  enter_rx();
659  return 0;
660  }
661 
662  memcpy(buf, rx_buf.mpdu, payload_len);
663  last_lqi = lqi_convert_to_802154_scale(rx_buf.mpdu[payload_len]);
664  last_rssi = -(nrf_radio_rssi_sample_get());
665 
666  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi);
667  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi);
668 
669  /* Latch timestamp values for this most recently received frame */
670  timestamps.phr = rx_buf.phr;
671  timestamps.framestart = nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3);
672  timestamps.end = nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL2);
673  timestamps.mpdu_duration = rx_buf.phr * BYTE_DURATION_RTIMER;
674 
675  /*
676  * Timestamp in rtimer ticks of the reception of the SFD. The SFD was
677  * received 1 byte before the PHR, therefore all we need to do is subtract
678  * 2 symbols (2 rtimer ticks) from the PPI FRAMESTART timestamp.
679  */
680  timestamps.sfd = timestamps.framestart - BYTE_DURATION_RTIMER;
681 
682  LOG_DBG("Read frame: len=%d, RSSI=%d, LQI=0x%02x\n", payload_len, last_rssi,
683  last_lqi);
684 
685  rx_buf_clear();
686  enter_rx();
687 
688  return payload_len;
689 }
690 /*---------------------------------------------------------------------------*/
691 static int
692 receiving_packet(void)
693 {
694  /* If we are powered off, we are not receiving */
695  if(radio_is_powered() == false) {
696  return NRF52840_RECEIVING_NO;
697  }
698 
699  /* If our state is not RX, we are not receiving */
700  if(nrf_radio_state_get() != NRF_RADIO_STATE_RX) {
701  return NRF52840_RECEIVING_NO;
702  }
703 
704  if(rf_config.poll_mode) {
705  /* In poll mode, if the PHR is invalid we can return early */
706  if(phr_is_valid(rx_buf.phr) == false) {
707  return NRF52840_RECEIVING_NO;
708  }
709 
710  /*
711  * If the PHR is valid and we are actually on, inspect EVENTS_CRCOK and
712  * _CRCERROR. If both of them are clear then reception is ongoing
713  */
714  if((nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK) == false) &&
715  (nrf_radio_event_check(NRF_RADIO_EVENT_CRCERROR) == false)) {
716  return NRF52840_RECEIVING_YES;
717  }
718 
719  return NRF52840_RECEIVING_NO;
720  }
721 
722  /*
723  * In non-poll mode, we are receiving if the PHR is valid but the buffer
724  * does not contain a full packet.
725  */
726  if(phr_is_valid(rx_buf.phr) == true && rx_buf.full == false) {
727  return NRF52840_RECEIVING_YES;
728  }
729  return NRF52840_RECEIVING_NO;
730 }
731 /*---------------------------------------------------------------------------*/
732 static int
733 pending_packet(void)
734 {
735  /*
736  * First check if we have received a PHR. When we enter RX the value of the
737  * PHR in our RX buffer is zero so we can return early.
738  */
739  if(phr_is_valid(rx_buf.phr) == false) {
740  return NRF52840_PENDING_NO;
741  }
742 
743  /*
744  * We have received a valid PHR. Either we are in the process of receiving
745  * a frame, or we have fully received one. If we have received a frame then
746  * EVENTS_CRCOK should be asserted. In poll mode that's enough. In non-poll
747  * mode the interrupt handler will clear the event (else the interrupt would
748  * fire again), but we save the state in rx_buf.full.
749  */
750  if((nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK) == true) ||
751  (rx_buf.full == true)) {
752  return NRF52840_PENDING_YES;
753  }
754 
755  return NRF52840_PENDING_NO;
756 }
757 /*---------------------------------------------------------------------------*/
758 static int
759 off(void)
760 {
761  nrf_radio_power_set(false);
762 
763  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
764 
765  return NRF52840_COMMAND_OK;
766 }
767 /*---------------------------------------------------------------------------*/
768 static radio_result_t
769 get_value(radio_param_t param, radio_value_t *value)
770 {
771  if(!value) {
773  }
774 
775  switch(param) {
777  return RADIO_RESULT_OK;
778  case RADIO_PARAM_CHANNEL:
779  *value = (radio_value_t)get_channel();
780  return RADIO_RESULT_OK;
781  case RADIO_PARAM_RX_MODE:
782  *value = 0;
783  if(rf_config.poll_mode) {
784  *value |= RADIO_RX_MODE_POLL_MODE;
785  }
786  return RADIO_RESULT_OK;
787  case RADIO_PARAM_TX_MODE:
788  *value = 0;
789  if(rf_config.send_on_cca) {
790  *value |= RADIO_TX_MODE_SEND_ON_CCA;
791  }
792  return RADIO_RESULT_OK;
793  case RADIO_PARAM_TXPOWER:
794  *value = (radio_value_t)rf_config.txpower;
795  return RADIO_RESULT_OK;
797  *value = (radio_value_t)rf_config.cca_corr_threshold;
798  return RADIO_RESULT_OK;
799  case RADIO_PARAM_RSSI:
800  *value = (radio_value_t)rssi_read();
801  return RADIO_RESULT_OK;
803  *value = (radio_value_t)last_rssi;
804  return RADIO_RESULT_OK;
806  *value = (radio_value_t)last_lqi;
807  return RADIO_RESULT_OK;
809  *value = 11;
810  return RADIO_RESULT_OK;
812  *value = 26;
813  return RADIO_RESULT_OK;
815  *value = (radio_value_t)RADIO_TXPOWER_TXPOWER_Neg40dBm;
816  return RADIO_RESULT_OK;
818  *value = (radio_value_t)RADIO_TXPOWER_TXPOWER_Pos8dBm;
819  return RADIO_RESULT_OK;
821  *value = (radio_value_t)RADIO_PHY_OVERHEAD;
822  return RADIO_RESULT_OK;
824  *value = (radio_value_t)RADIO_BYTE_AIR_TIME;
825  return RADIO_RESULT_OK;
827  *value = (radio_value_t)RADIO_DELAY_BEFORE_TX;
828  return RADIO_RESULT_OK;
830  *value = (radio_value_t)RADIO_DELAY_BEFORE_RX;
831  return RADIO_RESULT_OK;
833  *value = (radio_value_t)RADIO_DELAY_BEFORE_DETECT;
834  return RADIO_RESULT_OK;
835  case RADIO_CONST_MAX_PAYLOAD_LEN:
836  *value = (radio_value_t)MAX_PAYLOAD_LEN;
837  return RADIO_RESULT_OK;
838  case RADIO_PARAM_PAN_ID:
840  default:
842  }
843 }
844 /*---------------------------------------------------------------------------*/
845 static radio_result_t
846 set_value(radio_param_t param, radio_value_t value)
847 {
848  switch(param) {
850  if(value == RADIO_POWER_MODE_ON) {
851  on();
852  return RADIO_RESULT_OK;
853  }
854  if(value == RADIO_POWER_MODE_OFF) {
855  off();
856  return RADIO_RESULT_OK;
857  }
859  case RADIO_PARAM_CHANNEL:
860  if(value < NRF52840_CHANNEL_MIN ||
861  value > NRF52840_CHANNEL_MAX) {
863  }
864  rf_config.channel = value;
865 
866  /* If we are powered on, apply immediately. */
867  if(radio_is_powered()) {
868  off();
869  set_channel(value);
870  on();
871  }
872  return RADIO_RESULT_OK;
873  case RADIO_PARAM_RX_MODE:
874  if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
878  }
879 
880  set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0);
881 
882  return RADIO_RESULT_OK;
883  case RADIO_PARAM_TX_MODE:
884  if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) {
886  }
887 
888  rf_config.send_on_cca = (value & RADIO_TX_MODE_SEND_ON_CCA) != 0;
889  return RADIO_RESULT_OK;
890  case RADIO_PARAM_TXPOWER:
891  rf_config.txpower = value;
892  /* If we are powered on, apply immediately. */
893  if(radio_is_powered()) {
894  nrf_radio_txpower_set(value);
895  }
896  return RADIO_RESULT_OK;
898  rf_config.cca_corr_threshold = value;
899  /* If we are powered on, apply immediately. */
900  if(radio_is_powered()) {
901  cca_reconfigure();
902  }
903  return RADIO_RESULT_OK;
904 
906  case RADIO_PARAM_PAN_ID:
908  default:
910  }
911 }
912 /*---------------------------------------------------------------------------*/
913 static radio_result_t
914 get_object(radio_param_t param, void *dest, size_t size)
915 {
916  if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
917  if(size != sizeof(rtimer_clock_t) || !dest) {
919  }
920  *(rtimer_clock_t *)dest = timestamps.sfd;
921  return RADIO_RESULT_OK;
922  }
923 
924 #if MAC_CONF_WITH_TSCH
925  if(param == RADIO_CONST_TSCH_TIMING) {
926  if(size != sizeof(uint16_t *) || !dest) {
928  }
929  /* Assigned value: a pointer to the TSCH timing in usec */
930  *(const uint16_t **)dest = tsch_timeslot_timing_us_10000;
931  return RADIO_RESULT_OK;
932  }
933 #endif /* MAC_CONF_WITH_TSCH */
934 
935  /* The radio does not support h/w frame filtering based on addresses */
937 }
938 /*---------------------------------------------------------------------------*/
939 static radio_result_t
940 set_object(radio_param_t param, const void *src, size_t size)
941 {
942  /* The radio does not support h/w frame filtering based on addresses */
944 }
945 /*---------------------------------------------------------------------------*/
946 const struct radio_driver nrf52840_ieee_driver = {
947  init,
948  prepare,
949  transmit,
950  send,
951  read_frame,
955  on,
956  off,
957  get_value,
958  set_value,
959  get_object,
960  set_object
961 };
962 /*---------------------------------------------------------------------------*/
963 PROCESS_THREAD(nrf52840_ieee_rf_process, ev, data)
964 {
965  int len;
966  PROCESS_BEGIN();
967 
968  while(1) {
969  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
970 
971  LOG_DBG("Polled\n");
972 
973  if(pending_packet()) {
975  packetbuf_clear();
976  len = read_frame(packetbuf_dataptr(), PACKETBUF_SIZE);
977  if(len > 0) {
979  NETSTACK_MAC.input();
980  LOG_DBG("last frame (%u bytes) timestamps:\n", timestamps.phr);
981  LOG_DBG(" SFD=%lu (Derived)\n", timestamps.sfd);
982  LOG_DBG(" PHY=%lu (PPI)\n", timestamps.framestart);
983  LOG_DBG(" MPDU=%lu (Duration)\n", timestamps.mpdu_duration);
984  LOG_DBG(" END=%lu (PPI)\n", timestamps.end);
985  LOG_DBG(" Expected=%lu + %u + %lu = %lu\n", timestamps.sfd,
986  BYTE_DURATION_RTIMER, timestamps.mpdu_duration,
987  timestamps.sfd + BYTE_DURATION_RTIMER + timestamps.mpdu_duration);
988  }
989  }
990  }
991 
992  PROCESS_END();
993 }
994 /*---------------------------------------------------------------------------*/
995 void
996 RADIO_IRQHandler(void)
997 {
998  if(!rf_config.poll_mode) {
999  if(nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK)) {
1000  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK);
1001  rx_buf.full = true;
1002  process_poll(&nrf52840_ieee_rf_process);
1003  } else if(nrf_radio_event_check(NRF_RADIO_EVENT_CRCERROR)) {
1004  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR);
1005  rx_buf_clear();
1006  enter_rx();
1007  }
1008  }
1009 }
1010 /*---------------------------------------------------------------------------*/
1011 /**
1012  * @}
1013  * @}
1014  * @}
1015  */
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:762
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:143
The delay in usec between turning on the radio and it being actually listening (able to hear a preamb...
Definition: radio.h:347
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:572
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
The parameter is not supported.
Definition: radio.h:473
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:75
Header file for the energy estimation mechanism
TX failed due to a collision.
Definition: radio.h:503
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition: process.h:178
Header file for the radio API
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
The delay in usec between a call to the radio API&#39;s transmit function and the end of SFD transmission...
Definition: radio.h:341
The maximum transmission power in dBm.
Definition: radio.h:318
static void critical_exit(int_master_status_t status)
Exit a critical section and restore the master interrupt.
Definition: critical.h:81
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
Received signal strength indicator in dBm.
Definition: radio.h:218
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
Definition: radio.h:676
The short address (16 bits) for the radio, which is used by the h/w filter.
Definition: radio.h:166
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
Definition: radio.h:748
int(* pending_packet)(void)
Check if a packet has been received and is available in the radio driver&#39;s buffers.
Definition: radio.h:689
The structure of a Contiki-NG radio device driver.
Definition: radio.h:526
static void set_channel(uint8_t channel)
Set the current operating channel.
Definition: cc2538-rf.c:175
Channel used for radio communication.
Definition: radio.h:134
For enabling and disabling the SHR search.
Definition: radio.h:296
The value argument was incorrect.
Definition: radio.h:474
The parameter was set/read successfully.
Definition: radio.h:472
int(* channel_clear)(void)
Perform a Clear-Channel Assessment (CCA) to find out if there is a packet in the air or not...
Definition: radio.h:664
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio...
Definition: radio.h:88
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
Definition: radio.h:180
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Definition: mac.h:52
static int_master_status_t critical_enter()
Enter a critical section.
Definition: critical.h:65
The RSSI value of the last received packet.
Definition: radio.h:226
The physical layer header (PHR) + MAC layer footer (MFR) overhead in bytes.
Definition: radio.h:330
Clear channel assessment threshold in dBm.
Definition: radio.h:205
INT_MASTER_STATUS_DATATYPE int_master_status_t
Master interrupt state representation data type.
Definition: int-master.h:62
void(* input)(void)
Callback for getting notified of incoming packet.
Definition: mac.h:72
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
Definition: radio.h:623
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
Definition: radio.h:611
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
int(* off)(void)
Turn the radio off.
Definition: radio.h:721
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
Definition: radio.h:150
The lowest radio channel number.
Definition: radio.h:303
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
Definition: radio.h:173
The highest radio channel number.
Definition: radio.h:308
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:67
The air time of one byte in usec, e.g.
Definition: radio.h:335
Main API declarations for TSCH.
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
Definition: radio.h:443
When getting the value of this parameter, the radio driver should indicate whether the radio is on or...
Definition: radio.h:119
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.
Definition: radio.h:466
#define RADIO_RX_MODE_AUTOACK
Enable automatic transmission of ACK frames.
Definition: radio.h:448
int(* init)(void)
Initialise the radio hardware.
Definition: radio.h:547
The delay in usec between the end of SFD reception for an incoming frame and the radio API starting t...
Definition: radio.h:353
#define RADIO_RX_MODE_POLL_MODE
Enable/disable/get the state of radio driver poll mode operation.
Definition: radio.h:453
Link quality indicator of the last received packet.
Definition: radio.h:236
The minimum transmission power in dBm.
Definition: radio.h:313
Radio powered on and able to receive frames.
Definition: radio.h:392
Transmission power in dBm.
Definition: radio.h:192
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.
Definition: watchdog.c:85
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:733
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1110
Last packet timestamp, of type rtimer_clock_t.
Definition: radio.h:278
An error occurred during transmission.
Definition: radio.h:498
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.
Definition: radio.h:779
Radio powered off and in the lowest possible power consumption state.
Definition: radio.h:387
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:136
TX was successful and where an ACK was requested one was received.
Definition: radio.h:490
const tsch_timeslot_timing_usec tsch_timeslot_timing_us_10000
TSCH timing attributes and description.
int(* on)(void)
Turn the radio on.
Definition: radio.h:703
#define RTIMER_BUSYWAIT(duration)
Busy-wait for a fixed duration.
Definition: rtimer.h:218
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
static uint8_t get_channel()
Get the current operating channel.
Definition: cc2538-rf.c:165