From 42e1da5573c7d5942b742eff482a8dc6db4b0a7f Mon Sep 17 00:00:00 2001 From: Jiacheng Guo Date: Mon, 21 Dec 2020 23:22:00 +0800 Subject: [PATCH] [nrf528xx] add max power table support (#5961) --- .../platforms/nrf528xx/src/platform-nrf5.h | 2 + examples/platforms/nrf528xx/src/radio.c | 69 ++++++++++++++++++- include/openthread/instance.h | 2 +- include/openthread/platform/radio.h | 6 ++ 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/examples/platforms/nrf528xx/src/platform-nrf5.h b/examples/platforms/nrf528xx/src/platform-nrf5.h index 339f0b946..e93e75734 100644 --- a/examples/platforms/nrf528xx/src/platform-nrf5.h +++ b/examples/platforms/nrf528xx/src/platform-nrf5.h @@ -197,4 +197,6 @@ otError nrf5SdErrorToOtError(uint32_t aSdError); void nrf5SdSocFlashProcess(uint32_t aEvtId); #endif // SOFTDEVICE_PRESENT +int8_t nrf5GetChannelMaxTransmitPower(uint8_t aChannel); + #endif // PLATFORM_NRF5_H_ diff --git a/examples/platforms/nrf528xx/src/radio.c b/examples/platforms/nrf528xx/src/radio.c index 172103317..71abf5240 100644 --- a/examples/platforms/nrf528xx/src/radio.c +++ b/examples/platforms/nrf528xx/src/radio.c @@ -43,6 +43,7 @@ #include +#include "common/code_utils.hpp" #include "utils/code_utils.h" #include "utils/mac_frame.h" @@ -107,6 +108,7 @@ static otInstance * sInstance = NULL; static otRadioFrame sAckFrame; static bool sAckedWithFramePending; +static int8_t sMaxTxPowerTable[OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN + 1]; static int8_t sDefaultTxPower; static int8_t sLnaGain = 0; @@ -144,10 +146,28 @@ static uint32_t sAckFrameCounter; static uint8_t sAckKeyId; #endif +static int8_t GetTransmitPowerForChannel(uint8_t aChannel) +{ + int8_t channelMaxPower = nrf5GetChannelMaxTransmitPower(aChannel); + int8_t power = 0; // 0 dbm as default value + + if (sDefaultTxPower != OT_RADIO_POWER_INVALID) + { + power = OT_MIN(channelMaxPower, sDefaultTxPower); + } + else if (channelMaxPower != OT_RADIO_POWER_INVALID) + { + power = channelMaxPower; + } + + return power; +} + static void dataInit(void) { sDisabled = true; + sDefaultTxPower = OT_RADIO_POWER_INVALID; sTransmitFrame.mPsdu = sTransmitPsdu + 1; #if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT sTransmitFrame.mInfo.mTxInfo.mIeInfo = &sTransmitIeInfo; @@ -160,6 +180,11 @@ static void dataInit(void) sReceivedFrames[i].mPsdu = NULL; } + for (size_t i = 0; i < OT_ARRAY_LENGTH(sMaxTxPowerTable); i++) + { + sMaxTxPowerTable[i] = OT_RADIO_POWER_INVALID; + } + memset(&sAckFrame, 0, sizeof(sAckFrame)); } @@ -451,7 +476,7 @@ otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) nrf5FemEnable(); } - nrf_802154_tx_power_set(sDefaultTxPower); + nrf_802154_tx_power_set(GetTransmitPowerForChannel(aChannel)); result = nrf_802154_receive(); clearPendingEvents(); @@ -695,11 +720,15 @@ otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower) otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower) { OT_UNUSED_VARIABLE(aInstance); + uint8_t channel = nrf_802154_channel_get(); + otError error = OT_ERROR_NONE; + VerifyOrExit(aPower != OT_RADIO_POWER_INVALID, error = OT_ERROR_INVALID_ARGS); sDefaultTxPower = aPower; - nrf_802154_tx_power_set(aPower); + nrf_802154_tx_power_set(GetTransmitPowerForChannel(channel)); - return OT_ERROR_NONE; +exit: + return error; } otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold) @@ -1299,3 +1328,37 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance * aInstance, return OT_ERROR_NOT_IMPLEMENTED; } #endif + +otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower) +{ + OT_UNUSED_VARIABLE(aInstance); + otError error = OT_ERROR_NONE; + + otEXPECT_ACTION(aChannel >= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN && aChannel <= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX, + error = OT_ERROR_INVALID_ARGS); + + sMaxTxPowerTable[aChannel - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN] = aMaxPower; + if (aChannel == nrf_802154_channel_get()) + { + nrf_802154_tx_power_set(GetTransmitPowerForChannel(aChannel)); + } + +exit: + return error; +} + +int8_t nrf5GetChannelMaxTransmitPower(uint8_t aChannel) +{ + int8_t power; + + if (aChannel < OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN || aChannel > OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX) + { + power = OT_RADIO_POWER_INVALID; + } + else + { + power = sMaxTxPowerTable[aChannel - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN]; + } + + return power; +} diff --git a/include/openthread/instance.h b/include/openthread/instance.h index b4fa5d26b..7e3d3bb96 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (56) +#define OPENTHREAD_API_VERSION (57) /** * @addtogroup api-instance diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h index f9e622f7e..c245bc700 100644 --- a/include/openthread/platform/radio.h +++ b/include/openthread/platform/radio.h @@ -425,6 +425,9 @@ void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aShortAddr /** * Get the radio's transmit power in dBm. * + * @note The transmit power returned will be no larger than the power specified in the max power table for + * the current channel. + * * @param[in] aInstance The OpenThread instance structure. * @param[out] aPower The transmit power in dBm. * @@ -438,6 +441,9 @@ otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower); /** * Set the radio's transmit power in dBm. * + * @note The real transmit power will be no larger than the power specified in the max power table for + * the current channel. + * * @param[in] aInstance The OpenThread instance structure. * @param[in] aPower The transmit power in dBm. *