diff --git a/boards/openmote-b/include/board.h b/boards/openmote-b/include/board.h index b79ce092fd..29c47f3b71 100644 --- a/boards/openmote-b/include/board.h +++ b/boards/openmote-b/include/board.h @@ -77,6 +77,15 @@ #define RF24_SWITCH_AT86RF215_TOGGLE (RF_SWITCH_PORT->DATA ^= RF24_SWITCH_AT86RF215_MASK) /** @} */ +/** + * @name RF CORE observable signals settings + * @{ + */ +#define CONFIG_CC2538_RF_OBS_SIG_0_PCX 5 /* PC5 */ +#define CONFIG_CC2538_RF_OBS_SIG_1_PCX 6 /* PC6 */ +#define CONFIG_CC2538_RF_OBS_SIG_2_PCX 7 /* PC7 */ +/** @} */ + /** * @name AT86RF215 configuration * @{ diff --git a/boards/openmote-cc2538/include/board.h b/boards/openmote-cc2538/include/board.h index e28144bbd5..0447de519c 100644 --- a/boards/openmote-cc2538/include/board.h +++ b/boards/openmote-cc2538/include/board.h @@ -81,6 +81,15 @@ #define CCA_BACKDOOR_ACTIVE_LEVEL (0) /**< Active low */ /** @} */ +/** + * @name RF CORE observable signals settings + * @{ + */ +#define CONFIG_CC2538_RF_OBS_SIG_0_PCX 5 /* PC5 */ +#define CONFIG_CC2538_RF_OBS_SIG_1_PCX 6 /* PC6 */ +#define CONFIG_CC2538_RF_OBS_SIG_2_PCX 7 /* PC7 */ +/** @} */ + /** * @brief Initialize board specific hardware, including clock, LEDs and std-IO */ diff --git a/cpu/cc2538/include/cc2538_rf.h b/cpu/cc2538/include/cc2538_rf.h index 1950914064..7803b46016 100644 --- a/cpu/cc2538/include/cc2538_rf.h +++ b/cpu/cc2538/include/cc2538_rf.h @@ -24,6 +24,8 @@ #include +#include "board.h" + #include "net/ieee802154.h" #include "kernel_defines.h" @@ -153,6 +155,15 @@ enum { /* * @brief RFCORE_XREG_FRMCTRL0 bits */ +enum { + SET_RXENMASK_ON_TX = BIT(0), + IGNORE_TX_UNDERF = BIT(1), + PENDING_OR = BIT(2), +}; + + /* + * @brief RFCORE_XREG_FRMCTRL1 bits + */ enum { ENERGY_SCAN = BIT(4), AUTOACK = BIT(5), @@ -187,7 +198,6 @@ enum { }; /* Values for use with CCTEST_OBSSELx registers: */ -#define OBSSEL_EN BIT(7) enum { rfc_obs_sig0 = 0, rfc_obs_sig1 = 1, @@ -196,27 +206,83 @@ enum { /* Values for RFCORE_XREG_RFC_OBS_CTRLx registers: */ enum { - constant_value_0 = 0x00, - constant_value_1 = 0x01, - rfc_sniff_data = 0x08, - rfc_sniff_clk = 0x09, - rssi_valid = 0x0c, - demod_cca = 0x0d, - sampled_cca = 0x0e, - sfd_sync = 0x0f, - tx_active = 0x10, - rx_active = 0x11, - ffctrl_fifo = 0x12, - ffctrl_fifop = 0x13, - packet_done = 0x14, - rfc_xor_rand_i_q = 0x16, - rfc_rand_q = 0x17, - rfc_rand_i = 0x18, - lock_status = 0x19, - pa_pd = 0x20, - lna_pd = 0x2a, + constant_value_0 = 0x00, /**< Constant value 0 */ + constant_value_1 = 0x01, /**< Constant value 1*/ + rfc_sniff_data = 0x08, /**< Data from packet sniffer. Sample data + on rising edges of sniff_clk.*/ + rfc_sniff_clk = 0x09, /**< 250kHz clock for packet sniffer data.*/ + rssi_valid = 0x0c, /**< Pin is high when the RSSI value has + been updated at least once since RX was + started. Cleared when leaving RX.*/ + demod_cca = 0x0d, /**< Clear channel assessment. See FSMSTAT1 + register for details on how to configure + the behavior of this signal. */ + sampled_cca = 0x0e, /**< A sampled version of the CCA bit from + demodulator. The value is updated whenever + a SSAMPLECCA or STXONCCA strobe is issued.*/ + sfd_sync = 0x0f, /**< Pin is high when a SFD has been received + or transmitted. Cleared when leaving + RX/TX respectively. Not to be confused + with the SFD exception.*/ + tx_active = 0x10, /**< Indicates that FFCTRL is in one of the TX + states. Active-high.*/ + rx_active = 0x11, /**< Indicates that FFCTRL is in one of the + RX states. Active-high. */ + ffctrl_fifo = 0x12, /**< Pin is high when one or more bytes are + in the RXFIFO. Low during RXFIFO overflow. */ + ffctrl_fifop = 0x13, /**< Pin is high when the number of bytes + in the RXFIFO exceeds the programmable + threshold or at least one complete + frame is in the RXFIFO. Also highduring + RXFIFO overflow. Not to be confused with + the FIFOP exception.*/ + packet_done = 0x14, /**< A complete frame has been received. + I.e., the number of bytes set by the + frame-length field has been received.*/ + rfc_xor_rand_i_q = 0x16, /**< XOR between I and Q random outputs. + Updated at 8 MHz.*/ + rfc_rand_q = 0x17, /**< Random data output from the Q channel + of the receiver. Updated at 8 MHz.*/ + rfc_rand_i = 0x18, /**< Random data output from the I channel + of the receiver. Updated at 8 MHz */ + lock_status = 0x19, /**< 1 when PLL is in lock, otherwise 0 */ + pa_pd = 0x20, /**< Power amplifier power-down signal */ + lna_pd = 0x2a, /**< LNA power-down signal*/ + disabled = 0xff, /**< disabled */ }; +/** @} */ + +/** + * @name RF CORE observable signals settings + */ +#ifndef CONFIG_CC2538_RF_OBS_0 +#define CONFIG_CC2538_RF_OBS_0 tx_active +#endif +#ifndef CONFIG_CC2538_RF_OBS_1 +#define CONFIG_CC2538_RF_OBS_1 rx_active +#endif +#ifndef CONFIG_CC2538_RF_OBS_2 +#define CONFIG_CC2538_RF_OBS_2 rssi_valid +#endif + +/* Default configration for cc2538dk or similar */ +#ifndef CONFIG_CC2538_RF_OBS_SIG_0_PCX +#define CONFIG_CC2538_RF_OBS_SIG_0_PCX 0 /* PC0 = LED_1 (red) */ +#endif +#ifndef CONFIG_CC2538_RF_OBS_SIG_1_PCX +#define CONFIG_CC2538_RF_OBS_SIG_1_PCX 1 /* PC0 = LED_2 (red) */ +#endif +#ifndef CONFIG_CC2538_RF_OBS_SIG_2_PCX +#define CONFIG_CC2538_RF_OBS_SIG_2_PCX 2 /* PC0 = LED_3 (red) */ +#endif +#if ((CONFIG_CC2538_RF_OBS_SIG_2_PCX > 7) || \ + (CONFIG_CC2538_RF_OBS_SIG_1_PCX > 7) || \ + (CONFIG_CC2538_RF_OBS_SIG_0_PCX > 7)) +#error "CONFIG_CC2538_RF_OBS_SIG_X_PCX must be between 0-7 (PC0-PC7)" +#endif +/** @} */ + /** * @brief Device descriptor for CC2538 transceiver * diff --git a/cpu/cc2538/radio/cc2538_rf.c b/cpu/cc2538/radio/cc2538_rf.c index bfaf6896b8..441a4d6088 100644 --- a/cpu/cc2538/radio/cc2538_rf.c +++ b/cpu/cc2538/radio/cc2538_rf.c @@ -28,7 +28,7 @@ #define ENABLE_DEBUG (0) #include "debug.h" -/* +/** * @brief MAC timer period * * The period is set to the CSMA-CA Backoff Period Unit (20 symbols, 320 us). @@ -38,42 +38,53 @@ #define TIMER_PERIOD_LSB (0xF2) #define TIMER_PERIOD_MSB (0x29) -typedef struct { - cc2538_reg_t *reg_addr; - uint32_t value; -} init_pair_t; +/** + * @brief MAC timer period + * + * The period is set to the CSMA-CA Backoff Period Unit (20 symbols, 320 us). + * The system clock runs at 32 MHz. Thus, the timeout period is + * 320us * 32MHz = ~10738 (0x29F2) + */ +#define CCTEST_OBSSELX_EN (BIT(7)) + +static void _cc2538_setup_mac_timer(void) +{ + RFCORE_SFR_MTMSEL &= ~CC2538_SFR_MTMSEL_MASK; + /* Select timer period */ + RFCORE_SFR_MTMSEL |= CC2538_SFR_MTMSEL_TIMER_P; + + /* Fix timer to Backoff period */ + RFCORE_SFR_MTM0 |= TIMER_PERIOD_LSB; + RFCORE_SFR_MTM1 |= TIMER_PERIOD_MSB; + + RFCORE_SFR_MTMSEL &= ~CC2538_SFR_MTMSEL_MASK; + RFCORE_SFR_MTCTRL |= CC2538_MCTRL_SYNC_MASK | CC2538_MCTRL_RUN_MASK; +} + +static void _cc2538_observable_signals(void) +{ + /* Select on which pin PC0:7 should the selected observable signals + be wired through, the signal is selected in CONFIG_CC2538_RF_OBS_% + and the pin in CONFIG_CC2538_RF_OBS_SIG_%_PCX */ + if (IS_USED(MODULE_CC2538_RF_OBS_SIG)) { + if (CONFIG_CC2538_RF_OBS_0 != disabled) { + RFCORE_XREG_RFC_OBS_CTRL0 = CONFIG_CC2538_RF_OBS_0; + *(&CCTEST_OBSSEL0 + CONFIG_CC2538_RF_OBS_SIG_0_PCX) = \ + CCTEST_OBSSELX_EN | rfc_obs_sig0; + } + if (CONFIG_CC2538_RF_OBS_1 != disabled) { + RFCORE_XREG_RFC_OBS_CTRL1 = CONFIG_CC2538_RF_OBS_1; + *(&CCTEST_OBSSEL0 + CONFIG_CC2538_RF_OBS_SIG_1_PCX) = \ + CCTEST_OBSSELX_EN | rfc_obs_sig1; + } + if (CONFIG_CC2538_RF_OBS_2 != disabled) { + RFCORE_XREG_RFC_OBS_CTRL2 = CONFIG_CC2538_RF_OBS_2; + *(&CCTEST_OBSSEL0 + CONFIG_CC2538_RF_OBS_SIG_2_PCX) = \ + CCTEST_OBSSELX_EN | rfc_obs_sig2; + } + } +} -static const init_pair_t init_table[] = { - {&SYS_CTRL_RCGCRFC, 0x01 }, - {&SYS_CTRL_SCGCRFC, 0x01 }, - {&SYS_CTRL_DCGCRFC, 0x01 }, - {&RFCORE_XREG_CCACTRL0, 0xf8 }, - {&RFCORE_XREG_TXFILTCFG, 0x09 }, - {&RFCORE_XREG_AGCCTRL1, 0x15 }, - {&ANA_REGS_IVCTRL, 0x0b }, - {&RFCORE_XREG_MDMTEST1, 0x08 }, - {&RFCORE_XREG_FSCAL1, 0x01 }, - {&RFCORE_XREG_RXCTRL, 0x3f }, - {&RFCORE_XREG_MDMCTRL1, 0x14 }, - {&RFCORE_XREG_ADCTEST0, 0x10 }, - {&RFCORE_XREG_ADCTEST1, 0x0e }, - {&RFCORE_XREG_ADCTEST2, 0x03 }, - {&RFCORE_XREG_CSPT, 0xff }, - {&RFCORE_XREG_MDMCTRL0, 0x85 }, - {&RFCORE_XREG_FSCTRL, 0x55 }, - {&RFCORE_XREG_FRMCTRL0, AUTOCRC | AUTOACK }, - {&RFCORE_XREG_FRMCTRL1, 0x00 }, - {&RFCORE_XREG_SRCMATCH, 0x00 }, - {&RFCORE_XREG_FIFOPCTRL, CC2538_RF_MAX_DATA_LEN }, -#if IS_USED(MODULE_IEEE802154_RADIO_HAL) - {&RFCORE_XREG_RFIRQM0, FIFOP | RXPKTDONE | SFD }, - {&RFCORE_XREG_RFIRQM1, TXDONE | CSP_STOP | TXACKDONE }, -#else - {&RFCORE_XREG_RFIRQM0, FIFOP | RXPKTDONE }, -#endif - {&RFCORE_XREG_RFERRM, STROBE_ERR | TXUNDERF | TXOVERF | RXUNDERF | RXOVERF | NLOCK}, - {NULL, 0}, -}; bool cc2538_channel_clear(void) { @@ -93,41 +104,54 @@ bool cc2538_channel_clear(void) void cc2538_init(void) { - const init_pair_t *pair; + /* Enable RF CORE clock in active mode */ + SYS_CTRL_RCGCRFC = 1UL; + /* Enable RF CORE clock in sleep mode */ + SYS_CTRL_SCGCRFC = 1UL; + /* Enable RF CORE clock in PM0 (system clock always powered down + in PM1-3) */ + SYS_CTRL_DCGCRFC = 1UL; + /* Wait for the clock enabling to take effect */ + while (!(SYS_CTRL_RCGCRFC & 1UL) || \ + !(SYS_CTRL_SCGCRFC & 1UL) || \ + !(SYS_CTRL_DCGCRFC & 1UL) + ) {} - for (pair = init_table; pair->reg_addr != NULL; pair++) { - *pair->reg_addr = pair->value; + /* Register Setting updates for optimal performance, RM section 23.15 */ + RFCORE_XREG_TXFILTCFG = 0x09; + RFCORE_XREG_AGCCTRL1 = 0x15; + RFCORE_XREG_FSCAL1 = 0x01; + ANA_REGS_IVCTRL = 0x0B; + + /* Enable AUTOCRC and AUTOACK by default*/ + RFCORE_XREG_FRMCTRL0 = AUTOCRC | AUTOACK; + + /* Disable RX after TX, let upper layer change the state */ + RFCORE_XREG_FRMCTRL1 = 0x00; + + /* Disable source address matching and pending bits */ + RFCORE_XREG_SRCMATCH = 0x00; + + /* Set FIFOP_THR to its max value*/ + RFCORE_XREG_FIFOPCTRL = CC2538_RF_MAX_DATA_LEN; + + /* Set default IRQ */ + if (IS_USED(MODULE_IEEE802154_RADIO_HAL)) { + RFCORE_XREG_RFIRQM1 = TXDONE | CSP_STOP | TXACKDONE; + RFCORE_XREG_RFIRQM0 = RXPKTDONE | FIFOP | SFD; + } else { + RFCORE_XREG_RFIRQM0 = RXPKTDONE | FIFOP; } - /* Select the observable signals (maximum of three) */ - RFCORE_XREG_RFC_OBS_CTRL0 = tx_active; - RFCORE_XREG_RFC_OBS_CTRL1 = rx_active; - RFCORE_XREG_RFC_OBS_CTRL2 = ffctrl_fifo; + /* Enable all RF CORE error interrupts */ + RFCORE_XREG_RFERRM = STROBE_ERR | TXUNDERF | TXOVERF | \ + RXUNDERF | RXOVERF | NLOCK; - /* Select output pins for the three observable signals */ -#ifdef BOARD_OPENMOTE_CC2538 - CCTEST_OBSSEL0 = 0; /* PC0 = USB_SEL */ - CCTEST_OBSSEL1 = 0; /* PC1 = N/C */ - CCTEST_OBSSEL2 = 0; /* PC2 = N/C */ - CCTEST_OBSSEL3 = 0; /* PC3 = USER_BUTTON */ - CCTEST_OBSSEL4 = OBSSEL_EN | rfc_obs_sig0; /* PC4 = RED_LED */ - CCTEST_OBSSEL5 = 0; /* PC5 = ORANGE_LED */ - CCTEST_OBSSEL6 = OBSSEL_EN | rfc_obs_sig1; /* PC6 = YELLOW_LED */ - CCTEST_OBSSEL7 = OBSSEL_EN | rfc_obs_sig2; /* PC7 = GREEN_LED */ -#else - /* Assume BOARD_CC2538DK (or similar). */ - CCTEST_OBSSEL0 = OBSSEL_EN | rfc_obs_sig0; /* PC0 = LED_1 (red) */ - CCTEST_OBSSEL1 = OBSSEL_EN | rfc_obs_sig1; /* PC1 = LED_2 (yellow) */ - CCTEST_OBSSEL2 = OBSSEL_EN | rfc_obs_sig2; /* PC2 = LED_3 (green) */ - CCTEST_OBSSEL3 = 0; /* PC3 = LED_4 (red) */ - CCTEST_OBSSEL4 = 0; /* PC4 = BTN_L */ - CCTEST_OBSSEL5 = 0; /* PC5 = BTN_R */ - CCTEST_OBSSEL6 = 0; /* PC6 = BTN_UP */ - CCTEST_OBSSEL7 = 0; /* PC7 = BTN_DN */ -#endif /* BOARD_OPENMOTE_CC2538 */ + _cc2538_observable_signals(); - if (SYS_CTRL->I_MAP) { - NVIC_SetPriority(RF_RXTX_ALT_IRQn, RADIO_IRQ_PRIO); + /* Enable IRQs */ + if (SYS_CTRL_I_MAP) { + NVIC_SetPriority(RF_RXTX_ALT_IRQn, CPU_DEFAULT_IRQ_PRIO); NVIC_EnableIRQ(RF_RXTX_ALT_IRQn); NVIC_SetPriority(RF_ERR_ALT_IRQn, CPU_DEFAULT_IRQ_PRIO); @@ -147,16 +171,8 @@ void cc2538_init(void) NVIC_EnableIRQ(MACTIMER_IRQn); } - RFCORE_SFR_MTMSEL &= ~CC2538_SFR_MTMSEL_MASK; - /* Select timer period */ - RFCORE_SFR_MTMSEL |= CC2538_SFR_MTMSEL_TIMER_P; - - /* Fix timer to Backoff period */ - RFCORE_SFR_MTM0 |= TIMER_PERIOD_LSB; - RFCORE_SFR_MTM1 |= TIMER_PERIOD_MSB; - - RFCORE_SFR_MTMSEL &= ~CC2538_SFR_MTMSEL_MASK; - RFCORE_SFR_MTCTRL |= CC2538_MCTRL_SYNC_MASK | CC2538_MCTRL_RUN_MASK; + /* setup mac timer */ + _cc2538_setup_mac_timer(); /* Flush the receive and transmit FIFOs */ RFCORE_SFR_RFST = ISFLUSHTX; @@ -165,7 +181,8 @@ void cc2538_init(void) bool cc2538_is_on(void) { - return RFCORE->XREG_FSMSTAT1bits.RX_ACTIVE || RFCORE->XREG_FSMSTAT1bits.TX_ACTIVE; + return RFCORE->XREG_FSMSTAT1bits.RX_ACTIVE || \ + RFCORE->XREG_FSMSTAT1bits.TX_ACTIVE; } void cc2538_off(void) diff --git a/cpu/cc2538/radio/cc2538_rf_internal.c b/cpu/cc2538/radio/cc2538_rf_internal.c index 4d2195dc93..fb2a576a6d 100644 --- a/cpu/cc2538/radio/cc2538_rf_internal.c +++ b/cpu/cc2538/radio/cc2538_rf_internal.c @@ -64,7 +64,7 @@ void isr_rfcoreerr(void) void isr_rfcorerxtx(void) { - cc2538_irq_handler(); + cc2538_irq_handler(); cortexm_isr_end(); } diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 41295be5f5..77eec98249 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -9,6 +9,7 @@ PSEUDOMODULES += can_mbox PSEUDOMODULES += can_pm PSEUDOMODULES += can_raw PSEUDOMODULES += ccn-lite-utils +PSEUDOMODULES += cc2538_rf_obs_sig PSEUDOMODULES += conn_can_isotp_multi PSEUDOMODULES += cord_ep_standalone PSEUDOMODULES += core_%