NRFX has introduced HALY software layer which is a superset of HAL
and aggregates some hardware registers manipulations in a single
function calls.
Quote from nrfx changelog:
"HALY is an extension of the HAL layer that aggregates basic hardware
use cases within single functions. Now it is used instead of HAL
in the corresponding drivers."
This commit zephyr's driver to be aligned with the approach used
in nrfx, where drivers has been switched to use HALY instead of HAL.
Signed-off-by: Adam Wojasinski <adam.wojasinski@nordicsemi.no>
The nrf53 pretick can be used with non-zero
`NRF_RTC_TIMER_USER_CHAN_COUNT` Kconfig option.
The nrf53 pretick requires just one RTC1 CC channel.
The nrf53 pretick handles also RTC1 and RTC0 both CCs and OVERFLOW
events by examination of events scheduled on them. The pretick is set
based on number of ticks to the closest event scheduled that can trigger
an interrupt.
Because the operation in `z_arm_on_enter_cpu_idle` hook would
take too much time with interrupts disabled, the
`z_arm_on_enter_cpu_idle_prepare` hook enabled by Kconfig option
`ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK` is used. It performs RTC0 and RTC1
examination, and sets pretick without interrupts being blocked.
The LDREX/STREX are leveraged to detect if exception took place
between start of `z_arm_on_enter_cpu_idle_prepare` and
`z_arm_on_enter_cpu_idle`. If exception has not been taken, the pretick
calculation can be trusted because source data could not changed and
too much time could not pass. Otherwise the sleep attempt is disallowed,
the idle will loop again and try later.
Prompt for `SOC_NRF53_RTC_PRETICK` Kconfig option allows to control
this option by an user and turn the feature off if necessary.
Signed-off-by: Andrzej Kuroś <andrzej.kuros@nordicsemi.no>
Add RTC pretick option that triggers HW activity one tick before and
RTC event that leads to the interrupt. Option is active only on nrf53
network core.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Timer "drivers" do not use the device model infrastructure, they are
singletons with a SYS_INIT call. This means they do not have to include
device.h but init.h. Things worked because device.h includes init.h.
Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
The function `z_nrf_rtc_timer_exact_set` is added to allow
setting compare channel without possible creeping of cc val.
Signed-off-by: Andrzej Kuroś <andrzej.kuros@nordicsemi.no>
The init infrastructure, found in `init.h`, is currently used by:
- `SYS_INIT`: to call functions before `main`
- `DEVICE_*`: to initialize devices
They are all sorted according to an initialization level + a priority.
`SYS_INIT` calls are really orthogonal to devices, however, the required
function signature requires a `const struct device *dev` as a first
argument. The only reason for that is because the same init machinery is
used by devices, so we have something like:
```c
struct init_entry {
int (*init)(const struct device *dev);
/* only set by DEVICE_*, otherwise NULL */
const struct device *dev;
}
```
As a result, we end up with such weird/ugly pattern:
```c
static int my_init(const struct device *dev)
{
/* always NULL! add ARG_UNUSED to avoid compiler warning */
ARG_UNUSED(dev);
...
}
```
This is really a result of poor internals isolation. This patch proposes
a to make init entries more flexible so that they can accept sytem
initialization calls like this:
```c
static int my_init(void)
{
...
}
```
This is achieved using a union:
```c
union init_function {
/* for SYS_INIT, used when init_entry.dev == NULL */
int (*sys)(void);
/* for DEVICE*, used when init_entry.dev != NULL */
int (*dev)(const struct device *dev);
};
struct init_entry {
/* stores init function (either for SYS_INIT or DEVICE*)
union init_function init_fn;
/* stores device pointer for DEVICE*, NULL for SYS_INIT. Allows
* to know which union entry to call.
*/
const struct device *dev;
}
```
This solution **does not increase ROM usage**, and allows to offer clean
public APIs for both SYS_INIT and DEVICE*. Note that however, init
machinery keeps a coupling with devices.
**NOTE**: This is a breaking change! All `SYS_INIT` functions will need
to be converted to the new signature. See the script offered in the
following commit.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
init: convert SYS_INIT functions to the new signature
Conversion scripted using scripts/utils/migrate_sys_init.py.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
manifest: update projects for SYS_INIT changes
Update modules with updated SYS_INIT calls:
- hal_ti
- lvgl
- sof
- TraceRecorderSource
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: devicetree: devices: adjust test
Adjust test according to the recently introduced SYS_INIT
infrastructure.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
tests: kernel: threads: adjust SYS_INIT call
Adjust to the new signature: int (*init_fn)(void);
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In general, RTC and TIMER driver implements counter API but there
are exception when those peripherals are used in a custom way
(e.g. for system timer or bluetooth). In that case, system must
prevent using counter based on a reserved instance. Previously,
it was managed by Kconfig options but that cannot be maintained
when switching to devicetree configuration of the counter driver.
A new approach removes Kconfig options and instead adds static
asserts in the files which are using direct peripherals. Those
asserts check if given node is not enabled in the device tree.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Make sure that the interrupt and event routing enable bits have the
reset values in case the Zephyr firmware image is chain-loaded.
When started by MCUboot, these registers values aren't the reset values,
but then Zephyr initializes them in same way. Yet, when the Zephyr
firmware image is chain-loaded by nRF5 bootloader, they may have values
that cause the scheduler to behave in unexpected ways.
Signed-off-by: Giancarlo Stasi <giancarlo.stasi.co@gmail.com>
This is a follow-up to commits cf871aec64
and 205e684958.
It turns out that the current implementation of the nrf_rtc_timer may
still fail to properly handle a timeout if that timeout is set in very
specific conditions - when a previously set timeout is about to expire.
When that happens, the new timeout is handled 512 seconds later (when
the system timer overflows) than it should be.
A recently added nrf_rtc_timer test case (test_tight_rescheduling)
exposes this problem and this commit fixes it by adding examination
of COMPARE events that appear during setting of the CC register value
for a given timeout.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
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>