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 
524  /* Start the RF driver process */
525  process_start(&nrf52840_ieee_rf_process, NULL);
526 
527  /* Prepare the RX buffer */
528  rx_buf_clear();
529 
530  /* Power on the radio */
531  power_on_and_configure();
532 
533  /* Set up initial state of poll mode. This will configure interrupts. */
534  set_poll_mode(rf_config.poll_mode);
535 
536  return RADIO_TX_OK;
537 }
538 /*---------------------------------------------------------------------------*/
539 static int
540 prepare(const void *payload, unsigned short payload_len)
541 {
542  LOG_DBG("Prepare %u bytes\n", payload_len);
543 
544  if(payload_len > MAX_PAYLOAD_LEN) {
545  LOG_ERR("Too long: %u bytes, max %u\n", payload_len, MAX_PAYLOAD_LEN);
546  return RADIO_TX_ERR;
547  }
548 
549  /* Populate the PHR. Packet length, including the FCS */
550  tx_buf.phr = (uint8_t)payload_len + FCS_LEN;
551 
552  /* Copy the payload over */
553  memcpy(tx_buf.mpdu, payload, payload_len);
554 
555  return RADIO_TX_OK;
556 }
557 /*---------------------------------------------------------------------------*/
558 static int
559 transmit(unsigned short transmit_len)
560 {
561  int i;
562 
563  LOG_DBG("TX %u bytes + FCS, channel=%u\n", transmit_len, get_channel());
564 
565  if(transmit_len > MAX_PAYLOAD_LEN) {
566  LOG_ERR("TX: too long (%u bytes)\n", transmit_len);
567  return RADIO_TX_ERR;
568  }
569 
570  on();
571 
572  if(rf_config.send_on_cca) {
573  if(channel_clear() == NRF52840_CCA_BUSY) {
574  LOG_DBG("TX: Busy\n");
575  return RADIO_TX_COLLISION;
576  }
577  }
578 
579  nrf_radio_txpower_set(rf_config.txpower);
580 
581  /* When we reach here we are in state RX. Send a STOP to drop to RXIDLE */
582  nrf_radio_task_trigger(NRF_RADIO_TASK_STOP);
583  while(nrf_radio_state_get() != NRF_RADIO_STATE_RXIDLE);
584 
585  LOG_DBG("Transmit: %u bytes=000000", tx_buf.phr);
586  for(i = 0; i < tx_buf.phr - 2; i++) {
587  LOG_DBG_(" %02x", tx_buf.mpdu[i]);
588  }
589  LOG_DBG_("\n");
590 
591  LOG_DBG("TX Start. State %u", nrf_radio_state_get());
592 
593  /* Pointer to the TX buffer in PACKETPTR before task START */
594  nrf_radio_packetptr_set(&tx_buf);
595 
596  /* Clear TX-related events */
597  nrf_radio_event_clear(NRF_RADIO_EVENT_END);
598  nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND);
599  nrf_radio_event_clear(NRF_RADIO_EVENT_TXREADY);
600 
601  /* Start the transmission */
602  ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
603 
604  /* Enable the SHORT between TXREADY and START before triggering TXRU */
605  nrf_radio_shorts_enable(NRF_RADIO_SHORT_TXREADY_START_MASK);
606  nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN);
607 
608  /*
609  * With fast rampup, the transition between TX and READY (TXRU duration)
610  * takes 40us. This means we will be in TX mode in less than 3 rtimer ticks
611  * (3x16=42 us). After this duration, we can busy wait for TX to finish.
612  */
613  RTIMER_BUSYWAIT(TXRU_DURATION_TIMER);
614 
615  LOG_DBG_("--->%u\n", nrf_radio_state_get());
616 
617  /* Wait for TX to complete */
618  while(nrf_radio_state_get() == NRF_RADIO_STATE_TX);
619 
620  LOG_DBG("TX: Done\n");
621 
622  /*
623  * Enter RX.
624  * TX has finished and we are in state TXIDLE. enter_rx will handle the
625  * transition from any state to RX, so we don't need to do anything further
626  * here.
627  */
628  enter_rx();
629 
630  /* We are now in RX */
631  ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
632 
633  return RADIO_TX_OK;
634 }
635 /*---------------------------------------------------------------------------*/
636 static int
637 send(const void *payload, unsigned short payload_len)
638 {
639  prepare(payload, payload_len);
640  return transmit(payload_len);
641 }
642 /*---------------------------------------------------------------------------*/
643 static int
644 read_frame(void *buf, unsigned short bufsize)
645 {
646  int payload_len;
647 
648  /* Clear all events */
649  rx_events_clear();
650 
651  payload_len = rx_buf.phr - FCS_LEN;
652 
653  if(phr_is_valid(rx_buf.phr) == false) {
654  LOG_DBG("Incorrect length: %d\n", payload_len);
655  rx_buf_clear();
656  enter_rx();
657  return 0;
658  }
659 
660  memcpy(buf, rx_buf.mpdu, payload_len);
661  last_lqi = lqi_convert_to_802154_scale(rx_buf.mpdu[payload_len]);
662  last_rssi = -(nrf_radio_rssi_sample_get());
663 
664  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi);
665  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_lqi);
666 
667  /* Latch timestamp values for this most recently received frame */
668  timestamps.phr = rx_buf.phr;
669  timestamps.framestart = nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3);
670  timestamps.end = nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL2);
671  timestamps.mpdu_duration = rx_buf.phr * BYTE_DURATION_RTIMER;
672 
673  /*
674  * Timestamp in rtimer ticks of the reception of the SFD. The SFD was
675  * received 1 byte before the PHR, therefore all we need to do is subtract
676  * 2 symbols (2 rtimer ticks) from the PPI FRAMESTART timestamp.
677  */
678  timestamps.sfd = timestamps.framestart - BYTE_DURATION_RTIMER;
679 
680  LOG_DBG("Read frame: len=%d, RSSI=%d, LQI=0x%02x\n", payload_len, last_rssi,
681  last_lqi);
682 
683  rx_buf_clear();
684  enter_rx();
685 
686  return payload_len;
687 }
688 /*---------------------------------------------------------------------------*/
689 static int
690 receiving_packet(void)
691 {
692  /* If we are powered off, we are not receiving */
693  if(radio_is_powered() == false) {
694  return NRF52840_RECEIVING_NO;
695  }
696 
697  /* If our state is not RX, we are not receiving */
698  if(nrf_radio_state_get() != NRF_RADIO_STATE_RX) {
699  return NRF52840_RECEIVING_NO;
700  }
701 
702  if(rf_config.poll_mode) {
703  /* In poll mode, if the PHR is invalid we can return early */
704  if(phr_is_valid(rx_buf.phr) == false) {
705  return NRF52840_RECEIVING_NO;
706  }
707 
708  /*
709  * If the PHR is valid and we are actually on, inspect EVENTS_CRCOK and
710  * _CRCERROR. If both of them are clear then reception is ongoing
711  */
712  if((nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK) == false) &&
713  (nrf_radio_event_check(NRF_RADIO_EVENT_CRCERROR) == false)) {
714  return NRF52840_RECEIVING_YES;
715  }
716 
717  return NRF52840_RECEIVING_NO;
718  }
719 
720  /*
721  * In non-poll mode, we are receiving if the PHR is valid but the buffer
722  * does not contain a full packet.
723  */
724  if(phr_is_valid(rx_buf.phr) == true && rx_buf.full == false) {
725  return NRF52840_RECEIVING_YES;
726  }
727  return NRF52840_RECEIVING_NO;
728 }
729 /*---------------------------------------------------------------------------*/
730 static int
731 pending_packet(void)
732 {
733  /*
734  * First check if we have received a PHR. When we enter RX the value of the
735  * PHR in our RX buffer is zero so we can return early.
736  */
737  if(phr_is_valid(rx_buf.phr) == false) {
738  return NRF52840_PENDING_NO;
739  }
740 
741  /*
742  * We have received a valid PHR. Either we are in the process of receiving
743  * a frame, or we have fully received one. If we have received a frame then
744  * EVENTS_CRCOK should be asserted. In poll mode that's enough. In non-poll
745  * mode the interrupt handler will clear the event (else the interrupt would
746  * fire again), but we save the state in rx_buf.full.
747  */
748  if((nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK) == true) ||
749  (rx_buf.full == true)) {
750  return NRF52840_PENDING_YES;
751  }
752 
753  return NRF52840_PENDING_NO;
754 }
755 /*---------------------------------------------------------------------------*/
756 static int
757 off(void)
758 {
759  nrf_radio_power_set(false);
760 
761  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
762 
763  return NRF52840_COMMAND_OK;
764 }
765 /*---------------------------------------------------------------------------*/
766 static radio_result_t
767 get_value(radio_param_t param, radio_value_t *value)
768 {
769  if(!value) {
771  }
772 
773  switch(param) {
775  return RADIO_RESULT_OK;
776  case RADIO_PARAM_CHANNEL:
777  *value = (radio_value_t)get_channel();
778  return RADIO_RESULT_OK;
779  case RADIO_PARAM_RX_MODE:
780  *value = 0;
781  if(rf_config.poll_mode) {
782  *value |= RADIO_RX_MODE_POLL_MODE;
783  }
784  return RADIO_RESULT_OK;
785  case RADIO_PARAM_TX_MODE:
786  *value = 0;
787  if(rf_config.send_on_cca) {
788  *value |= RADIO_TX_MODE_SEND_ON_CCA;
789  }
790  return RADIO_RESULT_OK;
791  case RADIO_PARAM_TXPOWER:
792  *value = (radio_value_t)rf_config.txpower;
793  return RADIO_RESULT_OK;
795  *value = (radio_value_t)rf_config.cca_corr_threshold;
796  return RADIO_RESULT_OK;
797  case RADIO_PARAM_RSSI:
798  *value = (radio_value_t)rssi_read();
799  return RADIO_RESULT_OK;
801  *value = (radio_value_t)last_rssi;
802  return RADIO_RESULT_OK;
804  *value = (radio_value_t)last_lqi;
805  return RADIO_RESULT_OK;
807  *value = 11;
808  return RADIO_RESULT_OK;
810  *value = 26;
811  return RADIO_RESULT_OK;
813  *value = (radio_value_t)RADIO_TXPOWER_TXPOWER_Neg40dBm;
814  return RADIO_RESULT_OK;
816  *value = (radio_value_t)RADIO_TXPOWER_TXPOWER_Pos8dBm;
817  return RADIO_RESULT_OK;
819  *value = (radio_value_t)RADIO_PHY_OVERHEAD;
820  return RADIO_RESULT_OK;
822  *value = (radio_value_t)RADIO_BYTE_AIR_TIME;
823  return RADIO_RESULT_OK;
825  *value = (radio_value_t)RADIO_DELAY_BEFORE_TX;
826  return RADIO_RESULT_OK;
828  *value = (radio_value_t)RADIO_DELAY_BEFORE_RX;
829  return RADIO_RESULT_OK;
831  *value = (radio_value_t)RADIO_DELAY_BEFORE_DETECT;
832  return RADIO_RESULT_OK;
833  case RADIO_CONST_MAX_PAYLOAD_LEN:
834  *value = (radio_value_t)MAX_PAYLOAD_LEN;
835  return RADIO_RESULT_OK;
836  case RADIO_PARAM_PAN_ID:
838  default:
840  }
841 }
842 /*---------------------------------------------------------------------------*/
843 static radio_result_t
844 set_value(radio_param_t param, radio_value_t value)
845 {
846  switch(param) {
848  if(value == RADIO_POWER_MODE_ON) {
849  on();
850  return RADIO_RESULT_OK;
851  }
852  if(value == RADIO_POWER_MODE_OFF) {
853  off();
854  return RADIO_RESULT_OK;
855  }
857  case RADIO_PARAM_CHANNEL:
858  if(value < NRF52840_CHANNEL_MIN ||
859  value > NRF52840_CHANNEL_MAX) {
861  }
862  rf_config.channel = value;
863 
864  /* If we are powered on, apply immediately. */
865  if(radio_is_powered()) {
866  set_channel(value);
867  }
868  return RADIO_RESULT_OK;
869  case RADIO_PARAM_RX_MODE:
870  if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
874  }
875 
876  set_poll_mode((value & RADIO_RX_MODE_POLL_MODE) != 0);
877 
878  return RADIO_RESULT_OK;
879  case RADIO_PARAM_TX_MODE:
880  if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) {
882  }
883 
884  rf_config.send_on_cca = (value & RADIO_TX_MODE_SEND_ON_CCA) != 0;
885  return RADIO_RESULT_OK;
886  case RADIO_PARAM_TXPOWER:
887  rf_config.txpower = value;
888  /* If we are powered on, apply immediately. */
889  if(radio_is_powered()) {
890  nrf_radio_txpower_set(value);
891  }
892  return RADIO_RESULT_OK;
894  rf_config.cca_corr_threshold = value;
895  /* If we are powered on, apply immediately. */
896  if(radio_is_powered()) {
897  cca_reconfigure();
898  }
899  return RADIO_RESULT_OK;
900 
902  case RADIO_PARAM_PAN_ID:
904  default:
906  }
907 }
908 /*---------------------------------------------------------------------------*/
909 static radio_result_t
910 get_object(radio_param_t param, void *dest, size_t size)
911 {
912  if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
913  if(size != sizeof(rtimer_clock_t) || !dest) {
915  }
916  *(rtimer_clock_t *)dest = timestamps.sfd;
917  return RADIO_RESULT_OK;
918  }
919 
920 #if MAC_CONF_WITH_TSCH
921  if(param == RADIO_CONST_TSCH_TIMING) {
922  if(size != sizeof(uint16_t *) || !dest) {
924  }
925  /* Assigned value: a pointer to the TSCH timing in usec */
926  *(const uint16_t **)dest = tsch_timeslot_timing_us_10000;
927  return RADIO_RESULT_OK;
928  }
929 #endif /* MAC_CONF_WITH_TSCH */
930 
931  /* The radio does not support h/w frame filtering based on addresses */
933 }
934 /*---------------------------------------------------------------------------*/
935 static radio_result_t
936 set_object(radio_param_t param, const void *src, size_t size)
937 {
938  /* The radio does not support h/w frame filtering based on addresses */
940 }
941 /*---------------------------------------------------------------------------*/
942 const struct radio_driver nrf52840_ieee_driver = {
943  init,
944  prepare,
945  transmit,
946  send,
947  read_frame,
951  on,
952  off,
953  get_value,
954  set_value,
955  get_object,
956  set_object
957 };
958 /*---------------------------------------------------------------------------*/
959 PROCESS_THREAD(nrf52840_ieee_rf_process, ev, data)
960 {
961  int len;
962  PROCESS_BEGIN();
963 
964  while(1) {
965  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
966 
967  LOG_DBG("Polled\n");
968 
969  if(pending_packet()) {
971  packetbuf_clear();
972  len = read_frame(packetbuf_dataptr(), PACKETBUF_SIZE);
973  if(len > 0) {
975  NETSTACK_MAC.input();
976  LOG_DBG("last frame (%u bytes) timestamps:\n", timestamps.phr);
977  LOG_DBG(" SFD=%lu (Derived)\n", timestamps.sfd);
978  LOG_DBG(" PHY=%lu (PPI)\n", timestamps.framestart);
979  LOG_DBG(" MPDU=%lu (Duration)\n", timestamps.mpdu_duration);
980  LOG_DBG(" END=%lu (PPI)\n", timestamps.end);
981  LOG_DBG(" Expected=%lu + %u + %lu = %lu\n", timestamps.sfd,
982  BYTE_DURATION_RTIMER, timestamps.mpdu_duration,
983  timestamps.sfd + BYTE_DURATION_RTIMER + timestamps.mpdu_duration);
984  }
985  }
986  }
987 
988  PROCESS_END();
989 }
990 /*---------------------------------------------------------------------------*/
991 void
992 RADIO_IRQHandler(void)
993 {
994  if(!rf_config.poll_mode) {
995  if(nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK)) {
996  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK);
997  rx_buf.full = true;
998  process_poll(&nrf52840_ieee_rf_process);
999  } else if(nrf_radio_event_check(NRF_RADIO_EVENT_CRCERROR)) {
1000  nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR);
1001  rx_buf_clear();
1002  enter_rx();
1003  }
1004  }
1005 }
1006 /*---------------------------------------------------------------------------*/
1007 /**
1008  * @}
1009  * @}
1010  * @}
1011  */
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
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
Disable External Interrupt.
Definition: core_cm0.h:653
#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
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
Enable External Interrupt.
Definition: core_cm0.h:642
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
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
Clear Pending Interrupt.
Definition: core_cm0.h:688
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