Implement counter capture callbacks for MCUX QTMR timer channels. Each
Zephyr counter device maps to one QTMR channel, so the API accepts
channel 0 and uses the DT secondary-source property as the capture
input.
Reject capture in modes that already consume the secondary source and
keep alarm and capture ownership exclusive on the channel. Add reset
support so generic counter capture tests can prepare the timer state.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
counter_get_frequency() is allowed to be called from a counter alarm or
top-value callback, which runs in the counter ISR. The Infineon TCPWM
counter driver implemented get_freq() by querying the peripheral clock
tree on every call via the PDL (Cy_SysClk_PeriPclkGetFrequency ->
Cy_SysClk_ClkHfGetFrequency).
On non-secure builds (TrustZone-M with TF-M) that PDL clock query is
serviced by the secure world through a PSA / secure-request round-trip.
Such calls are not permitted from interrupt context, so invoking
counter_ticks_to_us() / counter_get_frequency() from an alarm callback
made the secure request fail and the PDL assertion fault the core,
hanging the application. In thread context the same query works, and
secure builds read the clock registers directly, so the failure was
specific to the non-secure interrupt path.
The counter input clock is fixed once the peripheral divider is assigned
at init. Cache the frequency during device init (thread context) and
return the cached value from get_freq(). This makes
counter_get_frequency() safe to call from the counter ISR and also
avoids a clock-tree walk on every call.
Run the driver init at POST_KERNEL rather than PRE_KERNEL_1: on the CM55
the same clock query is relayed to the secure world over IPC and blocks
on a semaphore, which is not available before the kernel is up.
POST_KERNEL populates the cache once the kernel and the relay are ready,
and still before any application arms an alarm, so the cached value is
always valid when get_freq() runs from an ISR. Also fail init with -EIO
if the frequency reads back as 0.
Assisted-by: AI (GitHub Copilot)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
The syscall handler functions forward parameters with identical casts
that are redundant since the variables already have those types. Drop
the casts to let the compiler type-check the arguments unobstructed.
Signed-off-by: Flavio Ceolin <flavio@hubble.com>
The TTC provides three independent hardware counters supporting
free-running and interval modes, accessed via MMIO registers.
This driver implements the Zephyr counter API, including start/stop,
read, alarm, and top value configuration. Alarm events are delivered
using match interrupts.
Dynamic IRQ connection is used to support platforms where multiple
TTC counter instances share the same interrupt line. Each IRQ is
registered only once at runtime, and the ISR dispatches pending
events to all TTC instances mapped to that interrupt, ensuring correct
handling for both shared and dedicated interrupt configurations.
Signed-off-by: Satya Sri <satyasri.katru@amd.com>
Allow the MCUX QTMR counter driver to use clock providers without a
named clock cell, such as fixed-clock.
Existing users with named clock cells keep the previous behavior.
Also use the filter-period devicetree property when configuring the
QTMR fault filter period.
Signed-off-by: Samuel Slesar <samuel.slesar@nxp.com>
Fixes a bug in the protimer counter driver where the top callback
was not being called when the top value was reached.
Signed-off-by: David Boullie <David.Boullie@silabs.com>
Add support for the counter capture API to the MCUX CTIMER driver.
The driver stores capture callbacks per channel, maps Zephyr edge
flags to CTIMER capture modes, enables capture interrupts, and reports
captured TC values from the CTIMER CR registers.
Capture is mutually exclusive with alarms on the same channel because
both features share the counter channel namespace. Add optional
pinctrl and INPUTMUX routing support so boards can route CTIMER capture
sources from devicetree without changing the public counter API.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
The COND_CASE_1() allows writing chained/nested COND_CODE_1() checks in
a simpler way. Replace such patterns in the STM32 drivers with this new
utility macro.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
ifx_tcpwm_counter_set_top_value() previously updated only the software
cache (data->value) and never reset the hardware counter register.
After counter_set_top_value() reduced the period (PERIOD register), the
TCPWM CNT register kept its old value. If that value was greater than
the new period, the counter had to wrap the full 16-bit (or 32-bit)
range before terminal count, instead of one new period's worth of
ticks.
This caused tests/drivers/counter/counter_basic_api
test_set_top_value_with_alarm to fail on Infineon TCPWM-based boards:
the test computes its timeout assuming the alarm fires within a few
new periods, but the first turnaround took several seconds (e.g. ~6 s
on a 16-bit counter clocked at 10 kHz).
Reset the hardware counter to 0 after writing the new period. When
COUNTER_TOP_CFG_DONT_RESET is set, return -ETIME if the current value
is already past the new ticks (matching the counter API contract);
also reset to 0 in that case when COUNTER_TOP_CFG_RESET_WHEN_LATE is
set.
Verified on kit_pse84_eval (m33+m55), kit_pse84_ai (m33+m55) and
cyw920829m2evk_02: all counter_basic_api subtests pass.
Assisted-by: GitHub Copilot (Claude)
Signed-off-by: Bill Waters <bill.waters@infineon.com>
This works, because the API stayed the same between gecko_sdk and
simplicity_sdk.
This driver allows xg13 SoCs to use an RTCC based counter while the RTCC
peripheral is used for the silabs sleeptimer service.
Signed-off-by: Michael Zimmermann <michael.zimmermann@sevenlab.de>
Add counter capture support to the GP-Timer driver. A GPIO edge is
routed through the ETM to the timer capture task, latching the counter
value in hardware. Only available on ETM capable SoCs.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
The RTC (rtc_jdp) is a single hardware instance that can back either the
counter API or the system timer, but not both at once. When the
zephyr,system-timer chosen property points at an nxp,rtc-jdp node, skip
that instance in the counter driver so the counter and system timer
drivers never bind the same hardware. This mirrors the arbitration in
counter_mcux_lptmr.c.
The driver body is also guarded so that when the only nxp,rtc-jdp
instance is the chosen system timer, no unused counter device or static
functions remain.
Build-tested on frdm_mcxe31b: tests/drivers/counter/counter_basic_api
still instantiates the RTC counter in the default configuration, while
tests/kernel/timer/timer_api builds with the RTC as the system timer and
the counter instance compiled out.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
The changes are required to allow using a system timer driver
for the same device with the same compatible string.
The counter driver is used for each instance that is not used as
the chosen system timer.
Signed-off-by: Wojciech Sipak <wsipak@antmicro.com>
Add a counter driver for the NXP Time Stamp Timer (TSTMR), a 56-bit
free-running, read-only up-counter. The driver exposes it through the
Zephyr counter API (get_value/get_value_64 and get_freq); start/stop,
alarm, and top-value operations are unsupported as the hardware is
free-running with no compare or interrupt capability.
The frequency is SoC-specific and taken from the clock-frequency
devicetree property. A coherent 56-bit read is obtained by sampling the
low/high registers twice under an IRQ lock and handling low-word
rollover.
Add the binding, Kconfig, and build glue.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
The native_sim counter driver did not implement the counter capture API,
so the capture path could not be exercised on native_sim / in CI. There
was also no software way to inject a capture edge, unlike gpio_emul which
provides gpio_emul_input_set() for emulating GPIO events.
Implement the capture API in the native_sim counter driver and add a
test-only backend, analogous to gpio_emul:
- counter_capture_emul_input_set()/_get() (+ _dt variants) in the new
include/zephyr/drivers/counter/counter_capture_emul.h drive/read an
emulated capture input level. On a configured, enabled and matching
edge the capture callback is invoked synchronously with the current
counter value, honoring single-shot vs continuous mode.
- Supported edges are declared in devicetree via rising-edge/falling-edge
boolean properties and enforced in capture_configure(), mirroring
GPIO_EMUL_INT_CAPS.
The counter_capture test is reworked so the edge trigger is provided by a
small "trigger source" interface (trigger_src.h) with two CMake-selected
backends: gpio_src.c (GPIO loopback on real hardware) and
counter_capture_emul_src.c (emulated input on native_sim). The test body,
edge/single-shot/continuous coverage and assertions are unchanged. A
native_sim overlay and integration platform are added so the suite runs
on native_sim.
Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
Add an MCUX STM system timer driver selected through the existing
nxp,stm devicetree node referenced by zephyr,system-timer. The driver
uses the free-running STM counter and channel 0 absolute compare to
implement tickful and tickless sys_clock hooks.
The counter clock is derived at runtime from the STM clock-control
provider and the node prescaler, avoiding a second devicetree
clock-frequency source. The deadline math follows the same
last_elapsed model used by the ARM architectural and RISC-V machine
timer drivers, and uses sys_clock_announce_locked() so the kernel
clock lock is shared.
STM compare channels assert only when CNT matches CMP, so compare
programming uses a read-back/retry loop to ensure the programmed value
is genuinely ahead of the current counter and cannot be missed until
32-bit wraparound.
The STM counter driver skips the instance selected as the system timer,
so enabling both drivers does not reinitialize the same hardware.
Validated with west build -p always -b frdm_mcxe31b
zephyr/tests/kernel/timer/timer_behavior and strict UART capture on
FRDM-MCXE31B; all timer_behavior suites passed. Also built the same
test with CONFIG_COUNTER_MCUX_STM=y to cover the skipped counter
instance path.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
The main goal of this change is being able to use counter_gecko_rtcc.c and
leuart_gecko.c on boards without an LFXO. This is the case for tyzs3.
The main changes are in soc/silabs/common, the rest is just to migrate all
of the boards.
This uses the device tree for clock-initialization only. I did not
implement a clock_control driver, because I don't see a need for that. The
drivers use CMU_ClockEnable, which abstracts away SoC differences already.
The config SOC_GECKO_HAS_HFRCO_FREQRANGE was removed, because:
- This can be detected via macros provided by gecko_sdk.
- There is an alternative to that API which wasn't implemented previously,
but is now (cmuHFRCOBand_*).
I don't own any of the boards except for tuya tyzs3, but did my best to
avoid mistakes. That being said, I found several issues, which were present
in some of the boards already:
- sltb004a: This board has a 38.4MHz HFXO crystal, but it was configured to
40MHz. I fixed that.
- tomu: This board uses HFRCO as it's HF clock, even though the SoC does
not support SOC_GECKO_HAS_HFRCO_FREQRANGE. So it was probably running at
the initial 14MHz instead.
- Many boards enabled leuart and rtcc (counter) peripherals, which need(ed)
LFXO, without ever enabling LFXO. These peripherals were probably not
working before this change.
Noteworthy finds:
- slwrb4321a: This board uses HFRCO as it's HF clock, but has a board.c
where it enables HFXO to use it as the RMII reference clock. I'm not sure
if it's okay to do that without calling CMU_HFXOInit first. I did not
modify that code to not change behavior that I don't understand.
Signed-off-by: Michael Zimmermann <michael.zimmermann@sevenlab.de>
Remove the deprecated counter-based Maxim DS3231 driver and its
dedicated API, binding, sample, and test coverage.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Disable Wake-Up Timer before setting a new compare value to comply with
user guide recommendations.
Signed-off-by: Tahsin Mutlugun <Tahsin.Mutlugun@analog.com>
Add a counter driver for the Xilinx Zynq Ultrascale+ MPSoC Real Time
Clock. The hardware provides a 32-bit seconds counter driven by an
external crystal oscillator, one alarm channel, and a calibration
register with integer and fractional tick adjustment.
The driver implements the Zephyr counter API and is intended to be used
with the rtc_counter wrapper to expose the standard RTC API.
The RTC oscillator runs continuously so start() and stop() return
-ENOTSUP. Calibration support is gated by CONFIG_COUNTER_CALIBRATION.
Signed-off-by: Harini T <harini.t@amd.com>
Add optional set_calibration/get_calibration operations to the counter
driver API. Calibration is specified in parts per billion (ppb). The
operations are gated behind CONFIG_COUNTER_CALIBRATION and return
-ENOSYS if not implemented by the driver.
Signed-off-by: Harini T <harini.t@amd.com>
These drivers were used by Series 2 SoCs before they were migrated from
gecko_sdk to simplicity_sdk. Currently, Series 2 SoCs don't use them
anymore. In fact, their Kconfig dependencies don't even allow using them
for simplicity_sdk based SoCs.
Removing the leftovers simplifies the code and is a preparation for larger
changes in soc.c.
Signed-off-by: Michael Zimmermann <michael.zimmermann@sevenlab.de>
- Kconfigs in modules/ should not define configs with an SOC_ prefix.
Furthermore, these options are SDK specific, not SoC specific.
- The simplicity_sdk configs do the same.
Signed-off-by: Michael Zimmermann <michael.zimmermann@sevenlab.de>
The alarm ISR read data->alarm_active under the spinlock into a local
"rearmed" snapshot, released the lock, and only then acted on it by
stopping and reprogramming the LPTMR. That split the check from the
action: on SMP (or a nested context) a concurrent
counter_set_channel_alarm() could re-arm the alarm in the window
between the unlock and LPTMR_StopTimer(), and its freshly programmed
period/run state would be clobbered by the restore here.
Hold the lock across both the re-arm check and the stop/restore so the
decision and the HW action are atomic with respect to other lock
holders. Whichever context sets alarm_active under the lock owns the
timer configuration; the ISR only stops/restores when it observes
alarm_active == false while holding the lock, so it can no longer
overwrite a concurrent re-arm.
Signed-off-by: Felix Wang <fei.wang_3@nxp.com>
The alarm ISR was stopping and reprogramming the LPTMR before
invoking the user callback. Because LPTMR_StopTimer() resets the
counter back to zero, counter_get_value() called from inside the
callback observed 0 while the ticks argument still reflected the
pre-stop count. The single_shot_alarm scenarios in
tests/drivers/counter/counter_basic_api caught this as a large
diff between reported alarm and observed counter on
frdm_imxrt1186/mimxrt1186/cm7.
Move LPTMR_StopTimer() and LPTMR_SetTimerPeriod() to run after the
callback, skip them when the callback re-armed a new alarm via
counter_set_channel_alarm(): the counter API documents that the
channel becomes available inside the expiration handler and that
re-arming is allowed there.
Verified by building tests/drivers/counter/counter_basic_api for
frdm_imxrt1186/mimxrt1186/cm7 with armgcc.
Fixes#110250
Signed-off-by: Felix Wang <fei.wang_3@nxp.com>
Add a counter driver for the MCUX wake timer. The hardware is a
one-shot down-counter with one load/count register, so the driver
uses the register either for periodic top handling or for relative
single-shot alarms.
Absolute alarms are reported as unsupported because programming an
alarm reloads the hardware counter and changes the value space that
an absolute target would be measured against. Clear stale pending IRQ
state around start, stop, cancel, and alarm setup.
Built and ran tests/drivers/counter/counter_basic_api on frdm_mcxa153
with CONFIG_COUNTER_MCUX_WAKE_TIMER_ALARM=y.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
In counter_renesas_ra_agt_cancel_alarm(), the early return when
agtcmai_irq is BSP_IRQ_DISABLED skipped the spinlock release at
the out: label. Convert to goto out pattern to match the style of
the rest of the function. Also fix the out: label to return ret
rather than 0, so FSP errors are correctly propagated.
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Migrate the periodic loop to a standard for-loop to fix
an off-by-one check in the periodic timer shell command.
Signed-off-by: Surya Prakash T <suryat@aerlync.com>
Check calculated ticks against counter_get_max_top_value() to block
delays that exceed the hardware timer's range.
Signed-off-by: Surya Prakash T <suryat@aerlync.com>
Move k_sem_init() until after parse_device() completes successfully to
prevent leaving stale semaphore configurations on early error exits.
Signed-off-by: Surya Prakash T <suryat@aerlync.com>
Return the actual error code from counter_stop() instead of relying on
unreliable hardware tick comparisons via counter_get_value().
Signed-off-by: Surya Prakash T <suryat@aerlync.com>
Fixed the issue of possible out-of-bounds
access if write_data_block function was misused.
Size argument of the function was only validated
against the maximum allowed value, not the real
size of the data struct to be read, what could
cause accessing data past the boundary of the struct.
Fixes#81930.
Signed-off-by: Marcin Lyda <elektromarcin@gmail.com>
If the kQTMR_Compare1Flag is set when setting the alarm, the callback
would fire immediately causing unwanted behaviour in the applcation.
This PR clears this flag before setting an alarm to prevent this
premature firing.
Signed-off-by: Jaro Van Landschoot <jaro.vanlandschoot@basalte.be>
Implement the counter guard-period callbacks for the MCUX LPTMR alarm
configuration so late absolute alarms can be detected instead of being
silently skipped by users of the generic counter API.
Absolute alarms now compare the requested tick against the current
counter value and return -ETIME when the target is inside the late
window. The late check is disabled when the guard period is zero,
preserving the counter API contract that zero means no protection.
Convert accepted absolute alarms to relative compare values using the
LPTMR counter top value, so targets around wrap are treated consistently
with the counter API absolute-alarm semantics.
If COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE is set, the driver keeps the
alarm active and pends the interrupt so wrappers such as rtc_counter
can treat the late alarm as an immediate expiry.
Keep the non-alarm configuration returning -ENOSYS for guard-period
setup, since that mode still reserves the compare register for
top-value operation.
Tested on frdm_mcxa153 with tests/drivers/counter/counter_basic_api
using CONFIG_COUNTER_MCUX_LPTMR_ALARM=y, the same test with the LPTMR
alarm option disabled, and tests/drivers/rtc/rtc_api using a temporary
zephyr,rtc-counter node backed by lptmr0.
Also validated the review case with a temporary app that sets an
absolute tick-0 alarm while stopped. With guard period 0 the alarm API
returns 0 and fires the callback; with a nonzero guard period it returns
-ETIME and fires the callback when EXPIRE_WHEN_LATE is set.
The LPTMR late-alarm counter tests now run instead of being skipped,
and the RTC API suite passed 5/5 with PROJECT EXECUTION SUCCESSFUL.
Signed-off-by: Holt Sun <holt.sun@nxp.com>
Explicitly enable the timer clock source via esp_clk_tree
before programming the counter. Required on P4 where the
source clock is gated by default.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Add sleep retention support for counter driver. When peripheral
power down is enabled for light sleep, register data is lost,
so REGDMA backup is needed to mantein peripheral operational.
Signed-off-by: Raffael Rostagno <raffael.rostagno@espressif.com>
The previous late-detection logic for absolute alarms built the
target as (now & ~0xFFFFFFFFULL) | ticks and pushed it into the
next 32-bit window when the value was behind the counter. This
treated a target of ticks=0 after the counter had advanced as a
far-future alarm rather than a late one, so -ETIME was returned
only in the small window where now itself was below
guard_period.
Use a modular comparison instead: compute the forward distance
to the target modulo top + 1 and flag the alarm as late when
that distance exceeds top - guard_period. The hardware alarm
register is still programmed with the actual future target.
Also reset the counter to zero on counter_stop so the
capability probe in late_detection_capable does not leave the
counter past the guard window for the next test.
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Implements the counter_api reset callback for the NXP LPTIMER
driver to reset the counter to the initial value.
Signed-off-by: Andrej Butok <andrey.butok@nxp.com>
Implements the counter_api reset callback for the NXP GPT
driver to reset the counter to the initial value.
Signed-off-by: Andrej Butok <andrey.butok@nxp.com>
Add a Zephyr counter driver for the NXP MCUXpresso System Counter
(SYS_CTR). The driver supports:
- 56-bit free-running up-counter
- Selectable clock source: 24 MHz base clock or 32 kHz slow clock
- Two compare frames (alarm channels) with a shared interrupt
- Standard Zephyr counter alarm API
Signed-off-by: Felix Wang <fei.wang_3@nxp.com>
Restore the mcux LPTMR compare period to the default top value
when an alarm is cancelled.
The counter basic API alarm-capability probe can arm and cancel
a short LPTMR alarm before test_valid_function_without_alarm()
runs. Without restoring the compare period, a later
counter_start() may still use the previous short match value.
That causes the FRDM-MCXC444 test to fail with counter ticks not
in tolerance.
Reset the timer period back to max_top_value and clear the
compare flag during cancel so the device is left in the expected
state for subsequent starts.
Keep a clarifying code comment near the cancel path to note that
LPTMR uses one CMR register for both the period and alarm value.
Signed-off-by: Hake Huang <hake.huang@nxp.com>