Contiki-NG
ieee-mode.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
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  * \addtogroup cc13xx-cc26xx-rf
32  * @{
33  *
34  * \defgroup cc13xx-cc26xx-rf-ieee IEEE-mode driver for CC13xx/CC26xx
35  *
36  * @{
37  *
38  * \file
39  * Implementation of the CC13xx/CC26xx IEEE-mode NETSTACK_RADIO driver.
40  * \author
41  * Edvard Pettersen <e.pettersen@ti.com>
42  */
43 /*---------------------------------------------------------------------------*/
44 #include "contiki.h"
45 #include "net/packetbuf.h"
46 #include "net/linkaddr.h"
47 #include "net/netstack.h"
48 #include "sys/energest.h"
49 #include "sys/clock.h"
50 #include "sys/rtimer.h"
51 #include "sys/ctimer.h"
52 #include "sys/cc.h"
53 /*---------------------------------------------------------------------------*/
54 /* RF driver and RF Core API */
55 #include <ti/devices/DeviceFamily.h>
56 #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h)
57 #include DeviceFamily_constructPath(driverlib/rf_data_entry.h)
58 #include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
59 /*
60  * rf_ieee_cmd.h and rf_ieee_mailbox.h are included by RF settings because a
61  * discrepancy between CC13x0 and CC13x2 IEEE support. CC13x0 doesn't provide
62  * RFCore definitions of IEEE commands, and are therefore included locally
63  * from the Contiki build system. CC13x2 includes these normally from driverlib.
64  */
65 #if defined(DeviceFamily_CC13X0)
66 #include "driverlib/rf_ieee_mailbox.h"
67 #else
68 #include DeviceFamily_constructPath(driverlib/rf_ieee_mailbox.h)
69 #endif
70 
71 #include <ti/drivers/rf/RF.h>
72 /*---------------------------------------------------------------------------*/
73 /* SimpleLink Platform RF dev */
74 #include "rf/rf.h"
75 #include "rf/data-queue.h"
76 #include "rf/dot-15-4g.h"
77 #include "rf/sched.h"
78 #include "rf/settings.h"
79 #include "rf/tx-power.h"
80 #include "rf/rat.h"
81 #include "rf/radio-mode.h"
82 /*---------------------------------------------------------------------------*/
83 #include <stdint.h>
84 #include <stddef.h>
85 #include <string.h>
86 #include <stdio.h>
87 #include <stdbool.h>
88 /*---------------------------------------------------------------------------*/
89 /* Log configuration */
90 #include "sys/log.h"
91 #define LOG_MODULE "Radio"
92 #define LOG_LEVEL LOG_LEVEL_NONE
93 /*---------------------------------------------------------------------------*/
94 /* Configuration parameters */
95 #define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK
96 #define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS
97 #define IEEE_MODE_CCA_RSSI_THRESHOLD IEEE_MODE_CONF_CCA_RSSI_THRESHOLD
98 /*---------------------------------------------------------------------------*/
99 /* Timeout constants */
100 
101 /* How long to wait for RX to become active after scheduled */
102 #define TIMEOUT_ENTER_RX_WAIT (RTIMER_SECOND >> 10)
103 /*---------------------------------------------------------------------------*/
104 /* XXX: don't know what exactly is this */
105 #if defined(DEVICE_LINE_CC13XX)
106 #define RAT_TIMESTAMP_OFFSET USEC_TO_RAT(800)
107 #else
108 #define RAT_TIMESTAMP_OFFSET USEC_TO_RAT(-50)
109 #endif
110 /*---------------------------------------------------------------------------*/
111 #define STATUS_CORRELATION 0x3f /* bits 0-5 */
112 #define STATUS_REJECT_FRAME 0x40 /* bit 6 */
113 #define STATUS_CRC_FAIL 0x80 /* bit 7 */
114 /*---------------------------------------------------------------------------*/
115 /*
116  * The number of bytes appended at the end of an outgoing frame as a footer
117  * Currently fixed at 2 bytes for IEEE 802.15.4 compliance.
118  */
119 #define CHECKSUM_LEN 2
120 
121 /*
122  * The maximum number of bytes this driver can accept from the MAC layer for
123  * transmission or will deliver to the MAC layer after reception. Includes
124  * the MAC header and payload, but not the FCS.
125  */
126 #define MAX_PAYLOAD_LEN (127 - CHECKSUM_LEN)
127 /*---------------------------------------------------------------------------*/
128 #define FRAME_FCF_OFFSET 0
129 #define FRAME_SEQNUM_OFFSET 2
130 
131 #define FRAME_ACK_REQUEST 0x20 /* bit 5 */
132 
133 /* TX buf configuration */
134 #define TX_BUF_SIZE 180
135 /*---------------------------------------------------------------------------*/
136 /* Size of the Length representation in Data Entry, one byte in this case */
137 typedef uint8_t lensz_t;
138 
139 #define FRAME_OFFSET sizeof(lensz_t)
140 #define FRAME_SHAVE 8 /* FCS (2) + RSSI (1) + Status (1) + Timestamp (4) */
141 /*---------------------------------------------------------------------------*/
142 /* Used for checking result of CCA_REQ command */
143 typedef enum {
144  CCA_STATE_IDLE = 0,
145  CCA_STATE_BUSY = 1,
146  CCA_STATE_INVALID = 2
147 } cca_state_t;
148 /*---------------------------------------------------------------------------*/
149 /* RF Core typedefs */
150 typedef rfc_ieeeRxOutput_t rx_output_t;
151 typedef rfc_CMD_IEEE_MOD_FILT_t cmd_mod_filt_t;
152 typedef rfc_CMD_IEEE_CCA_REQ_t cmd_cca_req_t;
153 
154 typedef struct {
155  /* RF driver */
156  RF_Handle rf_handle;
157 
158  /* Are we currently in poll mode? */
159  bool poll_mode;
160 
161  /* RAT Overflow Upkeep */
162  struct {
163  struct ctimer overflow_timer;
164  rtimer_clock_t last_overflow;
165  volatile uint32_t overflow_count;
166  } rat;
167 
168  bool (* rx_is_active)(void);
169 
170  /* Outgoing frame buffer */
171  uint8_t tx_buf[TX_BUF_SIZE] CC_ALIGN(4);
172 
173  /* RF Statistics struct */
174  rx_output_t rx_stats;
175 
176  /* Indicates RF is supposed to be on or off */
177  bool rf_is_on;
178  /* Enable/disable CCA before sending */
179  bool send_on_cca;
180 
181  /* Last RX operation stats */
182  struct {
183  int8_t rssi;
184  uint8_t corr_lqi;
185  uint32_t timestamp;
186  } last;
187 } ieee_radio_t;
188 
189 static ieee_radio_t ieee_radio;
190 
191 /* Global RF Core commands */
192 static cmd_mod_filt_t cmd_mod_filt;
193 /*---------------------------------------------------------------------------*/
194 /* Convenience macros for more succinct access of RF commands */
195 #define cmd_radio_setup rf_cmd_ieee_radio_setup
196 #define cmd_fs rf_cmd_ieee_fs
197 #define cmd_tx rf_cmd_ieee_tx
198 #define cmd_rx rf_cmd_ieee_rx
199 #define cmd_rx_ack rf_cmd_ieee_rx_ack
200 
201 /* Convenience macros for volatile access with the RF commands */
202 #define v_cmd_radio_setup CC_ACCESS_NOW(rfc_CMD_RADIO_SETUP_t, rf_cmd_ieee_radio_setup)
203 #define v_cmd_fs CC_ACCESS_NOW(rfc_CMD_FS_t, rf_cmd_ieee_fs)
204 #define v_cmd_tx CC_ACCESS_NOW(rfc_CMD_IEEE_TX_t, rf_cmd_ieee_tx)
205 #define v_cmd_rx CC_ACCESS_NOW(rfc_CMD_IEEE_RX_t, rf_cmd_ieee_rx)
206 #define v_cmd_rx_ack CC_ACCESS_NOW(rfc_CMD_IEEE_RX_ACK_t, rf_cmd_ieee_rx_ack)
207 /*---------------------------------------------------------------------------*/
208 static inline bool
209 rx_is_active(void)
210 {
211  return v_cmd_rx.status == ACTIVE;
212 }
213 /*---------------------------------------------------------------------------*/
214 /* Forward declarations of Radio driver functions */
215 static int init(void);
216 static int prepare(const void *, unsigned short);
217 static int transmit(unsigned short);
218 static int send(const void *, unsigned short);
219 static int read(void *, unsigned short);
220 static int channel_clear(void);
221 static int receiving_packet(void);
222 static int pending_packet(void);
223 static int on(void);
224 static int off(void);
225 static radio_result_t get_value(radio_param_t, radio_value_t *);
226 static radio_result_t set_value(radio_param_t, radio_value_t);
227 static radio_result_t get_object(radio_param_t, void *, size_t);
228 static radio_result_t set_object(radio_param_t, const void *, size_t);
229 /*---------------------------------------------------------------------------*/
230 static void
231 init_rf_params(void)
232 {
233  cmd_radio_setup.config.frontEndMode = RF_2_4_GHZ_FRONT_END_MODE;
234  cmd_radio_setup.config.biasMode = RF_2_4_GHZ_BIAS_MODE;
235 
236  cmd_rx.pRxQ = data_queue_init(sizeof(lensz_t));
237  cmd_rx.pOutput = &ieee_radio.rx_stats;
238 
239 #if IEEE_MODE_PROMISCOUS
240  cmd_rx.frameFiltOpt.frameFiltEn = 0;
241 #else
242  cmd_rx.frameFiltOpt.frameFiltEn = 1;
243 #endif
244 
245 #if IEEE_MODE_AUTOACK
246  cmd_rx.frameFiltOpt.autoAckEn = 1;
247 #else
248  cmd_rx.frameFiltOpt.autoAckEn = 0;
249 #endif
250 
251  cmd_rx.ccaRssiThr = IEEE_MODE_CCA_RSSI_THRESHOLD;
252 
253  cmd_tx.pNextOp = (RF_Op *)&cmd_rx_ack;
254  cmd_tx.condition.rule = COND_NEVER; /* Initially ACK turned off */
255 
256  /*
257  * ACK packet is transmitted 192 us after the end of the received packet,
258  * takes 352 us for ACK transmission, total of 546 us of expected time to
259  * recieve ACK in ideal conditions. 700 us endTime for CMD_IEEE_RX_ACK
260  * should give some margins.
261  * The ACK frame consists of 6 bytes of SHR/PDR and 5 bytes of PSDU, total
262  * of 11 bytes. 11 bytes x 32 us/byte equals 352 us of ACK transmission time.
263  */
264  cmd_rx_ack.startTrigger.triggerType = TRIG_NOW;
265  cmd_rx_ack.endTrigger.triggerType = TRIG_REL_START;
266  cmd_rx_ack.endTime = RF_convertUsToRatTicks(700);
267 
268  /* Initialize address filter command */
269  cmd_mod_filt.commandNo = CMD_IEEE_MOD_FILT;
270  memcpy(&(cmd_mod_filt.newFrameFiltOpt), &(cmd_rx.frameFiltOpt), sizeof(cmd_rx.frameFiltOpt));
271  memcpy(&(cmd_mod_filt.newFrameTypes), &(cmd_rx.frameTypes), sizeof(cmd_rx.frameTypes));
272 }
273 /*---------------------------------------------------------------------------*/
274 static rf_result_t
275 set_channel(uint8_t channel)
276 {
277  if(!dot_15_4g_chan_in_range(channel)) {
278  LOG_WARN("Supplied hannel %d is illegal, defaults to %d\n",
279  (int)channel, DOT_15_4G_DEFAULT_CHAN);
280  channel = DOT_15_4G_DEFAULT_CHAN;
281  }
282 
283  /*
284  * cmd_rx.channel is initialized to 0, causing any initial call to
285  * set_channel() to cause a synth calibration, since channel must be in
286  * range 11-26.
287  */
288  if(channel == v_cmd_rx.channel) {
289  /* We are already calibrated to this channel */
290  return true;
291  }
292 
293  if(ieee_radio.rf_is_on) {
294  /* Force RAT and RTC resync */
295  rf_restart_rat();
296  }
297 
298  v_cmd_rx.channel = channel;
299 
300  const uint32_t new_freq = dot_15_4g_freq(channel);
301  const uint16_t freq = (uint16_t)(new_freq / 1000);
302  const uint16_t frac = (uint16_t)(((new_freq - (freq * 1000)) * 0x10000) / 1000);
303 
304  LOG_DBG("Set channel to %d, frequency 0x%04X.0x%04X (%lu)\n",
305  (int)channel, freq, frac, new_freq);
306 
307  v_cmd_fs.frequency = freq;
308  v_cmd_fs.fractFreq = frac;
309 
310  return netstack_sched_fs();
311 }
312 /*---------------------------------------------------------------------------*/
313 static void
314 set_send_on_cca(bool enable)
315 {
316  ieee_radio.send_on_cca = enable;
317 }
318 /*---------------------------------------------------------------------------*/
319 static int
320 init(void)
321 {
322  RF_Params rf_params;
323  RF_TxPowerTable_Value tx_power_value;
324  RF_Stat rf_stat;
325 
326  ieee_radio.rx_is_active = rx_is_active;
327  radio_mode = (simplelink_radio_mode_t *)&ieee_radio;
328 
329  if(ieee_radio.rf_handle) {
330  LOG_WARN("Radio already initialized\n");
331  return RF_RESULT_OK;
332  }
333 
334  /* RX is off */
335  ieee_radio.rf_is_on = false;
336 
337  init_rf_params();
338 
339  /* Init RF params and specify non-default params */
340  RF_Params_init(&rf_params);
341  rf_params.nInactivityTimeout = RF_CONF_INACTIVITY_TIMEOUT;
342 
343  ieee_radio.rf_handle = netstack_open(&rf_params);
344 
345  if(ieee_radio.rf_handle == NULL) {
346  LOG_ERR("Unable to open RF driver\n");
347  return RF_RESULT_ERROR;
348  }
349 
350  set_channel(DOT_15_4G_DEFAULT_CHAN);
351 
352  tx_power_value = RF_TxPowerTable_findValue(rf_tx_power_table, RF_TXPOWER_DBM);
353  if(tx_power_value.rawValue != RF_TxPowerTable_INVALID_VALUE) {
354  rf_stat = RF_setTxPower(ieee_radio.rf_handle, tx_power_value);
355  if(rf_stat == RF_StatSuccess) {
356  LOG_INFO("TX power configured to %d dBm\n", RF_TXPOWER_DBM);
357  } else {
358  LOG_WARN("Setting TX power to %d dBm failed, stat=0x%02X", RF_TXPOWER_DBM, rf_stat);
359  }
360  } else {
361  LOG_WARN("Unable to find TX power %d dBm in the TX power table\n", RF_TXPOWER_DBM);
362  }
363 
364  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
365 
366  /* Start RAT overflow upkeep */
367  rat_init();
368 
369  /* Start RF process */
370  process_start(&rf_sched_process, NULL);
371 
372  return RF_RESULT_OK;
373 }
374 /*---------------------------------------------------------------------------*/
375 static int
376 prepare(const void *payload, unsigned short payload_len)
377 {
378  if(payload_len > TX_BUF_SIZE || payload_len > MAX_PAYLOAD_LEN) {
379  return RADIO_TX_ERR;
380  }
381  memcpy(ieee_radio.tx_buf, payload, payload_len);
382  return 0;
383 }
384 /*---------------------------------------------------------------------------*/
385 static int
386 transmit(unsigned short transmit_len)
387 {
388  rf_result_t res;
389 
390  if(transmit_len > MAX_PAYLOAD_LEN) {
391  LOG_ERR("Too long\n");
392  return RADIO_TX_ERR;
393  }
394 
395  if(ieee_radio.send_on_cca && channel_clear() != 1) {
396  LOG_WARN("Channel is not clear for transmission\n");
397  return RADIO_TX_COLLISION;
398  }
399 
400  /*
401  * Are we expecting ACK? The ACK Request flag is in the first Frame
402  * Control Field byte, that is the first byte in the frame.
403  */
404  bool ack_request;
405  if(!ieee_radio.poll_mode &&
406  (ieee_radio.tx_buf[FRAME_FCF_OFFSET] & FRAME_ACK_REQUEST)) {
407  ack_request = true;
408  } else {
409  ack_request = false;
410  }
411  if(ack_request) {
412  /* Yes, turn on chaining */
413  v_cmd_tx.condition.rule = COND_STOP_ON_FALSE;
414 
415  /* Reset CMD_IEEE_RX_ACK command */
416  v_cmd_rx_ack.status = IDLE;
417  /* Sequence number is the third byte in the frame */
418  v_cmd_rx_ack.seqNo = ieee_radio.tx_buf[FRAME_SEQNUM_OFFSET];
419  } else {
420  /* No, turn off chaining */
421  v_cmd_tx.condition.rule = COND_NEVER;
422  }
423 
424  /* Configure TX command */
425  v_cmd_tx.payloadLen = (uint8_t)transmit_len;
426  v_cmd_tx.pPayload = ieee_radio.tx_buf;
427 
428  res = netstack_sched_ieee_tx(transmit_len, ack_request);
429 
430  if(res != RF_RESULT_OK) {
431  return RADIO_TX_ERR;
432  }
433 
434  if(ack_request) {
435  switch(v_cmd_rx_ack.status) {
436  /* CMD_IEEE_RX_ACK timed out, i.e. never received ACK */
437  case IEEE_DONE_TIMEOUT: return RADIO_TX_NOACK;
438  /* An ACK was received with either pending data bit set or cleared */
439  case IEEE_DONE_ACK: /* fallthrough */
440  case IEEE_DONE_ACKPEND: return RADIO_TX_OK;
441  /* Any other statuses are errors */
442  default: return RADIO_TX_ERR;
443  }
444  }
445 
446  /* No ACK expected, TX OK */
447  return RADIO_TX_OK;
448 }
449 /*---------------------------------------------------------------------------*/
450 static int
451 send(const void *payload, unsigned short payload_len)
452 {
453  prepare(payload, payload_len);
454  return transmit(payload_len);
455 }
456 /*---------------------------------------------------------------------------*/
457 static int
458 read(void *buf, unsigned short buf_len)
459 {
460  volatile data_entry_t *data_entry = data_queue_current_entry();
461 
462  const rtimer_clock_t t0 = RTIMER_NOW();
463  /* Only wait if the Radio timer is accessing the entry */
464  while((data_entry->status == DATA_ENTRY_BUSY) &&
465  RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + RADIO_FRAME_DURATION(MAX_PAYLOAD_LEN))) ;
466 
467  if(data_entry->status != DATA_ENTRY_FINISHED) {
468  /* No available data */
469  return 0;
470  }
471 
472  /*
473  * lensz bytes (1) in the data entry are the length of the received frame.
474  * Data frame is on the following format:
475  * Length (1) + Payload (N) + FCS (2) + RSSI (1) + Status (1) + Timestamp (4)
476  * Data frame DOES NOT contain the following:
477  * no PHY Header bytes
478  * no Source Index bytes
479  * Visual representation of frame format:
480  *
481  * +--------+---------+---------+--------+--------+-----------+
482  * | 1 byte | N bytes | 2 bytes | 1 byte | 1 byte | 4 bytes |
483  * +--------+---------+---------+--------+--------+-----------+
484  * | Length | Payload | FCS | RSSI | Status | Timestamp |
485  * +--------+---------+---------+--------+--------+-----------+
486  *
487  * Length bytes equal total length of entire frame excluding itself,
488  * Length = N + FCS (2) + RSSI (1) + Status (1) + Timestamp (4)
489  * Length = N + 8
490  * N = Length - 8
491  */
492  uint8_t *const frame_ptr = (uint8_t *)&data_entry->data;
493  const lensz_t frame_len = *(lensz_t *)frame_ptr;
494 
495  /* Sanity check that Frame is at least Frame Shave bytes long */
496  if(frame_len < FRAME_SHAVE) {
497  LOG_ERR("Received frame too short, len=%d\n", frame_len);
498 
499  data_queue_release_entry();
500  return 0;
501  }
502 
503  const uint8_t *payload_ptr = frame_ptr + sizeof(lensz_t);
504  const unsigned short payload_len = (unsigned short)(frame_len - FRAME_SHAVE);
505 
506  /* Sanity check that Payload fits in buffer. */
507  if(payload_len > buf_len) {
508  LOG_ERR("MAC payload too large for buffer, len=%d buf_len=%d\n",
509  payload_len, buf_len);
510 
511  data_queue_release_entry();
512  return 0;
513  }
514 
515  memcpy(buf, payload_ptr, payload_len);
516 
517  /* RSSI stored FCS (2) bytes after payload. */
518  ieee_radio.last.rssi = (int8_t)payload_ptr[payload_len + 2];
519  /* LQI retrieved from Status byte, FCS (2) + RSSI (1) bytes after payload. */
520  ieee_radio.last.corr_lqi = (uint8_t)(payload_ptr[payload_len + 3] & STATUS_CORRELATION);
521  /* Timestamp stored FCS (2) + RSSI (1) + Status (1) bytes after payload. */
522  const uint32_t rat_ticks = *(uint32_t *)(payload_ptr + payload_len + 4);
523  /* Correct timestamp so that it refers to the end of the SFD */
524  ieee_radio.last.timestamp = rat_to_timestamp(rat_ticks, RAT_TIMESTAMP_OFFSET);
525 
526  if(!ieee_radio.poll_mode) {
527  /* Not in poll mode: packetbuf should not be accessed in interrupt context. */
528  /* In poll mode, the last packet RSSI and link quality can be obtained through */
529  /* RADIO_PARAM_LAST_RSSI and RADIO_PARAM_LAST_LINK_QUALITY */
530  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (packetbuf_attr_t)ieee_radio.last.rssi);
531  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, (packetbuf_attr_t)ieee_radio.last.corr_lqi);
532  }
533 
534  data_queue_release_entry();
535  return (int)payload_len;
536 }
537 /*---------------------------------------------------------------------------*/
538 static rf_result_t
539 cca_request(cmd_cca_req_t *cmd_cca_req)
540 {
541  RF_Stat stat = RF_StatRadioInactiveError;
542  rf_result_t res;
543  bool stop_rx = false;
544 
545  /* RX is required to be running in order to do a CCA request */
546  if(!rx_is_active()) {
547  /* If RX is not pending, i.e. soon to be running, schedule the RX command */
548  if(v_cmd_rx.status != PENDING) {
549  res = netstack_sched_rx(false);
550  if(res != RF_RESULT_OK) {
551  LOG_ERR("CCA request failed to schedule RX\n");
552  return res;
553  }
554 
555  /* We only stop RX if we had to schedule it */
556  stop_rx = true;
557  }
558 
559  /* Make sure RX is running before we continue, unless we timeout and fail */
560  RTIMER_BUSYWAIT_UNTIL(rx_is_active(), TIMEOUT_ENTER_RX_WAIT);
561 
562  if(!rx_is_active()) {
563  LOG_ERR("CCA request failed to turn on RX, RX status=0x%04X\n", v_cmd_rx.status);
564  return RF_RESULT_ERROR;
565  }
566  }
567 
568  /* Perform the CCA request */
569  do {
570  memset(cmd_cca_req, 0x00, sizeof(cmd_cca_req_t));
571  cmd_cca_req->commandNo = CMD_IEEE_CCA_REQ;
572  cmd_cca_req->ccaInfo.ccaState = CCA_STATE_INVALID;
573 
574  stat = RF_runImmediateCmd(ieee_radio.rf_handle, (uint32_t *)cmd_cca_req);
575 
576  if(stat != RF_StatCmdDoneSuccess) {
577  LOG_ERR("CCA request command failed, stat=0x%02X\n", stat);
578  if(stop_rx) {
579  netstack_stop_rx();
580  }
581  return RF_RESULT_ERROR;
582  }
583  } while(cmd_cca_req->ccaInfo.ccaState == CCA_STATE_INVALID);
584 
585  if(stop_rx) {
586  netstack_stop_rx();
587  }
588 
589  return RF_RESULT_OK;
590 }
591 /*---------------------------------------------------------------------------*/
592 static int
593 channel_clear(void)
594 {
595  cmd_cca_req_t cmd_cca_req;
596 
597  if(cca_request(&cmd_cca_req) != RF_RESULT_OK) {
598  return 0;
599  }
600 
601  /* Channel is clear if CCA state is IDLE */
602  return cmd_cca_req.ccaInfo.ccaState == CCA_STATE_IDLE;
603 }
604 /*---------------------------------------------------------------------------*/
605 static int
606 receiving_packet(void)
607 {
608  cmd_cca_req_t cmd_cca_req;
609 
610  if(cca_request(&cmd_cca_req) != RF_RESULT_OK) {
611  return 0;
612  }
613 
614  /* If we are transmitting (can only be an ACK here), we are not receiving */
615  if((cmd_cca_req.ccaInfo.ccaEnergy == CCA_STATE_BUSY) &&
616  (cmd_cca_req.ccaInfo.ccaCorr == CCA_STATE_BUSY) &&
617  (cmd_cca_req.ccaInfo.ccaSync == CCA_STATE_BUSY)) {
618  LOG_WARN("We are TXing ACK, therefore not receiving packets\n");
619  return 0;
620  }
621 
622  /* We are receiving a packet if a CCA sync has been seen, i.e. ccaSync is busy (1) */
623  return cmd_cca_req.ccaInfo.ccaSync == CCA_STATE_BUSY;
624 }
625 /*---------------------------------------------------------------------------*/
626 static int
627 pending_packet(void)
628 {
629  const data_entry_t *const read_entry = data_queue_current_entry();
630  volatile const data_entry_t *curr_entry = read_entry;
631 
632  int num_pending = 0;
633 
634  /* Go through RX Circular buffer and check each data entry status */
635  do {
636  const uint8_t status = curr_entry->status;
637  if((status == DATA_ENTRY_FINISHED) ||
638  (status == DATA_ENTRY_BUSY)) {
639  num_pending += 1;
640  }
641 
642  /* Stop when we have looped the circular buffer */
643  curr_entry = (data_entry_t *)curr_entry->pNextEntry;
644  } while(curr_entry != read_entry);
645 
646  if(num_pending > 0 && !ieee_radio.poll_mode) {
647  process_poll(&rf_sched_process);
648  }
649 
650  /* If we didn't find an entry at status finished or busy, no frames are pending */
651  return num_pending;
652 }
653 /*---------------------------------------------------------------------------*/
654 static int
655 on(void)
656 {
657  rf_result_t res;
658 
659  if(ieee_radio.rf_is_on) {
660  LOG_WARN("Radio is already on\n");
661  return RF_RESULT_OK;
662  }
663 
664  data_queue_reset();
665 
666  res = netstack_sched_rx(true);
667 
668  if(res != RF_RESULT_OK) {
669  return RF_RESULT_ERROR;
670  }
671 
672  ieee_radio.rf_is_on = true;
673  return RF_RESULT_OK;
674 }
675 /*---------------------------------------------------------------------------*/
676 static int
677 off(void)
678 {
679  if(!ieee_radio.rf_is_on) {
680  LOG_WARN("Radio is already off\n");
681  return RF_RESULT_OK;
682  }
683 
684  rf_yield();
685 
686  ieee_radio.rf_is_on = false;
687  return RF_RESULT_OK;
688 }
689 /*---------------------------------------------------------------------------*/
690 static radio_result_t
691 get_value(radio_param_t param, radio_value_t *value)
692 {
693  rf_result_t res;
694 
695  if(!value) {
697  }
698 
699  switch(param) {
700 
701  /* Power Mode */
703  *value = (ieee_radio.rf_is_on)
706  return RADIO_RESULT_OK;
707 
708  /* Channel */
709  case RADIO_PARAM_CHANNEL:
710  *value = (radio_value_t)v_cmd_rx.channel;
711  return RADIO_RESULT_OK;
712 
713  /* PAN ID */
714  case RADIO_PARAM_PAN_ID:
715  *value = (radio_value_t)v_cmd_rx.localPanID;
716  return RADIO_RESULT_OK;
717 
718  /* 16-bit address */
720  *value = (radio_value_t)v_cmd_rx.localShortAddr;
721  return RADIO_RESULT_OK;
722 
723  /* RX mode */
724  case RADIO_PARAM_RX_MODE:
725  *value = 0;
726  if(v_cmd_rx.frameFiltOpt.frameFiltEn) {
728  }
729  if(v_cmd_rx.frameFiltOpt.autoAckEn) {
731  }
732  if(ieee_radio.poll_mode) {
734  }
735  return RADIO_RESULT_OK;
736 
737  /* TX mode */
738  case RADIO_PARAM_TX_MODE:
739  *value = 0;
740  return RADIO_RESULT_OK;
741 
742  /* TX power */
743  case RADIO_PARAM_TXPOWER:
744  res = rf_get_tx_power(ieee_radio.rf_handle, rf_tx_power_table, (int8_t *)&value);
745  return ((res == RF_RESULT_OK) &&
746  (*value != RF_TxPowerTable_INVALID_DBM))
749 
750  /* CCA threshold */
752  *value = v_cmd_rx.ccaRssiThr;
753  return RADIO_RESULT_OK;
754 
755  /* RSSI */
756  case RADIO_PARAM_RSSI:
757  *value = RF_getRssi(ieee_radio.rf_handle);
758  return (*value == RF_GET_RSSI_ERROR_VAL)
760  : RADIO_RESULT_OK;
761 
762  /* Channel min */
764  *value = (radio_value_t)DOT_15_4G_CHAN_MIN;
765  return RADIO_RESULT_OK;
766 
767  /* Channel max */
769  *value = (radio_value_t)DOT_15_4G_CHAN_MAX;
770  return RADIO_RESULT_OK;
771 
773  *value = (radio_value_t)tx_power_min(rf_tx_power_table);
774  return RADIO_RESULT_OK;
775 
776  /* TX power max */
778  *value = (radio_value_t)tx_power_max(rf_tx_power_table, rf_tx_power_table_size);
779  return RADIO_RESULT_OK;
780 
781  /* Last RSSI */
783  *value = (radio_value_t)ieee_radio.last.rssi;
784  return RADIO_RESULT_OK;
785 
786  /* Last link quality */
788  *value = (radio_value_t)ieee_radio.last.corr_lqi;
789  return RADIO_RESULT_OK;
790 
791  case RADIO_CONST_MAX_PAYLOAD_LEN:
792  *value = (radio_value_t)MAX_PAYLOAD_LEN;
793  return RADIO_RESULT_OK;
794 
795  default:
797  }
798 }
799 /*---------------------------------------------------------------------------*/
800 static radio_result_t
801 set_value(radio_param_t param, radio_value_t value)
802 {
803  rf_result_t res;
804 
805  switch(param) {
806 
807  /* Power Mode */
809 
810  if(value == RADIO_POWER_MODE_ON) {
811  return (on() == RF_RESULT_OK)
814  } else if(value == RADIO_POWER_MODE_OFF) {
815  off();
816  return RADIO_RESULT_OK;
817  }
818 
820 
821  /* Channel */
822  case RADIO_PARAM_CHANNEL:
823  if(!dot_15_4g_chan_in_range(value)) {
825  }
826  set_channel((uint8_t)value);
827  return RADIO_RESULT_OK;
828 
829  /* PAN ID */
830  case RADIO_PARAM_PAN_ID:
831  v_cmd_rx.localPanID = (uint16_t)value;
832  if(!ieee_radio.rf_is_on) {
833  return RADIO_RESULT_OK;
834  }
835 
836  netstack_stop_rx();
837  res = netstack_sched_rx(false);
838  return (res == RF_RESULT_OK)
841 
842  /* 16bit address */
844  v_cmd_rx.localShortAddr = (uint16_t)value;
845  if(!ieee_radio.rf_is_on) {
846  return RADIO_RESULT_OK;
847  }
848 
849  netstack_stop_rx();
850  res = netstack_sched_rx(false);
851  return (res == RF_RESULT_OK)
854 
855  /* RX Mode */
856  case RADIO_PARAM_RX_MODE: {
857  if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
861  }
862 
863  v_cmd_rx.frameFiltOpt.frameFiltEn = (value & RADIO_RX_MODE_ADDRESS_FILTER) != 0;
864  v_cmd_rx.frameFiltOpt.frameFiltStop = 1;
865  v_cmd_rx.frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
866  v_cmd_rx.frameFiltOpt.slottedAckEn = 0;
867  v_cmd_rx.frameFiltOpt.autoPendEn = 0;
868  v_cmd_rx.frameFiltOpt.defaultPend = 0;
869  v_cmd_rx.frameFiltOpt.bPendDataReqOnly = 0;
870  v_cmd_rx.frameFiltOpt.bPanCoord = 0;
871  v_cmd_rx.frameFiltOpt.bStrictLenFilter = 0;
872 
873  const bool old_poll_mode = ieee_radio.poll_mode;
874  ieee_radio.poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
875  if(old_poll_mode == ieee_radio.poll_mode) {
876  /* Do not turn the radio off and on, just send an update command */
877  memcpy(&cmd_mod_filt.newFrameFiltOpt, &(cmd_rx.frameFiltOpt), sizeof(cmd_rx.frameFiltOpt));
878  const RF_Stat stat = RF_runImmediateCmd(ieee_radio.rf_handle, (uint32_t *)&cmd_mod_filt);
879  if(stat != RF_StatCmdDoneSuccess) {
880  LOG_ERR("Setting address filter failed, stat=0x%02X\n", stat);
881  return RADIO_RESULT_ERROR;
882  }
883  return RADIO_RESULT_OK;
884  }
885  if(!ieee_radio.rf_is_on) {
886  return RADIO_RESULT_OK;
887  }
888 
889  netstack_stop_rx();
890  res = netstack_sched_rx(false);
891  return (res == RF_RESULT_OK)
894  }
895 
896  /* TX Mode */
897  case RADIO_PARAM_TX_MODE:
898  if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) {
900  }
901  set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0);
902  return RADIO_RESULT_OK;
903 
904  /* TX Power */
905  case RADIO_PARAM_TXPOWER:
906  if(!tx_power_in_range((int8_t)value, rf_tx_power_table, rf_tx_power_table_size)) {
908  }
909  res = rf_set_tx_power(ieee_radio.rf_handle, rf_tx_power_table, (int8_t)value);
910  return (res == RF_RESULT_OK)
913 
914  /* CCA Threshold */
916  v_cmd_rx.ccaRssiThr = (int8_t)value;
917  if(!ieee_radio.rf_is_on) {
918  return RADIO_RESULT_OK;
919  }
920 
921  netstack_stop_rx();
922  res = netstack_sched_rx(false);
923  return (res == RF_RESULT_OK)
926 
927  default:
929  }
930 }
931 /*---------------------------------------------------------------------------*/
932 static radio_result_t
933 get_object(radio_param_t param, void *dest, size_t size)
934 {
935  if(!dest) {
937  }
938 
939  switch(param) {
940  /* 64bit address */
941  case RADIO_PARAM_64BIT_ADDR: {
942  const size_t srcSize = sizeof(v_cmd_rx.localExtAddr);
943  if(size != srcSize) {
945  }
946 
947  const uint8_t *pSrc = (uint8_t *)&(v_cmd_rx.localExtAddr);
948  uint8_t *pDest = dest;
949  for(size_t i = 0; i < srcSize; ++i) {
950  pDest[i] = pSrc[srcSize - 1 - i];
951  }
952 
953  return RADIO_RESULT_OK;
954  }
955  /* Last packet timestamp */
957  if(size != sizeof(rtimer_clock_t)) {
959  }
960 
961  *(rtimer_clock_t *)dest = ieee_radio.last.timestamp;
962 
963  return RADIO_RESULT_OK;
964 
965  default:
967  }
968 }
969 /*---------------------------------------------------------------------------*/
970 static radio_result_t
971 set_object(radio_param_t param, const void *src, size_t size)
972 {
973  rf_result_t res;
974 
975  if(!src) {
977  }
978 
979  switch(param) {
980  /* 64-bit address */
981  case RADIO_PARAM_64BIT_ADDR: {
982  const size_t destSize = sizeof(v_cmd_rx.localExtAddr);
983  if(size != destSize) {
985  }
986 
987  const uint8_t *pSrc = (const uint8_t *)src;
988  volatile uint8_t *pDest = (uint8_t *)&(v_cmd_rx.localExtAddr);
989  for(size_t i = 0; i < destSize; ++i) {
990  pDest[i] = pSrc[destSize - 1 - i];
991  }
992 
993  if(!rx_is_active()) {
994  return RADIO_RESULT_OK;
995  }
996 
997  netstack_stop_rx();
998  res = netstack_sched_rx(false);
999  return (res == RF_RESULT_OK)
1000  ? RADIO_RESULT_OK
1002  }
1003  default:
1005  }
1006 }
1007 /*---------------------------------------------------------------------------*/
1008 const struct radio_driver ieee_mode_driver = {
1009  init,
1010  prepare,
1011  transmit,
1012  send,
1013  read,
1014  channel_clear,
1017  on,
1018  off,
1019  get_value,
1020  set_value,
1021  get_object,
1022  set_object,
1023 };
1024 /*---------------------------------------------------------------------------*/
1025 /**
1026  * @}
1027  * @}
1028  */
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:762
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:572
Header file of TX power functionality of CC13xx/CC26xx.
The parameter is not supported.
Definition: radio.h:473
static uint8_t rf_is_on(void)
Checks whether the RFC domain is accessible and the RFC is in IEEE RX.
Definition: ieee-mode.c:267
#define FRAME_SHAVE
RSSI (1) + Timestamp (4) + Status (1)
Definition: prop-mode.c:169
Header file for the energy estimation mechanism
TX failed due to a collision.
Definition: radio.h:503
The maximum transmission power in dBm.
Definition: radio.h:318
Header file for the link-layer address representation
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
Header file of the generic radio mode API.
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
#define RTIMER_BUSYWAIT_UNTIL(cond, max_time)
Busy-wait until a condition for at most max_time.
Definition: rtimer.h:211
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
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
An error occurred when getting/setting the parameter, but the arguments were otherwise correct...
Definition: radio.h:480
Header file of the CC13xx/CC26xx RAT timer handler.
Radio transmission mode determines if the radio has send on CCA (RADIO_TX_MODE_SEND_ON_CCA) enabled o...
Definition: radio.h:180
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:185
The RSSI value of the last received packet.
Definition: radio.h:226
Clear channel assessment threshold in dBm.
Definition: radio.h:205
Header file of the CC13xx/CC26xx RF scheduler.
Header file for the callback timer
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
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
#define RF_CONF_INACTIVITY_TIMEOUT
2 ms
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
Header file for the real-time timer module.
The highest radio channel number.
Definition: radio.h:308
A unicast frame was sent OK but an ACK was not received.
Definition: radio.h:508
#define RADIO_RX_MODE_ADDRESS_FILTER
Enable address-based frame filtering.
Definition: radio.h:443
Header file of the CC13xx/CC26xx RF data queue.
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
Header file of RF settings for CC13xx/CC26xx.
#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
Long (64 bits) address for the radio, which is used by the address filter.
Definition: radio.h:255
The minimum transmission power in dBm.
Definition: radio.h:313
Radio powered on and able to receive frames.
Definition: radio.h:392
int(* read)(void *buf, unsigned short buf_len)
Read a received packet into a buffer.
Definition: radio.h:647
Transmission power in dBm.
Definition: radio.h:192
Header file of common CC13xx/CC26xx RF functionality.
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:733
Default definitions of C compiler quirk work-arounds.
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
TX was successful and where an ACK was requested one was received.
Definition: radio.h:490
int(* on)(void)
Turn the radio on.
Definition: radio.h:703
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99