40 #include "dev/watchdog.h" 51 #include "hw_rfc_dbell.h" 52 #include "hw_rfc_pwr.h" 55 #include "driverlib/rf_mailbox.h" 56 #include "driverlib/rf_common_cmd.h" 57 #include "driverlib/rf_data_entry.h" 66 #define PRINTF(...) printf(__VA_ARGS__) 71 #ifdef RF_CORE_CONF_DEBUG_CRC 72 #define RF_CORE_DEBUG_CRC RF_CORE_CONF_DEBUG_CRC 74 #define RF_CORE_DEBUG_CRC DEBUG 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 84 #define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ | RX_NOK_IRQ) 86 #define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ) 89 #define ENABLED_IRQS_POLL_MODE (ENABLED_IRQS & ~(RX_FRAME_IRQ | ERROR_IRQ)) 91 #define cc26xx_rf_cpe0_isr RFCCPE0IntHandler 92 #define cc26xx_rf_cpe1_isr RFCCPE1IntHandler 94 typedef ChipType_t chip_type_t;
97 static rfc_radioOp_t *last_radio_op = NULL;
103 #define RAT_RANGE 4294967296ull 105 #define RAT_OVERFLOW_PERIOD_SECONDS (60 * 18) 108 #define RAT_OVERFLOW_TIMER_INTERVAL (CLOCK_SECOND * RAT_OVERFLOW_PERIOD_SECONDS / 3) 111 static int32_t rat_offset;
112 static bool rat_offset_known;
115 static uint32_t rat_last_value;
118 static struct ctimer rat_overflow_timer;
119 static volatile uint32_t rat_overflow_counter;
120 static rtimer_clock_t rat_last_overflow;
122 static void rat_overflow_check_timer_cb(
void *);
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;
129 uint8_t rf_core_poll_mode = 0;
132 volatile bool rf_core_rx_is_full =
false;
134 volatile uint32_t last_cmd_status;
136 PROCESS(rf_core_process,
"CC13xx / CC26xx RF driver");
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) 144 #define RF_CMD0 0x0607 149 if(ti_lib_prcm_rf_ready()) {
150 return RF_CORE_ACCESSIBLE;
152 return RF_CORE_NOT_ACCESSIBLE;
158 uint32_t timeout_count = 0;
159 bool interrupts_disabled;
160 bool is_radio_op =
false;
163 last_cmd_status = (uint32_t)-1;
164 *status = last_cmd_status;
170 if((cmd & 0x03) == 0) {
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) {
176 ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE;
184 interrupts_disabled = ti_lib_int_master_disable();
187 PRINTF(
"rf_core_send_cmd: RF was off\n");
188 if(!interrupts_disabled) {
189 ti_lib_int_master_enable();
191 return RF_CORE_CMD_ERROR;
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;
202 HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd;
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();
210 *status = last_cmd_status;
211 return RF_CORE_CMD_ERROR;
213 }
while((last_cmd_status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_PENDING);
215 if(!interrupts_disabled) {
216 ti_lib_int_master_enable();
223 *status = last_cmd_status;
224 return (last_cmd_status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_DONE;
230 volatile rfc_radioOp_t *command = (rfc_radioOp_t *)cmd;
231 uint32_t timeout_cnt = 0;
238 if(++timeout_cnt > 500000) {
239 return RF_CORE_CMD_ERROR;
241 }
while((command->status & RF_CORE_RADIO_OP_MASKED_STATUS)
242 != RF_CORE_RADIO_OP_MASKED_STATUS_DONE);
244 last_cmd_status = command->status;
245 return (command->status & RF_CORE_RADIO_OP_MASKED_STATUS)
246 == RF_CORE_RADIO_OP_STATUS_DONE_OK;
252 return last_cmd_status;
258 rfc_CMD_FS_POWERDOWN_t cmd;
264 PRINTF(
"fs_powerdown: CMDSTA=0x%08lx\n", cmd_status);
265 return RF_CORE_CMD_ERROR;
269 PRINTF(
"fs_powerdown: CMDSTA=0x%08lx, status=0x%04x\n",
270 cmd_status, cmd.status);
271 return RF_CORE_CMD_ERROR;
274 return RF_CORE_CMD_OK;
281 bool interrupts_disabled = ti_lib_int_master_disable();
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);
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);
293 ti_lib_prcm_domain_enable(PRCM_DOMAIN_RFCORE);
294 ti_lib_prcm_load_set();
295 while(!ti_lib_prcm_load_get());
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);
302 if(!interrupts_disabled) {
303 ti_lib_int_master_enable();
306 rf_switch_power_up();
309 HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK;
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);
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;
323 return RF_CORE_CMD_OK;
330 rfc_CMD_SYNC_START_RAT_t cmd_start;
336 cmd_start.rat0 = rat_offset;
339 PRINTF(
"rf_core_get_rat_rtc_offset: SYNC_START_RAT fail, CMDSTA=0x%08lx\n",
341 return RF_CORE_CMD_ERROR;
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;
351 return RF_CORE_CMD_OK;
357 rfc_CMD_SYNC_STOP_RAT_t cmd_stop;
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",
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);
377 if(!rat_offset_known) {
379 rat_offset_known =
true;
380 rat_offset = cmd_stop.rat0;
383 return RF_CORE_CMD_OK;
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);
394 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
395 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0;
404 ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE);
405 ti_lib_prcm_load_set();
406 while(!ti_lib_prcm_load_get());
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);
413 rf_switch_power_down();
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();
427 uint8_t rv = RF_CORE_CMD_ERROR;
428 chip_type_t chip_type = ti_lib_chipinfo_get_chip_type();
430 if(chip_type == CHIP_TYPE_CC2650) {
431 HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
433 }
else if(chip_type == CHIP_TYPE_CC2630) {
434 HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2;
436 }
else if(chip_type == CHIP_TYPE_CC1310) {
437 HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3;
439 }
else if(chip_type == CHIP_TYPE_CC1350) {
440 HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5;
442 #if CPU_FAMILY_CC26X0R2 443 }
else if(chip_type == CHIP_TYPE_CC2640R2) {
444 HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE1;
456 PRINTF(
"rf_core_boot: rf_core_power_up() failed\n");
460 return RF_CORE_CMD_ERROR;
464 PRINTF(
"rf_core_boot: rf_core_start_rat() failed\n");
468 return RF_CORE_CMD_ERROR;
471 return RF_CORE_CMD_OK;
478 PRINTF(
"rf_core_restart_rat: rf_core_stop_rat() failed\n");
483 PRINTF(
"rf_core_restart_rat: rf_core_start_rat() failed\n");
487 return RF_CORE_CMD_ERROR;
490 return RF_CORE_CMD_OK;
496 bool interrupts_disabled;
497 const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
501 PRINTF(
"setup_interrupts: No access\n");
506 interrupts_disabled = ti_lib_int_master_disable();
509 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ;
512 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = enabled_irqs;
515 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0;
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);
522 if(!interrupts_disabled) {
523 ti_lib_int_master_enable();
531 const uint32_t enabled_irqs = rf_core_poll_mode ? ENABLED_IRQS_POLL_MODE : ENABLED_IRQS;
533 if(!rf_core_poll_mode) {
534 irq = fg ? IRQ_LAST_FG_COMMAND_DONE : IRQ_LAST_COMMAND_DONE;
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;
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;
551 return last_radio_op;
559 op->commandNo = command;
560 op->condition.rule = COND_NEVER;
573 if(primary_mode->
abort) {
574 primary_mode->
abort();
584 return primary_mode->
restore();
588 return RF_CORE_CMD_ERROR;
594 rat_last_value = HWREG(RFC_RAT_BASE + RATCNT);
596 ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_TIMER_INTERVAL,
597 rat_overflow_check_timer_cb, NULL);
605 uint32_t rat_current_value;
606 uint8_t interrupts_disabled;
609 if(primary_mode == NULL || !primary_mode->
is_on()) {
613 interrupts_disabled = ti_lib_int_master_disable();
615 rat_current_value = HWREG(RFC_RAT_BASE + RATCNT);
616 if(rat_current_value + RAT_RANGE / 4 < rat_last_value) {
619 rat_overflow_counter++;
621 rat_last_value = rat_current_value;
623 if(!interrupts_disabled) {
624 ti_lib_int_master_enable();
631 rat_overflow_check_timer_cb(
void *unused)
636 if(primary_mode != NULL) {
638 if(!primary_mode->
is_on()) {
640 if(NETSTACK_RADIO.on() != RF_CORE_CMD_OK) {
641 PRINTF(
"overflow: on() failed\n");
643 rat_overflow_check_timer_cb, NULL);
651 NETSTACK_RADIO.off();
657 ctimer_set(&rat_overflow_timer, RAT_OVERFLOW_TIMER_INTERVAL,
658 rat_overflow_check_timer_cb, NULL);
662 rat_overflow_check_timer_cb, NULL);
669 uint64_t rat_timestamp64;
670 uint32_t adjusted_overflow_counter;
673 if(primary_mode == NULL) {
674 PRINTF(
"rf_core_convert_rat_to_rtimer: not initialized\n");
678 if(!primary_mode->
is_on()) {
686 NETSTACK_RADIO.off();
689 adjusted_overflow_counter = rat_overflow_counter;
693 if(rat_timestamp > (uint32_t)(RAT_RANGE * 3 / 4)) {
695 rat_last_overflow + RAT_OVERFLOW_PERIOD_SECONDS *
RTIMER_SECOND / 4)) {
696 adjusted_overflow_counter--;
701 rat_timestamp64 = rat_timestamp + RAT_RANGE * adjusted_overflow_counter;
705 return RADIO_TO_RTIMER(rat_timestamp64 - rat_offset);
724 NETSTACK_MAC.
input();
737 cc26xx_rf_cpe1_isr(
void)
739 PRINTF(
"RF Error\n");
747 if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & IRQ_RX_BUF_FULL) {
748 PRINTF(
"\nRF: BUF_FULL\n\n");
750 rf_core_rx_is_full =
true;
754 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ~(IRQ_RX_BUF_FULL);
758 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF;
762 cc26xx_rf_cpe0_isr(
void)
765 PRINTF(
"RF ISR called but RF not ready... PANIC!!\n");
767 PRINTF(
"rf_core_power_up() failed\n");
772 ti_lib_int_master_disable();
774 if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) {
776 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFF7FFFFF;
780 if(RF_CORE_DEBUG_CRC) {
781 if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) {
783 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFDFFFF;
788 if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) &
789 (IRQ_LAST_FG_COMMAND_DONE | IRQ_LAST_COMMAND_DONE)) {
791 HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0xFFFFFFF5;
794 ti_lib_int_master_enable();
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
#define PROCESS(name, strname)
Declare a process.
Header file with macros which rename TI CC26xxware functions.
void packetbuf_clear(void)
Clear and reset the packetbuf.
Header file for the energy estimation mechanism
#define PROCESS_YIELD_UNTIL(c)
Yield the currently running process until a condition occurs.
rfc_radioOp_t * rf_core_get_last_radio_op()
Returns a pointer to the most recent proto-dependent Radio Op.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
int rf_core_power_up()
Turn on power to the RFC and boot it.
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
Header file for the CC13xx/CC26xx RF core driver.
void rf_core_primary_mode_abort()
Abort the currently running primary radio op.
#define RTIMER_SECOND
Number of rtimer ticks for 1 second.
int16_t sfd_timestamp_offset
Offset of the end of SFD when compared to the radio HW-generated timestamp.
#define RTIMER_NOW()
Get the current clock time.
uint32_t rf_core_cmd_status(void)
Get the status of the last issued radio command.
uint32_t rf_core_convert_rat_to_rtimer(uint32_t rat_timestamp)
Convert from RAT timestamp to rtimer ticks.
#define CLOCK_SECOND
A second, measured in system clock time.
void(* input)(void)
Callback for getting notified of incoming packet.
void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode)
Register a primary mode for radio operation.
A data strcuture representing the radio's primary mode of operation.
uint8_t(* is_on)(void)
A pointer to a function that checks if the radio is on.
void process_poll(struct process *p)
Request a process to be polled.
uint8_t rf_core_rat_init(void)
Initialize the RAT to RTC conversion machinery.
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
void rf_core_cmd_done_dis(void)
Disable the LAST_CMD_DONE and LAST_FG_CMD_DONE interrupts.
Header file for the Contiki process interface.
uint8_t(* restore)(void)
A pointer to a function that will restore the previous radio op.
void rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command)
Prepare a buffer to host a Radio Op.
uint8_t rf_core_primary_mode_restore()
Abort the currently running primary radio op.
Header file with definitions related to RF switch support.
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
void(* abort)(void)
A pointer to a function used to abort the current radio op.
uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status)
Sends a command to the RF core.
Header file for the Packet buffer (packetbuf) management
void rf_core_setup_interrupts(void)
Setup RF core interrupts.
Include file for the Contiki low-layer network stack (NETSTACK)
uint8_t rf_core_start_rat(void)
Start the CM0 RAT.
void watchdog_periodic(void)
Writes the WDT clear sequence.
uint8_t rf_core_restart_rat(void)
Restart the CM0 RAT.
Default definitions of C compiler quirk work-arounds.
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
uint8_t rf_core_boot()
Boot the RF Core.
void rf_core_cmd_done_en(bool fg)
Enable interrupt on command done.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
uint8_t rf_core_stop_rat(void)
Stop the CM0 RAT synchronously.
uint8_t rf_core_check_rat_overflow(void)
Check if RAT overflow has occured and increment the overflow counter if so.
uint_fast8_t rf_core_wait_cmd_done(void *cmd)
Block and wait for a Radio op to complete.