diff --git a/examples/Makefile-cc2538 b/examples/Makefile-cc2538 index 6aa766f0f..7bcd64dd1 100644 --- a/examples/Makefile-cc2538 +++ b/examples/Makefile-cc2538 @@ -70,6 +70,49 @@ COMMONCFLAGS := \ include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk +# Optional CC2592 options, first and foremost, whether to enable support for it +# at all. +ifeq ($(CC2592),1) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2538_WITH_CC2592=1 + +# If the PA_EN is on another port C pin, specify it with CC2592_PA_PIN. +ifneq ($(CC2592_PA_EN),) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2592_PA_EN_PIN=$(CC2592_PA_EN) +endif + +# If the LNA_EN is on another port C pin, specify it with CC2592_LNA_PIN. +ifneq ($(CC2592_LNA_EN),) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2592_LNA_EN_PIN=$(CC2592_LNA_EN) +endif + +# If we're not using HGM, set CC2538_USE_HGM to 0. +ifeq ($(CC2592_USE_HGM),0) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2592_USE_HGM=0 +else # CC2592_USE_HGM=1 + +# HGM in use, if not on port D, specify the port here (A, B or C) with CC2592_HGM_PORT. +ifneq ($(CC2592_HGM_PORT),) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2592_HGM_PORT=GPIO_$(CC2592_HGM_PORT)_BASE +endif + +# If HGM is not at pin 2, specify which pin here with CC2592_HGM_PIN. +ifneq ($(CC2592_HGM_PIN),) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2592_HGM_PIN=$(CC2592_HGM_PIN) +endif + +# If we want it off by default, specify CC2592_HGM_DEFAULT_STATE=0 +ifeq ($(CC2592_HGM_DEFAULT_STATE),0) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2592_HGM_DEFAULT_STATE=false +endif + +endif # CC2592_USE_HGM + +endif # CC2592 + +ifneq ($(CC2538_RECEIVE_SENSITIVITY),) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_CC2538_RECEIVE_SENSITIVITY=$(CC2538_RECEIVE_SENSITIVITY) +endif + CPPFLAGS += \ $(COMMONCFLAGS) \ $(target_CPPFLAGS) \ diff --git a/examples/platforms/cc2538/README.md b/examples/platforms/cc2538/README.md index f4539899f..64c6d31ae 100644 --- a/examples/platforms/cc2538/README.md +++ b/examples/platforms/cc2538/README.md @@ -34,6 +34,45 @@ $ ./bootstrap $ make -f examples/Makefile-cc2538 ``` +### CC2592 support + +If your board has a CC2592 range extender front-end IC connected to the CC2538 +(e.g. the CC2538-CC2592 EM reference design), you need to initialise this part +before reception of radio traffic will work. + +Support is enabled in OpenThread by building with `CC2592=1`: + +```bash +$ make -f examples/Makefile-cc2538 CC2592=1 +``` + +The default settings should work for any design following the integration +advice given in TI's application report ["AN130 - Using CC2592 Front End With +CC2538"](http://www.ti.com/lit/pdf/swra447). + +Additional settings can be customised: + +* `CC2592_PA_EN`: This specifies which pin (on port C of the CC2538) connects to the + CC2592's `PA_EN` pin. The default is `3` (PC3). +* `CC2592_LNA_EN`: This specifies which pin (on port C of the CC2538) connects to the + CC2592's `LNA_EN` pin. The default is `2` (PC2). +* `CC2592_USE_HGM`: This defines whether the HGM pin of the CC2592 is under GPIO control + or not. If not, it is assumed that the HGM pin is tied to a power rail. +* `CC2592_HGM_PORT`: The HGM pin can be connected to any free GPIO. TI recommend using + PD2, however if you've used a pin on another GPIO port, you may specify that port (`A`, + `B` or `C`) here. +* `CC2592_HGM_PORT`: The HGM pin can be connected to any free GPIO. TI recommend using + PD2, however if you've used a pin on another GPIO port, you may specify that port (`A`, + `B` or `C`) here. Default is `D`. +* `CC2592_HGM_PIN`: The HGM pin can be connected to any free GPIO. TI recommend using + PD2, however if you've used a pin on another GPIO pin, you can specify the pin here. + Default is `2`. +* `CC2592_HGM_DEFAULT_STATE`: By default, HGM is enabled at power-on, but you may want + to have it default to off, specify `CC2592_HGM_DEFAULT_STATE=0` to do so. +* `CC2538_RECEIVE_SENSITIVITY`: If you have tied the HGM pin to a power rail, this allows + you to calibrate the RSSI values according to the new receive sensitivity. This has no + effect if `CC2592_USE_HGM=1` (the default). + ## Flash Binaries If the build completed successfully, the `elf` files may be found in diff --git a/examples/platforms/cc2538/cc2538-reg.h b/examples/platforms/cc2538/cc2538-reg.h index 98e8d234d..0da810b8a 100644 --- a/examples/platforms/cc2538/cc2538-reg.h +++ b/examples/platforms/cc2538/cc2538-reg.h @@ -41,6 +41,14 @@ #define HWREG(x) (*((volatile uint32_t *)(x))) +/*! + * For registers that are arrays of 32-bit integers. + * + * @param reg Register address + * @param idx Register array index + */ +#define HWREG_ARR(reg, idx) HWREG((reg) + ((idx) << 2)) + #define NVIC_ST_CTRL 0xE000E010 // SysTick Control and Status #define NVIC_ST_RELOAD 0xE000E014 // SysTick Reload Value Register #define NVIC_EN0 0xE000E100 // Interrupt 0-31 Set Enable @@ -89,12 +97,14 @@ #define RFCORE_XREG_CCACTRL0 0x40088658 // CCA threshold #define RFCORE_XREG_RSSISTAT 0x40088664 // RSSI valid status register #define RFCORE_XREG_AGCCTRL1 0x400886C8 // AGC reference level +#define RFCORE_XREG_RFC_OBS_CTRL 0x400887AC // RF Core observable output #define RFCORE_XREG_TXFILTCFG 0x400887E8 // TX filter configuration #define RFCORE_XREG_RFRND 0x4008869C // Random data #define RFCORE_SFR_RFDATA 0x40088828 // The TX FIFO and RX FIFO #define RFCORE_SFR_RFERRF 0x4008882C // RF error interrupt flags #define RFCORE_SFR_RFIRQF0 0x40088834 // RF interrupt flags #define RFCORE_SFR_RFST 0x40088838 // RF CSMA-CA/strobe processor +#define CCTEST_OBSSEL 0x44010014 // CCTEST observable output route #define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN 0x00000001 // Enables frame filtering @@ -157,6 +167,27 @@ #define RFCORE_XREG_RSSISTAT_RSSI_VALID 0x00000001 // RSSI value is valid. +#define RFCORE_XREG_RFC_OBS_POL_INV 0x00000040 // Invert polarity of OBS signal +#define RFCORE_XREG_RFC_OBS_MUX_ZERO 0x00000000 // Observable = constant zero +#define RFCORE_XREG_RFC_OBS_MUX_ONE 0x00000001 // Observable = constant one +#define RFCORE_XREG_RFC_OBS_MUX_SNIFF_DATA 0x00000008 // RFC sniff data +#define RFCORE_XREG_RFC_OBS_MUX_SNIFF_CLK 0x00000009 // RFC sniff clock +#define RFCORE_XREG_RFC_OBS_MUX_RSSI_VALID 0x0000000c // RSSI valid +#define RFCORE_XREG_RFC_OBS_MUX_DEMOD_CCA 0x0000000d // Clear channel assessment +#define RFCORE_XREG_RFC_OBS_MUX_SAMPLED_CCA 0x0000000e // Sampled CCA signal +#define RFCORE_XREG_RFC_OBS_MUX_SFD_SYNC 0x0000000f // SFD received or transmitted +#define RFCORE_XREG_RFC_OBS_MUX_TX_ACTIVE 0x00000010 // Transmitter is active +#define RFCORE_XREG_RFC_OBS_MUX_RX_ACTIVE 0x00000011 // Receiver is active +#define RFCORE_XREG_RFC_OBS_MUX_FFCTRL_FIFO 0x00000012 // One or more bytes in FIFO +#define RFCORE_XREG_RFC_OBS_MUX_FFCTRL_FIFOP 0x00000013 // One or more frames in FIFO +#define RFCORE_XREG_RFC_OBS_MUX_PACKET_DONE 0x00000014 // Packet received +#define RFCORE_XREG_RFC_OBS_MUX_RFC_XOR_RAND_IQ 0x00000016 // RAND I ^ RAND Q +#define RFCORE_XREG_RFC_OBS_MUX_RFC_RAND_Q 0x00000017 // Random data from Q channel +#define RFCORE_XREG_RFC_OBS_MUX_RFC_RAND_I 0x00000018 // Random data from I channel +#define RFCORE_XREG_RFC_OBS_MUX_LOCK_STATUS 0x00000019 // PLL is in lock +#define RFCORE_XREG_RFC_OBS_MUX_PA_PD 0x00000028 // Power amp power down +#define RFCORE_XREG_RFC_OBS_MUX_LNA_PD 0x0000002a // LNA power down + #define RFCORE_SFR_RFERRF_NLOCK 0x00000001 // Failed to achieve PLL lock. #define RFCORE_SFR_RFERRF_RXABO 0x00000002 // RX Aborted. #define RFCORE_SFR_RFERRF_RXOVERF 0x00000004 // RX FIFO overflowed. @@ -171,6 +202,11 @@ #define RFCORE_SFR_RFST_INSTR_FLUSHRX 0xED // Instruction set flush rx buffer #define RFCORE_SFR_RFST_INSTR_FLUSHTX 0xEE // Instruction set flush tx buffer +#define CCTEST_OBSSEL_EN 0x00000080 // Enable the OBS output on this pin +#define CCTEST_OBSSEL_SEL_OBS0 0x00000000 // Route OBS0 to pin +#define CCTEST_OBSSEL_SEL_OBS1 0x00000001 // Route OBS1 to pin +#define CCTEST_OBSSEL_SEL_OBS2 0x00000002 // Route OBS2 to pin + #define ANA_REGS_BASE 0x400D6000 // ANA_REGS #define ANA_REGS_O_IVCTRL 0x00000004 // Analog control register @@ -229,15 +265,23 @@ #define UART0_BASE 0x4000C000 #define UART1_BASE 0x4000D000 -#define GPIO_A_BASE 0x400D9000 // GPIO +#define GPIO_A_BASE 0x400D9000 // GPIO A +#define GPIO_B_BASE 0x400DA000 // GPIO B +#define GPIO_C_BASE 0x400DB000 // GPIO C +#define GPIO_D_BASE 0x400DC000 // GPIO D #define GPIO_O_DIR 0x00000400 #define GPIO_O_AFSEL 0x00000420 +#define GPIO_PIN(x) (1UL << x) // Arbitrary GPIO pin #define GPIO_PIN_0 0x00000001 // GPIO pin 0 #define GPIO_PIN_1 0x00000002 // GPIO pin 1 #define GPIO_PIN_2 0x00000004 // GPIO pin 2 #define GPIO_PIN_3 0x00000008 // GPIO pin 3 +#define GPIO_PIN_4 0x00000010 // GPIO pin 4 +#define GPIO_PIN_5 0x00000020 // GPIO pin 5 +#define GPIO_PIN_6 0x00000040 // GPIO pin 6 +#define GPIO_PIN_7 0x00000080 // GPIO pin 7 #define UART_O_DR 0x00000000 // UART data #define UART_O_FR 0x00000018 // UART flag diff --git a/examples/platforms/cc2538/openthread-core-cc2538-config.h b/examples/platforms/cc2538/openthread-core-cc2538-config.h index d03444e85..2e08d1b8f 100644 --- a/examples/platforms/cc2538/openthread-core-cc2538-config.h +++ b/examples/platforms/cc2538/openthread-core-cc2538-config.h @@ -80,17 +80,146 @@ * The actual physical address used for the cc2538 is set by the * linker file, the value here is "relative to the base address" set * in the linker file. + * */ #define SETTINGS_CONFIG_BASE_ADDRESS 0 /** - * @def The CC2538 linker script sets aside 2 pages. + * @def SETTINGS_CONFIG_PAGE_NUM + * + * The CC2538 linker script sets aside 2 pages. + * */ #define SETTINGS_CONFIG_PAGE_NUM 2 /** - * @def The page size of settings, 2K bytes + * @def SETTINGS_CONFIG_PAGE_SIZE + * + * The page size of settings, 2K bytes + * */ #define SETTINGS_CONFIG_PAGE_SIZE 2048 +/** + * @def OPENTHREAD_CONFIG_CC2538_WITH_CC2592 + * + * Enable support for the CC2592 range-extender front-end. + * + * This is a feature of the CC2538-CC2592 EM and other peripherals which + * extends the range of the bare CC2538 to over a kilometre line-of-sight. + * The CC2592 needs to be wired up to the RF port on the CC2538 in accordance + * with application note 130 ("Using CC2592 Front End With CC2538", TI doc + * SWRA447). + * + * If you have such a board, change this to 1. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2538_WITH_CC2592 +#define OPENTHREAD_CONFIG_CC2538_WITH_CC2592 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2592_PA_EN_PIN + * + * Define the pin (on port C) that connects to the CC2592 PA_EN pin. + * + * One of the 3 observable channels on the CC2538 radio module will be + * configured to take the "PA power down" signal from the radio module itself, + * invert it, and emit it on this GPIO pin. Due to hardware constraints, it + * may only be connected to a pin on GPIO port C. + * + * The default (PC3) is as per TI recommendations in AN130. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2592_PA_EN_PIN +#define OPENTHREAD_CONFIG_CC2592_PA_EN_PIN 3 +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2592_LNA_EN_PIN + * + * Define the pin (on port C) that connects to the CC2592 LNA_EN pin. + * + * One of the 3 observable channels on the CC2538 radio module will be + * configured to take the "LNA power down" signal from the radio module itself, + * invert it, and emit it on this GPIO pin. Due to hardware constraints, it + * may only be connected to a pin on GPIO port C. + * + * The default (PC2) is as per TI recommendations in AN130. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2592_LNA_EN_PIN +#define OPENTHREAD_CONFIG_CC2592_LNA_EN_PIN 2 +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2592_USE_HGM + * + * Enable control of the high-gain mode signal. + * + * High-gain mode is enabled through the `HGM` pin on the CC2592, which may be + * connected to any free GPIO pin for software control, or may be linked to + * VDD or 0V to hard-wire it to a given state. + * + * Set this to 0 if you have wired this pin to a power rail, or have a + * non-standard way of controlling it. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2592_USE_HGM +#define OPENTHREAD_CONFIG_CC2592_USE_HGM 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2538_RECEIVE_SENSITIVITY + * + * Set the CC2538 receive sensitivity. + * + * A bare CC2538 has a receive sensitivity of -88dBm. The CC2592 changes this + * to -85 or -81 depending on whether the HGM pin is high or low. If + * `OPENTHREAD_CONFIG_CC2592_USE_HGM` is 0, then this sets the receive + * sensitivity. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2538_RECEIVE_SENSITIVITY +#define OPENTHREAD_CONFIG_CC2538_RECEIVE_SENSITIVITY -88 +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2592_HGM_PORT + * + * Define the GPIO port that the HGM pin is connected to. It may be + * connected to any available GPIO pin. + * + * The default (GPIO port D) is as per TI recommendations. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2592_HGM_PORT +#define OPENTHREAD_CONFIG_CC2592_HGM_PORT GPIO_D_BASE +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2592_HGM_PIN + * + * Define the pin on the GPIO port that the HGM pin is connected to. It + * may be connected to any available GPIO pin. + * + * The default (PD2) is as per TI recommendations. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2592_HGM_PIN +#define OPENTHREAD_CONFIG_CC2592_HGM_PIN 2 +#endif + +/** + * @def OPENTHREAD_CONFIG_CC2592_HGM_DEFAULT_STATE + * + * Define the default state of the CC2592's HGM pin. + * + * The default is to turn high-gain mode on. + * + */ +#ifndef OPENTHREAD_CONFIG_CC2592_HGM_DEFAULT_STATE +#define OPENTHREAD_CONFIG_CC2592_HGM_DEFAULT_STATE true +#endif + #endif // OPENTHREAD_CORE_CC2538_CONFIG_H_ diff --git a/examples/platforms/cc2538/platform-cc2538.h b/examples/platforms/cc2538/platform-cc2538.h index 41bd0b988..5fee64710 100644 --- a/examples/platforms/cc2538/platform-cc2538.h +++ b/examples/platforms/cc2538/platform-cc2538.h @@ -90,4 +90,18 @@ void cc2538RandomInit(void); */ void cc2538UartProcess(void); +#if OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM +/** + * Change the state of the CC2592 HGM pin. + * + * @param aState Whether or not to enable HGM + */ +void cc2538RadioSetHgm(bool aState); + +/** + * Retrieve the state of the CC2592 HGM pin. + */ +bool cc2538RadioGetHgm(void); +#endif // OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM + #endif // PLATFORM_CC2538_H_ diff --git a/examples/platforms/cc2538/radio.c b/examples/platforms/cc2538/radio.c index 23e70c813..31bb10e82 100644 --- a/examples/platforms/cc2538/radio.c +++ b/examples/platforms/cc2538/radio.c @@ -41,6 +41,52 @@ #include "common/logging.hpp" #include "utils/code_utils.h" +#define RFCORE_RXTX_INT (141) + +#define RFCORE_XREG_RFIRQM0 0x4008868C // RF interrupt masks +#define RFCORE_XREG_RFIRQM1 0x40088690 // RF interrupt masks +#define RFCORE_XREG_RFERRM 0x40088694 // RF error interrupt mask + +#define RFCORE_SFR_RFIRQF0_RXMASKZERO 0x00000080 // RXENABLE is now completely clear +#define RFCORE_SFR_RFIRQF0_RXPKTDONE 0x00000040 // A complete frame has been received +#define RFCORE_SFR_RFIRQF0_FRAME_ACCEPTED 0x00000020 // Frame has passed frame filtering +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_FOUND 0x00000010 // Source match is found +#define RFCORE_SFR_RFIRQF0_SRC_MATCH_DONE 0x00000008 // Source matching is complete +#define RFCORE_SFR_RFIRQF0_FIFOP 0x00000004 // The number of bytes in the RX fifo is above threshold +#define RFCORE_SFR_RFIRQF0_SFD 0x00000002 // SFD has been received or transmitted +#define RFCORE_SFR_RFIRQF0_ACT_UNUSED 0x00000001 // Reserved + +#define RFCORE_XREG_RFIRQM0_RXMASKZERO 0x00000080 +#define RFCORE_XREG_RFIRQM0_RXPKTDONE 0x00000040 +#define RFCORE_XREG_RFIRQM0_FRAME_ACCEPTED 0x00000020 +#define RFCORE_XREG_RFIRQM0_SRC_MATCH_FOUND 0x00000010 +#define RFCORE_XREG_RFIRQM0_SRC_MATCH_DONE 0x00000008 +#define RFCORE_XREG_RFIRQM0_FIFOP 0x00000004 +#define RFCORE_XREG_RFIRQM0_SFD 0x00000002 +#define RFCORE_XREG_RFIRQM0_ACT_UNUSED 0x00000001 + +#define RFCORE_SFR_RFIRQF1_CSP_WAIT 0x00000020 +#define RFCORE_SFR_RFIRQF1_CSP_STOP 0x00000010 +#define RFCORE_SFR_RFIRQF1_CSP_MANINT 0x00000008 +#define RFCORE_SFR_RFIRQF1_RF_IDLE 0x00000004 +#define RFCORE_SFR_RFIRQF1_TXDONE 0x00000002 +#define RFCORE_SFR_RFIRQF1_TXACKDONE 0x00000001 + +#define RFCORE_XREG_RFIRQM1_CSP_WAIT 0x00000020 +#define RFCORE_XREG_RFIRQM1_CSP_STOP 0x00000010 +#define RFCORE_XREG_RFIRQM1_CSP_MANINT 0x00000008 +#define RFCORE_XREG_RFIRQM1_RF_IDLE 0x00000004 +#define RFCORE_XREG_RFIRQM1_TXDONE 0x00000002 +#define RFCORE_XREG_RFIRQM1_TXACKDONE 0x00000001 + +#define RFCORE_XREG_RFERRM_STROBE_ERR 0x00000040 +#define RFCORE_XREG_RFERRM_TXUNDERF 0x00000020 +#define RFCORE_XREG_RFERRM_TXOVERF 0x00000010 +#define RFCORE_XREG_RFERRM_RXUNDERF 0x00000008 +#define RFCORE_XREG_RFERRM_RXOVERF 0x00000004 +#define RFCORE_XREG_RFERRM_RXABO 0x00000002 +#define RFCORE_XREG_RFERRM_NLOCK 0x00000001 + enum { IEEE802154_MIN_LENGTH = 5, @@ -60,9 +106,12 @@ enum CC2538_LQI_BIT_MASK = 0x7f, }; +// All values in dBm enum { - CC2538_RECEIVE_SENSITIVITY = -88, // dBm + CC2538_RECEIVE_SENSITIVITY = OPENTHREAD_CONFIG_CC2538_RECEIVE_SENSITIVITY, + CC2592_RECEIVE_SENSITIVITY_LGM = -81, + CC2592_RECEIVE_SENSITIVITY_HGM = -85, }; typedef struct TxPowerTable @@ -71,8 +120,25 @@ typedef struct TxPowerTable uint8_t mTxPowerReg; } TxPowerTable; -// The transmit power table, the values are from SmartRF Studio 2.4.0 +// The transmit power table. static const TxPowerTable sTxPowerTable[] = { +#if OPENTHREAD_CONFIG_CC2538_WITH_CC2592 + // CC2538 using CC2592 PA + // Values are from AN130 table 6 (page 4) + {22, 0xFF}, // 22.0dBm =~ 158.5mW + {21, 0xD5}, // 20.9dBm =~ 123.0mW + {20, 0xC5}, // 20.1dBm =~ 102.3mW + {19, 0xB0}, // 19.0dBm =~ 79.4mW + {18, 0xA1}, // 17.8dBm =~ 60.3mW + {16, 0x91}, // 16.4dBm =~ 43.7mW + {15, 0x88}, // 14.9dBm =~ 30.9mW + {13, 0x72}, // 13.0dBm =~ 20.0mW + {11, 0x62}, // 11.0dBm =~ 12.6mW + {10, 0x58}, // 9.5dBm =~ 8.9mW + {8, 0x42}, // 7.5dBm =~ 5.6mW +#else + // CC2538 operating "bare foot" + // Values are from SmartRF Studio 2.4.0 {7, 0xFF}, // {5, 0xED}, // {3, 0xD5}, // @@ -87,6 +153,7 @@ static const TxPowerTable sTxPowerTable[] = { {-13, 0x58}, // {-15, 0x42}, // {-24, 0x00}, // +#endif }; static otRadioFrame sTransmitFrame; @@ -256,6 +323,11 @@ void cc2538RadioInit(void) sReceiveFrame.mLength = 0; sReceiveFrame.mPsdu = sReceivePsdu; + // Enable interrupts for RX/TX, interrupt 141. + // That's NVIC index 5 bit 13. + HWREG(NVIC_EN0 + (5 * 4)) = (1 << 13); + HWREG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_RXPKTDONE; + // enable clock HWREG(SYS_CTRL_RCGCRFC) = SYS_CTRL_RCGCRFC_RFC0; HWREG(SYS_CTRL_SCGCRFC) = SYS_CTRL_SCGCRFC_RFC0; @@ -277,9 +349,60 @@ void cc2538RadioInit(void) HWREG(RFCORE_XREG_TXPOWER) = sTxPowerTable[0].mTxPowerReg; sTxPower = sTxPowerTable[0].mTxPowerVal; +#if OPENTHREAD_CONFIG_CC2538_WITH_CC2592 + // PA_EN pin configuration. + // Step 1. make it an output + HWREG(GPIO_C_BASE | GPIO_O_DIR) |= GPIO_PIN(OPENTHREAD_CONFIG_CC2592_PA_EN_PIN); + // Step 2. Route PA_PD to OBS0 and invert it to produce PA_EN + HWREG_ARR(RFCORE_XREG_RFC_OBS_CTRL, 0) = RFCORE_XREG_RFC_OBS_POL_INV // Invert the output + | RFCORE_XREG_RFC_OBS_MUX_PA_PD; // PA "power down" signal + // Step 3. Connect the selected pin to OBS0 and enable OBS0. + HWREG_ARR(CCTEST_OBSSEL, OPENTHREAD_CONFIG_CC2592_PA_EN_PIN) = CCTEST_OBSSEL_EN // Enable the output + | CCTEST_OBSSEL_SEL_OBS0; // Select OBS0 + + // LNA_EN pin configuration. + HWREG(GPIO_C_BASE | GPIO_O_DIR) |= GPIO_PIN(OPENTHREAD_CONFIG_CC2592_LNA_EN_PIN); + HWREG_ARR(RFCORE_XREG_RFC_OBS_CTRL, 1) = RFCORE_XREG_RFC_OBS_POL_INV | RFCORE_XREG_RFC_OBS_MUX_LNA_PD; + HWREG_ARR(CCTEST_OBSSEL, OPENTHREAD_CONFIG_CC2592_LNA_EN_PIN) = CCTEST_OBSSEL_EN | CCTEST_OBSSEL_SEL_OBS1; + +#if OPENTHREAD_CONFIG_CC2592_USE_HGM + // HGM pin configuration. Set the pin state first so we don't glitch. + cc2538RadioSetHgm(OPENTHREAD_CONFIG_CC2592_HGM_DEFAULT_STATE); + HWREG(OPENTHREAD_CONFIG_CC2592_HGM_PORT | GPIO_O_DIR) |= GPIO_PIN(OPENTHREAD_CONFIG_CC2592_HGM_PIN); +#endif // OPENTHREAD_CONFIG_CC2592_USE_HGM +#endif // OPENTHREAD_CONFIG_CC2538_WITH_CC2592 + otLogInfoPlat("Initialized", NULL); } +#if OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM +void cc2538RadioSetHgm(bool aState) +{ + if (aState) + { + HWREG_ARR(OPENTHREAD_CONFIG_CC2592_HGM_PORT, GPIO_PIN(OPENTHREAD_CONFIG_CC2592_HGM_PIN)) = + GPIO_PIN(OPENTHREAD_CONFIG_CC2592_HGM_PIN); + } + else + { + HWREG_ARR(OPENTHREAD_CONFIG_CC2592_HGM_PORT, GPIO_PIN(OPENTHREAD_CONFIG_CC2592_HGM_PIN)) = 0; + } +} + +bool cc2538RadioGetHgm(void) +{ + if (HWREG_ARR(OPENTHREAD_CONFIG_CC2592_HGM_PORT, GPIO_PIN(OPENTHREAD_CONFIG_CC2592_HGM_PIN)) & + GPIO_PIN(OPENTHREAD_CONFIG_CC2592_HGM_PIN)) + { + return true; + } + else + { + return false; + } +} +#endif // OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM + bool otPlatRadioIsEnabled(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); @@ -958,5 +1081,16 @@ int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); +#if OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM + if (cc2538RadioGetHgm()) + { + return CC2592_RECEIVE_SENSITIVITY_HGM; + } + else + { + return CC2592_RECEIVE_SENSITIVITY_LGM; + } +#else // OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM return CC2538_RECEIVE_SENSITIVITY; +#endif // OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM }