|
| 1 | +/* |
| 2 | + * Copyright (c) 2025 Nordic Semiconductor ASA |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause |
| 5 | + */ |
| 6 | + |
| 7 | +#include <zephyr/kernel.h> |
| 8 | +#include <zephyr/drivers/gpio.h> |
| 9 | +#include <zephyr/pm/device.h> |
| 10 | +#include <zephyr/pm/device_runtime.h> |
| 11 | +#include <zephyr/drivers/timer/nrf_grtc_timer.h> |
| 12 | +#include <hal/nrf_grtc.h> |
| 13 | + |
| 14 | +#define TIMER_COUNT_TIME_MS 995 |
| 15 | +#define SLEEP_TIME_MS 1500 |
| 16 | +/* |
| 17 | + * The timer value readout is not time synchronised, |
| 18 | + * this tolerance accounts for the readout delay |
| 19 | + */ |
| 20 | +#define READOUT_TIMER_TOLERANCE_IN_TICKS 1500 |
| 21 | +#define EXPECTED_READOUT_VALUE \ |
| 22 | + (sys_clock_hw_cycles_per_sec() / 1000) * (SLEEP_TIME_MS - TIMER_COUNT_TIME_MS) |
| 23 | + |
| 24 | +static volatile uint64_t isr_count_value; |
| 25 | +static volatile bool count_isr_triggered; |
| 26 | + |
| 27 | +static void timer_compare_interrupt_handler(int32_t id, uint64_t expire_time, void *user_data) |
| 28 | +{ |
| 29 | + isr_count_value = z_nrf_grtc_timer_read(); |
| 30 | + count_isr_triggered = true; |
| 31 | +} |
| 32 | + |
| 33 | +int main(void) |
| 34 | +{ |
| 35 | + int err; |
| 36 | + uint64_t test_ticks = 0; |
| 37 | + uint64_t compare_value = 0; |
| 38 | + uint64_t count_difference = 0; |
| 39 | + char user_data[] = "test_timer_count_in_compare_mode\n"; |
| 40 | + int32_t channel = z_nrf_grtc_timer_chan_alloc(); |
| 41 | + |
| 42 | + __ASSERT(channel > 0, "GRTC channel not allocated\n"); |
| 43 | + while (1) { |
| 44 | + count_isr_triggered = false; |
| 45 | + test_ticks = z_nrf_grtc_timer_get_ticks(K_MSEC(TIMER_COUNT_TIME_MS)); |
| 46 | + err = z_nrf_grtc_timer_set(channel, test_ticks, timer_compare_interrupt_handler, |
| 47 | + (void *)user_data); |
| 48 | + |
| 49 | + __ASSERT(err == 0, "z_nrf_grtc_timer_set raised an error: %d", err); |
| 50 | + |
| 51 | + z_nrf_grtc_timer_compare_read(channel, &compare_value); |
| 52 | + __ASSERT(K_TIMEOUT_EQ(K_TICKS(compare_value), K_TICKS(test_ticks)) == true, |
| 53 | + "Compare register set failed"); |
| 54 | + __ASSERT(err == 0, "Unexpected error raised when setting timer, err: %d", err); |
| 55 | + |
| 56 | + /* Got to sleep */ |
| 57 | + k_sleep(K_MSEC(SLEEP_TIME_MS)); |
| 58 | + |
| 59 | + /* |
| 60 | + * Read counter value after exiting the sleep |
| 61 | + * and compare it to the value captured in the ISR |
| 62 | + */ |
| 63 | + count_difference = z_nrf_grtc_timer_read() - isr_count_value; |
| 64 | + __ASSERT((EXPECTED_READOUT_VALUE - READOUT_TIMER_TOLERANCE_IN_TICKS <= |
| 65 | + count_difference) && |
| 66 | + (count_difference <= |
| 67 | + EXPECTED_READOUT_VALUE + READOUT_TIMER_TOLERANCE_IN_TICKS), |
| 68 | + "GRTC timer readout after sleep returned incorrect value. Returned, " |
| 69 | + "expected, abs tolerance (%lld/%d/%d)", |
| 70 | + count_difference, EXPECTED_READOUT_VALUE, |
| 71 | + READOUT_TIMER_TOLERANCE_IN_TICKS); |
| 72 | + } |
| 73 | + |
| 74 | + z_nrf_grtc_timer_chan_free(channel); |
| 75 | + return 0; |
| 76 | +} |
0 commit comments