This function name is misleading as the absolute time values handled
by the driver are 64-bit and this function receives a 32-bit parameter,
which is supposed to be a CC register value, not the target time.
Correct the name of this function and its parameter, and remove a now
unnecessary masking from its body.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This is a follow-up to commit 205e684958.
The recently added nrf_rtc_timer test case (test_next_cycle_timeouts)
revealed a problem in the current implementation of this function.
Adjust it to avoid missing COMPARE events in specific circumstances.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
There is no need to disable interrupts while just checking if
a channel needs to be processed in the ISR, as that section
does not contain anything that needs to be protected against
overwriting from some other context. In particular, if a given
timeout is changed or even aborted while its event is being
checked, this will be correctly handled in the code that follows
and that checks the expiration time.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Values to be set to the comparator need to be specified in RTC cycles,
not ticks, so the initial value used in the tickless mode needs to be
MAX_CYCLES, otherwise when CONFIG_SYS_CLOCK_TICKS_PER_SEC is set to
a value less then the RTC frequency, the initially configured timeout
will be unnecessarily shorter.
On the occassion, remove also the call to counter() when setting the
initial timeout value in non-tickless mode. RTC is cleared a few lines
above, so at this point it will most likely be 0, and even if it was
not, compare_set() would properly handle a target time value that had
already passed.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
In non-tickless mode, the timeout handler always announced maximum 1
tick to kernel, but in fact it cannot be guaranteed that the handler
execution is not delayed and that the number of elapsed ticks does not
exceed 1. Use the actual number instead.
Switch also to using a 32-bit value for `dticks` to get a bit simpler
generated code (ticks delta is not supposed to be that huge).
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Align the condition checked in compare_set_no_locks() with what
set_absolute_alarm() actually provides (and slightly correct the
latter function so that it provides what it is supposed to).
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Add missing masking against `BIT(chan)` when handling a forced ISR
to avoid unnecessary processing of multiple channels instead of just
the one that actually requires it.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Remove a piece of code that was supposed to bring an extra update
of the anchor value but which in fact was not able to provide it,
because of the target time checking performed in process_channel(),
and which is anyway unnecessary because the timeout span is limited
to MAX_CYCLES in sys_clock_set_timeout(), so the timeout handler is
guaranteed to be executed at least twice per each RTC overflow.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Eliminate waiting for a potential COMPARE event when setting a CC
value close to the previously set one and rely instead on checking
target time when processing channel events in the ISR.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Remove unnecessary decreasing of the number of ticks by 1 (it was then
increased by 1 when it was converted to the number of cycles) and add
a comment that clarifies the way that ticks < 1 are handled.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
RTC is 24 bit width and k_timer is 64 bit. It is hard to test corner
cases but RTC hardware feature can help here. There is a task which
moves counter to 0xfffff0 which is close to overflow. However, there
is an internal driver state that also needs to be aligned to shift
the time properly. Adding optional function which triggers overflow
and updates internal state. This can be used for testing corner cases.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
CC setting algorithm is handling a case when CC is too soon (next
tick from now). It was setting CC to one tick further in the future
if that was detected. Step was repeated if counter incremented during
setting CC and CC was behind the counter because of risk of setting
CC too late. In certain scenarios we might spend a lot of time in
that loop, especially if optimization is turned off. Test shown that
loop was executed dozens of time (up. to 700us). To prevent
prolonged execution whenever CC setting fails we set CC to one more
tick further in future.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Change automated searching for files using "IRQ_CONNECT()" API not
including <zephyr/irq.h>.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit fixes the incomplete assert conditions for the `chan`
argument passed to the nRF RTC timer functions.
Note that the `chan` argument for this driver is of a **signed**
integer type, so it is necessary to check that its value is
non-negative.
This fixes the warnings generated by the GCC 12 such as:
error: array subscript -1 is below array bounds of '...'
Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
In order to bring consistency in-tree, migrate all drivers to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to #45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Add an explicit Kconfig option to enable use of
__disable_irq() in nRF RTC timer driver to prevent higher
priority contexts (including ZLIs) that might preempt the
handler and call nrf_rtc_timer API from destroying the
internal state in nrf_rtc_timer.
Relates to commit fcda8699cb ("drivers: timer: extend
nrf_rtc_timer").
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit introduces the following changes:
* nrf_rtc_timer is extended with a capability to handle RTC overflow,
allowing it to operate on absolute RTC ticks, rather than relative
ticks.
* overflow handling is ZLI-proof and relies on the sys clock
handler being executed twice every RTC counter's overflow.
* callbacks are given an absolute RTC tick value as a parameter instead
of CC register's value. The absolute RTC tick value is the RTC counter
value set during CC channel configuration extended to 64 bits.
* in case the timer's target time is in the past or is the current tick,
the timer fires as soon as possible, however still from the RTC's ISR
context.
* in case an active timer is set again with the same target time, it is
not scheduled again - only its event data is updated. Otherwise, the
timer is scheduled as usual.
* a scheduled timer can be aborted.
* system clock functions are now using 64 bit values internally.
Signed-off-by: Andrzej Kuroś <andrzej.kuros@nordicsemi.no>
Signed-off-by: Jedrzej Ciupis <jedrzej.ciupis@nordicsemi.no>
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Signed-off-by: Paweł Kwiek <pawel.kwiek@nordicsemi.no>
This commit introduces the following changes:
* nrf_rtc_timer is extended with a capability to handle RTC overflow,
allowing it to operate on absolute RTC ticks, rather than relative
ticks.
* overflow handling is ZLI-proof and relies on the sys clock
handler being executed twice every RTC counter's overflow.
* callbacks are given an absolute RTC tick value as a parameter instead
of CC register's value. The absolute RTC tick value is the RTC counter
value set during CC channel configuration extended to 64 bits.
* in case the timer's target time is in the past or is the current tick,
the timer fires as soon as possible, however still from the RTC's ISR
context.
* in case an active timer is set again with the same target time, it is
not scheduled again - only its event data is updated. Otherwise, the
timer is scheduled as usual.
* a scheduled timer can be aborted.
* system clock functions are now using 64 bit values internally.
Signed-off-by: Andrzej Kuroś <andrzej.kuros@nordicsemi.no>
Signed-off-by: Jedrzej Ciupis <jedrzej.ciupis@nordicsemi.no>
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Signed-off-by: Paweł Kwiek <pawel.kwiek@nordicsemi.no>
The weak symbol sys_clock_driver_init has been removed, therefore moving
the init responsability to the drivers themselves. As a result, the init
function has now been made static on all drivers and moved to the
bottom, following the convention used in other areas.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
RTC interrupt was reading CC value and passing it to the handler.
However, higher priority interrupt could preempt RTC interrupt
and set new CC value. In that case CC value read in the RTC
interrupt context was not the one that triggered the interrupt.
Added fallback to COUNTER value if that case is detected.
Using COUNTER is not as precise as CC because it returns time
when event was handled and not when event occured but it is the
only option since CC value is overwritten.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
As per description of the sys_clock_elapsed() function, "the kernel
will call this with appropriate locking, the driver needs only provide
an instantaneous answer". Remove then the unnecessary locking from the
function, as it only adds an undesirable delay.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
There was an inconsistency in the API as z_nrf_rtc_timer_chan_alloc
returned int but other function were using uint32_t for channel
argument. Updated api to use int32_t everywhere.
Update nrf_802154 driver which was using this api to use int32_t.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This is another API that is being used in all timer drivers and is not
internal to the clock subsystem. Remove the leading z_ and make promote
it to a cross-subsystem API.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The clock/timer APIs are not application facing APIs, however, similar
to arch_ and a few other APIs they are available to implement drivers
and add support for new hardware and are documented and available to be
used outside of the clock/kernel subsystems.
Remove the leading z_ and provide them as clock_* APIs for someone
writing a new timer driver to use.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Due to clock discrepancy, busy waiting for 15us was not covering for
half tick in certain cases. Busy wait runs from HF clock source.
Increased to 19us to cover it. Anyway, this case is hit very rarely,
only when there was aborted, not-cancelled compare value that was
about to expire. Because of that, increase shall not impact the
performance.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
When tickless mode was disable, sys clock timeout handler was calling
public API function for setting new compare value. Public API function
asserts when chan 0 is used which is reserved for system clock.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Added clearing of CC event which may occure due to previous
CC value which was closed to current counter value.
Fixed int_mask initialization.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Extended nrf_rtc_timer driver to expose API for using RTC for
other purposes. System timer is using one compare channels,
other channels may be used through this API.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Replaces all existing variants of value clamping with the MIN and MAX
macros with the CLAMP macro.
Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
Added configuration for approach to starting system clock source.
There are 3 options: no wait, wait untill available, wait until
stable.
Added support for those modes in clock control driver which handles
low frequency source clock.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Now that device_api attribute is unmodified at runtime, as well as all
the other attributes, it is possible to switch all device driver
instance to be constant.
A coccinelle rule is used for this:
@r_const_dev_1
disable optional_qualifier
@
@@
-struct device *
+const struct device *
@r_const_dev_2
disable optional_qualifier
@
@@
-struct device * const
+const struct device *
Fixes#27399
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Adapted driver to clock_control changes (usage of onoff manager).
Since timer is permanenty requesting the clock, it is using API
dedicated for that: z_nrf_clock_control_lf_on().
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
When checking the absolute value of cycles set to the comparator
use the MAX_CYCLES instead of MAX_TICKS.
The commit changes function names and comments to make it clear
where ticks (system ticks) and where RTC cycles are used.
Fixes#26701
Signed-off-by: Pawel Dunaj <pawel.dunaj@nordicsemi.no>
If timeout is being overwrite exactly when previous one is expiring
then hardware event was cleared correctly but interrupt was already
triggered. Interrupt routine was assuming that compare event is set
and proceed with that assumption. However, in that corner case when
compare event was overwritten and event was cleared, that was not the
case.
As the outcome, timeout could be triggered prematurely. Fixed by
clearing pending interrupt after handling previous compare value.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Some kernel tests use `CONFIG_TICKLESS_KERNEL=n` with
`CONFIG_SYS_CLOCK_TICKS_PER_SEC=1` to detect when a test runs longer
than 1 second. These tests break if a tick is announced every time a
timeout occurs. Only announce if the measured duration since the last
tick is at least the duration of a tick.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
User reported a flaw in the current algorithm which fails when Zero
Latency Interrupts (ZLI) are used. Ported algorithm from
counter_nrfx_rtc.c which covers all cases. Algorithm is lockless so
no distinction for ZLI is needed.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Add a k_timeout_t type, and use it everywhere that kernel API
functions were accepting a millisecond timeout argument. Instead of
forcing milliseconds everywhere (which are often not integrally
representable as system ticks), do the conversion to ticks at the
point where the timeout is created. This avoids an extra unit
conversion in some application code, and allows us to express the
timeout in units other than milliseconds to achieve greater precision.
The existing K_MSEC() et. al. macros now return initializers for a
k_timeout_t.
The K_NO_WAIT and K_FOREVER constants have now become k_timeout_t
values, which means they cannot be operated on as integers.
Applications which have their own APIs that need to inspect these
vs. user-provided timeouts can now use a K_TIMEOUT_EQ() predicate to
test for equality.
Timer drivers, which receive an integer tick count in ther
z_clock_set_timeout() functions, now use the integer-valued
K_TICKS_FOREVER constant instead of K_FOREVER.
For the initial release, to preserve source compatibility, a
CONFIG_LEGACY_TIMEOUT_API kconfig is provided. When true, the
k_timeout_t will remain a compatible 32 bit value that will work with
any legacy Zephyr application.
Some subsystems present timeout (or timeout-like) values to their own
users as APIs that would re-use the kernel's own constants and
conventions. These will require some minor design work to adapt to
the new scheme (in most cases just using k_timeout_t directly in their
own API), and they have not been changed in this patch, instead
selecting CONFIG_LEGACY_TIMEOUT_API via kconfig. These subsystems
include: CAN Bus, the Microbit display driver, I2S, LoRa modem
drivers, the UART Async API, Video hardware drivers, the console
subsystem, and the network buffer abstraction.
k_sleep() now takes a k_timeout_t argument, with a k_msleep() variant
provided that works identically to the original API.
Most of the changes here are just type/configuration management and
documentation, but there are logic changes in mempool, where a loop
that used a timeout numerically has been reworked using a new
z_timeout_end_calc() predicate. Also in queue.c, a (when POLL was
enabled) a similar loop was needlessly used to try to retry the
k_poll() call after a spurious failure. But k_poll() does not fail
spuriously, so the loop was removed.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The CONFIG_ prefixes were missing on these.
Found with a work-in-progress scripts/kconfig/lint.py check.
This symbol is defined in kernel/Kconfig.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>