diff --git a/drivers/counter/counter_mcux_lpit.c b/drivers/counter/counter_mcux_lpit.c index 697a4e1efe4e2..3c0500fa84b75 100644 --- a/drivers/counter/counter_mcux_lpit.c +++ b/drivers/counter/counter_mcux_lpit.c @@ -161,7 +161,7 @@ static void mcux_lpit_isr(const struct device *dev) LPIT_CHANNEL_DATA(config->channels[channel_index]); if (data->top_callback != NULL) { - data->top_callback(dev, data->top_user_data); + data->top_callback(config->channels[channel_index], data->top_user_data); } } } diff --git a/samples/drivers/counter/alarm/boards/frdm_ke17z.conf b/samples/drivers/counter/alarm/boards/frdm_ke17z.conf new file mode 100644 index 0000000000000..e196cda4baee9 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/frdm_ke17z.conf @@ -0,0 +1,7 @@ +# +# Copyright 2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_COUNTER_MCUX_LPIT=y diff --git a/samples/drivers/counter/alarm/boards/frdm_ke17z.overlay b/samples/drivers/counter/alarm/boards/frdm_ke17z.overlay new file mode 100644 index 0000000000000..33fddcf26846d --- /dev/null +++ b/samples/drivers/counter/alarm/boards/frdm_ke17z.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&lpit0 { + status = "okay"; +}; + +&lpit0_channel0 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/boards/mimxrt1180_evk_mimxrt1189_cm33.conf b/samples/drivers/counter/alarm/boards/mimxrt1180_evk_mimxrt1189_cm33.conf new file mode 100644 index 0000000000000..2c596e280bba2 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/mimxrt1180_evk_mimxrt1189_cm33.conf @@ -0,0 +1,7 @@ +# +# Copyright 2024-2025 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_COUNTER_MCUX_LPIT=y diff --git a/samples/drivers/counter/alarm/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay b/samples/drivers/counter/alarm/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay new file mode 100644 index 0000000000000..12b40aac87193 --- /dev/null +++ b/samples/drivers/counter/alarm/boards/mimxrt1180_evk_mimxrt1189_cm33.overlay @@ -0,0 +1,13 @@ +/* + * Copyright 2024-2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&lpit1 { + status = "okay"; +}; + +&lpit1_channel0 { + status = "okay"; +}; diff --git a/samples/drivers/counter/alarm/src/main.c b/samples/drivers/counter/alarm/src/main.c index fae92eb86eded..ebd4fc5311d2d 100644 --- a/samples/drivers/counter/alarm/src/main.c +++ b/samples/drivers/counter/alarm/src/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019 Linaro Limited + * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +15,7 @@ #define ALARM_CHANNEL_ID 0 struct counter_alarm_cfg alarm_cfg; +struct counter_top_cfg top_cfg; #if defined(CONFIG_BOARD_SAMD20_XPRO) #define TIMER DT_NODELABEL(tc4) @@ -72,6 +74,11 @@ struct counter_alarm_cfg alarm_cfg; #define TIMER DT_INST(0, renesas_rz_gtm_counter) #elif defined(CONFIG_COUNTER_CC23X0_RTC) #define TIMER DT_NODELABEL(rtc0) +#elif defined(CONFIG_COUNTER_MCUX_LPIT) +/* Index may start from 1 or 0 depends on name convention from RM */ +#define TIMER \ + COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(lpit0_channel0)), \ + (DT_NODELABEL(lpit0_channel0)), (DT_NODELABEL(lpit1_channel0))) #else #error Unable to find a counter device node in devicetree #endif @@ -117,40 +124,102 @@ static void test_counter_interrupt_fn(const struct device *counter_dev, } } -int main(void) +static void test_counter_top_interrupt_fn(const struct device *counter_dev, void *user_data) { - const struct device *const counter_dev = DEVICE_DT_GET(TIMER); + struct counter_top_cfg *config = user_data; + uint32_t now_ticks; + uint64_t now_usec; + int now_sec; int err; - printk("Counter alarm sample\n\n"); + now_ticks = counter_get_top_value(counter_dev); + now_usec = counter_ticks_to_us(counter_dev, now_ticks); + now_sec = (int)(now_usec / USEC_PER_SEC); - if (!device_is_ready(counter_dev)) { - printk("device not ready.\n"); - return 0; + printk("!!! Alarm !!!\n"); + printk("Now: %u\n", now_sec); + + /* Set a new alarm with a double length duration */ + config->ticks = config->ticks * 2U; + + printk("Set alarm in %u sec (%u ticks)\n", + (uint32_t)(counter_ticks_to_us(counter_dev, config->ticks) / USEC_PER_SEC), + config->ticks); + + err = counter_set_top_value(counter_dev, user_data); + if (err != 0) { + printk("Alarm could not be set\n"); } +} - counter_start(counter_dev); +static int alarm_setup(const struct device *counter_dev, uint32_t ticks) +{ + int err; alarm_cfg.flags = 0; - alarm_cfg.ticks = counter_us_to_ticks(counter_dev, DELAY); + alarm_cfg.ticks = ticks; alarm_cfg.callback = test_counter_interrupt_fn; alarm_cfg.user_data = &alarm_cfg; err = counter_set_channel_alarm(counter_dev, ALARM_CHANNEL_ID, &alarm_cfg); - printk("Set alarm in %u sec (%u ticks)\n", - (uint32_t)(counter_ticks_to_us(counter_dev, - alarm_cfg.ticks) / USEC_PER_SEC), - alarm_cfg.ticks); if (-EINVAL == err) { printk("Alarm settings invalid\n"); } else if (-ENOTSUP == err) { printk("Alarm setting request not supported\n"); - } else if (err != 0) { - printk("Error\n"); } + return err; +} + +static int top_setup(const struct device *counter_dev, uint32_t ticks) +{ + int err; + + top_cfg.flags = 0; + top_cfg.ticks = ticks; + top_cfg.callback = test_counter_top_interrupt_fn; + top_cfg.user_data = &top_cfg; + + err = counter_set_top_value(counter_dev, &top_cfg); + + if (-EINVAL == err) { + printk("Top settings invalid\n"); + } else if (-ENOTSUP == err) { + printk("Top setting request not supported\n"); + } + + return err; +} + +int main(void) +{ + const struct device *const counter_dev = DEVICE_DT_GET(TIMER); + uint32_t ticks = counter_us_to_ticks(counter_dev, DELAY); + int err; + + printk("Counter alarm sample\n\n"); + + if (!device_is_ready(counter_dev)) { + printk("device not ready.\n"); + return 0; + } + + counter_start(counter_dev); + + err = alarm_setup(counter_dev, ticks); + if (err != 0) { + /* If alarm setup fails, try top setup */ + err = top_setup(counter_dev, ticks); + if (err != 0) { + printk("Error\n"); + } + } + + printk("Set alarm in %u sec (%u ticks)\n", + (uint32_t)(counter_ticks_to_us(counter_dev, ticks) / USEC_PER_SEC), ticks); + while (1) { k_sleep(K_FOREVER); }