Branch data Line data Source code
1 : : /* 2 : : * Copyright (c) 2020 Nordic Semiconductor ASA 3 : : * 4 : : * SPDX-License-Identifier: Apache-2.0 5 : : */ 6 : : 7 : : #include <stdbool.h> 8 : : #include <stdint.h> 9 : : #include "hw_models_top.h" 10 : : #include "board_soc.h" 11 : : #include "board_irq.h" 12 : : #include "irq_ctrl.h" 13 : : 14 : : uint64_t hw_counter_timer; 15 : : 16 : : static bool counter_running; 17 : : static uint64_t counter_value; 18 : : static uint64_t counter_target; 19 : : static uint64_t counter_period; 20 : : static uint64_t counter_wrap; 21 : : 22 : : /** 23 : : * Initialize the counter with prescaler of HW 24 : : */ 25 : 1 : void hw_counter_init(void) 26 : : { 27 : 1 : hw_counter_timer = NEVER; 28 : 1 : counter_target = NEVER; 29 : 1 : counter_value = 0; 30 : 1 : counter_running = false; 31 : 1 : counter_period = NEVER; 32 : 1 : counter_wrap = NEVER; 33 : 1 : } 34 : : 35 : 0 : void hw_counter_triggered(void) 36 : : { 37 [ # # ]: 0 : if (!counter_running) { 38 : 0 : hw_counter_timer = NEVER; 39 : 0 : return; 40 : : } 41 : : 42 : 0 : hw_counter_timer = hwm_get_time() + counter_period; 43 : 0 : counter_value = (counter_value + 1) % counter_wrap; 44 : : 45 [ # # ]: 0 : if (counter_value == counter_target) { 46 : 0 : hw_irq_ctrl_set_irq(COUNTER_EVENT_IRQ); 47 : : } 48 : : } 49 : : 50 : : /** 51 : : * Configures the counter period. 52 : : * The counter will be incremented every 'period' microseconds. 53 : : */ 54 : 0 : void hw_counter_set_period(uint64_t period) 55 : : { 56 : 0 : counter_period = period; 57 : 0 : } 58 : : 59 : : /* 60 : : * Set the count value at which the counter will wrap 61 : : * The counter will count up to (counter_wrap-1), i.e.: 62 : : * 0, 1, 2,.., (counter_wrap - 1), 0 63 : : */ 64 : 0 : void hw_counter_set_wrap_value(uint64_t wrap_value) 65 : : { 66 : 0 : counter_wrap = wrap_value; 67 : 0 : } 68 : : 69 : : /** 70 : : * Starts the counter. It must be previously configured with 71 : : * hw_counter_set_period() and hw_counter_set_target(). 72 : : */ 73 : 0 : void hw_counter_start(void) 74 : : { 75 [ # # ]: 0 : if (counter_running) { 76 : : return; 77 : : } 78 : : 79 : 0 : counter_running = true; 80 : : 81 : 0 : hw_counter_timer = hwm_get_time() + counter_period; 82 : 0 : hwm_find_next_timer(); 83 : : } 84 : : 85 : : /** 86 : : * Stops the counter at current value. 87 : : * On the next call to hw_counter_start, the counter will 88 : : * start from the value at which it was stopped. 89 : : */ 90 : 0 : void hw_counter_stop(void) 91 : : { 92 : 0 : counter_running = false; 93 : 0 : hw_counter_timer = NEVER; 94 : 0 : hwm_find_next_timer(); 95 : 0 : } 96 : : 97 : 0 : bool hw_counter_is_started(void) 98 : : { 99 : 0 : return counter_running; 100 : : } 101 : : 102 : : /** 103 : : * Returns the current counter value. 104 : : */ 105 : 0 : uint64_t hw_counter_get_value(void) 106 : : { 107 : 0 : return counter_value; 108 : : } 109 : : 110 : : /** 111 : : * Resets the counter value. 112 : : */ 113 : 0 : void hw_counter_reset(void) 114 : : { 115 : 0 : counter_value = 0; 116 : 0 : } 117 : : 118 : : /** 119 : : * Configures the counter to generate an interrupt 120 : : * when its count value reaches target. 121 : : */ 122 : 0 : void hw_counter_set_target(uint64_t target) 123 : : { 124 : 0 : counter_target = target; 125 : 0 : }