[cc2538] add energy scan (#5681)

This commit provides a simple energy scan implementation on CC2538
platform.
This commit is contained in:
Yakun Xu
2020-10-22 10:43:30 -07:00
committed by GitHub
parent cf5f5ee08b
commit a04b6ea753
4 changed files with 98 additions and 5 deletions
+20
View File
@@ -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;
+2
View File
@@ -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_
+61 -5
View File
@@ -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)