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 /*---------------------------------------------------------------------------*/
134 PROCESS(rf_core_process, "CC13xx / CC26xx RF driver");
135 /*---------------------------------------------------------------------------*/
136 #define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \
137  | RFC_PWR_PWMCLKEN_CPERAM_M | RFC_PWR_PWMCLKEN_FSCA_M \
138  | RFC_PWR_PWMCLKEN_PHA_M | RFC_PWR_PWMCLKEN_RAT_M \
139  | RFC_PWR_PWMCLKEN_RFERAM_M | RFC_PWR_PWMCLKEN_RFE_M \
140  | RFC_PWR_PWMCLKEN_MDMRAM_M | RFC_PWR_PWMCLKEN_MDM_M)
141 /*---------------------------------------------------------------------------*/
142 #define RF_CMD0 0x0607
143 /*---------------------------------------------------------------------------*/
144 uint8_t
146 {
147  if(ti_lib_prcm_rf_ready()) {
148  return RF_CORE_ACCESSIBLE;
149  }
150  return RF_CORE_NOT_ACCESSIBLE;
151 }
152 /*---------------------------------------------------------------------------*/
153 uint_fast8_t
154 rf_core_send_cmd(uint32_t cmd, uint32_t *status)
155 {
156  uint32_t timeout_count = 0;
157  bool interrupts_disabled;
158  bool is_radio_op = false;
159 
160  /*
161  * If cmd is 4-byte aligned, then it's either a radio OP or an immediate
162  * command. Clear the status field if it's a radio OP
163  */
164  if((cmd & 0x03) == 0) {
165  uint32_t cmd_type;
166  cmd_type = ((rfc_command_t *)cmd)->commandNo & RF_CORE_COMMAND_TYPE_MASK;
167  if(cmd_type == RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP ||
168  cmd_type == RF_CORE_COMMAND_TYPE_RADIO_OP) {
169  is_radio_op = true;
170  ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
171  }
172  }
173 
174  /*
175  * Make sure ContikiMAC doesn't turn us off from within an interrupt while
176  * we are accessing RF Core registers
177  */
178  interrupts_disabled = ti_lib_int_master_disable();
179 
180  if(!rf_core_is_accessible()) {
181  PRINTF("rf_core_send_cmd: RF was off\n");
182  if(!interrupts_disabled) {
183  ti_lib_int_master_enable();
184  }
185  return RF_CORE_CMD_ERROR;
186  }
187 
188  if(is_radio_op) {
189  uint16_t command_no = ((rfc_radioOp_t *)cmd)->commandNo;
190  if((command_no & RF_CORE_COMMAND_PROTOCOL_MASK) != RF_CORE_COMMAND_PROTOCOL_COMMON &&
191  (command_no & RF_CORE_COMMAND_TYPE_MASK) == RF_CORE_COMMAND_TYPE_RADIO_OP) {
192  last_radio_op = (rfc_radioOp_t *)cmd;
193  }
194  }
195 
196  HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd;
197  do {
198  *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA);
199  if(++timeout_count > 50000) {
200  PRINTF("rf_core_send_cmd: 0x%08lx Timeout\n", cmd);
201  if(!interrupts_disabled) {
202  ti_lib_int_master_enable();
203  }
204  return RF_CORE_CMD_ERROR;
205  }
206  } while((*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_PENDING);
207 
208  if(!interrupts_disabled) {
209  ti_lib_int_master_enable();
210  }
211 
212  /*
213  * If we reach here the command is no longer pending. It is either completed
214  * successfully or with error
215  */
216  return (*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_DONE;
217 }
218 /*---------------------------------------------------------------------------*/
219 uint_fast8_t
221 {
222  volatile rfc_radioOp_t *command = (rfc_radioOp_t *)cmd;
223  uint32_t timeout_cnt = 0;
224 
225  /*
226  * 0xn4nn=DONE, 0x0400=DONE_OK while all other "DONE" values means done
227  * but with some kind of error (ref. "Common radio operation status codes")
228  */
229  do {
230  if(++timeout_cnt > 500000) {
231  return RF_CORE_CMD_ERROR;
232  }
233  } while((command->status & RF_CORE_RADIO_OP_MASKED_STATUS)
234  != RF_CORE_RADIO_OP_MASKED_STATUS_DONE);
235 
236  return (command->status & RF_CORE_RADIO_OP_MASKED_STATUS)
237  == RF_CORE_RADIO_OP_STATUS_DONE_OK;
238 }
239 /*---------------------------------------------------------------------------*/
240 static int
241 fs_powerdown(void)
242 {
243  rfc_CMD_FS_POWERDOWN_t cmd;
244  uint32_t cmd_status;
245 
246  rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_FS_POWERDOWN);
247 
248  if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) {
249  PRINTF("fs_powerdown: CMDSTA=0x%08lx\n", cmd_status);
250  return RF_CORE_CMD_ERROR;
251  }
252 
253  if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) {
254  PRINTF("fs_powerdown: CMDSTA=0x%08lx, status=0x%04x\n",
255  cmd_status, cmd.status);
256  return RF_CORE_CMD_ERROR;
257  }
258 
259  return RF_CORE_CMD_OK;
260 }
261 /*---------------------------------------------------------------------------*/
262 int
264 {
265  uint32_t cmd_status;
266  bool interrupts_disabled = ti_lib_int_master_disable();
267 
268  ti_lib_int_pend_clear(INT_RFC_CPE_0);
269  ti_lib_int_pend_clear(INT_RFC_CPE_1);
270  ti_lib_int_disable(INT_RFC_CPE_0);
271  ti_lib_int_disable(INT_RFC_CPE_1);
272 
273  /* Enable RF Core power domain */
274  ti_lib_prcm_power_domain_on(PRCM_DOMAIN_RFCORE);
275  while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE)
276  != PRCM_DOMAIN_POWER_ON);
277 
278  ti_lib_prcm_domain_enable(PRCM_DOMAIN_RFCORE);
279  ti_lib_prcm_load_set();
280  while(!ti_lib_prcm_load_get());
281 
282  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
283  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
284  ti_lib_int_enable(INT_RFC_CPE_0);
285  ti_lib_int_enable(INT_RFC_CPE_1);
286 
287  if(!interrupts_disabled) {
288  ti_lib_int_master_enable();
289  }
290 
291  rf_switch_power_up();
292 
293  /* Let CPE boot */
294  HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK;
295 
296  /* Turn on additional clocks on boot */
297  HWREG(RFC_DBELL_BASE + RFC_DBELL_O_RFACKIFG) = 0;
298  HWREG(RFC_DBELL_BASE+RFC_DBELL_O_CMDR) =
299  CMDR_DIR_CMD_2BYTE(RF_CMD0,
300  RFC_PWR_PWMCLKEN_MDMRAM | RFC_PWR_PWMCLKEN_RFERAM);
301 
302  /* Send ping (to verify RFCore is ready and alive) */
303  if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_PING), &cmd_status) != RF_CORE_CMD_OK) {
304  PRINTF("rf_core_power_up: CMD_PING fail, CMDSTA=0x%08lx\n", cmd_status);
305  return RF_CORE_CMD_ERROR;
306  }
307 
308  return RF_CORE_CMD_OK;
309 }
310 /*---------------------------------------------------------------------------*/
311 uint8_t
313 {
314  uint32_t cmd_status;
315  rfc_CMD_SYNC_START_RAT_t cmd_start;
316 
317  /* Start radio timer (RAT) */
318  rf_core_init_radio_op((rfc_radioOp_t *)&cmd_start, sizeof(cmd_start), CMD_SYNC_START_RAT);
319 
320  /* copy the value and send back */
321  cmd_start.rat0 = rat_offset;
322 
323  if(rf_core_send_cmd((uint32_t)&cmd_start, &cmd_status) != RF_CORE_CMD_OK) {
324  PRINTF("rf_core_get_rat_rtc_offset: SYNC_START_RAT fail, CMDSTA=0x%08lx\n",
325  cmd_status);
326  return RF_CORE_CMD_ERROR;
327  }
328 
329  /* Wait until done (?) */
330  if(rf_core_wait_cmd_done(&cmd_start) != RF_CORE_CMD_OK) {
331  PRINTF("rf_core_cmd_ok: SYNC_START_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n",
332  cmd_status, cmd_start.status);
333  return RF_CORE_CMD_ERROR;
334  }
335 
336  return RF_CORE_CMD_OK;
337 }
338 /*---------------------------------------------------------------------------*/
339 uint8_t
341 {
342  rfc_CMD_SYNC_STOP_RAT_t cmd_stop;
343  uint32_t cmd_status;
344 
345  rf_core_init_radio_op((rfc_radioOp_t *)&cmd_stop, sizeof(cmd_stop), CMD_SYNC_STOP_RAT);
346 
347  int ret = rf_core_send_cmd((uint32_t)&cmd_stop, &cmd_status);
348  if(ret != RF_CORE_CMD_OK) {
349  PRINTF("rf_core_get_rat_rtc_offset: SYNC_STOP_RAT fail, ret %d CMDSTA=0x%08lx\n",
350  ret, cmd_status);
351  return ret;
352  }
353 
354  /* Wait until done */
355  ret = rf_core_wait_cmd_done(&cmd_stop);
356  if(ret != RF_CORE_CMD_OK) {
357  PRINTF("rf_core_cmd_ok: SYNC_STOP_RAT wait, CMDSTA=0x%08lx, status=0x%04x\n",
358  cmd_status, cmd_stop.status);
359  return ret;
360  }
361 
362  if(!rat_offset_known) {
363  /* save the offset, but only if this is the first time */
364  rat_offset_known = true;
365  rat_offset = cmd_stop.rat0;
366  }
367 
368  return RF_CORE_CMD_OK;
369 }
370 /*---------------------------------------------------------------------------*/
371 void
373 {
374  bool interrupts_disabled = ti_lib_int_master_disable();
375  ti_lib_int_disable(INT_RFC_CPE_0);
376  ti_lib_int_disable(INT_RFC_CPE_1);
377 
378  if(rf_core_is_accessible()) {
379  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
380  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
381 
382  /* need to send FS_POWERDOWN or analog components will use power */
383  fs_powerdown();
384  }
385 
387 
388  /* Shut down the RFCORE clock domain in the MCU VD */
389  ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE);
390  ti_lib_prcm_load_set();
391  while(!ti_lib_prcm_load_get());
392 
393  /* Turn off RFCORE PD */
394  ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE);
395  while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE)
396  != PRCM_DOMAIN_POWER_OFF);
397 
398  rf_switch_power_down();
399 
400  ti_lib_int_pend_clear(INT_RFC_CPE_0);
401  ti_lib_int_pend_clear(INT_RFC_CPE_1);
402  ti_lib_int_enable(INT_RFC_CPE_0);
403  ti_lib_int_enable(INT_RFC_CPE_1);
404  if(!interrupts_disabled) {
405  ti_lib_int_master_enable();
406  }
407 }
408 /*---------------------------------------------------------------------------*/
409 uint8_t
411 {
412  uint8_t rv = RF_CORE_CMD_ERROR;
413  chip_type_t chip_type = ti_lib_chipinfo_get_chip_type();
414 
415  if(chip_type == CHIP_TYPE_CC2650) {
416  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
417  rv = RF_CORE_CMD_OK;
418  } else if(chip_type == CHIP_TYPE_CC2630) {
419  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2;
420  rv = RF_CORE_CMD_OK;
421  } else if(chip_type == CHIP_TYPE_CC1310) {
422  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3;
423  rv = RF_CORE_CMD_OK;
424  } else if(chip_type == CHIP_TYPE_CC1350) {
425  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
426  rv = RF_CORE_CMD_OK;
427 #if CPU_FAMILY_CC26X0R2
428  } else if(chip_type == CHIP_TYPE_CC2640R2) {
429  HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE1;
430  rv = RF_CORE_CMD_OK;
431 #endif
432  }
433 
434  return rv;
435 }
436 /*---------------------------------------------------------------------------*/
437 uint8_t
439 {
440  if(rf_core_power_up() != RF_CORE_CMD_OK) {
441  PRINTF("rf_core_boot: rf_core_power_up() failed\n");
442 
444 
445  return RF_CORE_CMD_ERROR;
446  }
447 
448  if(rf_core_start_rat() != RF_CORE_CMD_OK) {
449  PRINTF("rf_core_boot: rf_core_start_rat() failed\n");
450 
452 
453  return RF_CORE_CMD_ERROR;
454  }
455 
456  return RF_CORE_CMD_OK;
457 }
458 /*---------------------------------------------------------------------------*/
459 uint8_t
461 {
462  if(rf_core_stop_rat() != RF_CORE_CMD_OK) {
463  PRINTF("rf_core_restart_rat: rf_core_stop_rat() failed\n");
464  /* Don't bail out here, still try to start it */
465  }
466 
467  if(rf_core_start_rat() != RF_CORE_CMD_OK) {
468  PRINTF("rf_core_restart_rat: rf_core_start_rat() failed\n");
469 
471 
472  return RF_CORE_CMD_ERROR;
473  }
474 
475  return RF_CORE_CMD_OK;
476 }
477 /*---------------------------------------------------------------------------*/
478 void
480 {
481  bool interrupts_disabled;
482  const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
483 
484  /* We are already turned on by the caller, so this should not happen */
485  if(!rf_core_is_accessible()) {
486  PRINTF("setup_interrupts: No access\n");
487  return;
488  }
489 
490  /* Disable interrupts */
491  interrupts_disabled = ti_lib_int_master_disable();
492 
493  /* Set all interrupt channels to CPE0 channel, error to CPE1 */
494  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ;
495 
496  /* Acknowledge configured interrupts */
497  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs;
498 
499  /* Clear interrupt flags, active low clear(?) */
500  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
501 
502  ti_lib_int_pend_clear(INT_RFC_CPE_0);
503  ti_lib_int_pend_clear(INT_RFC_CPE_1);
504  ti_lib_int_enable(INT_RFC_CPE_0);
505  ti_lib_int_enable(INT_RFC_CPE_1);
506 
507  if(!interrupts_disabled) {
508  ti_lib_int_master_enable();
509  }
510 }
511 /*---------------------------------------------------------------------------*/
512 void
514 {
515  uint32_t irq = 0;
516  const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
517 
518  if(!rf_core_poll_mode) {
519  irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE;
520  }
521 
522  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = enabled_irqs;
523  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs | irq;
524 }
525 /*---------------------------------------------------------------------------*/
526 void
528 {
529  const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
530  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs;
531 }
532 /*---------------------------------------------------------------------------*/
533 rfc_radioOp_t *
535 {
536  return last_radio_op;
537 }
538 /*---------------------------------------------------------------------------*/
539 void
540 rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
541 {
542  memset(op, 0, len);
543 
544  op->commandNo = command;
545  op->condition.rule = COND_NEVER;
546 }
547 /*---------------------------------------------------------------------------*/
548 void
550 {
551  primary_mode = mode;
552 }
553 /*---------------------------------------------------------------------------*/
554 void
556 {
557  if(primary_mode) {
558  if(primary_mode->abort) {
559  primary_mode->abort();
560  }
561  }
562 }
563 /*---------------------------------------------------------------------------*/
564 uint8_t
566 {
567  if(primary_mode) {
568  if(primary_mode->restore) {
569  return primary_mode->restore();
570  }
571  }
572 
573  return RF_CORE_CMD_ERROR;
574 }
575 /*---------------------------------------------------------------------------*/
576 uint8_t
578 {
579  rat_last_value = HWREG(RFC_RAT_BASE + RATCNT);
580 
581  ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_TIMER_INTERVAL,
582  rat_overflow_check_timer_cb, NULL);
583 
584  return 1;
585 }
586 /*---------------------------------------------------------------------------*/
587 uint8_t
589 {
590  uint32_t rat_current_value;
591  uint8_t interrupts_disabled;
592 
593  /* Bail out if the RF is not on */
594  if(primary_mode == NULL || !primary_mode->is_on()) {
595  return 0;
596  }
597 
598  interrupts_disabled = ti_lib_int_master_disable();
599 
600  rat_current_value = HWREG(RFC_RAT_BASE + RATCNT);
601  if(rat_current_value + RAT_RANGE / 4 < rat_last_value) {
602  /* Overflow detected */
603  rat_last_overflow = RTIMER_NOW();
604  rat_overflow_counter++;
605  }
606  rat_last_value = rat_current_value;
607 
608  if(!interrupts_disabled) {
609  ti_lib_int_master_enable();
610  }
611 
612  return 1;
613 }
614 /*---------------------------------------------------------------------------*/
615 static void
616 rat_overflow_check_timer_cb(void *unused)
617 {
618  uint8_t success = 0;
619  uint8_t was_off = 0;
620 
621  if(primary_mode != NULL) {
622 
623  if(!primary_mode->is_on()) {
624  was_off = 1;
625  if(NETSTACK_RADIO.on() != RF_CORE_CMD_OK) {
626  PRINTF("overflow: on() failed\n");
627  ctimer_set(&rat_overflow_timer, CLOCK_SECOND,
628  rat_overflow_check_timer_cb, NULL);
629  return;
630  }
631  }
632 
633  success = rf_core_check_rat_overflow();
634 
635  if(was_off) {
636  NETSTACK_RADIO.off();
637  }
638  }
639 
640  if(success) {
641  /* Retry after half of the interval */
642  ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_TIMER_INTERVAL,
643  rat_overflow_check_timer_cb, NULL);
644  } else {
645  /* Retry sooner */
646  ctimer_set(&rat_overflow_timer, CLOCK_SECOND,
647  rat_overflow_check_timer_cb, NULL);
648  }
649 }
650 /*---------------------------------------------------------------------------*/
651 uint32_t
652 rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
653 {
654  uint64_t rat_timestamp64;
655  uint32_t adjusted_overflow_counter;
656  uint8_t was_off = 0;
657 
658  if(primary_mode == NULL) {
659  PRINTF("rf_core_convert_rat_to_rtimer: not initialized\n");
660  return 0;
661  }
662 
663  if(!primary_mode->is_on()) {
664  was_off = 1;
665  NETSTACK_RADIO.on();
666  }
667 
669 
670  if(was_off) {
671  NETSTACK_RADIO.off();
672  }
673 
674  adjusted_overflow_counter = rat_overflow_counter;
675 
676  /* if the timestamp is large and the last oveflow was recently,
677  assume that the timestamp refers to the time before the overflow */
678  if(rat_timestamp > (uint32_t)(RAT_RANGE * 3 / 4)) {
679  if(RTIMER_CLOCK_LT(RTIMER_NOW(),
680  rat_last_overflow + RAT_OVERFLOW_PERIOD_SECONDS * RTIMER_SECOND / 4)) {
681  adjusted_overflow_counter--;
682  }
683  }
684 
685  /* add the overflowed time to the timestamp */
686  rat_timestamp64 = rat_timestamp + RAT_RANGE * adjusted_overflow_counter;
687  /* correct timestamp so that it refers to the end of the SFD */
688  rat_timestamp64 += primary_mode->sfd_timestamp_offset;
689 
690  return RADIO_TO_RTIMER(rat_timestamp64 - rat_offset);
691 }
692 /*---------------------------------------------------------------------------*/
693 PROCESS_THREAD(rf_core_process, ev, data)
694 {
695  int len;
696 
697  PROCESS_BEGIN();
698 
699  while(1) {
700  PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
701  do {
703  packetbuf_clear();
704  len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE);
705 
706  if(len > 0) {
708 
709  NETSTACK_MAC.input();
710  }
711  } while(len > 0);
712  }
713  PROCESS_END();
714 }
715 /*---------------------------------------------------------------------------*/
716 static void
717 rx_nok_isr(void)
718 {
719 }
720 /*---------------------------------------------------------------------------*/
721 void
722 cc26xx_rf_cpe1_isr(void)
723 {
724  PRINTF("RF Error\n");
725 
726  if(!rf_core_is_accessible()) {
727  if(rf_core_power_up() != RF_CORE_CMD_OK) {
728  return;
729  }
730  }
731 
732  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & IRQ_RX_BUF_FULL) {
733  PRINTF("\nRF: BUF_FULL\n\n");
734  /* set a flag that the buffer is full*/
735  rf_core_rx_is_full = true;
736  /* make sure read_frame() will be called to make space in RX buffer */
737  process_poll(&rf_core_process);
738  /* Clear the IRQ_RX_BUF_FULL interrupt flag by writing zero to bit */
739  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ~(IRQ_RX_BUF_FULL);
740  }
741 
742  /* Clear INTERNAL_ERROR interrupt flag */
743  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF;
744 }
745 /*---------------------------------------------------------------------------*/
746 void
747 cc26xx_rf_cpe0_isr(void)
748 {
749  if(!rf_core_is_accessible()) {
750  printf("RF ISR called but RF not ready... PANIC!!\n");
751  if(rf_core_power_up() != RF_CORE_CMD_OK) {
752  PRINTF("rf_core_power_up() failed\n");
753  return;
754  }
755  }
756 
757  ti_lib_int_master_disable();
758 
759  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) {
760  /* Clear the RX_ENTRY_DONE interrupt flag */
761  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF;
762  process_poll(&rf_core_process);
763  }
764 
765  if(RF_CORE_DEBUG_CRC) {
766  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) {
767  /* Clear the RX_NOK interrupt flag */
768  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF;
769  rx_nok_isr();
770  }
771  }
772 
773  if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) &
774  (IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) {
775  /* Clear the two TX-related interrupt flags */
776  HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5;
777  }
778 
779  ti_lib_int_master_enable();
780 }
781 /*---------------------------------------------------------------------------*/
782 /** @} */
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:534
#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:263
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
Definition: rf-core.c:372
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
Definition: rf-core.c:410
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:555
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:160
uint32_t rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
Convert from RAT timestamp to rtimer ticks.
Definition: rf-core.c:652
#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:549
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:577
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:66
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:527
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:540
uint8_t rf_core_primary_mode_restore()
Abort the currently running primary radio op.
Definition: rf-core.c:565
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:145
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:154
Header file for the Packet buffer (packetbuf) management
void rf_core_setup_interrupts(void)
Setup RF core interrupts.
Definition: rf-core.c:479
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:312
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:460
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:1035
uint8_t rf_core_boot()
Boot the RF Core.
Definition: rf-core.c:438
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
Definition: rf-core.c:513
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:340
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:588
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.
Definition: rf-core.c:220