mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 03:07:47 +00:00
[cc2538] add energy scan (#5681)
This commit provides a simple energy scan implementation on CC2538 platform.
This commit is contained in:
@@ -52,6 +52,17 @@ static uint32_t sAlarmT0 = 0;
|
||||
static uint32_t sAlarmDt = 0;
|
||||
static bool sIsRunning = false;
|
||||
|
||||
static uint8_t sTimersIsRunning = 0;
|
||||
static uint32_t sTimersExpireAt[OT_CC2538_TIMERS_COUNT];
|
||||
|
||||
extern void cc2538EnergyScanTimerHandler(void);
|
||||
|
||||
void cc2538SetTimer(otCC2538Timer aTimer, uint32_t aDelay)
|
||||
{
|
||||
sTimersIsRunning |= (1 << aTimer);
|
||||
sTimersExpireAt[aTimer] = sCounter + aDelay;
|
||||
}
|
||||
|
||||
void cc2538AlarmInit(void)
|
||||
{
|
||||
HWREG(NVIC_ST_RELOAD) = kSystemClock / kTicksPerSec;
|
||||
@@ -84,6 +95,15 @@ void cc2538AlarmProcess(otInstance *aInstance)
|
||||
uint32_t expires;
|
||||
bool fire = false;
|
||||
|
||||
if (sTimersIsRunning)
|
||||
{
|
||||
if ((int32_t)(sTimersExpireAt[OT_CC2538_TIMER_ENERGY_SCAN] - sCounter) < 0)
|
||||
{
|
||||
sTimersIsRunning &= ~(1 << OT_CC2538_TIMER_ENERGY_SCAN);
|
||||
cc2538EnergyScanTimerHandler();
|
||||
}
|
||||
}
|
||||
|
||||
if (sIsRunning)
|
||||
{
|
||||
expires = sAlarmT0 + sAlarmDt;
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
#define RFCORE_XREG_FSMSTAT1 0x4008864C // Radio status register
|
||||
#define RFCORE_XREG_FIFOPCTRL 0x40088650 // FIFOP threshold
|
||||
#define RFCORE_XREG_CCACTRL0 0x40088658 // CCA threshold
|
||||
#define RFCORE_XREG_RSSI 0x40088660 // RSSI status register
|
||||
#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
|
||||
@@ -109,6 +110,7 @@
|
||||
#define RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN 0x00000001 // Enables frame filtering
|
||||
|
||||
#define RFCORE_XREG_FRMCTRL0_AUTOACK 0x00000020
|
||||
#define RFCORE_XREG_FRMCTRL0_ENERGY_SCAN 0x00000010
|
||||
#define RFCORE_XREG_FRMCTRL0_AUTOCRC 0x00000040
|
||||
#define RFCORE_XREG_FRMCTRL0_INFINITY_RX 0x00000008
|
||||
|
||||
|
||||
@@ -104,4 +104,19 @@ void cc2538RadioSetHgm(bool aState);
|
||||
bool cc2538RadioGetHgm(void);
|
||||
#endif // OPENTHREAD_CONFIG_CC2538_WITH_CC2592 && OPENTHREAD_CONFIG_CC2592_USE_HGM
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OT_CC2538_TIMER_ENERGY_SCAN, ///< Internal timer for energy scan
|
||||
OT_CC2538_TIMERS_COUNT, ///< Number of internal timers
|
||||
} otCC2538Timer;
|
||||
|
||||
/**
|
||||
* This function sets the internal timer.
|
||||
*
|
||||
* @param[in] aTimer The timer identifier.
|
||||
* @param[in] aDelay The delay to trigger the timer, and must be no more than `INT32_MAX`.
|
||||
*
|
||||
*/
|
||||
void cc2538SetTimer(otCC2538Timer aTimer, uint32_t aDelay);
|
||||
|
||||
#endif // PLATFORM_CC2538_H_
|
||||
|
||||
@@ -178,6 +178,8 @@ static bool sIsReceiverEnabled = false;
|
||||
static uint8_t sDroppedFrameLength = 0;
|
||||
#endif
|
||||
|
||||
static int8_t cc2538RadioGetRssiOffset(void);
|
||||
|
||||
void enableReceiver(void)
|
||||
{
|
||||
if (!sIsReceiverEnabled)
|
||||
@@ -622,14 +624,30 @@ int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
return 0;
|
||||
int8_t rssi = OT_RADIO_RSSI_INVALID;
|
||||
|
||||
if ((HWREG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) != 0)
|
||||
{
|
||||
rssi = HWREG(RFCORE_XREG_RSSI) & 0xff;
|
||||
|
||||
if (rssi <= cc2538RadioGetRssiOffset() - 128)
|
||||
{
|
||||
rssi -= cc2538RadioGetRssiOffset();
|
||||
}
|
||||
else
|
||||
{
|
||||
rssi = -128;
|
||||
}
|
||||
}
|
||||
|
||||
return rssi;
|
||||
}
|
||||
|
||||
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
return OT_RADIO_CAPS_NONE;
|
||||
return OT_RADIO_CAPS_ENERGY_SCAN;
|
||||
}
|
||||
|
||||
static bool cc2538RadioGetPromiscuous(void)
|
||||
@@ -1017,6 +1035,23 @@ int8_t findSrcMatchAvailEntry(bool aShort)
|
||||
return entry;
|
||||
}
|
||||
|
||||
void cc2538EnergyScanTimerHandler(void)
|
||||
{
|
||||
int8_t rssi = otPlatRadioGetRssi(sInstance);
|
||||
|
||||
disableReceiver();
|
||||
|
||||
HWREG(RFCORE_XREG_FRMCTRL0) &= ~RFCORE_XREG_FRMCTRL0_ENERGY_SCAN;
|
||||
HWREG(RFCORE_XREG_FREQCTRL) = 11 + (sChannel - 11) * 5;
|
||||
|
||||
if (sIsReceiverEnabled)
|
||||
{
|
||||
enableReceiver();
|
||||
}
|
||||
|
||||
otPlatRadioEnergyScanDone(sInstance, rssi);
|
||||
}
|
||||
|
||||
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
@@ -1155,10 +1190,31 @@ void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
||||
otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
OT_UNUSED_VARIABLE(aScanChannel);
|
||||
OT_UNUSED_VARIABLE(aScanDuration);
|
||||
|
||||
return OT_ERROR_NOT_IMPLEMENTED;
|
||||
otLogInfoPlat("ScanChannel=%d", aScanChannel);
|
||||
|
||||
if (aScanChannel != sChannel)
|
||||
{
|
||||
if (sIsReceiverEnabled)
|
||||
{
|
||||
disableReceiver();
|
||||
}
|
||||
|
||||
HWREG(RFCORE_XREG_FREQCTRL) = 11 + (aScanChannel - 11) * 5;
|
||||
|
||||
enableReceiver();
|
||||
}
|
||||
else if (!sIsReceiverEnabled)
|
||||
{
|
||||
enableReceiver();
|
||||
}
|
||||
|
||||
// Collect peak signal strength
|
||||
HWREG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_ENERGY_SCAN;
|
||||
|
||||
cc2538SetTimer(OT_CC2538_TIMER_ENERGY_SCAN, aScanDuration);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
|
||||
|
||||
Reference in New Issue
Block a user