Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 28 additions & 45 deletions subsys/mpsl/pm/mpsl_pm_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <zephyr/pm/policy.h>
#include <zephyr/logging/log.h>

#include <mpsl/mpsl_work.h>
#include <mpsl/mpsl_pm_utils.h>

LOG_MODULE_REGISTER(mpsl_pm_utils, CONFIG_MPSL_LOG_LEVEL);
Expand All @@ -23,9 +22,6 @@ LOG_MODULE_REGISTER(mpsl_pm_utils, CONFIG_MPSL_LOG_LEVEL);
#define TIME_TO_REGISTER_EVENT_IN_ZEPHYR_US 1000
#define PM_MAX_LATENCY_HCI_COMMANDS_US 499999

static void m_work_handler(struct k_work *work);
static K_WORK_DELAYABLE_DEFINE(pm_work, m_work_handler);

static uint8_t m_pm_prev_flag_value;
static bool m_pm_event_is_registered;
static uint32_t m_prev_lat_value_us;
Expand All @@ -41,7 +37,7 @@ static void m_update_latency_request(uint32_t lat_value_us)
}
}

void mpsl_pm_utils_work_handler(void)
void m_register_event(void)
{
mpsl_pm_params_t params = {0};
bool pm_param_valid = mpsl_pm_params_get(&params);
Expand All @@ -58,8 +54,6 @@ void mpsl_pm_utils_work_handler(void)
switch (params.event_state) {
case MPSL_PM_EVENT_STATE_NO_EVENTS_LEFT:
{
/* No event scheduled, so set latency to restrict deepest sleep states*/
m_update_latency_request(PM_MAX_LATENCY_HCI_COMMANDS_US);
if (m_pm_event_is_registered) {
pm_policy_event_unregister(&m_evt);
m_pm_event_is_registered = false;
Expand All @@ -68,60 +62,49 @@ void mpsl_pm_utils_work_handler(void)
}
case MPSL_PM_EVENT_STATE_BEFORE_EVENT:
{
/* In case we missed a state and are in zero-latency, set low-latency.*/
m_update_latency_request(PM_MAX_LATENCY_HCI_COMMANDS_US);

/* Note: Considering an overflow could only happen if the system runs many years,
* it needen't be considered here.
*/
int64_t current_time_us = k_uptime_get() * 1000;
uint64_t relative_time_us = params.event_time_abs_us - current_time_us;
uint64_t max_cycles_until_event = k_us_to_cyc_floor64(relative_time_us);

if (max_cycles_until_event > UINT32_MAX) {
/* The event is too far in the future and would
* exceed the 32-bit cycle limit.
*/
uint64_t event_delay_us = params.event_time_abs_us - current_time_us -
TIME_TO_REGISTER_EVENT_IN_ZEPHYR_US;
#ifdef CONFIG_TIMEOUT_64BIT
mpsl_work_schedule(&pm_work, K_USEC(event_delay_us));
#else
if (event_delay_us > UINT32_MAX) {
mpsl_work_schedule(&pm_work, K_USEC(UINT32_MAX));
} else {
mpsl_work_schedule(&pm_work, K_USEC((uint32_t)event_delay_us));
}
#endif
return;
}

/* Event scheduled */
if (m_pm_event_is_registered) {
pm_policy_event_update(&m_evt,
k_us_to_cyc_floor32(params.event_time_abs_us));
k_us_to_ticks_floor64(params.event_time_abs_us));
} else {
pm_policy_event_register(&m_evt,
k_us_to_cyc_floor32(params.event_time_abs_us));
k_us_to_ticks_floor64(params.event_time_abs_us));
m_pm_event_is_registered = true;
}
break;
}
case MPSL_PM_EVENT_STATE_IN_EVENT:
{
m_update_latency_request(0);
break;
}
default:
__ASSERT(false, "MPSL PM is in an undefined state.");
}
m_pm_prev_flag_value = params.cnt_flag;
}

static void m_work_handler(struct k_work *work)
static void m_register_latency(void)
{
switch (mpsl_pm_low_latency_state_get()) {
case MPSL_PM_LOW_LATENCY_STATE_OFF:
if (mpsl_pm_low_latency_requested()) {
mpsl_pm_low_latency_state_set(MPSL_PM_LOW_LATENCY_STATE_REQUESTING);
m_update_latency_request(0);
mpsl_pm_low_latency_state_set(MPSL_PM_LOW_LATENCY_STATE_ON);
}
break;
case MPSL_PM_LOW_LATENCY_STATE_ON:
if (!mpsl_pm_low_latency_requested()) {
mpsl_pm_low_latency_state_set(MPSL_PM_LOW_LATENCY_STATE_RELEASING);
m_update_latency_request(PM_MAX_LATENCY_HCI_COMMANDS_US);
mpsl_pm_low_latency_state_set(MPSL_PM_LOW_LATENCY_STATE_OFF);
}
break;
default:
break;
}
}

void mpsl_pm_utils_work_handler(void)
{
ARG_UNUSED(work);
mpsl_pm_utils_work_handler();
m_register_event();
m_register_latency();
}

void mpsl_pm_utils_init(void)
Expand Down
6 changes: 0 additions & 6 deletions tests/subsys/mpsl/pm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ project(pm_test)
test_runner_generate(pm_test.c)

# Create mocks for pm module.
cmock_handle(${CMAKE_CURRENT_SOURCE_DIR}/kernel_minimal_mock.h)
cmock_handle(${ZEPHYR_BASE}/include/zephyr/pm/policy.h)
cmock_handle(${ZEPHYR_NRFXLIB_MODULE_DIR}/mpsl/include/mpsl_pm.h)
cmock_handle(${ZEPHYR_NRFXLIB_MODULE_DIR}/mpsl/include/mpsl_pm_config.h)
cmock_handle(${ZEPHYR_NRF_MODULE_DIR}/include/mpsl/mpsl_work.h)

# Add Unit Under Test source files
target_sources(app PRIVATE ${ZEPHYR_NRF_MODULE_DIR}/subsys/mpsl/pm/mpsl_pm_utils.c)
Expand All @@ -28,10 +26,6 @@ target_sources(app PRIVATE pm_test.c)
# Include paths
target_include_directories(app PRIVATE src)

# Preinclude file to the UUT to redefine mpsl_work_schedule().
set_property(SOURCE ${ZEPHYR_NRF_MODULE_DIR}/subsys/mpsl/pm/mpsl_pm_utils.c
PROPERTY COMPILE_FLAGS "-include mocks/kernel_minimal_mock.h -include mocks/mpsl_work.h")

# Options that cannot be passed through Kconfig fragments.
target_compile_options(app PRIVATE
-DCONFIG_PM=y
Expand Down
25 changes: 0 additions & 25 deletions tests/subsys/mpsl/pm/kernel_minimal_mock.h

This file was deleted.

Loading
Loading