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