Contiki 3.x
prop-mode.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, 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-prop CC13xx Prop mode driver
36  *
37  * @{
38  *
39  * \file
40  * Implementation of the CC13xx prop 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 "dev/watchdog.h"
48 #include "net/packetbuf.h"
49 #include "net/rime/rimestats.h"
50 #include "net/linkaddr.h"
51 #include "net/netstack.h"
52 #include "sys/energest.h"
53 #include "sys/clock.h"
54 #include "sys/rtimer.h"
55 #include "sys/cc.h"
56 #include "lpm.h"
57 #include "ti-lib.h"
58 #include "rf-core/rf-core.h"
59 #include "rf-core/rf-ble.h"
60 #include "rf-core/dot-15-4g.h"
61 /*---------------------------------------------------------------------------*/
62 /* RF core and RF HAL API */
63 #include "hw_rfc_dbell.h"
64 #include "hw_rfc_pwr.h"
65 /*---------------------------------------------------------------------------*/
66 /* RF Core Mailbox API */
67 #include "rf-core/api/mailbox.h"
68 #include "rf-core/api/common_cmd.h"
69 #include "rf-core/api/data_entry.h"
70 #include "rf-core/api/prop_mailbox.h"
71 #include "rf-core/api/prop_cmd.h"
72 /*---------------------------------------------------------------------------*/
73 /* CC13xxware patches */
74 #include "rf_patches/rf_patch_cpe_genfsk.h"
75 /*---------------------------------------------------------------------------*/
76 #include "rf-core/smartrf-settings.h"
77 /*---------------------------------------------------------------------------*/
78 #include <stdint.h>
79 #include <string.h>
80 #include <stdio.h>
81 #include <stdbool.h>
82 /*---------------------------------------------------------------------------*/
83 #define DEBUG 0
84 #if DEBUG
85 #define PRINTF(...) printf(__VA_ARGS__)
86 #else
87 #define PRINTF(...)
88 #endif
89 /*---------------------------------------------------------------------------*/
90 /* Data entry status field constants */
91 #define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */
92 #define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */
93 #define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */
94 #define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */
95 #define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */
96 /*---------------------------------------------------------------------------*/
97 /* Data whitener. 1: Whitener, 0: No whitener */
98 #ifdef PROP_MODE_CONF_DW
99 #define PROP_MODE_DW PROP_MODE_CONF_DW
100 #else
101 #define PROP_MODE_DW 0
102 #endif
103 
104 #ifdef PROP_MODE_CONF_USE_CRC16
105 #define PROP_MODE_USE_CRC16 PROP_MODE_CONF_USE_CRC16
106 #else
107 #define PROP_MODE_USE_CRC16 0
108 #endif
109 /*---------------------------------------------------------------------------*/
110 #ifdef PROP_MODE_CONF_SNIFFER
111 #define PROP_MODE_SNIFFER PROP_MODE_CONF_SNIFFER
112 #else
113 #define PROP_MODE_SNIFFER 0
114 #endif
115 
116 #if PROP_MODE_SNIFFER
117 static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 };
118 #endif
119 /*---------------------------------------------------------------------------*/
120 /**
121  * \brief Returns the current status of a running Radio Op command
122  * \param a A pointer with the buffer used to initiate the command
123  * \return The value of the Radio Op buffer's status field
124  *
125  * This macro can be used to e.g. return the status of a previously
126  * initiated background operation, or of an immediate command
127  */
128 #define RF_RADIO_OP_GET_STATUS(a) GET_FIELD_V(a, radioOp, status)
129 /*---------------------------------------------------------------------------*/
130 /* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */
131 #define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128
132 
133 /* Used for the return value of channel_clear */
134 #define RF_CCA_CLEAR 1
135 #define RF_CCA_BUSY 0
136 
137 /* Used as an error return value for get_cca_info */
138 #define RF_GET_CCA_INFO_ERROR 0xFF
139 
140 /*
141  * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's
142  * status struct
143  */
144 #define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */
145 #define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */
146 #define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */
147 
148 #ifdef PROP_MODE_CONF_RSSI_THRESHOLD
149 #define PROP_MODE_RSSI_THRESHOLD PROP_MODE_CONF_RSSI_THRESHOLD
150 #else
151 #define PROP_MODE_RSSI_THRESHOLD 0xA6
152 #endif
153 
154 static int8_t rssi_threshold = PROP_MODE_RSSI_THRESHOLD;
155 /*---------------------------------------------------------------------------*/
156 static int on(void);
157 static int off(void);
158 
159 static rfc_propRxOutput_t rx_stats;
160 /*---------------------------------------------------------------------------*/
161 /* Defines and variables related to the .15.4g PHY HDR */
162 #define DOT_4G_MAX_FRAME_LEN 2047
163 #define DOT_4G_PHR_LEN 2
164 
165 /* PHY HDR bits */
166 #define DOT_4G_PHR_CRC16 0x10
167 #define DOT_4G_PHR_DW 0x08
168 
169 #if PROP_MODE_USE_CRC16
170 /* CRC16 */
171 #define DOT_4G_PHR_CRC_BIT DOT_4G_PHR_CRC16
172 #define CRC_LEN 2
173 #else
174 /* CRC32 */
175 #define DOT_4G_PHR_CRC_BIT 0
176 #define CRC_LEN 4
177 #endif
178 
179 #if PROP_MODE_DW
180 #define DOT_4G_PHR_DW_BIT DOT_4G_PHR_DW
181 #else
182 #define DOT_4G_PHR_DW_BIT 0
183 #endif
184 /*---------------------------------------------------------------------------*/
185 /* How long to wait for an ongoing ACK TX to finish before starting frame TX */
186 #define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11)
187 
188 /* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */
189 #define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10)
190 /*---------------------------------------------------------------------------*/
191 /* TX Power dBm lookup table - values from SmartRF Studio */
192 typedef struct output_config {
193  radio_value_t dbm;
194  uint16_t tx_power; /* Value for the PROP_DIV_RADIO_SETUP.txPower field */
195 } output_config_t;
196 
197 static const output_config_t output_power[] = {
198  { 14, 0xa73f },
199  { 13, 0xa73f }, /* 12.5 */
200  { 12, 0xb818 },
201  { 11, 0x50da },
202  { 10, 0x38d3 },
203  { 9, 0x2ccd },
204  { 8, 0x24cb },
205  { 7, 0x20c9 },
206  { 6, 0x1cc7 },
207  { 5, 0x18c6 },
208  { 4, 0x18c5 },
209  { 3, 0x14c4 },
210  { 2, 0x1042 },
211  { 1, 0x10c3 },
212  { 0, 0x0041 },
213  {-10, 0x08c0 },
214 };
215 
216 #define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t))
217 
218 /* Max and Min Output Power in dBm */
219 #define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm)
220 #define OUTPUT_POWER_MAX (output_power[0].dbm)
221 #define OUTPUT_POWER_UNKNOWN 0xFFFF
222 
223 /* Default TX Power - position in output_power[] */
224 const output_config_t *tx_power_current = &output_power[1];
225 /*---------------------------------------------------------------------------*/
226 #ifdef PROP_MODE_CONF_LO_DIVIDER
227 #define PROP_MODE_LO_DIVIDER PROP_MODE_CONF_LO_DIVIDER
228 #else
229 #define PROP_MODE_LO_DIVIDER 0x05
230 #endif
231 /*---------------------------------------------------------------------------*/
232 #define DATA_ENTRY_LENSZ_NONE 0
233 #define DATA_ENTRY_LENSZ_BYTE 1
234 #define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */
235 
236 #define RX_BUF_SIZE 140
237 /* Receive buffers: 1 frame in each */
238 static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN(4);
239 static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN(4);
240 
241 /* The RX Data Queue */
242 static dataQueue_t rx_data_queue = { 0 };
243 
244 /* Receive entry pointer to keep track of read items */
245 volatile static uint8_t *rx_read_entry;
246 /*---------------------------------------------------------------------------*/
247 /* The outgoing frame buffer */
248 #define TX_BUF_PAYLOAD_LEN 180
249 #define TX_BUF_HDR_LEN 2
250 
251 static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN(4);
252 /*---------------------------------------------------------------------------*/
253 static uint8_t
254 rf_is_on(void)
255 {
256  if(!rf_core_is_accessible()) {
257  return 0;
258  }
259 
260  return smartrf_settings_cmd_prop_rx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE;
261 }
262 /*---------------------------------------------------------------------------*/
263 static uint8_t
264 transmitting(void)
265 {
266  return smartrf_settings_cmd_prop_tx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE;
267 }
268 /*---------------------------------------------------------------------------*/
269 static radio_value_t
270 get_rssi(void)
271 {
272  uint32_t cmd_status;
273  int8_t rssi;
274  uint8_t was_off = 0;
275  rfc_CMD_GET_RSSI_t cmd;
276 
277  /* If we are off, turn on first */
278  if(!rf_is_on()) {
279  was_off = 1;
280  if(on() != RF_CORE_CMD_OK) {
281  PRINTF("get_rssi: on() failed\n");
282  return RF_CMD_CCA_REQ_RSSI_UNKNOWN;
283  }
284  }
285 
286  memset(&cmd, 0x00, sizeof(cmd));
287  cmd.commandNo = CMD_GET_RSSI;
288 
289  rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN;
290 
291  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) {
292  /* Current RSSI in bits 23:16 of cmd_status */
293  rssi = (cmd_status >> 16) & 0xFF;
294  }
295 
296  /* If we were off, turn back off */
297  if(was_off) {
298  off();
299  }
300 
301  return rssi;
302 }
303 /*---------------------------------------------------------------------------*/
304 static uint8_t
305 get_channel(void)
306 {
307  uint32_t freq_khz;
308 
309  freq_khz = smartrf_settings_cmd_fs.frequency * 1000;
310 
311  /*
312  * For some channels, fractFreq * 1000 / 65536 will return 324.99xx.
313  * Casting the result to uint32_t will truncate decimals resulting in the
314  * function returning channel - 1 instead of channel. Thus, we do a quick
315  * positive integer round up.
316  */
317  freq_khz += (((smartrf_settings_cmd_fs.fractFreq * 1000) + 65535) / 65536);
318 
319  return (freq_khz - DOT_15_4G_CHAN0_FREQUENCY) / DOT_15_4G_CHANNEL_SPACING;
320 }
321 /*---------------------------------------------------------------------------*/
322 static void
323 set_channel(uint8_t channel)
324 {
325  uint32_t new_freq;
326  uint16_t freq, frac;
327 
328  new_freq = DOT_15_4G_CHAN0_FREQUENCY + (channel * DOT_15_4G_CHANNEL_SPACING);
329 
330  freq = (uint16_t)(new_freq / 1000);
331  frac = (new_freq - (freq * 1000)) * 65536 / 1000;
332 
333  PRINTF("set_channel: %u = 0x%04x.0x%04x (%lu)\n", channel, freq, frac,
334  new_freq);
335 
336  smartrf_settings_cmd_prop_radio_div_setup.centerFreq = freq;
337  smartrf_settings_cmd_fs.frequency = freq;
338  smartrf_settings_cmd_fs.fractFreq = frac;
339 }
340 /*---------------------------------------------------------------------------*/
341 /* Returns the current TX power in dBm */
342 static radio_value_t
343 get_tx_power(void)
344 {
345  return tx_power_current->dbm;
346 }
347 /*---------------------------------------------------------------------------*/
348 /*
349  * The caller must make sure to send a new CMD_PROP_RADIO_DIV_SETP to the
350  * radio after calling this function.
351  */
352 static void
353 set_tx_power(radio_value_t power)
354 {
355  int i;
356 
357  for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) {
358  if(power <= output_power[i].dbm) {
359  /*
360  * Merely save the value. It will be used in all subsequent usages of
361  * CMD_PROP_RADIO_DIV_SETP, including one immediately after this function
362  * has returned
363  */
364  tx_power_current = &output_power[i];
365 
366  return;
367  }
368  }
369 }
370 /*---------------------------------------------------------------------------*/
371 static int
372 prop_div_radio_setup(void)
373 {
374  uint32_t cmd_status;
375  rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_prop_radio_div_setup;
376 
377  /* Adjust loDivider depending on the selected band */
378  smartrf_settings_cmd_prop_radio_div_setup.loDivider = PROP_MODE_LO_DIVIDER;
379 
380  /* Update to the correct TX power setting */
381  smartrf_settings_cmd_prop_radio_div_setup.txPower = tx_power_current->tx_power;
382 
383  /* Send Radio setup to RF Core */
384  if(rf_core_send_cmd((uint32_t)cmd, &cmd_status) != RF_CORE_CMD_OK) {
385  PRINTF("prop_div_radio_setup: DIV_SETUP, CMDSTA=0x%08lx, status=0x%04x\n",
386  cmd_status, cmd->status);
387  return RF_CORE_CMD_ERROR;
388  }
389 
390  /* Wait until radio setup is done */
391  if(rf_core_wait_cmd_done(cmd) != RF_CORE_CMD_OK) {
392  PRINTF("prop_div_radio_setup: DIV_SETUP wait, CMDSTA=0x%08lx,"
393  "status=0x%04x\n", cmd_status, cmd->status);
394  return RF_CORE_CMD_ERROR;
395  }
396 
397  return RF_CORE_CMD_OK;
398 }
399 /*---------------------------------------------------------------------------*/
400 static uint8_t
401 rf_cmd_prop_rx()
402 {
403  uint32_t cmd_status;
404  rtimer_clock_t t0;
405  volatile rfc_CMD_PROP_RX_ADV_t *cmd_rx_adv;
406  int ret;
407 
408  cmd_rx_adv = (rfc_CMD_PROP_RX_ADV_t *)&smartrf_settings_cmd_prop_rx_adv;
409  cmd_rx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE;
410 
411  /*
412  * Set the max Packet length. This is for the payload only, therefore
413  * 2047 - length offset
414  */
415  cmd_rx_adv->maxPktLen = DOT_4G_MAX_FRAME_LEN - cmd_rx_adv->lenOffset;
416 
417  ret = rf_core_send_cmd((uint32_t)cmd_rx_adv, &cmd_status);
418 
419  if(ret != RF_CORE_CMD_OK) {
420  PRINTF("rf_cmd_prop_rx: send_cmd ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
421  ret, cmd_status, cmd_rx_adv->status);
422  return RF_CORE_CMD_ERROR;
423  }
424 
425  t0 = RTIMER_NOW();
426 
427  while(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE &&
428  (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT)));
429 
430  /* Wait to enter RX */
431  if(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE) {
432  PRINTF("rf_cmd_prop_rx: CMDSTA=0x%08lx, status=0x%04x\n",
433  cmd_status, cmd_rx_adv->status);
434  return RF_CORE_CMD_ERROR;
435  }
436 
437  return ret;
438 }
439 /*---------------------------------------------------------------------------*/
440 static int
441 rx_on_prop(void)
442 {
443  int ret;
444 
445  if(rf_is_on()) {
446  PRINTF("rx_on_prop: We were on. PD=%u, RX=0x%04x\n",
447  rf_core_is_accessible(), smartrf_settings_cmd_prop_rx_adv.status);
448  return RF_CORE_CMD_OK;
449  }
450 
451  /* Put CPE in RX using the currently configured parameters */
452  ret = rf_cmd_prop_rx();
453 
454  if(ret) {
455  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
456  }
457 
458  return ret;
459 }
460 /*---------------------------------------------------------------------------*/
461 static int
462 rx_off_prop(void)
463 {
464  uint32_t cmd_status;
465  int ret;
466 
467  /* If we are off, do nothing */
468  if(!rf_is_on()) {
469  return RF_CORE_CMD_OK;
470  }
471 
472  /* Send a CMD_ABORT command to RF Core */
473  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
474  PRINTF("rx_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status);
475  /* Continue nonetheless */
476  }
477 
478  while(rf_is_on());
479 
480  if(smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_STOPPED ||
481  smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_ABORT) {
482  /* Stopped gracefully */
483  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
484  ret = RF_CORE_CMD_OK;
485  } else {
486  PRINTF("rx_off_prop: status=0x%04x\n",
487  smartrf_settings_cmd_prop_rx_adv.status);
488  ret = RF_CORE_CMD_ERROR;
489  }
490 
491  return ret;
492 }
493 /*---------------------------------------------------------------------------*/
494 static uint8_t
495 request(void)
496 {
497  /*
498  * We rely on the RDC layer to turn us on and off. Thus, if we are on we
499  * will only allow sleep, standby otherwise
500  */
501  if(rf_is_on()) {
502  return LPM_MODE_SLEEP;
503  }
504 
505  return LPM_MODE_MAX_SUPPORTED;
506 }
507 /*---------------------------------------------------------------------------*/
508 LPM_MODULE(prop_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
509 /*---------------------------------------------------------------------------*/
510 static int
511 prop_fs(void)
512 {
513  uint32_t cmd_status;
514  rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_fs;
515 
516  /* Send the command to the RF Core */
517  if(rf_core_send_cmd((uint32_t)cmd, &cmd_status) != RF_CORE_CMD_OK) {
518  PRINTF("prop_fs: CMD_FS, CMDSTA=0x%08lx, status=0x%04x\n",
519  cmd_status, cmd->status);
520  return RF_CORE_CMD_ERROR;
521  }
522 
523  /* Wait until the command is done */
524  if(rf_core_wait_cmd_done(cmd) != RF_CORE_CMD_OK) {
525  PRINTF("prop_fs: CMD_FS wait, CMDSTA=0x%08lx, status=0x%04x\n",
526  cmd_status, cmd->status);
527  return RF_CORE_CMD_ERROR;
528  }
529 
530  return RF_CORE_CMD_OK;
531 }
532 /*---------------------------------------------------------------------------*/
533 static void
534 soft_off_prop(void)
535 {
536  uint32_t cmd_status;
537  volatile rfc_radioOp_t *cmd = rf_core_get_last_radio_op();
538 
539  if(!rf_core_is_accessible()) {
540  return;
541  }
542 
543  /* Send a CMD_ABORT command to RF Core */
544  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) {
545  PRINTF("soft_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status);
546  return;
547  }
548 
549  while((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) ==
550  RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING);
551 }
552 /*---------------------------------------------------------------------------*/
553 static uint8_t
554 soft_on_prop(void)
555 {
556  if(prop_div_radio_setup() != RF_CORE_CMD_OK) {
557  PRINTF("soft_on_prop: prop_div_radio_setup() failed\n");
558  return RF_CORE_CMD_ERROR;
559  }
560 
561  if(prop_fs() != RF_CORE_CMD_OK) {
562  PRINTF("soft_on_prop: prop_fs() failed\n");
563  return RF_CORE_CMD_ERROR;
564  }
565 
566  return rx_on_prop();
567 }
568 /*---------------------------------------------------------------------------*/
569 static const rf_core_primary_mode_t mode_prop = {
570  soft_off_prop,
571  soft_on_prop,
572 };
573 /*---------------------------------------------------------------------------*/
574 static int
575 init(void)
576 {
577  rfc_dataEntry_t *entry;
578 
579  lpm_register_module(&prop_lpm_module);
580 
581  if(ti_lib_chipinfo_chip_family_is_cc13xx() == false) {
582  return RF_CORE_CMD_ERROR;
583  }
584 
586 
587  /* Initialise RX buffers */
588  memset(rx_buf_0, 0, RX_BUF_SIZE);
589  memset(rx_buf_1, 0, RX_BUF_SIZE);
590 
591  entry = (rfc_dataEntry_t *)rx_buf_0;
592  entry->status = DATA_ENTRY_STATUS_PENDING;
593  entry->config.type = DATA_ENTRY_TYPE_GEN;
594  entry->config.lenSz = DATA_ENTRY_LENSZ_WORD;
595  entry->length = RX_BUF_SIZE - 8;
596  entry->pNextEntry = rx_buf_1;
597 
598  entry = (rfc_dataEntry_t *)rx_buf_1;
599  entry->status = DATA_ENTRY_STATUS_PENDING;
600  entry->config.type = DATA_ENTRY_TYPE_GEN;
601  entry->config.lenSz = DATA_ENTRY_LENSZ_WORD;
602  entry->length = RX_BUF_SIZE - 8;
603  entry->pNextEntry = rx_buf_0;
604 
605  /* Set of RF Core data queue. Circular buffer, no last entry */
606  rx_data_queue.pCurrEntry = rx_buf_0;
607  rx_data_queue.pLastEntry = NULL;
608 
609  /* Initialize current read pointer to first element (used in ISR) */
610  rx_read_entry = rx_buf_0;
611 
612  smartrf_settings_cmd_prop_rx_adv.pQueue = &rx_data_queue;
613  smartrf_settings_cmd_prop_rx_adv.pOutput = (uint8_t *)&rx_stats;
614 
615  set_channel(RF_CORE_CHANNEL);
616 
617  if(on() != RF_CORE_CMD_OK) {
618  PRINTF("init: on() failed\n");
619  return RF_CORE_CMD_ERROR;
620  }
621 
622  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
623 
624  rf_core_primary_mode_register(&mode_prop);
625 
626  process_start(&rf_core_process, NULL);
627 
628  return 1;
629 }
630 /*---------------------------------------------------------------------------*/
631 static int
632 prepare(const void *payload, unsigned short payload_len)
633 {
634  int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN);
635 
636  memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len);
637  return RF_CORE_CMD_OK;
638 }
639 /*---------------------------------------------------------------------------*/
640 static int
641 transmit(unsigned short transmit_len)
642 {
643  int ret;
644  uint8_t was_off = 0;
645  uint32_t cmd_status;
646  volatile rfc_CMD_PROP_TX_ADV_t *cmd_tx_adv;
647 
648  /* Length in .15.4g PHY HDR. Includes the CRC but not the HDR itself */
649  uint16_t total_length;
650 
651  if(!rf_is_on()) {
652  was_off = 1;
653  if(on() != RF_CORE_CMD_OK) {
654  PRINTF("transmit: on() failed\n");
655  return RADIO_TX_ERR;
656  }
657  }
658 
659  /*
660  * Prepare the .15.4g PHY header
661  * MS=0, Length MSBits=0, DW and CRC configurable
662  * Total length = transmit_len (payload) + CRC length
663  *
664  * The Radio will flip the bits around, so tx_buf[0] must have the length
665  * LSBs (PHR[15:8] and tx_buf[1] will have PHR[7:0]
666  */
667  total_length = transmit_len + CRC_LEN;
668 
669  tx_buf[0] = total_length & 0xFF;
670  tx_buf[1] = (total_length >> 8) + DOT_4G_PHR_DW_BIT + DOT_4G_PHR_CRC_BIT;
671 
672  /* Prepare the CMD_PROP_TX_ADV command */
673  cmd_tx_adv = (rfc_CMD_PROP_TX_ADV_t *)&smartrf_settings_cmd_prop_tx_adv;
674 
675  /*
676  * pktLen: Total number of bytes in the TX buffer, including the header if
677  * one exists, but not including the CRC (which is not present in the buffer)
678  */
679  cmd_tx_adv->pktLen = transmit_len + DOT_4G_PHR_LEN;
680  cmd_tx_adv->pPkt = tx_buf;
681 
682  /* Abort RX */
683  rx_off_prop();
684 
685  /* Enable the LAST_COMMAND_DONE interrupt to wake us up */
686  rf_core_cmd_done_en(false);
687 
688  ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status);
689 
690  if(ret) {
691  /* If we enter here, TX actually started */
692  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
693  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
694 
696 
697  /* Idle away while the command is running */
698  while((cmd_tx_adv->status & RF_CORE_RADIO_OP_MASKED_STATUS)
699  == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) {
700  lpm_sleep();
701  }
702 
703  if(cmd_tx_adv->status == RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK) {
704  /* Sent OK */
705  RIMESTATS_ADD(lltx);
706  ret = RADIO_TX_OK;
707  } else {
708  /* Operation completed, but frame was not sent */
709  PRINTF("transmit: Not Sent OK status=0x%04x\n",
710  cmd_tx_adv->status);
711  ret = RADIO_TX_ERR;
712  }
713  } else {
714  /* Failure sending the CMD_PROP_TX command */
715  PRINTF("transmit: PROP_TX_ERR ret=%d, CMDSTA=0x%08lx, status=0x%04x\n",
716  ret, cmd_status, cmd_tx_adv->status);
717  ret = RADIO_TX_ERR;
718  }
719 
720  /*
721  * Update ENERGEST state here, before a potential call to off(), which
722  * will correctly update it if required.
723  */
724  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
725  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
726 
727  /*
728  * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it
729  * except when we are transmitting
730  */
732 
733  /* Workaround. Set status to IDLE */
734  cmd_tx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE;
735 
736  rx_on_prop();
737 
738  if(was_off) {
739  off();
740  }
741 
742  return ret;
743 }
744 /*---------------------------------------------------------------------------*/
745 static int
746 send(const void *payload, unsigned short payload_len)
747 {
748  prepare(payload, payload_len);
749  return transmit(payload_len);
750 }
751 /*---------------------------------------------------------------------------*/
752 static int
753 read_frame(void *buf, unsigned short buf_len)
754 {
755  rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
756  uint8_t *data_ptr = &entry->data;
757  int len = 0;
758 
759  if(entry->status == DATA_ENTRY_STATUS_FINISHED) {
760 
761  /*
762  * First 2 bytes in the data entry are the length.
763  * Our data entry consists of: Payload + RSSI (1 byte) + Status (1 byte)
764  * This length includes all of those.
765  */
766  len = (*(uint16_t *)data_ptr);
767  data_ptr += 2;
768  len -= 2;
769 
770  if(len > 0) {
771  if(len <= buf_len) {
772  memcpy(buf, data_ptr, len);
773  }
774 
775  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (int8_t)data_ptr[len]);
776 
777 #if PROP_MODE_SNIFFER
778  {
779  int i;
780 
781  cc26xx_uart_write_byte(magic[0]);
782  cc26xx_uart_write_byte(magic[1]);
783  cc26xx_uart_write_byte(magic[2]);
784  cc26xx_uart_write_byte(magic[3]);
785 
786  cc26xx_uart_write_byte(len + 2);
787 
788  for(i = 0; i < len; ++i) {
789  cc26xx_uart_write_byte(((uint8_t *)(buf))[i]);
790  }
791 
792  cc26xx_uart_write_byte((uint8_t)rx_stats.lastRssi);
794 
795  while(cc26xx_uart_busy() == UART_BUSY);
796  }
797 #endif
798  }
799 
800  /* Move read entry pointer to next entry */
801  rx_read_entry = entry->pNextEntry;
802  entry->status = DATA_ENTRY_STATUS_PENDING;
803  }
804 
805  return len;
806 }
807 /*---------------------------------------------------------------------------*/
808 static int
809 channel_clear(void)
810 {
811  uint8_t was_off = 0;
812  uint32_t cmd_status;
813  int8_t rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN;
814 
815  /*
816  * If we are in the middle of a BLE operation, we got called by ContikiMAC
817  * from within an interrupt context. Indicate a clear channel
818  */
819  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
820  return RF_CCA_CLEAR;
821  }
822 
823  if(!rf_core_is_accessible()) {
824  was_off = 1;
825  if(on() != RF_CORE_CMD_OK) {
826  PRINTF("channel_clear: on() failed\n");
827  if(was_off) {
828  off();
829  }
830  return RF_CCA_CLEAR;
831  }
832  } else {
833  if(transmitting()) {
834  PRINTF("channel_clear: called while in TX\n");
835  return RF_CCA_CLEAR;
836  }
837  }
838 
839  while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) {
840  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_GET_RSSI), &cmd_status)
841  != RF_CORE_CMD_OK) {
842  break;
843  }
844  /* Current RSSI in bits 23:16 of cmd_status */
845  rssi = (cmd_status >> 16) & 0xFF;
846  }
847 
848  if(was_off) {
849  off();
850  }
851 
852  if(rssi >= rssi_threshold) {
853  return RF_CCA_BUSY;
854  }
855 
856  return RF_CCA_CLEAR;
857 }
858 /*---------------------------------------------------------------------------*/
859 static int
860 receiving_packet(void)
861 {
862  if(!rf_is_on()) {
863  return 0;
864  }
865 
866  if(channel_clear() == RF_CCA_CLEAR) {
867  return 0;
868  }
869 
870  return 1;
871 }
872 /*---------------------------------------------------------------------------*/
873 static int
874 pending_packet(void)
875 {
876  int rv = 0;
877  volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry;
878 
879  /* Go through all RX buffers and check their status */
880  do {
881  if(entry->status == DATA_ENTRY_STATUS_FINISHED) {
882  rv += 1;
883  process_poll(&rf_core_process);
884  }
885 
886  entry = (rfc_dataEntry_t *)entry->pNextEntry;
887  } while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry);
888 
889  /* If we didn't find an entry at status finished, no frames are pending */
890  return rv;
891 }
892 /*---------------------------------------------------------------------------*/
893 static int
894 on(void)
895 {
896  /*
897  * If we are in the middle of a BLE operation, we got called by ContikiMAC
898  * from within an interrupt context. Abort, but pretend everything is OK.
899  */
900  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
901  return RF_CORE_CMD_OK;
902  }
903 
904  /*
905  * Request the HF XOSC as the source for the HF clock. Needed before we can
906  * use the FS. This will only request, it will _not_ perform the switch.
907  */
909 
910  if(rf_is_on()) {
911  PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(),
912  smartrf_settings_cmd_prop_rx_adv.status);
913  return RF_CORE_CMD_OK;
914  }
915 
916  if(!rf_core_is_accessible()) {
917  if(rf_core_power_up() != RF_CORE_CMD_OK) {
918  PRINTF("on: rf_core_power_up() failed\n");
919 
921 
922  return RF_CORE_CMD_ERROR;
923  }
924 
925  rf_patch_cpe_genfsk();
926 
927  if(rf_core_start_rat() != RF_CORE_CMD_OK) {
928  PRINTF("on: rf_core_start_rat() failed\n");
929 
931 
932  return RF_CORE_CMD_ERROR;
933  }
934  }
935 
937 
938  /*
939  * Trigger a switch to the XOSC, so that we can subsequently use the RF FS
940  * This will block until the XOSC is actually ready, but give how we
941  * requested it early on, this won't be too long a wait/
942  */
944 
945  if(prop_div_radio_setup() != RF_CORE_CMD_OK) {
946  PRINTF("on: prop_div_radio_setup() failed\n");
947  return RF_CORE_CMD_ERROR;
948  }
949 
950  if(prop_fs() != RF_CORE_CMD_OK) {
951  PRINTF("on: prop_fs() failed\n");
952  return RF_CORE_CMD_ERROR;
953  }
954 
955  return rx_on_prop();
956 }
957 /*---------------------------------------------------------------------------*/
958 static int
959 off(void)
960 {
961  rfc_dataEntry_t *entry;
962 
963  /*
964  * If we are in the middle of a BLE operation, we got called by ContikiMAC
965  * from within an interrupt context. Abort, but pretend everything is OK.
966  */
967  if(rf_ble_is_active() == RF_BLE_ACTIVE) {
968  return RF_CORE_CMD_OK;
969  }
970 
971  rx_off_prop();
973 
974  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
975 
976  /* Switch HF clock source to the RCOSC to preserve power */
978 
979  /* We pulled the plug, so we need to restore the status manually */
980  smartrf_settings_cmd_prop_rx_adv.status = RF_CORE_RADIO_OP_STATUS_IDLE;
981 
982  entry = (rfc_dataEntry_t *)rx_buf_0;
983  entry->status = DATA_ENTRY_STATUS_PENDING;
984 
985  entry = (rfc_dataEntry_t *)rx_buf_1;
986  entry->status = DATA_ENTRY_STATUS_PENDING;
987 
988  return RF_CORE_CMD_OK;
989 }
990 /*---------------------------------------------------------------------------*/
991 static radio_result_t
992 get_value(radio_param_t param, radio_value_t *value)
993 {
994  if(!value) {
995  return RADIO_RESULT_INVALID_VALUE;
996  }
997 
998  switch(param) {
999  case RADIO_PARAM_POWER_MODE:
1000  /* On / off */
1001  *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF;
1002  return RADIO_RESULT_OK;
1003  case RADIO_PARAM_CHANNEL:
1004  *value = (radio_value_t)get_channel();
1005  return RADIO_RESULT_OK;
1006  case RADIO_PARAM_TXPOWER:
1007  *value = get_tx_power();
1008  return RADIO_RESULT_OK;
1009  case RADIO_PARAM_CCA_THRESHOLD:
1010  *value = rssi_threshold;
1011  return RADIO_RESULT_OK;
1012  case RADIO_PARAM_RSSI:
1013  *value = get_rssi();
1014 
1015  if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) {
1016  return RADIO_RESULT_ERROR;
1017  } else {
1018  return RADIO_RESULT_OK;
1019  }
1020  case RADIO_CONST_CHANNEL_MIN:
1021  *value = 0;
1022  return RADIO_RESULT_OK;
1023  case RADIO_CONST_CHANNEL_MAX:
1024  *value = DOT_15_4G_CHANNEL_MAX;
1025  return RADIO_RESULT_OK;
1026  case RADIO_CONST_TXPOWER_MIN:
1027  *value = OUTPUT_POWER_MIN;
1028  return RADIO_RESULT_OK;
1029  case RADIO_CONST_TXPOWER_MAX:
1030  *value = OUTPUT_POWER_MAX;
1031  return RADIO_RESULT_OK;
1032  default:
1033  return RADIO_RESULT_NOT_SUPPORTED;
1034  }
1035 }
1036 /*---------------------------------------------------------------------------*/
1037 static radio_result_t
1038 set_value(radio_param_t param, radio_value_t value)
1039 {
1040  uint8_t was_off = 0;
1041  radio_result_t rv = RADIO_RESULT_OK;
1042 
1043  switch(param) {
1044  case RADIO_PARAM_POWER_MODE:
1045  if(value == RADIO_POWER_MODE_ON) {
1046  if(on() != RF_CORE_CMD_OK) {
1047  PRINTF("set_value: on() failed (1)\n");
1048  return RADIO_RESULT_ERROR;
1049  }
1050  return RADIO_RESULT_OK;
1051  }
1052  if(value == RADIO_POWER_MODE_OFF) {
1053  off();
1054  return RADIO_RESULT_OK;
1055  }
1056  return RADIO_RESULT_INVALID_VALUE;
1057  case RADIO_PARAM_CHANNEL:
1058  if(value < 0 ||
1059  value > DOT_15_4G_CHANNEL_MAX) {
1060  return RADIO_RESULT_INVALID_VALUE;
1061  }
1062 
1063  if(get_channel() == (uint8_t)value) {
1064  /* We already have that very same channel configured.
1065  * Nothing to do here. */
1066  return RADIO_RESULT_OK;
1067  }
1068 
1069  set_channel((uint8_t)value);
1070  break;
1071  case RADIO_PARAM_TXPOWER:
1072  if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) {
1073  return RADIO_RESULT_INVALID_VALUE;
1074  }
1075 
1076  soft_off_prop();
1077 
1078  set_tx_power(value);
1079 
1080  if(soft_on_prop() != RF_CORE_CMD_OK) {
1081  PRINTF("set_value: soft_on_prop() failed\n");
1082  rv = RADIO_RESULT_ERROR;
1083  }
1084 
1085  return RADIO_RESULT_OK;
1086  case RADIO_PARAM_CCA_THRESHOLD:
1087  rssi_threshold = (int8_t)value;
1088  break;
1089  default:
1090  return RADIO_RESULT_NOT_SUPPORTED;
1091  }
1092 
1093  /* If we reach here we had no errors. Apply new settings */
1094  if(!rf_is_on()) {
1095  was_off = 1;
1096  if(on() != RF_CORE_CMD_OK) {
1097  PRINTF("set_value: on() failed (2)\n");
1098  return RADIO_RESULT_ERROR;
1099  }
1100  }
1101 
1102  if(rx_off_prop() != RF_CORE_CMD_OK) {
1103  PRINTF("set_value: rx_off_prop() failed\n");
1104  rv = RADIO_RESULT_ERROR;
1105  }
1106 
1107  if(rx_on_prop() != RF_CORE_CMD_OK) {
1108  PRINTF("set_value: rx_on_prop() failed\n");
1109  rv = RADIO_RESULT_ERROR;
1110  }
1111 
1112  /* If we were off, turn back off */
1113  if(was_off) {
1114  off();
1115  }
1116 
1117  return rv;
1118 }
1119 /*---------------------------------------------------------------------------*/
1120 static radio_result_t
1121 get_object(radio_param_t param, void *dest, size_t size)
1122 {
1123  return RADIO_RESULT_NOT_SUPPORTED;
1124 }
1125 /*---------------------------------------------------------------------------*/
1126 static radio_result_t
1127 set_object(radio_param_t param, const void *src, size_t size)
1128 {
1129  return RADIO_RESULT_NOT_SUPPORTED;
1130 }
1131 /*---------------------------------------------------------------------------*/
1132 const struct radio_driver prop_mode_driver = {
1133  init,
1134  prepare,
1135  transmit,
1136  send,
1137  read_frame,
1138  channel_clear,
1141  on,
1142  off,
1143  get_value,
1144  set_value,
1145  get_object,
1146  set_object,
1147 };
1148 /*---------------------------------------------------------------------------*/
1149 /**
1150  * @}
1151  * @}
1152  */
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
Header file for the real-time timer module.
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
Definition: rf-core.c:269
Header file for the radio API
Header file with macros which rename TI CC26xxware functions.
uint8_t cc26xx_uart_busy(void)
Returns the UART busy status.
Definition: cc26xx-uart.c:348
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
void lpm_sleep(void)
Enter sleep mode.
Definition: lpm.c:479
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
Default definitions of C compiler quirk work-arounds.
Header file for the CC13xx/CC26xx BLE driver.
int(* prepare)(const void *payload, unsigned short payload_len)
Prepare the radio with a packet to be sent.
Definition: radio.h:242
void cc26xx_uart_write_byte(uint8_t c)
Sends a single character down the UART.
Definition: cc26xx-uart.c:299
int(* receiving_packet)(void)
Check if the radio driver is currently receiving a packet.
Definition: radio.h:258
uint8_t rf_ble_is_active()
Check whether the BLE beacond is currently active.
Definition: rf-ble.c:203
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
Definition: oscillators.c:116
Header file for the energy estimation mechanism
The structure of a device driver for a radio in Contiki.
Definition: radio.h:237
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
Definition: lpm.c:498
Header file with descriptors for the various modes of operation defined in IEEE 802.15.4g.
int(* pending_packet)(void)
Check if the radio driver has just received a packet.
Definition: radio.h:261
Header file for the Rime 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
radio_result_t(* set_value)(radio_param_t param, radio_value_t value)
Set a radio parameter value.
Definition: radio.h:273
void rf_core_setup_interrupts()
Setup RF core interrupts.
Definition: rf-core.c:370
Header file for the CC13xx/CC26xx RF core driver.
Header file for the Rime address representation
int(* off)(void)
Turn the radio off.
Definition: radio.h:267
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
Definition: rf-core.c:110
#define NULL
The null pointer.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
Definition: oscillators.c:134
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
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
Definition: rf-core.c:303
static uint8_t transmitting(void)
Check the RF's TX status.
Definition: ieee-mode.c:267
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
Definition: rf-core.c:403
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64
radio_result_t(* get_object)(radio_param_t param, void *dest, size_t size)
Get a radio parameter object.
Definition: radio.h:280
int rf_core_power_up()
Turn on power to the RFC and boot it.
Definition: rf-core.c:228
int(* on)(void)
Turn the radio on.
Definition: radio.h:264
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
Definition: rf-core.c:433
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:249
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Definition: rf-core.c:119
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
radio_result_t(* get_value)(radio_param_t param, radio_value_t *value)
Get a radio parameter value.
Definition: radio.h:270
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
Definition: radio.h:248
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
Definition: rf-core.c:418
Header file for Rime statistics
Header file for the CC13xx/CC26xx UART driver.
uint8_t rf_core_start_rat()
Start the CM0 RAT.
Definition: rf-core.c:332
Header file for the CC13xx/CC26xx oscillator control.
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
int(* transmit)(unsigned short transmit_len)
Send the packet that has previously been prepared.
Definition: radio.h:245
void rf_core_cmd_done_dis()
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
Definition: rf-core.c:412
Include file for the Contiki low-layer network stack (NETSTACK)
radio_result_t(* set_object)(radio_param_t param, const void *src, size_t size)
Set a radio parameter object.
Definition: radio.h:286
A data strcuture representing the radio's primary mode of operation.
Definition: rf-core.h:93
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
Definition: rf-core.c:185