1 /*
2  * Copyright (c) 2017 Oticon A/S
3  * Copyright (c) 2023 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * RADIO Bitcounter functionality
8  * We treat it as a sub-peripheral
9  */
10 #include "bs_types.h"
11 #include "bs_tracing.h"
12 #include "time_machine_if.h"
13 #include "NRF_RADIO.h"
14 #include "NRF_RADIO_signals.h"
15 #include "NRF_HW_model_top.h"
16 
17 bs_time_t Timer_RADIO_bitcounter = TIME_NEVER;
18 
19 static bs_time_t Time_BitCounterStarted = TIME_NEVER;
20 static bool bit_counter_running = false;
21 
nrf_radio_bitcounter_reset()22 void nrf_radio_bitcounter_reset() {
23   Timer_RADIO_bitcounter = TIME_NEVER;
24   bit_counter_running = 0;
25 }
26 
nrf_radio_bitcounter_cleanup()27 void nrf_radio_bitcounter_cleanup() {
28 
29 }
30 
nrf_radio_bitcounter_timer_triggered()31 void nrf_radio_bitcounter_timer_triggered() {
32   nrf_radio_signal_BCMATCH();
33   Timer_RADIO_bitcounter = TIME_NEVER;
34   nrf_hw_find_next_timer_to_trigger();
35   //Note that we leave the bit counter running, so a new BCC can be programmed to make it trigger later
36 }
37 
nrf_radio_tasks_BCSTART()38 void nrf_radio_tasks_BCSTART() {
39   /* Note that we do not validate that the end of the address has been received */
40 
41   if (bit_counter_running) {
42     bs_trace_warning_line_time("NRF_RADIO: BCSTART received while the bitcounter was already running."
43         "New BCSTART is just ignored\n");
44     return;
45   }
46   bit_counter_running = true;
47   Time_BitCounterStarted = tm_get_hw_time();
48   Timer_RADIO_bitcounter = Time_BitCounterStarted + NRF_RADIO_regs.BCC/nrf_radio_get_bpus();
49   nrf_hw_find_next_timer_to_trigger();
50 }
51 
nrf_radio_stop_bit_counter()52 void nrf_radio_stop_bit_counter() {
53   if (!bit_counter_running){
54     return;
55   }
56   bit_counter_running = false;
57   if (Timer_RADIO_bitcounter != TIME_NEVER) {
58     Timer_RADIO_bitcounter = TIME_NEVER;
59     nrf_hw_find_next_timer_to_trigger();
60   }
61 }
62 
nrf_radio_tasks_BCSTOP()63 void nrf_radio_tasks_BCSTOP() {
64   nrf_radio_stop_bit_counter();
65 }
66 
nrf_radio_regw_sideeffects_BCC()67 void nrf_radio_regw_sideeffects_BCC() {
68   if (!bit_counter_running){
69     return;
70   }
71   Timer_RADIO_bitcounter = Time_BitCounterStarted + NRF_RADIO_regs.BCC/nrf_radio_get_bpus();
72   if (Timer_RADIO_bitcounter < tm_get_hw_time()) {
73     bs_trace_warning_line_time("NRF_RADIO: Reprogrammed bitcounter with a BCC which has already"
74         "passed (%"PRItime") => we ignore it\n",
75         Timer_RADIO_bitcounter);
76     Timer_RADIO_bitcounter = TIME_NEVER;
77   }
78   nrf_hw_find_next_timer_to_trigger();
79 }
80