diff --git a/examples/platforms/nrf528xx/src/fem.c b/examples/platforms/nrf528xx/src/fem.c index 2b4d2c116..4a17849b5 100644 --- a/examples/platforms/nrf528xx/src/fem.c +++ b/examples/platforms/nrf528xx/src/fem.c @@ -38,11 +38,125 @@ #include #include +#include "platform-config.h" #include "platform-fem.h" #define ENABLE_FEM 1 #include +// clang-format off + +/** + * @brief Configuration parameters for the Front End Module. + */ +#define PLATFORM_FEM_DEFAULT_PA_PIN 26 /**< Default Power Amplifier pin. */ +#define PLATFORM_FEM_DEFAULT_LNA_PIN 27 /**< Default Low Noise Amplifier pin. */ +#define PLATFORM_FEM_DEFAULT_PDN_PIN 28 /**< Default Power Down pin. */ +#define PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL 15 /**< Default PPI channel for pin setting. */ +#define PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL 16 /**< Default PPI channel for pin clearing. */ +#define PLATFORM_FEM_DEFAULT_PDN_PPI_CHANNEL 14 /**< Default PPI channel for Power Down control. */ +#define PLATFORM_FEM_DEFAULT_TIMER_MATCH_PPI_GROUP 4 /**< Default PPI channel group used to disable timer match PPI. */ +#define PLATFORM_FEM_DEFAULT_RADIO_DISABLED_PPI_GROUP 5 /**< Default PPI channel group used to disable radio disabled PPI. */ +#define PLATFORM_FEM_DEFAULT_PA_GPIOTE_CHANNEL 6 /**< Default PA GPIOTE channel for FEM control. */ +#define PLATFORM_FEM_DEFAULT_LNA_GPIOTE_CHANNEL 7 /**< Default LNA GPIOTE channel for FEM control. */ +#define PLATFORM_FEM_DEFAULT_PDN_GPIOTE_CHANNEL 5 /**< Default PDN GPIOTE channel for FEM control. */ + +/** + * @brief Configuration parameters for the Front End Module timings and gain. + */ +#define PLATFORM_FEM_PA_TIME_IN_ADVANCE_US 13 /**< Default time in microseconds when PA GPIO is activated before the radio is ready for transmission. */ +#define PLATFORM_FEM_LNA_TIME_IN_ADVANCE_US 13 /**< Default time in microseconds when LNA GPIO is activated before the radio is ready for reception. */ +#define PLATFORM_FEM_PDN_SETTLE_US 18 /**< Default the time between activating the PDN and asserting the RX_EN/TX_EN. */ +#define PLATFORM_FEM_TRX_HOLD_US 5 /**< Default the time between deasserting the RX_EN/TX_EN and deactivating PDN. */ +#define PLATFORM_FEM_PA_GAIN_DB 0 /**< Default PA gain. Ignored if the amplifier is not supporting this feature. */ +#define PLATFORM_FEM_LNA_GAIN_DB 0 /**< Default LNA gain. Ignored if the amplifier is not supporting this feature. */ + +// clang-format on + +#define PLATFORM_FEM_DEFAULT_CONFIG \ + ((PlatformFemConfigParams){ \ + .mFemPhyCfg = \ + { \ + .mPaTimeGapUs = PLATFORM_FEM_PA_TIME_IN_ADVANCE_US, \ + .mLnaTimeGapUs = PLATFORM_FEM_LNA_TIME_IN_ADVANCE_US, \ + .mPdnSettleUs = PLATFORM_FEM_PDN_SETTLE_US, \ + .mTrxHoldUs = PLATFORM_FEM_TRX_HOLD_US, \ + .mPaGainDb = PLATFORM_FEM_PA_GAIN_DB, \ + .mLnaGainDb = PLATFORM_FEM_LNA_GAIN_DB, \ + }, \ + .mPaCfg = \ + { \ + .mEnable = 1, \ + .mActiveHigh = 1, \ + .mGpioPin = PLATFORM_FEM_DEFAULT_PA_PIN, \ + .mGpioteChId = PLATFORM_FEM_DEFAULT_PA_GPIOTE_CHANNEL, \ + }, \ + .mLnaCfg = \ + { \ + .mEnable = 1, \ + .mActiveHigh = 1, \ + .mGpioPin = PLATFORM_FEM_DEFAULT_LNA_PIN, \ + .mGpioteChId = PLATFORM_FEM_DEFAULT_LNA_GPIOTE_CHANNEL, \ + }, \ + .mPdnCfg = \ + { \ + .mEnable = 1, \ + .mActiveHigh = 1, \ + .mGpioPin = PLATFORM_FEM_DEFAULT_PDN_PIN, \ + .mGpioteChId = PLATFORM_FEM_DEFAULT_PDN_GPIOTE_CHANNEL, \ + }, \ + .mPpiChIdClr = PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL, \ + .mPpiChIdSet = PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL, \ + .mPpiChIdPdn = PLATFORM_FEM_DEFAULT_PDN_PPI_CHANNEL, \ + }) + +/** + * @brief Configuration parameters for FEM PHY. + */ +typedef struct +{ + uint32_t mPaTimeGapUs; + uint32_t mLnaTimeGapUs; + uint32_t mPdnSettleUs; + uint32_t mTrxHoldUs; + uint8_t mPaGainDb; + uint8_t mLnaGainDb; +} PlatformFemPhyConfig; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t mEnable : 1; /**< Enable toggling for this amplifier */ + uint8_t mActiveHigh : 1; /**< Set the pin to be active high */ + uint8_t mGpioPin : 6; /**< The GPIO pin to toggle for this amplifier */ + uint8_t mGpioteChId; /**< The GPIOTE Channel ID used for toggling pins */ +} PlatformFemPinConfig; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the nRF 802.15.4 radio driver to toggle pins when the radio + * is active for use with a power amplifier and/or a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note Changing this configuration while the radio is in use may have undefined + * consequences and must be avoided by the application. + */ +typedef struct +{ + PlatformFemPhyConfig mFemPhyCfg; /**< Front End Module Physical layer configuration */ + PlatformFemPinConfig mPaCfg; /**< Power Amplifier configuration */ + PlatformFemPinConfig mLnaCfg; /**< Low Noise Amplifier configuration */ + PlatformFemPinConfig mPdnCfg; /**< Power Down configuration */ + uint8_t mPpiChIdSet; /**< PPI channel to be used for setting pins */ + uint8_t mPpiChIdClr; /**< PPI channel to be used for clearing pins */ + uint8_t mPpiChIdPdn; /**< PPI channel to handle PDN pin */ +} PlatformFemConfigParams; + void PlatformFemSetConfigParams(const PlatformFemConfigParams *aConfig) { nrf_fem_interface_config_t cfg; @@ -73,3 +187,22 @@ void PlatformFemSetConfigParams(const PlatformFemConfigParams *aConfig) nrf_fem_interface_configuration_set(&cfg); } + +void nrf5FemInit(void) +{ +#if PLATFORM_FEM_ENABLE_DEFAULT_CONFIG + PlatformFemSetConfigParams(&PLATFORM_FEM_DEFAULT_CONFIG); +#endif +} + +void nrf5FemDeinit(void) +{ +} + +void nrf5FemEnable(void) +{ +} + +void nrf5FemDisable(void) +{ +} diff --git a/examples/platforms/nrf528xx/src/platform-fem.h b/examples/platforms/nrf528xx/src/platform-fem.h index 7a7cf445d..c6ab1623f 100644 --- a/examples/platforms/nrf528xx/src/platform-fem.h +++ b/examples/platforms/nrf528xx/src/platform-fem.h @@ -37,123 +37,28 @@ #include -// clang-format off - /** - * @brief Configuration parameters for the Front End Module. - */ -#define PLATFORM_FEM_DEFAULT_PA_PIN 26 /**< Default Power Amplifier pin. */ -#define PLATFORM_FEM_DEFAULT_LNA_PIN 27 /**< Default Low Noise Amplifier pin. */ -#define PLATFORM_FEM_DEFAULT_PDN_PIN 28 /**< Default Power Down pin. */ -#define PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL 15 /**< Default PPI channel for pin setting. */ -#define PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL 16 /**< Default PPI channel for pin clearing. */ -#define PLATFORM_FEM_DEFAULT_PDN_PPI_CHANNEL 14 /**< Default PPI channel for Power Down control. */ -#define PLATFORM_FEM_DEFAULT_TIMER_MATCH_PPI_GROUP 4 /**< Default PPI channel group used to disable timer match PPI. */ -#define PLATFORM_FEM_DEFAULT_RADIO_DISABLED_PPI_GROUP 5 /**< Default PPI channel group used to disable radio disabled PPI. */ -#define PLATFORM_FEM_DEFAULT_PA_GPIOTE_CHANNEL 6 /**< Default PA GPIOTE channel for FEM control. */ -#define PLATFORM_FEM_DEFAULT_LNA_GPIOTE_CHANNEL 7 /**< Default LNA GPIOTE channel for FEM control. */ -#define PLATFORM_FEM_DEFAULT_PDN_GPIOTE_CHANNEL 5 /**< Default PDN GPIOTE channel for FEM control. */ - -/** - * @brief Configuration parameters for the Front End Module timings and gain. - */ -#define PLATFORM_FEM_PA_TIME_IN_ADVANCE_US 13 /**< Default time in microseconds when PA GPIO is activated before the radio is ready for transmission. */ -#define PLATFORM_FEM_LNA_TIME_IN_ADVANCE_US 13 /**< Default time in microseconds when LNA GPIO is activated before the radio is ready for reception. */ -#define PLATFORM_FEM_PDN_SETTLE_US 18 /**< Default the time between activating the PDN and asserting the RX_EN/TX_EN. */ -#define PLATFORM_FEM_TRX_HOLD_US 5 /**< Default the time between deasserting the RX_EN/TX_EN and deactivating PDN. */ -#define PLATFORM_FEM_PA_GAIN_DB 0 /**< Default PA gain. Ignored if the amplifier is not supporting this feature. */ -#define PLATFORM_FEM_LNA_GAIN_DB 0 /**< Default LNA gain. Ignored if the amplifier is not supporting this feature. */ - -// clang-format on - -#define PLATFORM_FEM_DEFAULT_CONFIG \ - ((PlatformFemConfigParams){ \ - .mFemPhyCfg = \ - { \ - .mPaTimeGapUs = PLATFORM_FEM_PA_TIME_IN_ADVANCE_US, \ - .mLnaTimeGapUs = PLATFORM_FEM_LNA_TIME_IN_ADVANCE_US, \ - .mPdnSettleUs = PLATFORM_FEM_PDN_SETTLE_US, \ - .mTrxHoldUs = PLATFORM_FEM_TRX_HOLD_US, \ - .mPaGainDb = PLATFORM_FEM_PA_GAIN_DB, \ - .mLnaGainDb = PLATFORM_FEM_LNA_GAIN_DB, \ - }, \ - .mPaCfg = \ - { \ - .mEnable = 1, \ - .mActiveHigh = 1, \ - .mGpioPin = PLATFORM_FEM_DEFAULT_PA_PIN, \ - .mGpioteChId = PLATFORM_FEM_DEFAULT_PA_GPIOTE_CHANNEL, \ - }, \ - .mLnaCfg = \ - { \ - .mEnable = 1, \ - .mActiveHigh = 1, \ - .mGpioPin = PLATFORM_FEM_DEFAULT_LNA_PIN, \ - .mGpioteChId = PLATFORM_FEM_DEFAULT_LNA_GPIOTE_CHANNEL, \ - }, \ - .mPdnCfg = \ - { \ - .mEnable = 1, \ - .mActiveHigh = 1, \ - .mGpioPin = PLATFORM_FEM_DEFAULT_PDN_PIN, \ - .mGpioteChId = PLATFORM_FEM_DEFAULT_PDN_GPIOTE_CHANNEL, \ - }, \ - .mPpiChIdClr = PLATFORM_FEM_DEFAULT_CLR_PPI_CHANNEL, \ - .mPpiChIdSet = PLATFORM_FEM_DEFAULT_SET_PPI_CHANNEL, \ - .mPpiChIdPdn = PLATFORM_FEM_DEFAULT_PDN_PPI_CHANNEL, \ - }) - -/** - * @brief Configuration parameters for FEM PHY. - */ -typedef struct -{ - uint32_t mPaTimeGapUs; - uint32_t mLnaTimeGapUs; - uint32_t mPdnSettleUs; - uint32_t mTrxHoldUs; - uint8_t mPaGainDb; - uint8_t mLnaGainDb; -} PlatformFemPhyConfig; - -/** - * @brief Configuration parameters for the PA and LNA. - */ -typedef struct -{ - uint8_t mEnable : 1; /**< Enable toggling for this amplifier */ - uint8_t mActiveHigh : 1; /**< Set the pin to be active high */ - uint8_t mGpioPin : 6; /**< The GPIO pin to toggle for this amplifier */ - uint8_t mGpioteChId; /**< The GPIOTE Channel ID used for toggling pins */ -} PlatformFemPinConfig; - -/** - * @brief PA & LNA GPIO toggle configuration - * - * This option configures the nRF 802.15.4 radio driver to toggle pins when the radio - * is active for use with a power amplifier and/or a low noise amplifier. - * - * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided - * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. - * - * @note Changing this configuration while the radio is in use may have undefined - * consequences and must be avoided by the application. - */ -typedef struct -{ - PlatformFemPhyConfig mFemPhyCfg; /**< Front End Module Physical layer configuration */ - PlatformFemPinConfig mPaCfg; /**< Power Amplifier configuration */ - PlatformFemPinConfig mLnaCfg; /**< Low Noise Amplifier configuration */ - PlatformFemPinConfig mPdnCfg; /**< Power Down configuration */ - uint8_t mPpiChIdSet; /**< PPI channel to be used for setting pins */ - uint8_t mPpiChIdClr; /**< PPI channel to be used for clearing pins */ - uint8_t mPpiChIdPdn; /**< PPI channel to handle PDN pin */ -} PlatformFemConfigParams; - -/** - * Function used to set parameters of FEM. + * Initialization of the FEM. * */ -void PlatformFemSetConfigParams(const PlatformFemConfigParams *aConfig); +void nrf5FemInit(void); + +/** + * Deinitialization of the FEM. + * + */ +void nrf5FemDeinit(void); + +/** + * Enable the FEM. + * + */ +void nrf5FemEnable(void); + +/** + * Disable the FEM. + * + */ +void nrf5FemDisable(void); #endif // PLATFORM_FEM_H_ diff --git a/examples/platforms/nrf528xx/src/radio.c b/examples/platforms/nrf528xx/src/radio.c index 490ae79a1..76198a675 100644 --- a/examples/platforms/nrf528xx/src/radio.c +++ b/examples/platforms/nrf528xx/src/radio.c @@ -54,6 +54,7 @@ #include #include "openthread-system.h" +#include "platform-fem.h" #include "platform-nrf5.h" #include @@ -425,6 +426,7 @@ otError otPlatRadioSleep(otInstance *aInstance) if (nrf_802154_sleep_if_idle() == NRF_802154_SLEEP_ERROR_NONE) { + nrf5FemDisable(); clearPendingEvents(); } else @@ -443,7 +445,14 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) bool result; nrf_802154_channel_set(aChannel); + if (nrf_802154_state_get() == NRF_802154_STATE_SLEEP) + { + // Enable FEM before RADIO leaving SLEEP state. + nrf5FemEnable(); + } + nrf_802154_tx_power_set(sDefaultTxPower); + result = nrf_802154_receive(); clearPendingEvents(); @@ -457,6 +466,12 @@ otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) aFrame->mPsdu[-1] = aFrame->mLength; + if (nrf_802154_state_get() == NRF_802154_STATE_SLEEP) + { + // Enable FEM before RADIO leaving SLEEP state. + nrf5FemEnable(); + } + nrf_802154_channel_set(aFrame->mChannel); #if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 @@ -884,6 +899,7 @@ void nrf5RadioProcess(otInstance *aInstance) { if (nrf_802154_sleep_if_idle() == NRF_802154_SLEEP_ERROR_NONE) { + nrf5FemDisable(); resetPendingEvent(kPendingEventSleep); } else diff --git a/examples/platforms/nrf528xx/src/system.c b/examples/platforms/nrf528xx/src/system.c index eaea7cc91..824d47772 100644 --- a/examples/platforms/nrf528xx/src/system.c +++ b/examples/platforms/nrf528xx/src/system.c @@ -102,16 +102,14 @@ void otSysInit(int argc, char *argv[]) nrf5MiscInit(); nrf5RadioInit(); nrf5TempInit(); - -#if PLATFORM_FEM_ENABLE_DEFAULT_CONFIG - PlatformFemSetConfigParams(&PLATFORM_FEM_DEFAULT_CONFIG); -#endif + nrf5FemInit(); gPlatformPseudoResetWasRequested = false; } void otSysDeinit(void) { + nrf5FemDeinit(); nrf5TempDeinit(); nrf5RadioDeinit(); nrf5MiscDeinit(); diff --git a/third_party/NordicSemiconductor/drivers/radio/fal/nrf_802154_fal.c b/third_party/NordicSemiconductor/drivers/radio/fal/nrf_802154_fal.c index efed33688..7a2352456 100644 --- a/third_party/NordicSemiconductor/drivers/radio/fal/nrf_802154_fal.c +++ b/third_party/NordicSemiconductor/drivers/radio/fal/nrf_802154_fal.c @@ -36,9 +36,10 @@ #include +#include "compiler_abstraction.h" #include "nrf_802154_fal.h" -int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power) +__WEAK int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power) { (void)channel;