From 345bb0e8a8ce339540d83b434ac33d7a00f5b84d Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Fri, 5 Sep 2025 20:36:02 +0800 Subject: [PATCH 1/3] drivers: timer: Add NXP Utick support Add NXP micro tick (utick) timer implementation. It is a simple, ultra-low-power timer that can run and wake up the chip from Low-power mode. Signed-off-by: Yves Wang --- drivers/timer/CMakeLists.txt | 1 + drivers/timer/Kconfig | 1 + drivers/timer/Kconfig.mcux_utick | 22 +++ drivers/timer/mcux_utick_timer.c | 125 ++++++++++++++++++ dts/bindings/timer/nxp,utick.yaml | 24 ++++ .../mcux/mcux-sdk-ng/drivers/drivers.cmake | 1 + 6 files changed, 174 insertions(+) create mode 100644 drivers/timer/Kconfig.mcux_utick create mode 100644 drivers/timer/mcux_utick_timer.c create mode 100644 dts/bindings/timer/nxp,utick.yaml diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index a354de5e35e31..796ebb33d1b9b 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -26,6 +26,7 @@ zephyr_library_sources_ifdef(CONFIG_MCHP_SAM_PIT64B_TIMER mchp_sam_pit64b_timer. zephyr_library_sources_ifdef(CONFIG_MCUX_LPTMR_TIMER mcux_lptmr_timer.c) zephyr_library_sources_ifdef(CONFIG_MCUX_OS_TIMER mcux_os_timer.c) zephyr_library_sources_ifdef(CONFIG_MCUX_GPT_TIMER mcux_gpt_timer.c) +zephyr_library_sources_ifdef(CONFIG_MCUX_UTICK_TIMER mcux_utick_timer.c) zephyr_library_sources_ifdef(CONFIG_MIPS_CP0_TIMER mips_cp0_timer.c) zephyr_library_sources_ifdef(CONFIG_NATIVE_SIM_TIMER native_sim_timer.c) zephyr_library_sources_ifdef(CONFIG_NPCX_ITIM_TIMER npcx_itim_timer.c) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 1cb165f329ff8..97e9f9d6093c0 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -83,6 +83,7 @@ source "drivers/timer/Kconfig.mchp_sam" source "drivers/timer/Kconfig.mcux_gpt" source "drivers/timer/Kconfig.mcux_lptmr" source "drivers/timer/Kconfig.mcux_os" +source "drivers/timer/Kconfig.mcux_utick" source "drivers/timer/Kconfig.mips_cp0" source "drivers/timer/Kconfig.native_sim" source "drivers/timer/Kconfig.npcx_itim" diff --git a/drivers/timer/Kconfig.mcux_utick b/drivers/timer/Kconfig.mcux_utick new file mode 100644 index 0000000000000..9b8640095367c --- /dev/null +++ b/drivers/timer/Kconfig.mcux_utick @@ -0,0 +1,22 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +config MCUX_UTICK_TIMER + bool "MCUX Micro-Tick Timer" + default n + depends on DT_HAS_NXP_UTICK_ENABLED + select TICKLESS_CAPABLE + select SYSTEM_TIMER_HAS_DISABLE_SUPPORT + help + This module implements a kernel device driver for the NXP MCUX Micro + Tick timer and provides the standard "system clock driver" interfaces. + +if MCUX_UTICK_TIMER + +config SYS_CLOCK_HW_CYCLES_PER_SEC + int + default 1000000 + help + UTICK source frequency in Hz (e.g. 1 MHz). Must match real UTICK clock. + +endif diff --git a/drivers/timer/mcux_utick_timer.c b/drivers/timer/mcux_utick_timer.c new file mode 100644 index 0000000000000..fa4722da97488 --- /dev/null +++ b/drivers/timer/mcux_utick_timer.c @@ -0,0 +1,125 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_utick + +#include +#include +#include +#include +#include +#include +#include +#include +#include "fsl_utick.h" + +LOG_MODULE_REGISTER(mcux_utick_timer, LOG_LEVEL_ERR); + +/* Timer cycles per tick */ +#define CYC_PER_TICK \ + ((uint32_t)((uint64_t)sys_clock_hw_cycles_per_sec() / \ + (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)) +/* UTICK: DELAYVAL is 31-bit; actual delay = (DELAYVAL+1) cycles */ +#define MAX_CYC (UTICK_CTRL_DELAYVAL_MASK) +/* The minimum usable tick interval is one clock cycle, for a delay of two timer clocks. */ +#define MIN_CYC (1u) +#define MAX_TICKS ((MAX_CYC + 1u) / CYC_PER_TICK) + +static struct k_spinlock lock; +/* UTICK did not provide a readable counter register, so use accumulate software cycles */ +static volatile uint64_t sw_cycle64; +/* Ticks programmed for the next interrupt (used as elapsed on IRQ) */ +static volatile uint32_t programmed_ticks; + +static UTICK_Type *base = (UTICK_Type *)DT_INST_REG_ADDR(0); + +static inline uint32_t ticks_to_cycles(uint32_t ticks) +{ + uint64_t cyc = (uint64_t)ticks * (uint64_t)CYC_PER_TICK; + + if (cyc < MIN_CYC + 1) { + cyc = MIN_CYC + 1; + } + if (cyc > MAX_CYC + 1) { + cyc = MAX_CYC + 1; + } + return (uint32_t)(cyc - 1); +} + +static void utick_cb(void) +{ + uint32_t elapsed = programmed_ticks ? programmed_ticks : 1u; + + sw_cycle64 += (uint64_t)elapsed * (uint64_t)CYC_PER_TICK; + programmed_ticks = 0u; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + programmed_ticks = 1u; + UTICK_SetTick(base, kUTICK_Onetime, ticks_to_cycles(programmed_ticks), utick_cb); + sys_clock_announce(1); + } else { + sys_clock_announce((int32_t)elapsed); + } +} + +static void mcux_utick_isr(const void *arg) +{ + ARG_UNUSED(arg); + + UTICK_HandleIRQ(base, utick_cb); +} + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + /* Not supported on tickful kernels */ + return; + } + ARG_UNUSED(idle); + + ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks; + ticks = CLAMP((ticks - 1), 0, (int32_t)MAX_TICKS); + + k_spinlock_key_t key = k_spin_lock(&lock); + + programmed_ticks = (uint32_t)ticks; + UTICK_SetTick(base, kUTICK_Onetime, ticks_to_cycles(programmed_ticks), utick_cb); + k_spin_unlock(&lock, key); +} + +void sys_clock_disable(void) +{ + UTICK_Deinit(base); +} + +uint32_t sys_clock_elapsed(void) +{ + return 0; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + return (uint32_t)sw_cycle64; +} + +uint64_t sys_clock_cycle_get_64(void) +{ + return sw_cycle64; +} + +static int sys_clock_driver_init(void) +{ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), mcux_utick_isr, NULL, 0); + irq_enable(DT_INST_IRQN(0)); + UTICK_Init(base); + + programmed_ticks = IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? MAX_TICKS : 1u; + UTICK_SetTick(base, kUTICK_Onetime, ticks_to_cycles(programmed_ticks), utick_cb); + + return 0; +} + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/dts/bindings/timer/nxp,utick.yaml b/dts/bindings/timer/nxp,utick.yaml new file mode 100644 index 0000000000000..e18fb6a8843c2 --- /dev/null +++ b/dts/bindings/timer/nxp,utick.yaml @@ -0,0 +1,24 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP Micro-Tick Timer + +compatible: "nxp,utick" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clk-source: + type: int + enum: [0, 1, 2, 3] + description: Utick function clock source + + clk-divider: + type: int + description: Utick function clock divider diff --git a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake index 62c55bf75a73f..dfe7cc6ada4d5 100644 --- a/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake +++ b/modules/hal_nxp/mcux/mcux-sdk-ng/drivers/drivers.cmake @@ -42,6 +42,7 @@ set_variable_ifdef(CONFIG_SPI_MCUX_FLEXCOMM CONFIG_MCUX_COMPONENT_driver.fle set_variable_ifdef(CONFIG_UART_MCUX_FLEXCOMM CONFIG_MCUX_COMPONENT_driver.flexcomm) set_variable_ifdef(CONFIG_UART_MCUX_FLEXCOMM CONFIG_MCUX_COMPONENT_driver.flexcomm_usart) set_variable_ifdef(CONFIG_MCUX_OS_TIMER CONFIG_MCUX_COMPONENT_driver.ostimer) +set_variable_ifdef(CONFIG_MCUX_UTICK_TIMER CONFIG_MCUX_COMPONENT_driver.utick) set_variable_ifdef(CONFIG_PWM_MCUX_SCTIMER CONFIG_MCUX_COMPONENT_driver.sctimer) set_variable_ifdef(CONFIG_PWM_MCUX_CTIMER CONFIG_MCUX_COMPONENT_driver.ctimer) set_variable_ifdef(CONFIG_SOC_FLASH_LPC CONFIG_MCUX_COMPONENT_driver.flashiap) From bef34f8b14811172a3cae3ffee1371e8d94e730c Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Fri, 5 Sep 2025 20:42:10 +0800 Subject: [PATCH 2/3] dts: nxp: Add utick support Add utick instance for mcxa153 mcxn23x mcxnx4x and rt7xx cm33_cpu0. Add MCUX_UTICK0_CLK for future clock control support on utick. Signed-off-by: Yves Wang --- boards/nxp/frdm_mcxn947/board.c | 5 +++++ boards/nxp/mimxrt700_evk/board.c | 7 +++++++ dts/arm/nxp/nxp_mcxa153.dtsi | 10 ++++++++++ dts/arm/nxp/nxp_mcxn23x_common.dtsi | 10 ++++++++++ dts/arm/nxp/nxp_mcxnx4x_common.dtsi | 8 ++++++++ dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi | 10 ++++++++++ .../zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h | 4 +++- 7 files changed, 53 insertions(+), 1 deletion(-) diff --git a/boards/nxp/frdm_mcxn947/board.c b/boards/nxp/frdm_mcxn947/board.c index 81610187fc6c5..5b2ff1ef532a8 100644 --- a/boards/nxp/frdm_mcxn947/board.c +++ b/boards/nxp/frdm_mcxn947/board.c @@ -448,6 +448,11 @@ void board_early_init_hook(void) CLOCK_EnableClock(kCLOCK_Ewm0); #endif +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(utick0)) + /* Enable FRO 1MHz clock for UTICK */ + CLOCK_SetupClockCtrl(kCLOCK_FRO1MHZ_ENA); +#endif + /* Set SystemCoreClock variable. */ SystemCoreClock = CLOCK_INIT_CORE_CLOCK; } diff --git a/boards/nxp/mimxrt700_evk/board.c b/boards/nxp/mimxrt700_evk/board.c index d3e24ed9b483e..aa3b0fc9a62f3 100644 --- a/boards/nxp/mimxrt700_evk/board.c +++ b/boards/nxp/mimxrt700_evk/board.c @@ -532,6 +532,13 @@ void board_early_init_hook(void) CLOCK_EnableClock(kCLOCK_Acmp0); RESET_ClearPeripheralReset(kACMP0_RST_SHIFT_RSTn); #endif + +#if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(utick0)) + /* Enable FRO1_DIV2 clock for UTICK */ + CLOCK_AttachClk(kFRO1_DIV2_to_UTICK0_CLK); + /* Use 1MHz clock */ + CLOCK_SetClkDiv(kCLOCK_DivUtick0Clk, 96U); +#endif } static void GlikeyWriteEnable(GLIKEY_Type *base, uint8_t idx) diff --git a/dts/arm/nxp/nxp_mcxa153.dtsi b/dts/arm/nxp/nxp_mcxa153.dtsi index e9a120041a6ca..db796503983c2 100644 --- a/dts/arm/nxp/nxp_mcxa153.dtsi +++ b/dts/arm/nxp/nxp_mcxa153.dtsi @@ -66,6 +66,16 @@ prescale = <0>; }; + utick0: utick@4000b000 { + compatible = "nxp,utick"; + reg = <0x4000b000 0x20>; + interrupts = <59 0>; + clocks = <&syscon MCUX_UTICK0_CLK>; + clk-source = <2>; + clk-divider = <0>; + status = "disabled"; + }; + edma0: dma-controller@40080000 { #dma-cells = <2>; compatible = "nxp,mcux-edma"; diff --git a/dts/arm/nxp/nxp_mcxn23x_common.dtsi b/dts/arm/nxp/nxp_mcxn23x_common.dtsi index ab6b1f9ee9362..0b4d364e68253 100644 --- a/dts/arm/nxp/nxp_mcxn23x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn23x_common.dtsi @@ -73,6 +73,16 @@ }; }; + utick0: utick@12000 { + compatible = "nxp,utick"; + reg = <0x12000 0x20>; + interrupts = <29 0>; + clocks = <&syscon MCUX_UTICK0_CLK>; + clk-source = <2>; + clk-divider = <0>; + status = "disabled"; + }; + porta: pinmux@116000 { compatible = "nxp,port-pinmux"; reg = <0x116000 0x1000>; diff --git a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi index 9b112504dd3a1..59408369734f2 100644 --- a/dts/arm/nxp/nxp_mcxnx4x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxnx4x_common.dtsi @@ -80,6 +80,14 @@ }; }; + utick0: utick@12000 { + compatible = "nxp,utick"; + reg = <0x12000 0x20>; + interrupts = <29 0>; + clocks = <&syscon MCUX_UTICK0_CLK>; + status = "disabled"; + }; + porta: pinmux@116000 { compatible = "nxp,port-pinmux"; reg = <0x116000 0x1000>; diff --git a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi index 040d2936487b1..4e308a3b2891a 100644 --- a/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi +++ b/dts/arm/nxp/nxp_rt7xx_cm33_cpu0.dtsi @@ -145,6 +145,16 @@ * and secure modes (0x50000000). */ + utick0: utick@f000 { + compatible = "nxp,utick"; + reg = <0xf000 0x20>; + interrupts = <1 0>; + clk-source = <3>; + clk-divider = <96>; + clocks = <&clkctl0 MCUX_UTICK0_CLK>; + status = "disabled"; + }; + lpadc0: adc@20c000 { compatible = "nxp,lpc-lpadc"; reg = <0x20c000 0x304>; diff --git a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h index 0f63ed45a581c..5d3f56d184edd 100644 --- a/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h +++ b/include/zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 NXP + * Copyright 2020-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -129,4 +129,6 @@ #define MCUX_LPSPI0_CLK MCUX_LPC_CLK_ID(0x17, 0x00) #define MCUX_LPSPI1_CLK MCUX_LPC_CLK_ID(0x17, 0x01) +#define MCUX_UTICK0_CLK MCUX_LPC_CLK_ID(0x18, 0x00) + #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MCUX_LPC_SYSCON_H_ */ From eb96c595968dd254e3fcd5d5ce0f16a9d5323cb9 Mon Sep 17 00:00:00 2001 From: Yves Wang Date: Fri, 5 Sep 2025 20:44:09 +0800 Subject: [PATCH 3/3] tests: drivers: timer: Add utick driver test Test utick in ms accurancy and ensure it work properly in oneshot and periodic modes. Add utick test support for frdm_mcxa153, frdm_mcxn236, frdm_mcxn947 and mimxrt798s/cm33_cpu0 Signed-off-by: Yves Wang --- .../timer/nxp_utick_timer/CMakeLists.txt | 10 ++ .../drivers/timer/nxp_utick_timer/app.overlay | 10 ++ .../timer/nxp_utick_timer/boards/common.conf | 5 + tests/drivers/timer/nxp_utick_timer/prj.conf | 5 + .../drivers/timer/nxp_utick_timer/src/main.c | 93 +++++++++++++++++++ .../timer/nxp_utick_timer/testcase.yaml | 18 ++++ 6 files changed, 141 insertions(+) create mode 100644 tests/drivers/timer/nxp_utick_timer/CMakeLists.txt create mode 100644 tests/drivers/timer/nxp_utick_timer/app.overlay create mode 100644 tests/drivers/timer/nxp_utick_timer/boards/common.conf create mode 100644 tests/drivers/timer/nxp_utick_timer/prj.conf create mode 100644 tests/drivers/timer/nxp_utick_timer/src/main.c create mode 100644 tests/drivers/timer/nxp_utick_timer/testcase.yaml diff --git a/tests/drivers/timer/nxp_utick_timer/CMakeLists.txt b/tests/drivers/timer/nxp_utick_timer/CMakeLists.txt new file mode 100644 index 0000000000000..f098e509f7f66 --- /dev/null +++ b/tests/drivers/timer/nxp_utick_timer/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(nxp_utick_timer) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/timer/nxp_utick_timer/app.overlay b/tests/drivers/timer/nxp_utick_timer/app.overlay new file mode 100644 index 0000000000000..270fb416d271d --- /dev/null +++ b/tests/drivers/timer/nxp_utick_timer/app.overlay @@ -0,0 +1,10 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&utick0 +{ + status = "okay"; +}; diff --git a/tests/drivers/timer/nxp_utick_timer/boards/common.conf b/tests/drivers/timer/nxp_utick_timer/boards/common.conf new file mode 100644 index 0000000000000..c6b9850d7cc4c --- /dev/null +++ b/tests/drivers/timer/nxp_utick_timer/boards/common.conf @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_CORTEX_M_SYSTICK=n +CONFIG_MCUX_OS_TIMER=n diff --git a/tests/drivers/timer/nxp_utick_timer/prj.conf b/tests/drivers/timer/nxp_utick_timer/prj.conf new file mode 100644 index 0000000000000..4679e008b6b94 --- /dev/null +++ b/tests/drivers/timer/nxp_utick_timer/prj.conf @@ -0,0 +1,5 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_MCUX_UTICK_TIMER=y diff --git a/tests/drivers/timer/nxp_utick_timer/src/main.c b/tests/drivers/timer/nxp_utick_timer/src/main.c new file mode 100644 index 0000000000000..a4334ef9941be --- /dev/null +++ b/tests/drivers/timer/nxp_utick_timer/src/main.c @@ -0,0 +1,93 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define CYC_PER_TICK \ + ((uint64_t)sys_clock_hw_cycles_per_sec() / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +#define SLEEP_TIME_MS 200U +#define TIMER_COUNT_TIME_MS 10U +#define WAIT_FOR_TIMER_EVENT_TIME_MS (TIMER_COUNT_TIME_MS + 5U) +#define NUMBER_OF_TRIES 2000U + +static atomic_t g_cnt; +static void inc_cb(struct k_timer *t) +{ + atomic_inc(&g_cnt); +} + +K_TIMER_DEFINE(oneshot_t, inc_cb, NULL); +K_TIMER_DEFINE(abort_t, inc_cb, NULL); +K_TIMER_DEFINE(period_t, inc_cb, NULL); + +static inline uint32_t ticks_to_ms(uint32_t ticks) +{ + uint32_t tps = CONFIG_SYS_CLOCK_TICKS_PER_SEC; + uint32_t num = ticks * 1000U + (tps - 1U); + + return num / tps; +} + +ZTEST(nxp_utick_timer, test_sleep_ms_accuracy) +{ + uint32_t now = k_uptime_get_32(); + + k_msleep(SLEEP_TIME_MS); + uint32_t delta = k_uptime_get_32() - now; + + zassert_true(delta == SLEEP_TIME_MS, "Real slept time %d not equal to %d", delta, + SLEEP_TIME_MS); +} + +ZTEST(nxp_utick_timer, test_timer_count_in_oneshot_mode) +{ + atomic_clear(&g_cnt); + k_timer_start(&oneshot_t, K_MSEC(TIMER_COUNT_TIME_MS), K_NO_WAIT); + + k_msleep(WAIT_FOR_TIMER_EVENT_TIME_MS); + zassert_equal((uint32_t)atomic_get(&g_cnt), 1U, "oneshot not fired exactly once"); + k_msleep(50); + zassert_equal((uint32_t)atomic_get(&g_cnt), 1U, "oneshot fired more than once"); +} + +ZTEST(nxp_utick_timer, test_timer_abort_in_oneshot_mode) +{ + atomic_clear(&g_cnt); + k_timer_start(&abort_t, K_MSEC(TIMER_COUNT_TIME_MS), K_NO_WAIT); + k_timer_stop(&abort_t); + + k_msleep(WAIT_FOR_TIMER_EVENT_TIME_MS); + zassert_equal((uint32_t)atomic_get(&g_cnt), 0U, "abort should not fire"); +} + +ZTEST(nxp_utick_timer, test_timer_count_in_periodic_mode) +{ + const uint32_t per_ms = 10U, run_ms = 300U; + uint32_t p_cnt, exp; + + atomic_clear(&g_cnt); + k_timer_start(&period_t, K_MSEC(per_ms), K_MSEC(per_ms)); + k_msleep(run_ms); + k_timer_stop(&period_t); + p_cnt = (uint32_t)atomic_get(&g_cnt); + exp = run_ms / per_ms; + zassert_true(p_cnt == exp, "period count %u not equal to %u", p_cnt, exp); +} + +/* For UTICK timer, sys_clock_elapsed() may always return 0 */ +ZTEST(nxp_utick_timer, test_sys_clock_elapsed_zero) +{ + zassert_equal(sys_clock_elapsed(), 0U, NULL); + k_yield(); + zassert_equal(sys_clock_elapsed(), 0U, NULL); +} + +ZTEST_SUITE(nxp_utick_timer, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/timer/nxp_utick_timer/testcase.yaml b/tests/drivers/timer/nxp_utick_timer/testcase.yaml new file mode 100644 index 0000000000000..db9e831180db7 --- /dev/null +++ b/tests/drivers/timer/nxp_utick_timer/testcase.yaml @@ -0,0 +1,18 @@ +common: + filter: CONFIG_MCUX_UTICK_TIMER + vendor_allow: + - nxp + tags: + - drivers + - timer + timeout: 60 +tests: + drivers.timer.utick_timer: + integration_platforms: + - frdm_mcxa153 + platform_allow: + - frdm_mcxa153 + - frdm_mcxn236 + - frdm_mcxn947 + - mimxrt798s/cm33_cpu0 + extra_args: EXTRA_CONF_FILE="boards/common.conf"