Skip to content

Commit

Permalink
[sdk] update to GSDK 4.4.3 (#904)
Browse files Browse the repository at this point in the history
  • Loading branch information
lmnotran authored Jul 3, 2024
1 parent dbb531a commit ae03498
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 96 deletions.
168 changes: 135 additions & 33 deletions src/src/alarm.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,31 +50,90 @@
#include "rail.h"
#include "sl_sleeptimer.h"

// timer data for handling wrapping
typedef struct wrap_timer_data wrap_timer_data_t;
struct wrap_timer_data
{
uint16_t overflow_counter;
uint16_t overflow_max;
};

// millisecond timer (sleeptimer)
static sl_sleeptimer_timer_handle_t sl_handle;
static uint32_t sMsAlarm = 0;
static bool sIsMsRunning = false;
static uint64_t sMsAlarm = 0;
static bool sIsMsRunning = false;
static wrap_timer_data_t milli_timer_data = {0};

// microsecond timer (RAIL timer)
static uint32_t sUsAlarm = 0;
static bool sIsUsRunning = false;

static RAIL_MultiTimer_t rail_timer;
static uint64_t sUsAlarm = 0;
static bool sIsUsRunning = false;
static wrap_timer_data_t micro_timer_data = {0};

// millisecond-alarm callback
static void AlarmCallback(sl_sleeptimer_timer_handle_t *aHandle, void *aData)
{
OT_UNUSED_VARIABLE(aHandle);
OT_UNUSED_VARIABLE(aData);
otSysEventSignalPending();
if (aData == NULL)
{
OT_UNUSED_VARIABLE(aHandle);
otSysEventSignalPending();
}
else
{
sl_status_t status;
wrap_timer_data_t *timer_data = (wrap_timer_data_t *)aData;

if (timer_data->overflow_counter < timer_data->overflow_max)
{
status = sl_sleeptimer_start_timer_ms(aHandle,
sl_sleeptimer_get_max_ms32_conversion(),
AlarmCallback,
(void *)timer_data,
0,
SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG);
OT_ASSERT(status == SL_STATUS_OK);
timer_data->overflow_counter++;
}
else
{
if (timer_data->overflow_max != 0)
{
sIsMsRunning = false;
sl_sleeptimer_stop_timer(aHandle);
}
}
}
}

// microsecond-alarm callback
static void radioTimerExpired(struct RAIL_MultiTimer *tmr, RAIL_Time_t expectedTimeOfEvent, void *cbArg)
{
OT_UNUSED_VARIABLE(tmr);
OT_UNUSED_VARIABLE(expectedTimeOfEvent);
OT_UNUSED_VARIABLE(cbArg);
if (cbArg == NULL)
{
OT_UNUSED_VARIABLE(tmr);
OT_UNUSED_VARIABLE(expectedTimeOfEvent);
otSysEventSignalPending();
}
else
{
RAIL_Status_t status;
wrap_timer_data_t *timer_data = (wrap_timer_data_t *)cbArg;

otSysEventSignalPending();
if (timer_data->overflow_counter < timer_data->overflow_max)
{
status = RAIL_SetMultiTimer(tmr, UINT32_MAX, RAIL_TIME_DELAY, radioTimerExpired, NULL);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
timer_data->overflow_counter++;
}
else
{
if (timer_data->overflow_max != 0)
{
sIsUsRunning = false;
RAIL_CancelMultiTimer(tmr);
}
}
}
}

void efr32AlarmInit(void)
Expand Down Expand Up @@ -111,13 +170,15 @@ uint32_t otPlatTimeGetXtalAccuracy(void)
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
OT_UNUSED_VARIABLE(aInstance);

sl_status_t status;
int32_t remaining;
int64_t remaining;
uint32_t initial_wrap_time;

sl_sleeptimer_stop_timer(&sl_handle);

sMsAlarm = aT0 + aDt;
remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
sMsAlarm = (uint64_t)aT0 + (uint64_t)aDt;
remaining = (int64_t)sMsAlarm - (int64_t)otPlatAlarmMilliGetNow();
sIsMsRunning = true;

if (remaining <= 0)
Expand All @@ -126,23 +187,46 @@ void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
}
else
{
status = sl_sleeptimer_start_timer(&sl_handle,
sl_sleeptimer_ms_to_tick(remaining),
AlarmCallback,
NULL,
0,
SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG);
OT_ASSERT(status == SL_STATUS_OK);
// The maximum value accepted by sleep timer ms32 APIs can be retrieved
// using sl_sleeptimer_get_max_ms32_conversion().
//
// (See platform/service/sleeptimer/inc/sl_sleeptimer.h)
//
if (remaining > sl_sleeptimer_get_max_ms32_conversion())
{
initial_wrap_time = (uint32_t)(remaining % sl_sleeptimer_get_max_ms32_conversion());
milli_timer_data.overflow_max = (uint16_t)(remaining / sl_sleeptimer_get_max_ms32_conversion());
milli_timer_data.overflow_counter = 0;

// Start a timer with the initial time
status = sl_sleeptimer_start_timer_ms(&sl_handle,
initial_wrap_time,
AlarmCallback,
(void *)&milli_timer_data,
0,
SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG);
OT_ASSERT(status == SL_STATUS_OK);
}
else
{
status = sl_sleeptimer_start_timer_ms(&sl_handle,
(uint32_t)remaining,
AlarmCallback,
NULL,
0,
SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG);
OT_ASSERT(status == SL_STATUS_OK);
}
}
}

uint32_t efr32AlarmPendingTime(void)
uint64_t efr32AlarmPendingTime(void)
{
uint32_t remaining = 0;
uint64_t remaining = 0;
uint32_t now = otPlatAlarmMilliGetNow();
if (sIsMsRunning && (sMsAlarm > now))
{
remaining = sMsAlarm - now;
remaining = sMsAlarm - (uint64_t)now;
}
return remaining;
}
Expand All @@ -162,7 +246,7 @@ void otPlatAlarmMilliStop(otInstance *aInstance)

void efr32AlarmProcess(otInstance *aInstance)
{
int32_t remaining;
int64_t remaining;
bool alarmMilliFired = false;
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
bool alarmMicroFired = false;
Expand All @@ -173,7 +257,7 @@ void efr32AlarmProcess(otInstance *aInstance)

if (sIsMsRunning)
{
remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
remaining = (int64_t)sMsAlarm - (int64_t)otPlatAlarmMilliGetNow();
if (remaining <= 0)
{
otPlatAlarmMilliStop(aInstance);
Expand All @@ -184,7 +268,7 @@ void efr32AlarmProcess(otInstance *aInstance)
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
if (sIsUsRunning)
{
remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
remaining = (int64_t)sUsAlarm - (int64_t)otPlatAlarmMicroGetNow();
if (remaining <= 0)
{
otPlatAlarmMicroStop(aInstance);
Expand Down Expand Up @@ -247,12 +331,13 @@ void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
int32_t remaining;
int64_t remaining;
uint32_t initial_wrap_time;

RAIL_CancelMultiTimer(&rail_timer);

sUsAlarm = aT0 + aDt;
remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
sUsAlarm = (uint64_t)aT0 + (uint64_t)aDt;
remaining = (int64_t)sUsAlarm - (int64_t)otPlatAlarmMicroGetNow();
sIsUsRunning = true;

if (remaining <= 0)
Expand All @@ -261,8 +346,25 @@ void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
}
else
{
status = RAIL_SetMultiTimer(&rail_timer, remaining, RAIL_TIME_DELAY, radioTimerExpired, NULL);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
if (remaining > UINT32_MAX)
{
initial_wrap_time = (uint32_t)(remaining % UINT32_MAX);
micro_timer_data.overflow_max = (uint16_t)(remaining / UINT32_MAX);
micro_timer_data.overflow_counter = 0;

// Start a timer with the initial time
status = RAIL_SetMultiTimer(&rail_timer,
initial_wrap_time,
RAIL_TIME_DELAY,
radioTimerExpired,
(void *)&micro_timer_data);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
}
else
{
status = RAIL_SetMultiTimer(&rail_timer, remaining, RAIL_TIME_DELAY, radioTimerExpired, NULL);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
}
}
}

Expand Down
26 changes: 24 additions & 2 deletions src/src/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@
#define GET_GPIO_PIN(x) (x & GPIO_PIN_BITMASK)
#define GET_GPIO_PORT(x) ((x & GPIO_PORT_BITMASK) >> 16)

// To cache the transmit power, so that we don't override it while loading the
// channel config or setting the channel.
static int8_t sTxPower = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;

struct PlatformDiagCommand
{
const char *mName;
Expand Down Expand Up @@ -309,12 +313,30 @@ otError otPlatDiagRadioAutoAck(bool aAutoAckEnabled)

void otPlatDiagChannelSet(uint8_t aChannel)
{
OT_UNUSED_VARIABLE(aChannel);
otError error = OT_ERROR_NONE;
RAIL_Status_t status;

RAIL_SchedulerInfo_t bgRxSchedulerInfo = {
.priority = RADIO_SCHEDULER_BACKGROUND_RX_PRIORITY,
// sliptime/transaction time is not used for bg rx
};

error = efr32RadioLoadChannelConfig(aChannel, sTxPower);
OT_ASSERT(error == OT_ERROR_NONE);

status = RAIL_StartRx(gRailHandle, aChannel, &bgRxSchedulerInfo);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
}

void otPlatDiagTxPowerSet(int8_t aTxPower)
{
OT_UNUSED_VARIABLE(aTxPower);
RAIL_Status_t status;

// RAIL_SetTxPowerDbm() takes power in units of deci-dBm (0.1dBm)
// Multiply by 10 because aPower is supposed be in units dBm
status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aTxPower) * 10);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
sTxPower = aTxPower;
}

void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
Expand Down
18 changes: 13 additions & 5 deletions src/src/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,24 @@ void otPlatReset(otInstance *aInstance)
NVIC_SystemReset();
}

#if defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE
OT_TOOL_WEAK void bootloader_rebootAndInstall(void)
{
// Weak stub function
// This should be discarded in favor of the function definition in bootloader_interface code, when that component is
// used
}

otError otPlatResetToBootloader(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
bootloader_rebootAndInstall();
return OT_ERROR_NONE;

// This should only be reached if the bootloader_interface component is not present.
// When it is present, the stubbed bootloader_rebootAndInstall above is not used.
// Instead, the non-weak definition of the function in the component is used, causing
// the device to reset.
return OT_ERROR_NOT_CAPABLE;
}
#endif
#endif

otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
Expand Down
4 changes: 4 additions & 0 deletions src/src/openthread-core-efr32-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,12 @@
* Allow triggering a platform reset to bootloader mode, if supported.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE
#if defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
#define OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE 1
#else
#define OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE 0
#endif
#endif

/**
Expand Down
14 changes: 13 additions & 1 deletion src/src/platform-efr32.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void efr32AlarmInit(void);
* This function provides the remaining time (in milliseconds) on an alarm service.
*
*/
uint32_t efr32AlarmPendingTime(void);
uint64_t efr32AlarmPendingTime(void);

/**
* This function checks if the alarm service is running.
Expand Down Expand Up @@ -188,6 +188,18 @@ RAIL_Status_t efr32RadioSetCcaMode(uint8_t aMode);

bool efr32AllowSleepCallback(void);

/**
* Load the channel configurations.
*
* @param[in] aChannel The radio channel.
* @param[in] aTxPower The radio transmit power in dBm.
*
* @retval OT_ERROR_NONE Successfully enabled/disabled .
* @retval OT_ERROR_INVALID_ARGS Invalid channel.
*
*/
otError efr32RadioLoadChannelConfig(uint8_t aChannel, int8_t aTxPower);

otError railStatusToOtError(RAIL_Status_t status);

#ifdef __cplusplus
Expand Down
Loading

0 comments on commit ae03498

Please sign in to comment.