Contiki-NG
ieee-mode.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, 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 /**
32  * \addtogroup rf-core
33  * @{
34  *
35  * \defgroup rf-core-ieee CC13xx/CC26xx IEEE mode driver
36  *
37  * @{
38  *
39  * \file
40  * Implementation of the CC13xx/CC26xx IEEE mode NETSTACK_RADIO driver
41  */
42 /*---------------------------------------------------------------------------*/
43 #include "contiki.h"
44 #include "dev/radio.h"
45 #include "dev/cc26xx-uart.h"
46 #include "dev/oscillators.h"
47 #include "net/packetbuf.h"
48 #include "net/linkaddr.h"
49 #include "net/netstack.h"
50 #include "sys/energest.h"
51 #include "sys/clock.h"
52 #include "sys/rtimer.h"
53 #include "sys/ctimer.h"
54 #include "sys/cc.h"
55 #include "lpm.h"
56 #include "ti-lib.h"
57 #include "rf-core/rf-core.h"
58 #include "rf-core/rf-switch.h"
59 #include "rf-core/rf-ble.h"
60 /*---------------------------------------------------------------------------*/
61 /* RF core and RF HAL API */
62 #include "hw_rfc_dbell.h"
63 #include "hw_rfc_pwr.h"
64 /*---------------------------------------------------------------------------*/
65 /* RF Core Mailbox API */
66 #include "rf-core/api/ieee_cmd.h"
67 #include "rf-core/api/ieee_mailbox.h"
68 #include "driverlib/rf_mailbox.h"
69 #include "driverlib/rf_common_cmd.h"
70 #include "driverlib/rf_data_entry.h"
71 /*---------------------------------------------------------------------------*/
72 #include "smartrf-settings.h"
73 /*---------------------------------------------------------------------------*/
74 #include <stdint.h>
75 #include <string.h>
76 #include <stdio.h>
77 #include <stdbool.h>
78 /*---------------------------------------------------------------------------*/
79 #define DEBUG 0
80 #if DEBUG
81 #define PRINTF(...) printf(__VA_ARGS__)
82 #else
83 #define PRINTF(...)
84 #endif
85 
86 /* Configuration to enable/disable auto ACKs in IEEE mode */
87 #ifdef IEEE_MODE_CONF_AUTOACK
88 #define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK
89 #else
90 #define IEEE_MODE_AUTOACK 1
91 #endif /* IEEE_MODE_CONF_AUTOACK */
92 
93 /* Configuration to enable/disable frame filtering in IEEE mode */
94 #ifdef IEEE_MODE_CONF_PROMISCOUS
95 #define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS
96 #else
97 #define IEEE_MODE_PROMISCOUS 0
98 #endif /* IEEE_MODE_CONF_PROMISCOUS */
99 
100 #ifdef IEEE_MODE_CONF_RSSI_THRESHOLD
101 #define IEEE_MODE_RSSI_THRESHOLD IEEE_MODE_CONF_RSSI_THRESHOLD
102 #else
103 #define IEEE_MODE_RSSI_THRESHOLD 0xA6
104 #endif /* IEEE_MODE_CONF_RSSI_THRESHOLD */
105 /*---------------------------------------------------------------------------*/
106 #define STATUS_CRC_FAIL 0x80 /* bit 7 */
107 #define STATUS_REJECT_FRAME 0x40 /* bit 6 */
108 #define STATUS_CORRELATION 0x3f /* bits 0-5 */
109 /*---------------------------------------------------------------------------*/
110 /* Data entry status field constants */
111 #define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */
112 #define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */
113 #define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */
114 #define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */
115 #define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */
116 /*---------------------------------------------------------------------------*/
117 /* RF stats data structure */
118 static uint8_t rf_stats[16] = { 0 };
119 /*---------------------------------------------------------------------------*/
120 /* The size of the RF commands buffer */
121 #define RF_CMD_BUFFER_SIZE 128
122 /*---------------------------------------------------------------------------*/
123 /**
124  * \brief Returns the current status of a running Radio Op command
125  * \param a A pointer with the buffer used to initiate the command
126  * \return The value of the Radio Op buffer's status field
127  *
128  * This macro can be used to e.g. return the status of a previously
129  * initiated background operation, or of an immediate command
130  */
131 #define RF_RADIO_OP_GET_STATUS(a) (((rfc_radioOp_t *)a)->status)
132 /*---------------------------------------------------------------------------*/
133 /* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */
134 #define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128
135 
136 /* Used for the return value of channel_clear */
137 #define RF_CCA_CLEAR 1
138 #define RF_CCA_BUSY 0
139 
140 /* Used as an error return value for get_cca_info */
141 #define RF_GET_CCA_INFO_ERROR 0xFF
142 
143 /*
144  * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's
145  * status struct
146  */
147 #define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */
148 #define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */
149 #define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */
150 
151 #define RF_CMD_CCA_REQ_CCA_CORR_IDLE (0 << 4)
152 #define RF_CMD_CCA_REQ_CCA_CORR_BUSY (1 << 4)
153 #define RF_CMD_CCA_REQ_CCA_CORR_INVALID (3 << 4)
154 #define RF_CMD_CCA_REQ_CCA_CORR_MASK (3 << 4)
155 
156 #define RF_CMD_CCA_REQ_CCA_SYNC_BUSY (1 << 6)
157 /*---------------------------------------------------------------------------*/
158 #define IEEE_MODE_CHANNEL_MIN 11
159 #define IEEE_MODE_CHANNEL_MAX 26
160 /*---------------------------------------------------------------------------*/
161 /* How long to wait for an ongoing ACK TX to finish before starting frame TX */
162 #define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11)
163 
164 /* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */
165 #define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10)
166 
167 /* How long to wait for the RF to react on CMD_ABORT: around 1 msec */
168 #define RF_TURN_OFF_WAIT_TIMEOUT (RTIMER_SECOND >> 10)
169 
170 /* How long to wait for the RF to finish TX of a packet or an ACK */
171 #define TX_FINISH_WAIT_TIMEOUT (RTIMER_SECOND >> 7)
172 
173 #define LIMITED_BUSYWAIT(cond, timeout) do { \
174  rtimer_clock_t end_time = RTIMER_NOW() + timeout; \
175  while(cond) { \
176  if(!RTIMER_CLOCK_LT(RTIMER_NOW(), end_time)) { \
177  break; \
178  } \
179  } \
180  } while(0)
181 /*---------------------------------------------------------------------------*/
182 /* TX Power dBm lookup table - values from SmartRF Studio */
183 typedef struct output_config {
184  radio_value_t dbm;
185  uint16_t tx_power; /* Value for the CMD_RADIO_SETUP.txPower field */
186 } output_config_t;
187 
188 static const output_config_t output_power[] = {
189  { 5, 0x9330 },
190  { 4, 0x9324 },
191  { 3, 0x5a1c },
192  { 2, 0x4e18 },
193  { 1, 0x4214 },
194  { 0, 0x3161 },
195  { -3, 0x2558 },
196  { -6, 0x1d52 },
197  { -9, 0x194e },
198  {-12, 0x144b },
199  {-15, 0x0ccb },
200  {-18, 0x0cc9 },
201  {-21, 0x0cc7 },
202 };
203 
204 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
205 
206 /* Max and Min Output Power in dBm */
207 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm)
208 #define OUTPUT_POWER_MAX (output_power[0].dbm)
209 #define OUTPUT_POWER_UNKNOWN 0xFFFF
210 
211 /* Default TX Power - position in output_power[] */
212 static const output_config_t *tx_power_current = &output_power[0];
213 /*---------------------------------------------------------------------------*/
214 static volatile int8_t last_rssi = 0;
215 static volatile uint8_t last_corr_lqi = 0;
216 
217 extern int32_t rat_offset;
218 
219 /*---------------------------------------------------------------------------*/
220 /* SFD timestamp in RTIMER ticks */
221 static volatile uint32_t last_packet_timestamp = 0;
222 /* SFD timestamp in RAT ticks (but 64 bits) */
223 static uint64_t last_rat_timestamp64 = 0;
224 
225 /* For RAT overflow handling */
226 static struct ctimer rat_overflow_timer;
227 static volatile uint32_t rat_overflow_counter = 0;
228 static rtimer_clock_t last_rat_overflow = 0;
229 
230 /* RAT has 32-bit register, overflows once 18 minutes */
231 #define RAT_RANGE 4294967296ull
232 /* approximate value */
233 #define RAT_OVERFLOW_PERIOD_SECONDS (60 * 18)
234 
235 /* XXX: don't know what exactly is this, looks like the time to Tx 3 octets */
236 #define TIMESTAMP_OFFSET -(USEC_TO_RADIO(32 * 3) - 1) /* -95.75 usec */
237 /*---------------------------------------------------------------------------*/
238 /* Are we currently in poll mode? */
239 static uint8_t poll_mode = 0;
240 
241 static rfc_CMD_IEEE_MOD_FILT_t filter_cmd;
242 /*---------------------------------------------------------------------------*/
243 /*
244  * Buffers used to send commands to the RF core (generic and IEEE commands).
245  * Some of those buffers are re-usable, some are not.
246  *
247  * If you are uncertain, declare a new buffer.
248  */
249 /*
250  * A buffer to send a CMD_IEEE_RX and to subsequently monitor its status
251  * Do not use this buffer for any commands other than CMD_IEEE_RX
252  */
253 static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN(4);
254 /*---------------------------------------------------------------------------*/
255 #define DATA_ENTRY_LENSZ_NONE 0
256 #define DATA_ENTRY_LENSZ_BYTE 1
257 #define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */
258 
259 #define RX_BUF_SIZE 144
260 /* Four receive buffers entries with room for 1 IEEE802.15.4 frame in each */
261 static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4);
262 static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
263 static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN(4);
264 static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN(4);
265 
266 #define RX_BUF_INCLUDE_CRC 1
267 #define RX_BUF_INCLUDE_RSSI 1
268 #define RX_BUF_INCLUDE_CORR 1
269 #define RX_BUF_INCLUDE_TIMESTAMP 1
270 
271 /* The size of the metadata (excluding the packet length field) */
272 #define RX_BUF_METADATA_SIZE \
273  (2 * RX_BUF_INCLUDE_CRC + RX_BUF_INCLUDE_RSSI + RX_BUF_INCLUDE_CORR + 4 * RX_BUF_INCLUDE_TIMESTAMP)
274 
275 /* The offset of the packet length in a rx buffer */
276 #define RX_BUF_LENGTH_OFFSET sizeof(rfc_dataEntry_t)
277 /* The offset of the packet data in a rx buffer */
278 #define RX_BUF_DATA_OFFSET (RX_BUF_LENGTH_OFFSET + 1)
279 
280 /* The RX Data Queue */
281 static dataQueue_t rx_data_queue = { 0 };
282 
283 /* Receive entry pointer to keep track of read items */
284 volatile static uint8_t *rx_read_entry;
285 /*---------------------------------------------------------------------------*/
286 /* The outgoing frame buffer */
287 #define TX_BUF_PAYLOAD_LEN 180
288 #define TX_BUF_HDR_LEN 2
289 
290 static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
291 /*---------------------------------------------------------------------------*/
292 #ifdef IEEE_MODE_CONF_BOARD_OVERRIDES
293 #define IEEE_MODE_BOARD_OVERRIDES IEEE_MODE_CONF_BOARD_OVERRIDES
294 #else
295 #define IEEE_MODE_BOARD_OVERRIDES
296 #endif
297 /*---------------------------------------------------------------------------*/
298 /* Overrides for IEEE 802.15.4, differential mode */
299 static uint32_t ieee_overrides[] = {
300  0x00354038, /* Synth: Set RTRIM (POTAILRESTRIM) to 5 */
301  0x4001402D, /* Synth: Correct CKVD latency setting (address) */
302  0x00608402, /* Synth: Correct CKVD latency setting (value) */
303 // 0x4001405D, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (address) */
304 // 0x1801F800, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (value) */
305  0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */
306  0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */
307  0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */
308  0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */
309  0x002B50DC, /* Adjust AGC DC filter */
310  0x05000243, /* Increase synth programming timeout */
311  0x002082C3, /* Increase synth programming timeout */
312  IEEE_MODE_BOARD_OVERRIDES
313  0xFFFFFFFF, /* End of override list */
314 };
315 /*---------------------------------------------------------------------------*/
316 static int on(void);
317 static int off(void);
318 /*---------------------------------------------------------------------------*/
319 /**
320  * \brief Checks whether the RFC domain is accessible and the RFC is in IEEE RX
321  * \return 1: RFC in RX mode (and therefore accessible too). 0 otherwise
322  */
323 static uint8_t
324 rf_is_on(void)
325 {
326  if(!rf_core_is_accessible()) {
327  return 0;
328  }
329 
330  return RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == RF_CORE_RADIO_OP_STATUS_ACTIVE;
331 }
332 /*---------------------------------------------------------------------------*/
333 /**
334  * \brief Check the RF's TX status
335  * \return 1 RF is transmitting
336  * \return 0 RF is not transmitting
337  *
338  * TX mode may be triggered either by a CMD_IEEE_TX or by the automatic
339  * transmission of an ACK frame.
340  */
341 static uint8_t
343 {
344  uint32_t cmd_status;
345  rfc_CMD_IEEE_CCA_REQ_t cmd;
346 
347  /* If we are off, we are not in TX */
348  if(!rf_core_is_accessible()) {
349  return 0;
350  }
351 
352  memset(&cmd, 0x00, sizeof(cmd));
353 
354  cmd.commandNo = CMD_IEEE_CCA_REQ;
355 
356  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
357  PRINTF("transmitting: CMDSTA=0x%08lx\n", cmd_status);
358  return 0;
359  }
360 
361  if((cmd.currentRssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN) &&
362  (cmd.ccaInfo.ccaEnergy == RF_CMD_CCA_REQ_CCA_STATE_BUSY)) {
363  return 1;
364  }
365 
366  return 0;
367 }
368 /*---------------------------------------------------------------------------*/
369 /**
370  * \brief Returns CCA information
371  * \return RF_GET_CCA_INFO_ERROR if the RF was not on
372  * \return On success, the return value is formatted as per the ccaInfo field
373  * of CMD_IEEE_CCA_REQ
374  *
375  * It is the caller's responsibility to make sure the RF is on. This function
376  * will return RF_GET_CCA_INFO_ERROR if the RF is off
377  *
378  * This function will in fact wait for a valid CCA state
379  */
380 static uint8_t
382 {
383  uint32_t cmd_status;
384  rfc_CMD_IEEE_CCA_REQ_t cmd;
385 
386  if(!rf_is_on()) {
387  PRINTF("get_cca_info: Not on\n");
388  return RF_GET_CCA_INFO_ERROR;
389  }
390 
391  memset(&cmd, 0x00, sizeof(cmd));
392  cmd.ccaInfo.ccaState = RF_CMD_CCA_REQ_CCA_STATE_INVALID;
393 
394  while(cmd.ccaInfo.ccaState == RF_CMD_CCA_REQ_CCA_STATE_INVALID) {
395  memset(&cmd, 0x00, sizeof(cmd));
396  cmd.commandNo = CMD_IEEE_CCA_REQ;
397 
398  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
399  PRINTF("get_cca_info: CMDSTA=0x%08lx\n", cmd_status);
400 
401  return RF_GET_CCA_INFO_ERROR;
402  }
403  }
404 
405  /* We have a valid CCA state. Return the CCA Info */
406  return *((uint8_t *)&cmd.ccaInfo);
407 }
408 /*---------------------------------------------------------------------------*/
409 /**
410  * \brief Reads the current signal strength (RSSI)
411  * \return The current RSSI in dBm or CMD_GET_RSSI_UNKNOWN
412  *
413  * This function reads the current RSSI on the currently configured
414  * channel.
415  */
416 static radio_value_t
417 get_rssi(void)
418 {
419  uint32_t cmd_status;
420  uint8_t was_off = 0;
421  rfc_CMD_IEEE_CCA_REQ_t cmd;
422 
423  /* If we are off, turn on first */
424  if(!rf_is_on()) {
425  was_off = 1;
426  if(on() != RF_CORE_CMD_OK) {
427  PRINTF("get_rssi: on() failed\n");
428  return RF_CMD_CCA_REQ_RSSI_UNKNOWN;
429  }
430  }
431 
432  memset(&cmd, 0x00, sizeof(cmd));
433  cmd.ccaInfo.ccaEnergy = RF_CMD_CCA_REQ_CCA_STATE_INVALID;
434 
435  while(cmd.ccaInfo.ccaEnergy == RF_CMD_CCA_REQ_CCA_STATE_INVALID) {
436  memset(&cmd, 0x00, sizeof(cmd));
437  cmd.commandNo = CMD_IEEE_CCA_REQ;
438 
439  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
440  PRINTF("get_rssi: CMDSTA=0x%08lx\n", cmd_status);
441 
442  /* Make sure to return RSSI unknown */
443  cmd.currentRssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN;
444  break;
445  }
446  }
447 
448  /* If we were off, turn back off */
449  if(was_off) {
450  off();
451  }
452 
453  return cmd.currentRssi;
454 }
455 /*---------------------------------------------------------------------------*/
456 /* Returns the current TX power in dBm */
457 static radio_value_t
458 get_tx_power(void)
459 {
460  return tx_power_current->dbm;
461 }
462 /*---------------------------------------------------------------------------*/
463 /*
464  * Set TX power to 'at least' power dBm
465  * This works with a lookup table. If the value of 'power' does not exist in
466  * the lookup table, TXPOWER will be set to the immediately higher available
467  * value
468  */
469 static void
470 set_tx_power(radio_value_t power)
471 {
472  uint32_t cmd_status;
473  int i;
474  rfc_CMD_SET_TX_POWER_t cmd;
475 
476  /* First, find the correct setting and save it */
477  for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
478  if(power <= output_power[i].dbm) {
479  tx_power_current = &output_power[i];
480  break;
481  }
482  }
483 
484  /*
485  * If the core is not accessible, the new setting will be applied next
486  * time we send CMD_RADIO_SETUP, so we don't need to do anything further.
487  * If the core is accessible, we can apply the new setting immediately with
488  * CMD_SET_TX_POWER
489  */
490  if(rf_core_is_accessible() == RF_CORE_NOT_ACCESSIBLE) {
491  return;
492  }
493 
494  memset(&cmd, 0x00, sizeof(cmd));
495  cmd.commandNo = CMD_SET_TX_POWER;
496  cmd.txPower = output_power[i].tx_power;
497 
498  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
499  PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status);
500  }
501 }
502 /*---------------------------------------------------------------------------*/
503 static uint8_t
504 rf_radio_setup()
505 {
506  uint32_t cmd_status;
507  rfc_CMD_RADIO_SETUP_t cmd;
508 
509  rf_switch_select_path(RF_SWITCH_PATH_2_4GHZ);
510 
511  /* Create radio setup command */
512  rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP);
513 
514  cmd.txPower = tx_power_current->tx_power;
515  cmd.pRegOverride = ieee_overrides;
516  cmd.config.frontEndMode = RF_CORE_RADIO_SETUP_FRONT_END_MODE;
517  cmd.config.biasMode = RF_CORE_RADIO_SETUP_BIAS_MODE;
518  cmd.mode = 1;
519 
520  /* Send Radio setup to RF Core */
521  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) {
522  PRINTF("rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n",
523  cmd_status, cmd.status);
524  return RF_CORE_CMD_ERROR;
525  }
526 
527  /* Wait until radio setup is done */
528  if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) {
529  PRINTF("rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n",
530  cmd_status, cmd.status);
531  return RF_CORE_CMD_ERROR;
532  }
533 
534  return RF_CORE_CMD_OK;
535 }
536 /*---------------------------------------------------------------------------*/
537 /**
538  * \brief Set up radio in IEEE802.15.4 RX mode
539  *
540  * \return RF_CORE_CMD_OK Succeeded
541  * \return RF_CORE_CMD_ERROR Failed
542  *
543  * This function assumes that cmd_ieee_rx_buf has been previously populated
544  * with correct values. This can be done through init_rf_params (sets defaults)
545  * or through Contiki's extended RF API (set_value, set_object)
546  */
547 static uint8_t
549 {
550  uint32_t cmd_status;
551  int ret;
552 
553  ret = rf_core_send_cmd((uint32_t)cmd_ieee_rx_buf, &cmd_status);
554 
555  if(ret != RF_CORE_CMD_OK) {
556  PRINTF("rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
557  ret, cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf));
558  return RF_CORE_CMD_ERROR;
559  }
560 
561  LIMITED_BUSYWAIT(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_CORE_RADIO_OP_STATUS_ACTIVE,
562  ENTER_RX_WAIT_TIMEOUT);
563 
564  /* Wait to enter RX */
565  if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_CORE_RADIO_OP_STATUS_ACTIVE) {
566  PRINTF("rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n",
567  cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf));
568  return RF_CORE_CMD_ERROR;
569  }
570 
571  return ret;
572 }
573 /*---------------------------------------------------------------------------*/
574 static void
575 init_rx_buffers(void)
576 {
577  rfc_dataEntry_t *entry;
578 
579  entry = (rfc_dataEntry_t *)rx_buf_0;
580  entry->pNextEntry = rx_buf_1;
581  entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
582  entry->length = sizeof(rx_buf_0) - sizeof(*entry);
583 
584  entry = (rfc_dataEntry_t *)rx_buf_1;
585  entry->pNextEntry = rx_buf_2;
586  entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
587  entry->length = sizeof(rx_buf_0) - sizeof(*entry);
588 
589  entry = (rfc_dataEntry_t *)rx_buf_2;
590  entry->pNextEntry = rx_buf_3;
591  entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
592  entry->length = sizeof(rx_buf_0) - sizeof(*entry);
593 
594  entry = (rfc_dataEntry_t *)rx_buf_3;
595  entry->pNextEntry = rx_buf_0;
596  entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE;
597  entry->length = sizeof(rx_buf_0) - sizeof(*entry);
598 }
599 /*---------------------------------------------------------------------------*/
600 static void
601 init_rf_params(void)
602 {
603  rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
604 
605  memset(cmd_ieee_rx_buf, 0x00, RF_CMD_BUFFER_SIZE);
606 
607  cmd->commandNo = CMD_IEEE_RX;
608  cmd->status = RF_CORE_RADIO_OP_STATUS_IDLE;
609  cmd->pNextOp = NULL;
610  cmd->startTime = 0x00000000;
611  cmd->startTrigger.triggerType = TRIG_NOW;
612  cmd->condition.rule = COND_NEVER;
613  cmd->channel = IEEE802154_DEFAULT_CHANNEL;
614 
615  cmd->rxConfig.bAutoFlushCrc = 1;
616  cmd->rxConfig.bAutoFlushIgn = 0;
617  cmd->rxConfig.bIncludePhyHdr = 0;
618  cmd->rxConfig.bIncludeCrc = RX_BUF_INCLUDE_CRC;
619  cmd->rxConfig.bAppendRssi = RX_BUF_INCLUDE_RSSI;
620  cmd->rxConfig.bAppendCorrCrc = RX_BUF_INCLUDE_CORR;
621  cmd->rxConfig.bAppendSrcInd = 0;
622  cmd->rxConfig.bAppendTimestamp = RX_BUF_INCLUDE_TIMESTAMP;
623 
624  cmd->pRxQ = &rx_data_queue;
625  cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats;
626 
627 #if IEEE_MODE_PROMISCOUS
628  cmd->frameFiltOpt.frameFiltEn = 0;
629 #else
630  cmd->frameFiltOpt.frameFiltEn = 1;
631 #endif
632 
633  cmd->frameFiltOpt.frameFiltStop = 1;
634 
635 #if IEEE_MODE_AUTOACK
636  cmd->frameFiltOpt.autoAckEn = 1;
637 #else
638  cmd->frameFiltOpt.autoAckEn = 0;
639 #endif
640 
641  cmd->frameFiltOpt.slottedAckEn = 0;
642  cmd->frameFiltOpt.autoPendEn = 0;
643  cmd->frameFiltOpt.defaultPend = 0;
644  cmd->frameFiltOpt.bPendDataReqOnly = 0;
645  cmd->frameFiltOpt.bPanCoord = 0;
646  cmd->frameFiltOpt.maxFrameVersion = 2;
647  cmd->frameFiltOpt.bStrictLenFilter = 0;
648 
649  /* Receive all frame types */
650  cmd->frameTypes.bAcceptFt0Beacon = 1;
651  cmd->frameTypes.bAcceptFt1Data = 1;
652  cmd->frameTypes.bAcceptFt2Ack = 1;
653  cmd->frameTypes.bAcceptFt3MacCmd = 1;
654  cmd->frameTypes.bAcceptFt4Reserved = 1;
655  cmd->frameTypes.bAcceptFt5Reserved = 1;
656  cmd->frameTypes.bAcceptFt6Reserved = 1;
657  cmd->frameTypes.bAcceptFt7Reserved = 1;
658 
659  /* Configure CCA settings */
660  cmd->ccaOpt.ccaEnEnergy = 1;
661  cmd->ccaOpt.ccaEnCorr = 1;
662  cmd->ccaOpt.ccaEnSync = 1;
663  cmd->ccaOpt.ccaCorrOp = 1;
664  cmd->ccaOpt.ccaSyncOp = 0;
665  cmd->ccaOpt.ccaCorrThr = 3;
666 
667  cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD;
668 
669  cmd->numExtEntries = 0x00;
670  cmd->numShortEntries = 0x00;
671  cmd->pExtEntryList = 0;
672  cmd->pShortEntryList = 0;
673 
674  cmd->endTrigger.triggerType = TRIG_NEVER;
675  cmd->endTime = 0x00000000;
676 
677  /* set address filter command */
678  filter_cmd.commandNo = CMD_IEEE_MOD_FILT;
679  memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt, sizeof(cmd->frameFiltOpt));
680  memcpy(&filter_cmd.newFrameTypes, &cmd->frameTypes, sizeof(cmd->frameTypes));
681 }
682 /*---------------------------------------------------------------------------*/
683 static int
684 rx_on(void)
685 {
686  int ret;
687 
688  /* Get status of running IEEE_RX (if any) */
689  if(rf_is_on()) {
690  PRINTF("rx_on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(),
691  RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf));
692  return RF_CORE_CMD_OK;
693  }
694 
695  /* Put CPE in RX using the currently configured parameters */
696  ret = rf_cmd_ieee_rx();
697 
698  if(ret) {
699  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
700  }
701 
702  return ret;
703 }
704 /*---------------------------------------------------------------------------*/
705 static int
706 rx_off(void)
707 {
708  uint32_t cmd_status;
709  int ret;
710 
711  /* If we are off, do nothing */
712  if(!rf_is_on()) {
713  return RF_CORE_CMD_OK;
714  }
715 
716  /* Wait for ongoing ACK TX to finish */
717  LIMITED_BUSYWAIT(transmitting(), TX_FINISH_WAIT_TIMEOUT);
718 
719  /* Send a CMD_ABORT command to RF Core */
720  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
721  PRINTF("RX off: CMD_ABORT status=0x%08lx\n", cmd_status);
722  /* Continue nonetheless */
723  }
724 
725  LIMITED_BUSYWAIT(rf_is_on(), RF_TURN_OFF_WAIT_TIMEOUT);
726 
727  if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_STOPPED ||
728  RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_ABORT) {
729  /* Stopped gracefully */
730  ret = RF_CORE_CMD_OK;
731  } else {
732  PRINTF("RX off: BG status=0x%04x\n", RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf));
733  ret = RF_CORE_CMD_ERROR;
734  }
735 
736  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
737 
738  return ret;
739 }
740 /*---------------------------------------------------------------------------*/
741 static uint8_t
742 request(void)
743 {
744  /*
745  * We rely on the RDC layer to turn us on and off. Thus, if we are on we
746  * will only allow sleep, standby otherwise
747  */
748  if(rf_is_on()) {
749  return LPM_MODE_SLEEP;
750  }
751 
752  return LPM_MODE_MAX_SUPPORTED;
753 }
754 /*---------------------------------------------------------------------------*/
755 LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
756 /*---------------------------------------------------------------------------*/
757 static void
758 soft_off(void)
759 {
760  uint32_t cmd_status;
761  volatile rfc_radioOp_t *cmd = rf_core_get_last_radio_op();
762 
763  if(!rf_core_is_accessible()) {
764  return;
765  }
766 
767  PRINTF("soft_off: Aborting 0x%04x, Status=0x%04x\n", cmd->commandNo,
768  cmd->status);
769 
770  /* Send a CMD_ABORT command to RF Core */
771  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
772  PRINTF("soft_off: CMD_ABORT status=0x%08lx\n", cmd_status);
773  return;
774  }
775 
776  LIMITED_BUSYWAIT((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) ==
777  RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING, RF_TURN_OFF_WAIT_TIMEOUT);
778 }
779 /*---------------------------------------------------------------------------*/
780 static uint8_t
781 soft_on(void)
782 {
783  if(rf_radio_setup() != RF_CORE_CMD_OK) {
784  PRINTF("on: radio_setup() failed\n");
785  return RF_CORE_CMD_ERROR;
786  }
787 
788  return rx_on();
789 }
790 /*---------------------------------------------------------------------------*/
791 static const rf_core_primary_mode_t mode_ieee = {
792  soft_off,
793  soft_on,
794 };
795 /*---------------------------------------------------------------------------*/
796 static uint8_t
797 check_rat_overflow(bool first_time)
798 {
799  static uint32_t last_value;
800  uint32_t current_value;
801  uint8_t interrupts_disabled;
802 
803  /* Bail out if the RF is not on */
804  if(!rf_is_on()) {
805  return 0;
806  }
807 
808  interrupts_disabled = ti_lib_int_master_disable();
809  if(first_time) {
810  last_value = HWREG(RFC_RAT_BASE + RATCNT);
811  } else {
812  current_value = HWREG(RFC_RAT_BASE + RATCNT);
813  if(current_value + RAT_RANGE / 4 < last_value) {
814  /* Overflow detected */
815  last_rat_overflow = RTIMER_NOW();
816  rat_overflow_counter++;
817  }
818  last_value = current_value;
819  }
820  if(!interrupts_disabled) {
821  ti_lib_int_master_enable();
822  }
823  return 1;
824 }
825 /*---------------------------------------------------------------------------*/
826 static void
827 handle_rat_overflow(void *unused)
828 {
829  uint8_t success;
830  uint8_t was_off = 0;
831 
832  if(!rf_is_on()) {
833  was_off = 1;
834  if(on() != RF_CORE_CMD_OK) {
835  PRINTF("overflow: on() failed\n");
836  ctimer_set(&rat_overflow_timer, CLOCK_SECOND,
837  handle_rat_overflow, NULL);
838  return;
839  }
840  }
841 
842  success = check_rat_overflow(false);
843 
844  if(was_off) {
845  off();
846  }
847 
848  if(success) {
849  /* Retry after half of the interval */
850  ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2,
851  handle_rat_overflow, NULL);
852  } else {
853  /* Retry sooner */
854  ctimer_set(&rat_overflow_timer, CLOCK_SECOND,
855  handle_rat_overflow, NULL);
856  }
857 }
858 /*---------------------------------------------------------------------------*/
859 static int
860 init(void)
861 {
862  lpm_register_module(&cc26xx_rf_lpm_module);
863 
865 
866  /* Initialise RX buffers */
867  memset(rx_buf_0, 0, RX_BUF_SIZE);
868  memset(rx_buf_1, 0, RX_BUF_SIZE);
869  memset(rx_buf_2, 0, RX_BUF_SIZE);
870  memset(rx_buf_3, 0, RX_BUF_SIZE);
871 
872  /* Set of RF Core data queue. Circular buffer, no last entry */
873  rx_data_queue.pCurrEntry = rx_buf_0;
874 
875  rx_data_queue.pLastEntry = NULL;
876 
877  /* Initialize current read pointer to first element (used in ISR) */
878  rx_read_entry = rx_buf_0;
879 
880  /* Populate the RF parameters data structure with default values */
881  init_rf_params();
882 
883  if(on() != RF_CORE_CMD_OK) {
884  PRINTF("init: on() failed\n");
885  return RF_CORE_CMD_ERROR;
886  }
887 
888  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
889 
890  rf_core_primary_mode_register(&mode_ieee);
891 
892  check_rat_overflow(true);
893  ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_PERIOD_SECONDS * CLOCK_SECOND / 2,
894  handle_rat_overflow, NULL);
895 
896  process_start(&rf_core_process, NULL);
897  return 1;
898 }
899 /*---------------------------------------------------------------------------*/
900 static int
901 prepare(const void *payload, unsigned short payload_len)
902 {
903  int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN);
904 
905  memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len);
906  return 0;
907 }
908 /*---------------------------------------------------------------------------*/
909 static int
910 transmit(unsigned short transmit_len)
911 {
912  int ret;
913  uint8_t was_off = 0;
914  uint32_t cmd_status;
915  uint16_t stat;
916  uint8_t tx_active = 0;
917  rtimer_clock_t t0;
918  volatile rfc_CMD_IEEE_TX_t cmd;
919 
920  if(!rf_is_on()) {
921  was_off = 1;
922  if(on() != RF_CORE_CMD_OK) {
923  PRINTF("transmit: on() failed\n");
924  return RADIO_TX_ERR;
925  }
926  }
927 
928  /*
929  * We are certainly not TXing a frame as a result of CMD_IEEE_TX, but we may
930  * be in the process of TXing an ACK. In that case, wait for the TX to finish
931  * or return after approx TX_WAIT_TIMEOUT
932  */
933  t0 = RTIMER_NOW();
934 
935  do {
936  tx_active = transmitting();
937  } while(tx_active == 1 &&
938  (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + TX_WAIT_TIMEOUT)));
939 
940  if(tx_active) {
941  PRINTF("transmit: Already TXing and wait timed out\n");
942 
943  if(was_off) {
944  off();
945  }
946 
947  return RADIO_TX_COLLISION;
948  }
949 
950  /* Send the CMD_IEEE_TX command */
951  rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_IEEE_TX);
952 
953  cmd.payloadLen = transmit_len;
954  cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN];
955 
956  cmd.startTime = 0;
957  cmd.startTrigger.triggerType = TRIG_NOW;
958 
959  /* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */
960  rf_core_cmd_done_en(true, poll_mode);
961 
962  ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status);
963 
964  if(ret) {
965  /* If we enter here, TX actually started */
966  ENERGEST_SWITCH(ENERGEST_TYPE_LISTEN, ENERGEST_TYPE_TRANSMIT);
967 
968  /* Idle away while the command is running */
969  while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS)
970  == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
971  /* Note: for now sleeping while Tx'ing in polling mode is disabled.
972  * To enable it:
973  * 1) make the `lpm_sleep()` call here unconditional;
974  * 2) change the radio ISR priority to allow radio ISR to interrupt rtimer ISR.
975  */
976  if(!poll_mode) {
977  lpm_sleep();
978  }
979  }
980 
981  stat = cmd.status;
982 
983  if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) {
984  /* Sent OK */
985  ret = RADIO_TX_OK;
986  } else {
987  /* Operation completed, but frame was not sent */
988  PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret,
989  cmd_status, stat);
990  ret = RADIO_TX_ERR;
991  }
992  } else {
993  /* Failure sending the CMD_IEEE_TX command */
994  PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
995  ret, cmd_status, cmd.status);
996 
997  ret = RADIO_TX_ERR;
998  }
999 
1000  /*
1001  * Update ENERGEST state here, before a potential call to off(), which
1002  * will correctly update it if required.
1003  */
1004  ENERGEST_SWITCH(ENERGEST_TYPE_TRANSMIT, ENERGEST_TYPE_LISTEN);
1005 
1006  /*
1007  * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it
1008  * except when we are transmitting
1009  */
1010  rf_core_cmd_done_dis(poll_mode);
1011 
1012  if(was_off) {
1013  off();
1014  }
1015 
1016  return ret;
1017 }
1018 /*---------------------------------------------------------------------------*/
1019 static int
1020 send(const void *payload, unsigned short payload_len)
1021 {
1022  prepare(payload, payload_len);
1023  return transmit(payload_len);
1024 }
1025 /*---------------------------------------------------------------------------*/
1026 static void
1027 release_data_entry(void)
1028 {
1029  rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
1030 
1031  /* Clear the length byte */
1032  rx_read_entry[8] = 0;
1033 
1034  /* Set status to 0 "Pending" in element */
1035  entry->status = DATA_ENTRY_STATUS_PENDING;
1036  rx_read_entry = entry->pNextEntry;
1037 }
1038 /*---------------------------------------------------------------------------*/
1039 static uint32_t
1040 calc_last_packet_timestamp(uint32_t rat_timestamp)
1041 {
1042  uint64_t rat_timestamp64;
1043  uint32_t adjusted_overflow_counter;
1044  uint8_t was_off = 0;
1045 
1046  if(!rf_is_on()) {
1047  was_off = 1;
1048  on();
1049  }
1050 
1051  if(rf_is_on()) {
1052  check_rat_overflow(false);
1053  if(was_off) {
1054  off();
1055  }
1056  }
1057 
1058  adjusted_overflow_counter = rat_overflow_counter;
1059 
1060  /* if the timestamp is large and the last oveflow was recently,
1061  assume that the timestamp refers to the time before the overflow */
1062  if(rat_timestamp > (uint32_t)(RAT_RANGE * 3 / 4)) {
1063  if(RTIMER_CLOCK_LT(RTIMER_NOW(),
1064  last_rat_overflow + RAT_OVERFLOW_PERIOD_SECONDS * RTIMER_SECOND / 4)) {
1065  adjusted_overflow_counter--;
1066  }
1067  }
1068 
1069  /* add the overflowed time to the timestamp */
1070  rat_timestamp64 = rat_timestamp + RAT_RANGE * adjusted_overflow_counter;
1071  /* correct timestamp so that it refers to the end of the SFD */
1072  rat_timestamp64 += TIMESTAMP_OFFSET;
1073 
1074  last_rat_timestamp64 = rat_timestamp64 - rat_offset;
1075 
1076  return RADIO_TO_RTIMER(rat_timestamp64 - rat_offset);
1077 }
1078 /*---------------------------------------------------------------------------*/
1079 static int
1080 read_frame(void *buf, unsigned short buf_len)
1081 {
1082  int len = 0;
1083  rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
1084  uint32_t rat_timestamp;
1085 
1086  /* wait for entry to become finished */
1087  rtimer_clock_t t0 = RTIMER_NOW();
1088  while(entry->status == DATA_ENTRY_STATUS_BUSY
1089  && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (RTIMER_SECOND / 250)));
1090 
1091  if(entry->status != DATA_ENTRY_STATUS_FINISHED) {
1092  /* No available data */
1093  return 0;
1094  }
1095 
1096  len = rx_read_entry[RX_BUF_LENGTH_OFFSET];
1097  if(len <= RX_BUF_METADATA_SIZE) {
1098  PRINTF("RF: too short!");
1099 
1100  release_data_entry();
1101  return 0;
1102  }
1103 
1104  len -= RX_BUF_METADATA_SIZE;
1105  if(len > buf_len) {
1106  PRINTF("RF: too long\n");
1107 
1108  release_data_entry();
1109  return 0;
1110  }
1111 
1112  memcpy(buf, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET, len);
1113 
1114  last_rssi = (int8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 2];
1115  last_corr_lqi = (uint8_t)rx_read_entry[RX_BUF_DATA_OFFSET + len + 3] & STATUS_CORRELATION;
1116 
1117  /* get the timestamp */
1118  memcpy(&rat_timestamp, (uint8_t *)rx_read_entry + RX_BUF_DATA_OFFSET + len + 4, 4);
1119 
1120  last_packet_timestamp = calc_last_packet_timestamp(rat_timestamp);
1121 
1122  if(!poll_mode) {
1123  /* Not in poll mode: packetbuf should not be accessed in interrupt context.
1124  * In poll mode, the last packet RSSI and link quality can be obtained through
1125  * RADIO_PARAM_LAST_RSSI and RADIO_PARAM_LAST_LINK_QUALITY */
1126  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, last_rssi);
1127  packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, last_corr_lqi);
1128  }
1129 
1130  release_data_entry();
1131 
1132  return len;
1133 }
1134 /*---------------------------------------------------------------------------*/
1135 static int
1136 channel_clear(void)
1137 {
1138  uint8_t was_off = 0;
1139  uint8_t cca_info;
1140  int ret = RF_CCA_CLEAR;
1141 
1142  /*
1143  * If we are in the middle of a BLE operation, we got called by ContikiMAC
1144  * from within an interrupt context. Indicate a clear channel
1145  */
1146  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
1147  PRINTF("channel_clear: Interrupt context but BLE in progress\n");
1148  return RF_CCA_CLEAR;
1149  }
1150 
1151  if(rf_is_on()) {
1152  /*
1153  * Wait for potential leftover ACK still being sent.
1154  * Strictly speaking, if we are TXing an ACK then the channel is not clear.
1155  * However, channel_clear is only ever called to determine whether there is
1156  * someone else's packet in the air, not ours.
1157  *
1158  * We could probably even simply return that the channel is clear
1159  */
1160  LIMITED_BUSYWAIT(transmitting(), TX_FINISH_WAIT_TIMEOUT);
1161  } else {
1162  was_off = 1;
1163  if(on() != RF_CORE_CMD_OK) {
1164  PRINTF("channel_clear: on() failed\n");
1165  if(was_off) {
1166  off();
1167  }
1168  return RF_CCA_CLEAR;
1169  }
1170  }
1171 
1172  cca_info = get_cca_info();
1173 
1174  if(cca_info == RF_GET_CCA_INFO_ERROR) {
1175  PRINTF("channel_clear: CCA error\n");
1176  ret = RF_CCA_CLEAR;
1177  } else {
1178  /*
1179  * cca_info bits 1:0 - ccaStatus
1180  * Return 1 (clear) if idle or invalid.
1181  */
1182  ret = (cca_info & 0x03) != RF_CMD_CCA_REQ_CCA_STATE_BUSY;
1183  }
1184 
1185  if(was_off) {
1186  off();
1187  }
1188 
1189  return ret;
1190 }
1191 /*---------------------------------------------------------------------------*/
1192 static int
1193 receiving_packet(void)
1194 {
1195  uint8_t cca_info;
1196 
1197  /*
1198  * If we are in the middle of a BLE operation, we got called by ContikiMAC
1199  * from within an interrupt context. We are not receiving
1200  */
1201  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
1202  PRINTF("receiving_packet: Interrupt context but BLE in progress\n");
1203  return 0;
1204  }
1205 
1206  /* If we are off, we are not receiving */
1207  if(!rf_is_on()) {
1208  PRINTF("receiving_packet: We were off\n");
1209  return 0;
1210  }
1211 
1212  /* If we are transmitting (can only be an ACK here), we are not receiving */
1213  if(transmitting()) {
1214  PRINTF("receiving_packet: We were TXing\n");
1215  return 0;
1216  }
1217 
1218  cca_info = get_cca_info();
1219 
1220  /* If we can't read CCA info, return "not receiving" */
1221  if(cca_info == RF_GET_CCA_INFO_ERROR) {
1222  return 0;
1223  }
1224 
1225  /* If sync has been seen, return 1 (receiving) */
1226  if(cca_info & RF_CMD_CCA_REQ_CCA_SYNC_BUSY) {
1227  return 1;
1228  }
1229 
1230  return 0;
1231 }
1232 /*---------------------------------------------------------------------------*/
1233 static int
1234 pending_packet(void)
1235 {
1236  volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
1237  int rv = 0;
1238 
1239  /* Go through all RX buffers and check their status */
1240  do {
1241  if(entry->status == DATA_ENTRY_STATUS_FINISHED
1242  || entry->status == DATA_ENTRY_STATUS_BUSY) {
1243  rv = 1;
1244  if(!poll_mode) {
1245  process_poll(&rf_core_process);
1246  }
1247  }
1248 
1249  entry = (rfc_dataEntry_t *)entry->pNextEntry;
1250  } while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
1251 
1252  /* If we didn't find an entry at status finished, no frames are pending */
1253  return rv;
1254 }
1255 /*---------------------------------------------------------------------------*/
1256 static int
1257 on(void)
1258 {
1259  /*
1260  * If we are in the middle of a BLE operation, we got called by ContikiMAC
1261  * from within an interrupt context. Abort, but pretend everything is OK.
1262  */
1263  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
1264  PRINTF("on: Interrupt context but BLE in progress\n");
1265  return RF_CORE_CMD_OK;
1266  }
1267 
1268  /*
1269  * Request the HF XOSC as the source for the HF clock. Needed before we can
1270  * use the FS. This will only request, it will _not_ perform the switch.
1271  */
1273 
1274  if(rf_is_on()) {
1275  PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(),
1276  RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf));
1277  return RF_CORE_CMD_OK;
1278  }
1279 
1280  init_rx_buffers();
1281 
1282  /*
1283  * Trigger a switch to the XOSC, so that we can subsequently use the RF FS
1284  * This will block until the XOSC is actually ready, but give how we
1285  * requested it early on, this won't be too long a wait.
1286  * This should be done before starting the RAT.
1287  */
1289 
1290  if(rf_core_boot() != RF_CORE_CMD_OK) {
1291  PRINTF("on: rf_core_boot() failed\n");
1292  return RF_CORE_CMD_ERROR;
1293  }
1294 
1295  rf_core_setup_interrupts(poll_mode);
1296 
1297  if(rf_radio_setup() != RF_CORE_CMD_OK) {
1298  PRINTF("on: radio_setup() failed\n");
1299  return RF_CORE_CMD_ERROR;
1300  }
1301 
1302  return rx_on();
1303 }
1304 /*---------------------------------------------------------------------------*/
1305 static int
1306 off(void)
1307 {
1308  /*
1309  * If we are in the middle of a BLE operation, we got called by ContikiMAC
1310  * from within an interrupt context. Abort, but pretend everything is OK.
1311  */
1312  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
1313  PRINTF("off: Interrupt context but BLE in progress\n");
1314  return RF_CORE_CMD_OK;
1315  }
1316 
1317  LIMITED_BUSYWAIT(transmitting(), TX_FINISH_WAIT_TIMEOUT);
1318 
1319  /* stopping the rx explicitly results in lower sleep-mode power usage */
1320  rx_off();
1322 
1323  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
1324 
1325 #if !CC2650_FAST_RADIO_STARTUP
1326  /* Switch HF clock source to the RCOSC to preserve power.
1327  * This must be done after stopping RAT.
1328  */
1330 #endif
1331 
1332  /* We pulled the plug, so we need to restore the status manually */
1333  ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
1334 
1335  /*
1336  * Just in case there was an ongoing RX (which started after we begun the
1337  * shutdown sequence), we don't want to leave the buffer in state == ongoing
1338  */
1339  if(((rfc_dataEntry_t *)rx_buf_0)->status == DATA_ENTRY_STATUS_BUSY) {
1340  ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING;
1341  }
1342  if(((rfc_dataEntry_t *)rx_buf_1)->status == DATA_ENTRY_STATUS_BUSY) {
1343  ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING;
1344  }
1345  if(((rfc_dataEntry_t *)rx_buf_2)->status == DATA_ENTRY_STATUS_BUSY) {
1346  ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING;
1347  }
1348  if(((rfc_dataEntry_t *)rx_buf_3)->status == DATA_ENTRY_STATUS_BUSY) {
1349  ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING;
1350  }
1351 
1352  return RF_CORE_CMD_OK;
1353 }
1354 /*---------------------------------------------------------------------------*/
1355 /* Enable or disable CCA before sending */
1356 static radio_result_t
1357 set_send_on_cca(uint8_t enable)
1358 {
1359  if(enable) {
1360  /* this driver does not have support for CCA on Tx */
1361  return RADIO_RESULT_NOT_SUPPORTED;
1362  }
1363  return RADIO_RESULT_OK;
1364 }
1365 /*---------------------------------------------------------------------------*/
1366 static radio_result_t
1367 get_value(radio_param_t param, radio_value_t *value)
1368 {
1369  rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1370 
1371  if(!value) {
1372  return RADIO_RESULT_INVALID_VALUE;
1373  }
1374 
1375  switch(param) {
1376  case RADIO_PARAM_POWER_MODE:
1377  /* On / off */
1378  *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1379  return RADIO_RESULT_OK;
1380  case RADIO_PARAM_CHANNEL:
1381  *value = (radio_value_t)cmd->channel;
1382  return RADIO_RESULT_OK;
1383  case RADIO_PARAM_PAN_ID:
1384  *value = (radio_value_t)cmd->localPanID;
1385  return RADIO_RESULT_OK;
1386  case RADIO_PARAM_16BIT_ADDR:
1387  *value = (radio_value_t)cmd->localShortAddr;
1388  return RADIO_RESULT_OK;
1389  case RADIO_PARAM_RX_MODE:
1390  *value = 0;
1391  if(cmd->frameFiltOpt.frameFiltEn) {
1392  *value |= RADIO_RX_MODE_ADDRESS_FILTER;
1393  }
1394  if(cmd->frameFiltOpt.autoAckEn) {
1395  *value |= RADIO_RX_MODE_AUTOACK;
1396  }
1397  if(poll_mode) {
1398  *value |= RADIO_RX_MODE_POLL_MODE;
1399  }
1400 
1401  return RADIO_RESULT_OK;
1402  case RADIO_PARAM_TX_MODE:
1403  *value = 0;
1404  return RADIO_RESULT_OK;
1405  case RADIO_PARAM_TXPOWER:
1406  *value = get_tx_power();
1407  return RADIO_RESULT_OK;
1408  case RADIO_PARAM_CCA_THRESHOLD:
1409  *value = cmd->ccaRssiThr;
1410  return RADIO_RESULT_OK;
1411  case RADIO_PARAM_RSSI:
1412  *value = get_rssi();
1413 
1414  if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) {
1415  return RADIO_RESULT_ERROR;
1416  } else {
1417  return RADIO_RESULT_OK;
1418  }
1419  case RADIO_CONST_CHANNEL_MIN:
1420  *value = IEEE_MODE_CHANNEL_MIN;
1421  return RADIO_RESULT_OK;
1422  case RADIO_CONST_CHANNEL_MAX:
1423  *value = IEEE_MODE_CHANNEL_MAX;
1424  return RADIO_RESULT_OK;
1425  case RADIO_CONST_TXPOWER_MIN:
1426  *value = OUTPUT_POWER_MIN;
1427  return RADIO_RESULT_OK;
1428  case RADIO_CONST_TXPOWER_MAX:
1429  *value = OUTPUT_POWER_MAX;
1430  return RADIO_RESULT_OK;
1431  case RADIO_PARAM_LAST_RSSI:
1432  *value = last_rssi;
1433  return RADIO_RESULT_OK;
1434  case RADIO_PARAM_LAST_LINK_QUALITY:
1435  *value = last_corr_lqi;
1436  return RADIO_RESULT_OK;
1437  default:
1438  return RADIO_RESULT_NOT_SUPPORTED;
1439  }
1440 }
1441 /*---------------------------------------------------------------------------*/
1442 static radio_result_t
1443 set_value(radio_param_t param, radio_value_t value)
1444 {
1445  radio_result_t rv = RADIO_RESULT_OK;
1446  rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1447  uint8_t old_poll_mode;
1448 
1449  switch(param) {
1450  case RADIO_PARAM_POWER_MODE:
1451  if(value == RADIO_POWER_MODE_ON) {
1452  if(on() != RF_CORE_CMD_OK) {
1453  PRINTF("set_value: on() failed (1)\n");
1454  return RADIO_RESULT_ERROR;
1455  }
1456  return RADIO_RESULT_OK;
1457  }
1458  if(value == RADIO_POWER_MODE_OFF) {
1459  off();
1460  return RADIO_RESULT_OK;
1461  }
1462  return RADIO_RESULT_INVALID_VALUE;
1463  case RADIO_PARAM_CHANNEL:
1464  if(value < IEEE_MODE_CHANNEL_MIN ||
1465  value > IEEE_MODE_CHANNEL_MAX) {
1466  return RADIO_RESULT_INVALID_VALUE;
1467  }
1468 
1469  /* Note: this return may lead to long periods when RAT and RTC are not resynchronized */
1470  if(cmd->channel == (uint8_t)value) {
1471  /* We already have that very same channel configured.
1472  * Nothing to do here. */
1473  return RADIO_RESULT_OK;
1474  }
1475 
1476  cmd->channel = (uint8_t)value;
1477  break;
1478  case RADIO_PARAM_PAN_ID:
1479  cmd->localPanID = (uint16_t)value;
1480  break;
1481  case RADIO_PARAM_16BIT_ADDR:
1482  cmd->localShortAddr = (uint16_t)value;
1483  break;
1484  case RADIO_PARAM_RX_MODE:
1485  {
1486  if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER |
1487  RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_POLL_MODE)) {
1488  return RADIO_RESULT_INVALID_VALUE;
1489  }
1490 
1491  cmd->frameFiltOpt.frameFiltEn = (value & RADIO_RX_MODE_ADDRESS_FILTER) != 0;
1492  cmd->frameFiltOpt.frameFiltStop = 1;
1493  cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0;
1494  cmd->frameFiltOpt.slottedAckEn = 0;
1495  cmd->frameFiltOpt.autoPendEn = 0;
1496  cmd->frameFiltOpt.defaultPend = 0;
1497  cmd->frameFiltOpt.bPendDataReqOnly = 0;
1498  cmd->frameFiltOpt.bPanCoord = 0;
1499  cmd->frameFiltOpt.bStrictLenFilter = 0;
1500 
1501  old_poll_mode = poll_mode;
1502  poll_mode = (value & RADIO_RX_MODE_POLL_MODE) != 0;
1503  if(poll_mode == old_poll_mode) {
1504  uint32_t cmd_status;
1505 
1506  /* do not turn the radio on and off, just send an update command */
1507  memcpy(&filter_cmd.newFrameFiltOpt, &cmd->frameFiltOpt, sizeof(cmd->frameFiltOpt));
1508 
1509  if(rf_core_send_cmd((uint32_t)&filter_cmd, &cmd_status) == RF_CORE_CMD_ERROR) {
1510  PRINTF("setting address filter failed: CMDSTA=0x%08lx\n", cmd_status);
1511  return RADIO_RESULT_ERROR;
1512  }
1513  return RADIO_RESULT_OK;
1514  }
1515  break;
1516  }
1517 
1518  case RADIO_PARAM_TX_MODE:
1519  if(value & ~(RADIO_TX_MODE_SEND_ON_CCA)) {
1520  return RADIO_RESULT_INVALID_VALUE;
1521  }
1522  return set_send_on_cca((value & RADIO_TX_MODE_SEND_ON_CCA) != 0);
1523 
1524  case RADIO_PARAM_TXPOWER:
1525  if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1526  return RADIO_RESULT_INVALID_VALUE;
1527  }
1528 
1529  set_tx_power(value);
1530 
1531  return RADIO_RESULT_OK;
1532 
1533  case RADIO_PARAM_CCA_THRESHOLD:
1534  cmd->ccaRssiThr = (int8_t)value;
1535  break;
1536 
1537  default:
1538  return RADIO_RESULT_NOT_SUPPORTED;
1539  }
1540 
1541  /* If off, the new configuration will be applied the next time radio is started */
1542  if(!rf_is_on()) {
1543  return RADIO_RESULT_OK;
1544  }
1545 
1546  /* If we reach here we had no errors. Apply new settings */
1547  if(rx_off() != RF_CORE_CMD_OK) {
1548  PRINTF("set_value: rx_off() failed\n");
1549  rv = RADIO_RESULT_ERROR;
1550  }
1551 
1552  /* Restart the radio timer (RAT).
1553  This causes resynchronization between RAT and RTC: useful for TSCH. */
1554  if(rf_core_restart_rat() == RF_CORE_CMD_OK) {
1555  check_rat_overflow(false);
1556  }
1557 
1558  if(rx_on() != RF_CORE_CMD_OK) {
1559  PRINTF("set_value: rx_on() failed\n");
1560  rv = RADIO_RESULT_ERROR;
1561  }
1562 
1563  return rv;
1564 }
1565 /*---------------------------------------------------------------------------*/
1566 static radio_result_t
1567 get_object(radio_param_t param, void *dest, size_t size)
1568 {
1569  uint8_t *target;
1570  uint8_t *src;
1571  int i;
1572  rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1573 
1574  if(param == RADIO_PARAM_64BIT_ADDR) {
1575  if(size != 8 || !dest) {
1576  return RADIO_RESULT_INVALID_VALUE;
1577  }
1578 
1579  target = dest;
1580  src = (uint8_t *)(&cmd->localExtAddr);
1581 
1582  for(i = 0; i < 8; i++) {
1583  target[i] = src[7 - i];
1584  }
1585 
1586  return RADIO_RESULT_OK;
1587  }
1588 
1589  if(param == RADIO_PARAM_LAST_PACKET_TIMESTAMP) {
1590  if(size != sizeof(rtimer_clock_t) || !dest) {
1591  return RADIO_RESULT_INVALID_VALUE;
1592  }
1593  *(rtimer_clock_t *)dest = last_packet_timestamp;
1594 
1595  return RADIO_RESULT_OK;
1596  }
1597 
1598  return RADIO_RESULT_NOT_SUPPORTED;
1599 }
1600 /*---------------------------------------------------------------------------*/
1601 static radio_result_t
1602 set_object(radio_param_t param, const void *src, size_t size)
1603 {
1604  radio_result_t rv = RADIO_RESULT_OK;
1605  int i;
1606  uint8_t *dst;
1607  rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf;
1608 
1609  if(param == RADIO_PARAM_64BIT_ADDR) {
1610  if(size != 8 || !src) {
1611  return RADIO_RESULT_INVALID_VALUE;
1612  }
1613 
1614  dst = (uint8_t *)(&cmd->localExtAddr);
1615 
1616  for(i = 0; i < 8; i++) {
1617  dst[i] = ((uint8_t *)src)[7 - i];
1618  }
1619 
1620  /* If off, the new configuration will be applied the next time radio is started */
1621  if(!rf_is_on()) {
1622  return RADIO_RESULT_OK;
1623  }
1624 
1625  if(rx_off() != RF_CORE_CMD_OK) {
1626  PRINTF("set_object: rx_off() failed\n");
1627  rv = RADIO_RESULT_ERROR;
1628  }
1629 
1630  if(rx_on() != RF_CORE_CMD_OK) {
1631  PRINTF("set_object: rx_on() failed\n");
1632  rv = RADIO_RESULT_ERROR;
1633  }
1634 
1635  return rv;
1636  }
1637  return RADIO_RESULT_NOT_SUPPORTED;
1638 }
1639 /*---------------------------------------------------------------------------*/
1640 const struct radio_driver ieee_mode_driver = {
1641  init,
1642  prepare,
1643  transmit,
1644  send,
1645  read_frame,
1646  channel_clear,
1649  on,
1650  off,
1651  get_value,
1652  set_value,
1653  get_object,
1654  set_object,
1655 };
1656 /*---------------------------------------------------------------------------*/
1657 /**
1658  * @}
1659  * @}
1660  */
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:280
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch...
Definition: oscillators.c:94
static uint8_t transmitting(void)
Check the RF&#39;s TX status.
Definition: ieee-mode.c:342
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:242
static uint8_t rf_cmd_ieee_rx()
Set up radio in IEEE802.15.4 RX mode.
Definition: ieee-mode.c:548
void rf_core_setup_interrupts(bool poll_mode)
Setup RF core interrupts.
Definition: rf-core.c:449
Header file with macros which rename TI CC26xxware functions.
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:324
Header file for the energy estimation mechanism
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
Definition: rf-core.c:500
Header file for the radio API
Header file for the link-layer address representation
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
Definition: rf-core.c:347
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
Definition: radio.h:258
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
Definition: radio.h:273
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
Definition: radio.h:261
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
Definition: rf-core.c:385
The structure of a device driver for a radio in Contiki.
Definition: radio.h:237
void lpm_sleep(void)
Enter sleep mode.
Definition: lpm.c:374
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:255
Header file for the CC13xx/CC26xx RF core driver.
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
#define IEEE802154_DEFAULT_CHANNEL
The default channel for IEEE 802.15.4 networks.
Definition: mac.h:52
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:158
Header file for the CC13xx/CC26xx oscillator control.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
Definition: oscillators.c:134
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
Definition: rf-ble.c:262
Header file for the callback timer
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
Definition: rf-core.c:515
void rf_core_cmd_done_dis(bool poll_mode)
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
Definition: rf-core.c:493
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
Definition: radio.h:248
A data strcuture representing the radio&#39;s primary mode of operation.
Definition: rf-core.h:125
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
Definition: radio.h:245
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:267
Header file for the real-time timer module.
static radio_value_t get_rssi(void)
Reads the current signal strength (RSSI)
Definition: ieee-mode.c:417
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
void rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
Prepare a buffer to host a Radio Op.
Definition: rf-core.c:506
#define RADIO_RX_MODE_ADDRESS_FILTER
The radio reception mode controls address filtering and automatic transmission of acknowledgements in...
Definition: radio.h:204
Header file for the CC13xx/CC26xx BLE driver.
Header file with definitions related to RF switch support.
#define RADIO_TX_MODE_SEND_ON_CCA
The radio transmission mode controls whether transmissions should be done using clear channel assessm...
Definition: radio.h:216
static uint8_t get_cca_info(void)
Returns CCA information.
Definition: ieee-mode.c:381
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
Definition: rf-core.c:120
Header file for the CC13xx/CC26xx UART driver.
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
Definition: oscillators.c:116
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Definition: rf-core.c:129
void rf_core_cmd_done_en(bool fg, bool poll_mode)
Enable interrupt on command done.
Definition: rf-core.c:483
Header file for the Packet buffer (packetbuf) management
#define LPM_MODULE(n, m, s, w, l)
Declare a variable to be used in order to get notifications from LPM.
Definition: lpm.h:92
Include file for the Contiki low-layer network stack (NETSTACK)
uint8_t rf_core_restart_rat(void)
Restart the CM0 RAT.
Definition: rf-core.c:430
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:270
Default definitions of C compiler quirk work-arounds.
uint8_t rf_core_boot()
Boot the RF Core.
Definition: rf-core.c:408
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Definition: radio.h:286
int(* on)(void)
Turn the radio on.
Definition: radio.h:264
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
Definition: lpm.c:537
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
Definition: rf-core.c:195
#define RF_RADIO_OP_GET_STATUS(a)
Returns the current status of a running Radio Op command.
Definition: ieee-mode.c:131