mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 09:07:47 +00:00
[efr32] fix otPlatRadioGetRssi() for MG1, MG12, MG13 (#5238)
This fixes an issue with Channel Monitoring for the EFR32 platform (MG1, MG12, MG13), where in, turning the radio to a new channel and immediately gathering background RSSI information was returning invalid results. A further investigation with the RAIL team indicated that this issue was occurring because the usage of `RAIL_GetRssi()` is incorrect. While the Rail_GetRssi API functions as documented, the problem is that the current implementation of this API returns valid results only in certain specified radio states and does not fit the use case for the OpenThread Channel Monitoring feature. (i.e computing RSSI value in the RxWarm radio state). To fix the issue, I am switching the affected platforms to the efr32mg21 implementation for `otPlatRadioGetRssi()`, which uses `RAIL_StartAverageRssi()` instead of `RAIL_GetRssi()`. `RAIL_StartAverageRssi()` uses hardware to trigger an interrupt once the RSSI is valid and should provide valid results. This approach was added by Marven when testing DMP support with OpenThread (https://github.com/openthread/openthread/pull/4321)
This commit is contained in:
@@ -77,6 +77,7 @@ enum
|
||||
enum
|
||||
{
|
||||
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
|
||||
EFR32_RSSI_AVERAGING_TIME = 16, // us
|
||||
EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us
|
||||
};
|
||||
|
||||
@@ -657,19 +658,29 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||
|
||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
otError error;
|
||||
uint32_t start;
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX))
|
||||
error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME);
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
|
||||
start = RAIL_GetTime();
|
||||
|
||||
// waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE
|
||||
while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS &&
|
||||
((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT))
|
||||
;
|
||||
|
||||
if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
|
||||
{
|
||||
int16_t railRssi = RAIL_RSSI_INVALID;
|
||||
railRssi = RAIL_GetRssi(gRailHandle, true);
|
||||
if (railRssi != RAIL_RSSI_INVALID)
|
||||
{
|
||||
rssi = railRssi / QUARTER_DBM_IN_DBM;
|
||||
}
|
||||
rssi = sEnergyScanResultDbm;
|
||||
}
|
||||
|
||||
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
|
||||
exit:
|
||||
return rssi;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ enum
|
||||
enum
|
||||
{
|
||||
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
|
||||
EFR32_RSSI_AVERAGING_TIME = 16, // us
|
||||
EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us
|
||||
};
|
||||
|
||||
@@ -657,19 +658,29 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||
|
||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
otError error;
|
||||
uint32_t start;
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX))
|
||||
error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME);
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
|
||||
start = RAIL_GetTime();
|
||||
|
||||
// waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE
|
||||
while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS &&
|
||||
((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT))
|
||||
;
|
||||
|
||||
if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
|
||||
{
|
||||
int16_t railRssi = RAIL_RSSI_INVALID;
|
||||
railRssi = RAIL_GetRssi(gRailHandle, true);
|
||||
if (railRssi != RAIL_RSSI_INVALID)
|
||||
{
|
||||
rssi = railRssi / QUARTER_DBM_IN_DBM;
|
||||
}
|
||||
rssi = sEnergyScanResultDbm;
|
||||
}
|
||||
|
||||
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
|
||||
exit:
|
||||
return rssi;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ enum
|
||||
enum
|
||||
{
|
||||
EFR32_RECEIVE_SENSITIVITY = -100, // dBm
|
||||
EFR32_RSSI_AVERAGING_TIME = 16, // us
|
||||
EFR32_RSSI_AVERAGING_TIMEOUT = 300, // us
|
||||
};
|
||||
|
||||
@@ -657,19 +658,29 @@ otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||
|
||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
otError error;
|
||||
uint32_t start;
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
if ((RAIL_GetRadioState(gRailHandle) & RAIL_RF_STATE_RX))
|
||||
error = efr32StartEnergyScan(ENERGY_SCAN_MODE_SYNC, sReceiveFrame.mChannel, EFR32_RSSI_AVERAGING_TIME);
|
||||
otEXPECT(error == OT_ERROR_NONE);
|
||||
|
||||
start = RAIL_GetTime();
|
||||
|
||||
// waiting for the event RAIL_EVENT_RSSI_AVERAGE_DONE
|
||||
while (sEnergyScanStatus == ENERGY_SCAN_STATUS_IN_PROGRESS &&
|
||||
((RAIL_GetTime() - start) < EFR32_RSSI_AVERAGING_TIMEOUT))
|
||||
;
|
||||
|
||||
if (sEnergyScanStatus == ENERGY_SCAN_STATUS_COMPLETED)
|
||||
{
|
||||
int16_t railRssi = RAIL_RSSI_INVALID;
|
||||
railRssi = RAIL_GetRssi(gRailHandle, true);
|
||||
if (railRssi != RAIL_RSSI_INVALID)
|
||||
{
|
||||
rssi = railRssi / QUARTER_DBM_IN_DBM;
|
||||
}
|
||||
rssi = sEnergyScanResultDbm;
|
||||
}
|
||||
|
||||
sEnergyScanStatus = ENERGY_SCAN_STATUS_IDLE;
|
||||
exit:
|
||||
return rssi;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user