[cli] add command to set/get external FEM's LNA gain (#5563)

This commit is contained in:
Jintao Lin
2020-10-13 08:12:14 -07:00
committed by GitHub
parent d0d2b71af3
commit eee652cc9e
15 changed files with 290 additions and 16 deletions
+41 -1
View File
@@ -107,6 +107,7 @@ static otRadioFrame sAckFrame;
static bool sAckedWithFramePending;
static int8_t sDefaultTxPower;
static int8_t sLnaGain = 0;
static uint32_t sEnergyDetectionTime;
static uint8_t sEnergyDetectionChannel;
@@ -687,7 +688,7 @@ otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aT
{
nrf_802154_cca_cfg_get(&ccaConfig);
// The radio driver has no function to convert ED threshold to dBm
*aThreshold = (int8_t)ccaConfig.ed_threshold + NRF528XX_MIN_CCA_ED_THRESHOLD;
*aThreshold = (int8_t)ccaConfig.ed_threshold + NRF528XX_MIN_CCA_ED_THRESHOLD - sLnaGain;
}
return error;
@@ -700,6 +701,8 @@ otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aTh
otError error = OT_ERROR_NONE;
nrf_802154_cca_cfg_t ccaConfig;
aThreshold += sLnaGain;
// The minimum value of ED threshold for radio driver is -94 dBm
if (aThreshold < NRF528XX_MIN_CCA_ED_THRESHOLD)
{
@@ -717,6 +720,43 @@ otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aTh
return error;
}
otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
if (aGain == NULL)
{
error = OT_ERROR_INVALID_ARGS;
}
else
{
*aGain = sLnaGain;
}
return error;
}
otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain)
{
OT_UNUSED_VARIABLE(aInstance);
int8_t threshold;
int8_t oldLnaGain = sLnaGain;
otError error = OT_ERROR_NONE;
error = otPlatRadioGetCcaEnergyDetectThreshold(aInstance, &threshold);
otEXPECT(error == OT_ERROR_NONE);
sLnaGain = aGain;
error = otPlatRadioSetCcaEnergyDetectThreshold(aInstance, threshold);
otEXPECT_ACTION(error == OT_ERROR_NONE, sLnaGain = oldLnaGain);
exit:
return error;
}
void nrf5RadioProcess(otInstance *aInstance)
{
bool isEventPending = false;
+23
View File
@@ -111,6 +111,7 @@ static bool sPromiscuous = false;
static bool sTxWait = false;
static int8_t sTxPower = 0;
static int8_t sCcaEdThresh = -74;
static int8_t sLnaGain = 0;
static bool sSrcMatchEnabled = false;
@@ -983,6 +984,28 @@ otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aTh
return OT_ERROR_NONE;
}
otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain)
{
OT_UNUSED_VARIABLE(aInstance);
assert(aInstance != NULL && aGain != NULL);
*aGain = sLnaGain;
return OT_ERROR_NONE;
}
otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain)
{
OT_UNUSED_VARIABLE(aInstance);
assert(aInstance != NULL);
sLnaGain = aGain;
return OT_ERROR_NONE;
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
+27 -2
View File
@@ -431,7 +431,7 @@ otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower);
otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower);
/**
* Get the radio's CCA ED threshold in dBm.
* Get the radio's CCA ED threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aThreshold The CCA ED threshold in dBm.
@@ -444,7 +444,7 @@ otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower);
otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold);
/**
* Set the radio's CCA ED threshold in dBm.
* Set the radio's CCA ED threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aThreshold The CCA ED threshold in dBm.
@@ -456,6 +456,31 @@ otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aT
*/
otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold);
/**
* Get the external FEM's Rx LNA gain in dBm.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aGain The external FEM's Rx LNA gain in dBm.
*
* @retval OT_ERROR_NONE Successfully retrieved the external FEM's LNA gain.
* @retval OT_ERROR_INVALID_ARGS @p aGain was NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED External FEM's LNA setting is not implemented.
*
*/
otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain);
/**
* Set the external FEM's Rx LNA gain in dBm.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aGain The external FEM's Rx LNA gain in dBm.
*
* @retval OT_ERROR_NONE Successfully set the external FEM's LNA gain.
* @retval OT_ERROR_NOT_IMPLEMENTED External FEM's LNA gain setting is not implemented.
*
*/
otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain);
/**
* Get the status of promiscuous mode.
*
+33 -3
View File
@@ -49,6 +49,7 @@ Done
- [extpanid](#extpanid)
- [factoryreset](#factoryreset)
- [fake](#fake)
- [fem](#fem)
- [ifconfig](#ifconfig)
- [ipaddr](#ipaddr)
- [ipmaddr](#ipmaddr)
@@ -330,7 +331,7 @@ Done
### ccathreshold
Get the CCA threshold in dBm.
Get the CCA threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4.
```bash
> ccathreshold
@@ -340,7 +341,7 @@ Done
### ccathreshold \<ccathreshold\>
Set the CCA threshold.
Set the CCA threshold measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4.
```bash
> ccathreshold -62
@@ -868,6 +869,35 @@ Note: Only for certification test.
Done
```
### fem
Get external FEM parameters.
```bash
> fem
LNA gain 11 dBm
Done
```
### fem lnagain
Get the Rx LNA gain in dBm of the external FEM.
```bash
> fem lnagain
11
Done
```
### fem lnagain \<LNA gain\>
Set the Rx LNA gain in dBm of the external FEM.
```bash
> fem lnagain 8
Done
```
### ifconfig
Show the status of the IPv6 interface.
@@ -1945,7 +1975,7 @@ Done
### txpower \<txpower\>
Set the transmit power.
Set the transmit power in dBm.
```bash
> txpower -10
+37
View File
@@ -1547,6 +1547,43 @@ exit:
}
#endif
otError Interpreter::ProcessFem(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgsLength == 0)
{
int8_t lnaGain;
SuccessOrExit(error = otPlatRadioGetFemLnaGain(mInstance, &lnaGain));
OutputLine("LNA gain %d dBm", lnaGain);
}
else if (strcmp(aArgs[0], "lnagain") == 0)
{
if (aArgsLength == 1)
{
int8_t lnaGain;
SuccessOrExit(error = otPlatRadioGetFemLnaGain(mInstance, &lnaGain));
OutputLine("%d", lnaGain);
}
else
{
int8_t lnaGain;
SuccessOrExit(error = ParseAsInt8(aArgs[1], lnaGain));
SuccessOrExit(error = otPlatRadioSetFemLnaGain(mInstance, lnaGain));
}
}
else
{
error = OT_ERROR_INVALID_ARGS;
}
exit:
return error;
}
otError Interpreter::ProcessIfconfig(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
+2
View File
@@ -332,6 +332,7 @@ private:
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
otError ProcessFake(uint8_t aArgsLength, char *aArgs[]);
#endif
otError ProcessFem(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIfconfig(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIpAddr(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIpAddrAdd(uint8_t aArgsLength, char *aArgs[]);
@@ -601,6 +602,7 @@ private:
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
{"fake", &Interpreter::ProcessFake},
#endif
{"fem", &Interpreter::ProcessFem},
{"help", &Interpreter::ProcessHelp},
{"ifconfig", &Interpreter::ProcessIfconfig},
{"ipaddr", &Interpreter::ProcessIpAddr},
+16
View File
@@ -165,3 +165,19 @@ OT_TOOL_WEAK uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance)
return 0;
}
OT_TOOL_WEAK otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aGain);
return OT_ERROR_NOT_IMPLEMENTED;
}
OT_TOOL_WEAK otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aGain);
return OT_ERROR_NOT_IMPLEMENTED;
}
+24
View File
@@ -243,6 +243,30 @@ public:
*/
otError SetCcaEnergyDetectThreshold(int8_t aThreshold);
/**
* This method gets the FEM's Rx LNA gain in dBm.
*
* @param[out] aGain The FEM's Rx LNA gain in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetFemLnaGain(int8_t &aGain);
/**
* This method sets the FEM's Rx LNA gain in dBm.
*
* @param[in] aGain The FEM's Rx LNA gain in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetFemLnaGain(int8_t aGain);
/**
* This method returns the radio sw version string.
*
+17
View File
@@ -1168,6 +1168,15 @@ otError RadioSpinel<InterfaceType, ProcessContextType>::GetCcaEnergyDetectThresh
return error;
}
template <typename InterfaceType, typename ProcessContextType>
otError RadioSpinel<InterfaceType, ProcessContextType>::GetFemLnaGain(int8_t &aGain)
{
otError error = Get(SPINEL_PROP_PHY_FEM_LNA_GAIN, SPINEL_DATATYPE_INT8_S, &aGain);
LogIfFail("Get FEM LNA gain failed", error);
return error;
}
template <typename InterfaceType, typename ProcessContextType>
int8_t RadioSpinel<InterfaceType, ProcessContextType>::GetRssi(void)
{
@@ -1252,6 +1261,14 @@ otError RadioSpinel<InterfaceType, ProcessContextType>::SetCcaEnergyDetectThresh
return error;
}
template <typename InterfaceType, typename ProcessContextType>
otError RadioSpinel<InterfaceType, ProcessContextType>::SetFemLnaGain(int8_t aGain)
{
otError error = Set(SPINEL_PROP_PHY_FEM_LNA_GAIN, SPINEL_DATATYPE_INT8_S, aGain);
LogIfFail("Set FEM LNA gain failed", error);
return error;
}
template <typename InterfaceType, typename ProcessContextType>
otError RadioSpinel<InterfaceType, ProcessContextType>::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
{
+4
View File
@@ -1379,6 +1379,10 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "PHY_TX_POWER";
break;
case SPINEL_PROP_PHY_FEM_LNA_GAIN:
ret = "PHY_FEM_LNA_GAIN";
break;
case SPINEL_PROP_PHY_RSSI:
ret = "PHY_RSSI";
break;
+11 -10
View File
@@ -1506,16 +1506,17 @@ enum
SPINEL_PROP_BASE_EXT__END = 0x1100,
SPINEL_PROP_PHY__BEGIN = 0x20,
SPINEL_PROP_PHY_ENABLED = SPINEL_PROP_PHY__BEGIN + 0, ///< [b]
SPINEL_PROP_PHY_CHAN = SPINEL_PROP_PHY__BEGIN + 1, ///< [C]
SPINEL_PROP_PHY_CHAN_SUPPORTED = SPINEL_PROP_PHY__BEGIN + 2, ///< [A(C)]
SPINEL_PROP_PHY_FREQ = SPINEL_PROP_PHY__BEGIN + 3, ///< kHz [L]
SPINEL_PROP_PHY_CCA_THRESHOLD = SPINEL_PROP_PHY__BEGIN + 4, ///< dBm [c]
SPINEL_PROP_PHY_TX_POWER = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
SPINEL_PROP_PHY_RSSI = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
SPINEL_PROP_PHY_RX_SENSITIVITY = SPINEL_PROP_PHY__BEGIN + 7, ///< dBm [c]
SPINEL_PROP_PHY_PCAP_ENABLED = SPINEL_PROP_PHY__BEGIN + 8, ///< [b]
SPINEL_PROP_PHY_CHAN_PREFERRED = SPINEL_PROP_PHY__BEGIN + 9, ///< [A(C)]
SPINEL_PROP_PHY_ENABLED = SPINEL_PROP_PHY__BEGIN + 0, ///< [b]
SPINEL_PROP_PHY_CHAN = SPINEL_PROP_PHY__BEGIN + 1, ///< [C]
SPINEL_PROP_PHY_CHAN_SUPPORTED = SPINEL_PROP_PHY__BEGIN + 2, ///< [A(C)]
SPINEL_PROP_PHY_FREQ = SPINEL_PROP_PHY__BEGIN + 3, ///< kHz [L]
SPINEL_PROP_PHY_CCA_THRESHOLD = SPINEL_PROP_PHY__BEGIN + 4, ///< dBm [c]
SPINEL_PROP_PHY_TX_POWER = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
SPINEL_PROP_PHY_RSSI = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
SPINEL_PROP_PHY_RX_SENSITIVITY = SPINEL_PROP_PHY__BEGIN + 7, ///< dBm [c]
SPINEL_PROP_PHY_PCAP_ENABLED = SPINEL_PROP_PHY__BEGIN + 8, ///< [b]
SPINEL_PROP_PHY_CHAN_PREFERRED = SPINEL_PROP_PHY__BEGIN + 9, ///< [A(C)]
SPINEL_PROP_PHY_FEM_LNA_GAIN = SPINEL_PROP_PHY__BEGIN + 10, ///< dBm [c]
SPINEL_PROP_PHY__END = 0x30,
SPINEL_PROP_PHY_EXT__BEGIN = 0x1200,
+31
View File
@@ -2205,6 +2205,37 @@ exit:
return error;
}
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_PHY_FEM_LNA_GAIN>(void)
{
int8_t gain;
otError error = OT_ERROR_NONE;
error = otPlatRadioGetFemLnaGain(mInstance, &gain);
if (error == OT_ERROR_NONE)
{
error = mEncoder.WriteInt8(gain);
}
else
{
error = mEncoder.OverwriteWithLastStatusError(ThreadErrorToSpinelStatus(error));
}
return error;
}
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_FEM_LNA_GAIN>(void)
{
int8_t gain = 0;
otError error = OT_ERROR_NONE;
SuccessOrExit(error = mDecoder.ReadInt8(gain));
error = otPlatRadioSetFemLnaGain(mInstance, gain);
exit:
return error;
}
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_DEBUG_TEST_ASSERT>(void)
{
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+2
View File
@@ -74,6 +74,7 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_PCAP_ENABLED),
#endif
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN_PREFERRED),
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_FEM_LNA_GAIN),
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_STATE),
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_MASK),
OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_PERIOD),
@@ -361,6 +362,7 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
#if OPENTHREAD_MTD || OPENTHREAD_FTD
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_PCAP_ENABLED),
#endif
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_FEM_LNA_GAIN),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_STATE),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_MASK),
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_PERIOD),
+13
View File
@@ -356,6 +356,19 @@ otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aTh
return sRadioSpinel.SetCcaEnergyDetectThreshold(aThreshold);
}
otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain)
{
OT_UNUSED_VARIABLE(aInstance);
assert(aGain != nullptr);
return sRadioSpinel.GetFemLnaGain(*aGain);
}
otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain)
{
OT_UNUSED_VARIABLE(aInstance);
return sRadioSpinel.SetFemLnaGain(aGain);
}
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
+9
View File
@@ -66,6 +66,15 @@ send "delaytimermin 1 2\n"
send "counters mac 1\n"
expect "Error 7: InvalidArgs"
send "fem lnagain 11\n"
expect "Done"
send "fem lnagain\n"
expect -- "11"
expect "Done"
send "fem\n"
expect -- "LNA gain 11 dBm"
expect "Done"
send "ifconfig down\n"
expect "Done"
send "ifconfig\n"