Contiki-NG
rf-core.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  * \file
36  * Implementation of the CC13xx/CC26xx RF core driver
37  */
38 /*---------------------------------------------------------------------------*/
39 #include "contiki.h"
40 #include "dev/watchdog.h"
41 #include "sys/process.h"
42 #include "sys/energest.h"
43 #include "sys/cc.h"
44 #include "net/netstack.h"
45 #include "net/packetbuf.h"
46 #include "rf-core/rf-core.h"
47 #include "rf-core/rf-switch.h"
48 #include "ti-lib.h"
49 /*---------------------------------------------------------------------------*/
50 /* RF core and RF HAL API */
51 #include "hw_rfc_dbell.h"
52 #include "hw_rfc_pwr.h"
53 /*---------------------------------------------------------------------------*/
54 /* RF Core Mailbox API */
55 #include "driverlib/rf_mailbox.h"
56 #include "driverlib/rf_common_cmd.h"
57 #include "driverlib/rf_data_entry.h"
58 /*---------------------------------------------------------------------------*/
59 #include <stdint.h>
60 #include <stdbool.h>
61 #include <stdio.h>
62 #include <string.h>
63 /*---------------------------------------------------------------------------*/
64 #define DEBUG 0
65 #if DEBUG
66 #define PRINTF(...) printf(__VA_ARGS__)
67 #else
68 #define PRINTF(...)
69 #endif
70 /*---------------------------------------------------------------------------*/
71 #ifdef RF_CORE_CONF_DEBUG_CRC
72 #define RF_CORE_DEBUG_CRC RF_CORE_CONF_DEBUG_CRC
73 #else
74 #define RF_CORE_DEBUG_CRC DEBUG
75 #endif
76 /*---------------------------------------------------------------------------*/
77 /* RF interrupts */
78 #define RX_FRAME_IRQ IRQ_RX_ENTRY_DONE
79 #define ERROR_IRQ (IRQ_INTERNAL_ERROR | IRQ_RX_BUF_FULL)
80 #define RX_NOK_IRQ IRQ_RX_NOK
81 
82 /* Those IRQs are enabled all the time */
83 #if RF_CORE_DEBUG_CRC
84 #define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ | RX_NOK_IRQ)
85 #else
86 #define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ)
87 #endif
88 
89 #define ENABLED_IRQS_POLL_MODE (ENABLED_IRQS & ~(RX_FRAME_IRQ | ERROR_IRQ))
90 
91 #define cc26xx_rf_cpe0_isr RFCCPE0IntHandler
92 #define cc26xx_rf_cpe1_isr RFCCPE1IntHandler
93 /*---------------------------------------------------------------------------*/
94 typedef ChipType_t chip_type_t;
95 /*---------------------------------------------------------------------------*/
96 /* Remember the last Radio Op issued to the radio */
97 static rfc_radioOp_t *last_radio_op = NULL;
98 /*---------------------------------------------------------------------------*/
99 /* A struct holding pointers to the primary mode's abort() and restore() */
100 static const rf_core_primary_mode_t *primary_mode = NULL;
101 /*---------------------------------------------------------------------------*/
102 /* RAT has 32-bit register, overflows once 18 minutes */
103 #define RAT_RANGE 4294967296ull
104 /* approximate value */
105 #define RAT_OVERFLOW_PERIOD_SECONDS (60 * 18)
106 
107 /* how often to check for the overflow, as a minimum */
108 #define RAT_OVERFLOW_TIMER_INTERVAL (CLOCK_SECOND * RAT_OVERFLOW_PERIOD_SECONDS / 3)
109 
110 /* Radio timer (RAT) offset as compared to the rtimer counter (RTC) */
111 static int32_t rat_offset;
112 static bool rat_offset_known;
113 
114 /* Value during the last read of the RAT register */
115 static uint32_t rat_last_value;
116 
117 /* For RAT overflow handling */
118 static struct ctimer rat_overflow_timer;
119 static volatile uint32_t rat_overflow_counter;
120 static rtimer_clock_t rat_last_overflow;
121 
122 static void rat_overflow_check_timer_cb(void *);
123 /*---------------------------------------------------------------------------*/
124 volatile int8_t rf_core_last_rssi = RF_CORE_CMD_CCA_REQ_RSSI_UNKNOWN;
125 volatile uint8_t rf_core_last_corr_lqi = 0;
126 volatile uint32_t rf_core_last_packet_timestamp = 0;
127 /*---------------------------------------------------------------------------*/
128 /* Are we currently in poll mode? */
129 uint8_t rf_core_poll_mode = 0;
130 /*---------------------------------------------------------------------------*/
131 /* Buffer full flag */
132 volatile bool rf_core_rx_is_full = false;
133 /* Status of the last command sent */
134 volatile uint32_t last_cmd_status;
135 /*---------------------------------------------------------------------------*/
136 PROCESS(rf_core_process, "CC13xx / CC26xx RF driver");
137 /*---------------------------------------------------------------------------*/
138 #define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \
139  | RFC_PWR_PWMCLKEN_CPERAM_M | RFC_PWR_PWMCLKEN_FSCA_M \
140  | RFC_PWR_PWMCLKEN_PHA_M | RFC_PWR_PWMCLKEN_RAT_M \
141  | RFC_PWR_PWMCLKEN_RFERAM_M | RFC_PWR_PWMCLKEN_RFE_M \
142  | RFC_PWR_PWMCLKEN_MDMRAM_M | RFC_PWR_PWMCLKEN_MDM_M)
143 /*---------------------------------------------------------------------------*/
144 #define RF_CMD0 0x0607
145 /*---------------------------------------------------------------------------*/
146 uint8_t
148 {
149  if(ti_lib_prcm_rf_ready()) {
150  return RF_CORE_ACCESSIBLE;
151  }
152  return RF_CORE_NOT_ACCESSIBLE;
153 }
154 /*---------------------------------------------------------------------------*/
155 uint_fast8_t
156 rf_core_send_cmd(uint32_t cmd, uint32_t *status)
157 {
158  uint32_t timeout_count = 0;
159  bool interrupts_disabled;
160  bool is_radio_op = false;
161 
162  /* reset the status variables to invalid values */
163  last_cmd_status = (uint32_t)-1;
164  *status = last_cmd_status;
165 
166  /*
167  * If cmd is 4-byte aligned, then it's either a radio OP or an immediate
168  * command. Clear the status field if it's a radio OP
169  */
170  if((cmd & 0x03) == 0) {
171  uint32_t cmd_type;
172  cmd_type = ((rfc_command_t *)cmd)->commandNo & RF_CORE_COMMAND_TYPE_MASK;
173  if(cmd_type == RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP ||
174  cmd_type == RF_CORE_COMMAND_TYPE_RADIO_OP) {
175  is_radio_op = true;
176  ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
177  }
178  }
179 
180  /*
181  * Make sure ContikiMAC doesn't turn us off from within an interrupt while
182  * we are accessing RF Core registers
183  */
184  interrupts_disabled = ti_lib_int_master_disable();
185 
186  if(!rf_core_is_accessible()) {
187  PRINTF("rf_core_send_cmd: RF was off\n");
188  if(!interrupts_disabled) {
189  ti_lib_int_master_enable();
190  }
191  return RF_CORE_CMD_ERROR;
192  }
193 
194  if(is_radio_op) {
195  uint16_t command_no = ((rfc_radioOp_t *)cmd)->commandNo;
196  if((command_no & RF_CORE_COMMAND_PROTOCOL_MASK) != RF_CORE_COMMAND_PROTOCOL_COMMON &&
197  (command_no & RF_CORE_COMMAND_TYPE_MASK) == RF_CORE_COMMAND_TYPE_RADIO_OP) {
198  last_radio_op = (rfc_radioOp_t *)cmd;
199  }
200  }
201 
202  HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd;
203  do {
204  last_cmd_status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA);
205  if(++timeout_count > 50000) {
206  PRINTF("rf_core_send_cmd: 0x%08lx Timeout\n", cmd);
207  if(!interrupts_disabled) {
208  ti_lib_int_master_enable();
209  }
210  *status = last_cmd_status;
211  return RF_CORE_CMD_ERROR;
212  }
213  } while((last_cmd_status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_PENDING);
214 
215  if(!interrupts_disabled) {
216  ti_lib_int_master_enable();
217  }
218 
219  /*
220  * If we reach here the command is no longer pending. It is either completed
221  * successfully or with error
222  */
223  *status = last_cmd_status;
224  return (last_cmd_status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_DONE;
225 }
226 /*---------------------------------------------------------------------------*/
227 uint_fast8_t
229 {
230  volatile rfc_radioOp_t *command = (rfc_radioOp_t *)cmd;
231  uint32_t timeout_cnt = 0;
232 
233  /*
234  * 0xn4nn=DONE, 0x0400=DONE_OK while all other "DONE" values means done
235  * but with some kind of error (ref. "Common radio operation status codes")
236  */
237  do {
238  if(++timeout_cnt > 500000) {
239  return RF_CORE_CMD_ERROR;
240  }
241  } while((command->status & RF_CORE_RADIO_OP_MASKED_STATUS)
242  != RF_CORE_RADIO_OP_MASKED_STATUS_DONE);
243 
244  last_cmd_status = command->status;
245  return (command->status & RF_CORE_RADIO_OP_MASKED_STATUS)
246  == RF_CORE_RADIO_OP_STATUS_DONE_OK;
247 }
248 /*---------------------------------------------------------------------------*/
249 uint32_t
251 {
252  return last_cmd_status;
253 }
254 /*---------------------------------------------------------------------------*/
255 static int
256 fs_powerdown(void)
257 {
258  rfc_CMD_FS_POWERDOWN_t cmd;
259  uint32_t cmd_status;
260 
261  rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_FS_POWERDOWN);
262 
263  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) {
264  PRINTF("fs_powerdown: CMDSTA=0x%08lx\n", cmd_status);
265  return RF_CORE_CMD_ERROR;
266  }
267 
268  if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) {
269  PRINTF("fs_powerdown: CMDSTA=0x%08lx, status=0x%04x\n",
270  cmd_status, cmd.status);
271  return RF_CORE_CMD_ERROR;
272  }
273 
274  return RF_CORE_CMD_OK;
275 }
276 /*---------------------------------------------------------------------------*/
277 int
279 {
280  uint32_t cmd_status;
281  bool interrupts_disabled = ti_lib_int_master_disable();
282 
283  ti_lib_int_pend_clear(INT_RFC_CPE_0);
284  ti_lib_int_pend_clear(INT_RFC_CPE_1);
285  ti_lib_int_disable(INT_RFC_CPE_0);
286  ti_lib_int_disable(INT_RFC_CPE_1);
287 
288  /* Enable RF Core power domain */
289  ti_lib_prcm_power_domain_on(PRCM_DOMAIN_RFCORE);
290  while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE)
291  != PRCM_DOMAIN_POWER_ON);
292 
293  ti_lib_prcm_domain_enable(PRCM_DOMAIN_RFCORE);
294  ti_lib_prcm_load_set();
295  while(!ti_lib_prcm_load_get());
296 
297  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
298  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
299  ti_lib_int_enable(INT_RFC_CPE_0);
300  ti_lib_int_enable(INT_RFC_CPE_1);
301 
302  if(!interrupts_disabled) {
303  ti_lib_int_master_enable();
304  }
305 
306  rf_switch_power_up();
307 
308  /* Let CPE boot */
309  HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK;
310 
311  /* Turn on additional clocks on boot */
312  HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG) = 0;
313  HWREG(RFC_DBELL_BASE+RFC_DBELL_O_CMDR) =
314  CMDR_DIR_CMD_2BYTE(RF_CMD0,
315  RFC_PWR_PWMCLKEN_MDMRAM | RFC_PWR_PWMCLKEN_RFERAM);
316 
317  /* Send ping (to verify RFCore is ready and alive) */
318  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_PING), &cmd_status) != RF_CORE_CMD_OK) {
319  PRINTF("rf_core_power_up: CMD_PING fail, CMDSTA=0x%08lx\n", cmd_status);
320  return RF_CORE_CMD_ERROR;
321  }
322 
323  return RF_CORE_CMD_OK;
324 }
325 /*---------------------------------------------------------------------------*/
326 uint8_t
328 {
329  uint32_t cmd_status;
330  rfc_CMD_SYNC_START_RAT_t cmd_start;
331 
332  /* Start radio timer (RAT) */
333  rf_core_init_radio_op((rfc_radioOp_t *)&cmd_start, sizeof(cmd_start), CMD_SYNC_START_RAT);
334 
335  /* copy the value and send back */
336  cmd_start.rat0 = rat_offset;
337 
338  if(rf_core_send_cmd((uint32_t)&cmd_start, &cmd_status) != RF_CORE_CMD_OK) {
339  PRINTF("rf_core_get_rat_rtc_offset: SYNC_START_RAT fail, CMDSTA=0x%08lx\n",
340  cmd_status);
341  return RF_CORE_CMD_ERROR;
342  }
343 
344  /* Wait until done (?) */
345  if(rf_core_wait_cmd_done(&cmd_start) != RF_CORE_CMD_OK) {
346  PRINTF("rf_core_cmd_ok: SYNC_START_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n",
347  cmd_status, cmd_start.status);
348  return RF_CORE_CMD_ERROR;
349  }
350 
351  return RF_CORE_CMD_OK;
352 }
353 /*---------------------------------------------------------------------------*/
354 uint8_t
356 {
357  rfc_CMD_SYNC_STOP_RAT_t cmd_stop;
358  uint32_t cmd_status;
359 
360  rf_core_init_radio_op((rfc_radioOp_t *)&cmd_stop, sizeof(cmd_stop), CMD_SYNC_STOP_RAT);
361 
362  int ret = rf_core_send_cmd((uint32_t)&cmd_stop, &cmd_status);
363  if(ret != RF_CORE_CMD_OK) {
364  PRINTF("rf_core_get_rat_rtc_offset: SYNC_STOP_RAT fail, ret %d CMDSTA=0x%08lx\n",
365  ret, cmd_status);
366  return ret;
367  }
368 
369  /* Wait until done */
370  ret = rf_core_wait_cmd_done(&cmd_stop);
371  if(ret != RF_CORE_CMD_OK) {
372  PRINTF("rf_core_cmd_ok: SYNC_STOP_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n",
373  cmd_status, cmd_stop.status);
374  return ret;
375  }
376 
377  if(!rat_offset_known) {
378  /* save the offset, but only if this is the first time */
379  rat_offset_known = true;
380  rat_offset = cmd_stop.rat0;
381  }
382 
383  return RF_CORE_CMD_OK;
384 }
385 /*---------------------------------------------------------------------------*/
386 void
388 {
389  bool interrupts_disabled = ti_lib_int_master_disable();
390  ti_lib_int_disable(INT_RFC_CPE_0);
391  ti_lib_int_disable(INT_RFC_CPE_1);
392 
393  if(rf_core_is_accessible()) {
394  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
395  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
396 
397  /* need to send FS_POWERDOWN or analog components will use power */
398  fs_powerdown();
399  }
400 
402 
403  /* Shut down the RFCORE clock domain in the MCU VD */
404  ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE);
405  ti_lib_prcm_load_set();
406  while(!ti_lib_prcm_load_get());
407 
408  /* Turn off RFCORE PD */
409  ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE);
410  while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE)
411  != PRCM_DOMAIN_POWER_OFF);
412 
413  rf_switch_power_down();
414 
415  ti_lib_int_pend_clear(INT_RFC_CPE_0);
416  ti_lib_int_pend_clear(INT_RFC_CPE_1);
417  ti_lib_int_enable(INT_RFC_CPE_0);
418  ti_lib_int_enable(INT_RFC_CPE_1);
419  if(!interrupts_disabled) {
420  ti_lib_int_master_enable();
421  }
422 }
423 /*---------------------------------------------------------------------------*/
424 uint8_t
426 {
427  uint8_t rv = RF_CORE_CMD_ERROR;
428  chip_type_t chip_type = ti_lib_chipinfo_get_chip_type();
429 
430  if(chip_type == CHIP_TYPE_CC2650) {
431  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
432  rv = RF_CORE_CMD_OK;
433  } else if(chip_type == CHIP_TYPE_CC2630) {
434  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2;
435  rv = RF_CORE_CMD_OK;
436  } else if(chip_type == CHIP_TYPE_CC1310) {
437  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3;
438  rv = RF_CORE_CMD_OK;
439  } else if(chip_type == CHIP_TYPE_CC1350) {
440  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
441  rv = RF_CORE_CMD_OK;
442 #if CPU_FAMILY_CC26X0R2
443  } else if(chip_type == CHIP_TYPE_CC2640R2) {
444  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE1;
445  rv = RF_CORE_CMD_OK;
446 #endif
447  }
448 
449  return rv;
450 }
451 /*---------------------------------------------------------------------------*/
452 uint8_t
454 {
455  if(rf_core_power_up() != RF_CORE_CMD_OK) {
456  PRINTF("rf_core_boot: rf_core_power_up() failed\n");
457 
459 
460  return RF_CORE_CMD_ERROR;
461  }
462 
463  if(rf_core_start_rat() != RF_CORE_CMD_OK) {
464  PRINTF("rf_core_boot: rf_core_start_rat() failed\n");
465 
467 
468  return RF_CORE_CMD_ERROR;
469  }
470 
471  return RF_CORE_CMD_OK;
472 }
473 /*---------------------------------------------------------------------------*/
474 uint8_t
476 {
477  if(rf_core_stop_rat() != RF_CORE_CMD_OK) {
478  PRINTF("rf_core_restart_rat: rf_core_stop_rat() failed\n");
479  /* Don't bail out here, still try to start it */
480  }
481 
482  if(rf_core_start_rat() != RF_CORE_CMD_OK) {
483  PRINTF("rf_core_restart_rat: rf_core_start_rat() failed\n");
484 
486 
487  return RF_CORE_CMD_ERROR;
488  }
489 
490  return RF_CORE_CMD_OK;
491 }
492 /*---------------------------------------------------------------------------*/
493 void
495 {
496  bool interrupts_disabled;
497  const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
498 
499  /* We are already turned on by the caller, so this should not happen */
500  if(!rf_core_is_accessible()) {
501  PRINTF("setup_interrupts: No access\n");
502  return;
503  }
504 
505  /* Disable interrupts */
506  interrupts_disabled = ti_lib_int_master_disable();
507 
508  /* Set all interrupt channels to CPE0 channel, error to CPE1 */
509  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ;
510 
511  /* Acknowledge configured interrupts */
512  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs;
513 
514  /* Clear interrupt flags, active low clear(?) */
515  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
516 
517  ti_lib_int_pend_clear(INT_RFC_CPE_0);
518  ti_lib_int_pend_clear(INT_RFC_CPE_1);
519  ti_lib_int_enable(INT_RFC_CPE_0);
520  ti_lib_int_enable(INT_RFC_CPE_1);
521 
522  if(!interrupts_disabled) {
523  ti_lib_int_master_enable();
524  }
525 }
526 /*---------------------------------------------------------------------------*/
527 void
529 {
530  uint32_t irq = 0;
531  const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
532 
533  if(!rf_core_poll_mode) {
534  irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE;
535  }
536 
537  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = enabled_irqs;
538  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs | irq;
539 }
540 /*---------------------------------------------------------------------------*/
541 void
543 {
544  const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
545  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs;
546 }
547 /*---------------------------------------------------------------------------*/
548 rfc_radioOp_t *
550 {
551  return last_radio_op;
552 }
553 /*---------------------------------------------------------------------------*/
554 void
555 rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
556 {
557  memset(op, 0, len);
558 
559  op->commandNo = command;
560  op->condition.rule = COND_NEVER;
561 }
562 /*---------------------------------------------------------------------------*/
563 void
565 {
566  primary_mode = mode;
567 }
568 /*---------------------------------------------------------------------------*/
569 void
571 {
572  if(primary_mode) {
573  if(primary_mode->abort) {
574  primary_mode->abort();
575  }
576  }
577 }
578 /*---------------------------------------------------------------------------*/
579 uint8_t
581 {
582  if(primary_mode) {
583  if(primary_mode->restore) {
584  return primary_mode->restore();
585  }
586  }
587 
588  return RF_CORE_CMD_ERROR;
589 }
590 /*---------------------------------------------------------------------------*/
591 uint8_t
593 {
594  rat_last_value = HWREG(RFC_RAT_BASE + RATCNT);
595 
596  ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_TIMER_INTERVAL,
597  rat_overflow_check_timer_cb, NULL);
598 
599  return 1;
600 }
601 /*---------------------------------------------------------------------------*/
602 uint8_t
604 {
605  uint32_t rat_current_value;
606  uint8_t interrupts_disabled;
607 
608  /* Bail out if the RF is not on */
609  if(primary_mode == NULL || !primary_mode->is_on()) {
610  return 0;
611  }
612 
613  interrupts_disabled = ti_lib_int_master_disable();
614 
615  rat_current_value = HWREG(RFC_RAT_BASE + RATCNT);
616  if(rat_current_value + RAT_RANGE / 4 < rat_last_value) {
617  /* Overflow detected */
618  rat_last_overflow = RTIMER_NOW();
619  rat_overflow_counter++;
620  }
621  rat_last_value = rat_current_value;
622 
623  if(!interrupts_disabled) {
624  ti_lib_int_master_enable();
625  }
626 
627  return 1;
628 }
629 /*---------------------------------------------------------------------------*/
630 static void
631 rat_overflow_check_timer_cb(void *unused)
632 {
633  uint8_t success = 0;
634  uint8_t was_off = 0;
635 
636  if(primary_mode != NULL) {
637 
638  if(!primary_mode->is_on()) {
639  was_off = 1;
640  if(NETSTACK_RADIO.on() != RF_CORE_CMD_OK) {
641  PRINTF("overflow: on() failed\n");
642  ctimer_set(&rat_overflow_timer, CLOCK_SECOND,
643  rat_overflow_check_timer_cb, NULL);
644  return;
645  }
646  }
647 
648  success = rf_core_check_rat_overflow();
649 
650  if(was_off) {
651  NETSTACK_RADIO.off();
652  }
653  }
654 
655  if(success) {
656  /* Retry after half of the interval */
657  ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_TIMER_INTERVAL,
658  rat_overflow_check_timer_cb, NULL);
659  } else {
660  /* Retry sooner */
661  ctimer_set(&rat_overflow_timer, CLOCK_SECOND,
662  rat_overflow_check_timer_cb, NULL);
663  }
664 }
665 /*---------------------------------------------------------------------------*/
666 uint32_t
667 rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
668 {
669  uint64_t rat_timestamp64;
670  uint32_t adjusted_overflow_counter;
671  uint8_t was_off = 0;
672 
673  if(primary_mode == NULL) {
674  PRINTF("rf_core_convert_rat_to_rtimer: not initialized\n");
675  return 0;
676  }
677 
678  if(!primary_mode->is_on()) {
679  was_off = 1;
680  NETSTACK_RADIO.on();
681  }
682 
684 
685  if(was_off) {
686  NETSTACK_RADIO.off();
687  }
688 
689  adjusted_overflow_counter = rat_overflow_counter;
690 
691  /* if the timestamp is large and the last oveflow was recently,
692  assume that the timestamp refers to the time before the overflow */
693  if(rat_timestamp > (uint32_t)(RAT_RANGE * 3 / 4)) {
694  if(RTIMER_CLOCK_LT(RTIMER_NOW(),
695  rat_last_overflow + RAT_OVERFLOW_PERIOD_SECONDS * RTIMER_SECOND / 4)) {
696  adjusted_overflow_counter--;
697  }
698  }
699 
700  /* add the overflowed time to the timestamp */
701  rat_timestamp64 = rat_timestamp + RAT_RANGE * adjusted_overflow_counter;
702  /* correct timestamp so that it refers to the end of the SFD */
703  rat_timestamp64 += primary_mode->sfd_timestamp_offset;
704 
705  return RADIO_TO_RTIMER(rat_timestamp64 - rat_offset);
706 }
707 /*---------------------------------------------------------------------------*/
708 PROCESS_THREAD(rf_core_process, ev, data)
709 {
710  int len;
711 
712  PROCESS_BEGIN();
713 
714  while(1) {
715  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
716  do {
718  packetbuf_clear();
719  len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE);
720 
721  if(len > 0) {
723 
724  NETSTACK_MAC.input();
725  }
726  } while(len > 0);
727  }
728  PROCESS_END();
729 }
730 /*---------------------------------------------------------------------------*/
731 static void
732 rx_nok_isr(void)
733 {
734 }
735 /*---------------------------------------------------------------------------*/
736 void
737 cc26xx_rf_cpe1_isr(void)
738 {
739  PRINTF("RF Error\n");
740 
741  if(!rf_core_is_accessible()) {
742  if(rf_core_power_up() != RF_CORE_CMD_OK) {
743  return;
744  }
745  }
746 
747  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & IRQ_RX_BUF_FULL) {
748  PRINTF("\nRF: BUF_FULL\n\n");
749  /* set a flag that the buffer is full*/
750  rf_core_rx_is_full = true;
751  /* make sure read_frame() will be called to make space in RX buffer */
752  process_poll(&rf_core_process);
753  /* Clear the IRQ_RX_BUF_FULL interrupt flag by writing zero to bit */
754  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ~(IRQ_RX_BUF_FULL);
755  }
756 
757  /* Clear INTERNAL_ERROR interrupt flag */
758  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF;
759 }
760 /*---------------------------------------------------------------------------*/
761 void
762 cc26xx_rf_cpe0_isr(void)
763 {
764  if(!rf_core_is_accessible()) {
765  PRINTF("RF ISR called but RF not ready... PANIC!!\n");
766  if(rf_core_power_up() != RF_CORE_CMD_OK) {
767  PRINTF("rf_core_power_up() failed\n");
768  return;
769  }
770  }
771 
772  ti_lib_int_master_disable();
773 
774  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) {
775  /* Clear the RX_ENTRY_DONE interrupt flag */
776  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF;
777  process_poll(&rf_core_process);
778  }
779 
780  if(RF_CORE_DEBUG_CRC) {
781  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) {
782  /* Clear the RX_NOK interrupt flag */
783  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF;
784  rx_nok_isr();
785  }
786  }
787 
788  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) &
789  (IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) {
790  /* Clear the two TX-related interrupt flags */
791  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5;
792  }
793 
794  ti_lib_int_master_enable();
795 }
796 /*---------------------------------------------------------------------------*/
797 /** @} */
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:143
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
Header file with macros which rename TI CC26xxware functions.
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:75
Header file for the energy estimation mechanism
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
Definition: process.h:178
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
Definition: rf-core.c:549
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
int rf_core_power_up()
Turn on power to the RFC and boot it.
Definition: rf-core.c:278
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
Definition: rf-core.c:387
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
Definition: rf-core.c:425
Header file for the CC13xx/CC26xx RF core driver.
void rf_core_primary_mode_abort()
Abort the currently running primary radio op.
Definition: rf-core.c:570
#define RTIMER_SECOND
Number of rtimer ticks for 1 second.
Definition: rtimer.h:112
int16_t sfd_timestamp_offset
Offset of the end of SFD when compared to the radio HW-generated timestamp.
Definition: rf-core.h:146
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:185
uint32_t rf_core_cmd_status(void)
Get the status of the last issued radio command.
Definition: rf-core.c:250
uint32_t rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
Convert from RAT timestamp to rtimer ticks.
Definition: rf-core.c:667
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
void(* input)(void)
Callback for getting notified of incoming packet.
Definition: mac.h:72
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
Definition: rf-core.c:564
A data strcuture representing the radio&#39;s primary mode of operation.
Definition: rf-core.h:125
uint8_t(* is_on)(void)
A pointer to a function that checks if the radio is on.
Definition: rf-core.h:141
void process_poll(struct process *p)
Request a process to be polled.
Definition: process.c:371
uint8_t rf_core_rat_init(void)
Initialize the RAT to RTC conversion machinery.
Definition: rf-core.c:592
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:67
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_cmd_done_dis(void)
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
Definition: rf-core.c:542
Header file for the Contiki process interface.
uint8_t(* restore)(void)
A pointer to a function that will restore the previous radio op.
Definition: rf-core.h:135
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:555
uint8_t rf_core_primary_mode_restore()
Abort the currently running primary radio op.
Definition: rf-core.c:580
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:147
void(* abort)(void)
A pointer to a function used to abort the current radio op.
Definition: rf-core.h:129
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Definition: rf-core.c:156
Header file for the Packet buffer (packetbuf) management
void rf_core_setup_interrupts(void)
Setup RF core interrupts.
Definition: rf-core.c:494
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:327
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:85
uint8_t rf_core_restart_rat(void)
Restart the CM0 RAT.
Definition: rf-core.c:475
Default definitions of C compiler quirk work-arounds.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1110
uint8_t rf_core_boot()
Boot the RF Core.
Definition: rf-core.c:453
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
Definition: rf-core.c:528
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:136
uint8_t rf_core_stop_rat(void)
Stop the CM0 RAT synchronously.
Definition: rf-core.c:355
uint8_t rf_core_check_rat_overflow(void)
Check if RAT overflow has occured and increment the overflow counter if so.
Definition: rf-core.c:603
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
Definition: rf-core.c:228