Skip to content

Commit

Permalink
modules: nrfxlib: nrf_802154: add lptimer pm utils module
Browse files Browse the repository at this point in the history
Adds pm utils module that updates the Power Management module
upon the request from the 802.15.4 lptimer module.

Signed-off-by: Piotr Koziar <[email protected]>
  • Loading branch information
piotrkoziar committed Jan 18, 2025
1 parent 509fa66 commit 37ebaa0
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions modules/nrfxlib/nrf_802154/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION)
${CMAKE_CURRENT_SOURCE_DIR}/sl/platform/nrf_802154_platform_timestamper.c
${CMAKE_CURRENT_SOURCE_DIR}/sl/platform/nrf_802154_platform_sl_lptimer_grtc.c
${CMAKE_CURRENT_SOURCE_DIR}/sl/platform/nrf_802154_platform_sl_lptimer_grtc_hw_task.c
${CMAKE_CURRENT_SOURCE_DIR}/sl/platform/nrf_802154_platform_sl_lptimer_grtc_pm_utils.c
)
endif()
endif ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "platform/nrf_802154_platform_sl_lptimer.h"
#include "nrf_802154_platform_sl_lptimer_grtc_hw_task.h"
#include "nrf_802154_platform_sl_lptimer_grtc_pm_utils.h"

#include <assert.h>
#include <zephyr/sys/atomic.h>
Expand Down Expand Up @@ -95,13 +96,17 @@ void nrf_802154_platform_sl_lptimer_schedule_at(uint64_t fire_lpticks)
fire_lpticks,
timer_compare_handler,
NULL);

nrf_802154_platform_sl_lptimer_pm_utils_event_update(fire_lpticks);
}

void nrf_802154_platform_sl_lptimer_disable(void)
{
atomic_clear_bit(&m_enabled, 0);

z_nrf_grtc_timer_abort(m_callbacks_cc_channel);

nrf_802154_platform_sl_lptimer_pm_utils_event_unregister();
}

void nrf_802154_platform_sl_lptimer_critical_section_enter(void)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include "nrf_802154_platform_sl_lptimer_grtc_pm_utils.h"

#include <zephyr/kernel.h>
#include <zephyr/pm/policy.h>

#define LPTIMER_PM_UTILS_STACK_SIZE 1024

static K_SEM_DEFINE(m_lptimer_pm_utils_sem, 0, 1);

static struct pm_policy_event m_pm_event;
static int64_t m_trigger_time;
static bool m_event_registered;

#define SYS_TICK_PER_GRTC_CYC \
((uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC / (uint64_t)sys_clock_hw_cycles_per_sec())

static int64_t grtc_ticks_to_system_ticks(uint64_t abs_grtc)
{
int64_t curr_sys = k_uptime_ticks();
uint64_t curr_grtc = z_nrf_grtc_timer_read();

uint64_t result = (abs_grtc > curr_grtc) ? (abs_grtc - curr_grtc) : 0;

return curr_sys + result * SYS_TICK_PER_GRTC_CYC;
}

void nrf_802154_platform_sl_lptimer_pm_utils_event_update(uint64_t grtc_ticks)
{
int64_t event_time = (grtc_ticks > 0) ? grtc_ticks_to_system_ticks(grtc_ticks) : 0;

if (m_trigger_time != event_time) {
m_trigger_time = event_time;

k_sem_give(&m_lptimer_pm_utils_sem);
}
}

static void lptimer_pm_utils_thread_func(void *dummy1, void *dummy2, void *dummy3)
{
ARG_UNUSED(dummy1);
ARG_UNUSED(dummy2);
ARG_UNUSED(dummy3);

while (true) {
k_sem_take(&m_lptimer_pm_utils_sem, K_FOREVER);

if (m_trigger_time == 0) {
if (m_event_registered) {
pm_policy_event_unregister(&m_pm_event);
}
m_event_registered = false;
} else if (!m_event_registered) {
pm_policy_event_register(&m_pm_event, m_trigger_time);
m_event_registered = true;
} else {
pm_policy_event_update(&m_pm_event, m_trigger_time);
}
}
}

K_THREAD_DEFINE(lptimer_pm_utils_thread, LPTIMER_PM_UTILS_STACK_SIZE,
lptimer_pm_utils_thread_func, NULL, NULL, NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0);
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef NRF_802154_PLATFORM_SL_LPTIMER_GRTC_PM_UTILS_H_
#define NRF_802154_PLATFORM_SL_LPTIMER_GRTC_PM_UTILS_H_

#include <stdint.h>

/**
* @brief Updates the trigger time of an upcoming event, allowing forwarding it to
* the Power Management module.
*
* After some delay, the event's trigger time is sent to the Power Management module
* via @ref pm_policy_event_register or @ref pm_policy_event_update.
*
* This function opens a sequence that should be closed
* by @ref nrf_802154_platform_sl_lptimer_pm_utils_event_unregister call.
* In the meantime, the @ref nrf_802154_platform_sl_lptimer_pm_utils_event_update can be called
* multiple times.
*
* @note There is no guarantee, that the aforementioned pm_policy methods will be called before
* the event's trigger time.
*
* @param grtc_ticks When the event will occur, in absolute GRTC ticks.
*/
void nrf_802154_platform_sl_lptimer_pm_utils_event_update(uint64_t grtc_ticks);

/**
* @brief Informs that there are no events planned and the Power Management event
* registered by @ref nrf_802154_platform_sl_lptimer_pm_utils_event_update requires unregistration.
*
* Unless already called and if the @ref nrf_802154_platform_sl_lptimer_pm_utils_event_update
* precedes this function, the function will call @ref pm_policy_event_unregister with some delay.
*/
static inline void nrf_802154_platform_sl_lptimer_pm_utils_event_unregister(void)
{
return nrf_802154_platform_sl_lptimer_pm_utils_event_update(0);
}

#endif /* NRF_802154_PLATFORM_SL_LPTIMER_GRTC_PM_UTILS_H_ */

0 comments on commit 37ebaa0

Please sign in to comment.