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 * Notes: 11 * * If the bitcounter is started in a CodedPhy packet during FEC1, FEC2 has a different 12 * coding rate, and the BCC value gets it into the FEC2, the bitcounter model behavior 13 * will not be correct (it will keep counting at the bit rate of the FEC1) 14 * (It is unclear how the real RADIO HW handles this) 15 */ 16 #include "bs_types.h" 17 #include "bs_tracing.h" 18 #include "NHW_common_types.h" 19 #include "NHW_config.h" 20 #include "NHW_peri_types.h" 21 #include "NHW_RADIO.h" 22 #include "NHW_RADIO_signals.h" 23 #include "nsi_hw_scheduler.h" 24 #include "nsi_tasks.h" 25 #include "nsi_hws_models_if.h" 26 27 static bs_time_t Timer_RADIO_bitcounter = TIME_NEVER; 28 29 static bs_time_t Time_BitCounterStarted = TIME_NEVER; 30 static bool bit_counter_running = false; 31 32 extern NRF_RADIO_Type NRF_RADIO_regs; 33 nrf_radio_bitcounter_timer_triggered(void)34static void nrf_radio_bitcounter_timer_triggered(void) { 35 nhw_RADIO_signal_EVENTS_BCMATCH(0); 36 Timer_RADIO_bitcounter = TIME_NEVER; 37 nsi_hws_find_next_event(); 38 //Note that we leave the bit counter running, so a new BCC can be programmed to make it trigger later 39 } 40 41 NSI_HW_EVENT(Timer_RADIO_bitcounter, nrf_radio_bitcounter_timer_triggered, 50); 42 nhw_RADIO_TASK_BCSTART(void)43void nhw_RADIO_TASK_BCSTART(void) { 44 /* Note that we do not validate that the end of the address has been received */ 45 46 if (bit_counter_running) { 47 bs_trace_warning_line_time("NRF_RADIO: BCSTART received while the bitcounter was already running." 48 "New BCSTART is just ignored\n"); 49 return; 50 } 51 bit_counter_running = true; 52 Time_BitCounterStarted = nsi_hws_get_time(); 53 Timer_RADIO_bitcounter = Time_BitCounterStarted + NRF_RADIO_regs.BCC/nhw_radio_get_bpus(); 54 nsi_hws_find_next_event(); 55 } 56 nhw_radio_stop_bit_counter(void)57void nhw_radio_stop_bit_counter(void) { 58 if (!bit_counter_running){ 59 return; 60 } 61 bit_counter_running = false; 62 if (Timer_RADIO_bitcounter != TIME_NEVER) { 63 Timer_RADIO_bitcounter = TIME_NEVER; 64 nsi_hws_find_next_event(); 65 } 66 } 67 nhw_RADIO_TASK_BCSTOP(void)68void nhw_RADIO_TASK_BCSTOP(void) { 69 nhw_radio_stop_bit_counter(); 70 } 71 nhw_RADIO_regw_sideeffects_BCC(void)72void nhw_RADIO_regw_sideeffects_BCC(void) { 73 if (!bit_counter_running){ 74 return; 75 } 76 Timer_RADIO_bitcounter = Time_BitCounterStarted + NRF_RADIO_regs.BCC/nhw_radio_get_bpus(); 77 if (Timer_RADIO_bitcounter < nsi_hws_get_time()) { 78 bs_trace_warning_line_time("NRF_RADIO: Reprogrammed bitcounter with a BCC which has already" 79 "passed (%"PRItime") => we ignore it\n", 80 Timer_RADIO_bitcounter); 81 Timer_RADIO_bitcounter = TIME_NEVER; 82 } 83 nsi_hws_find_next_event(); 84 } 85