1 /*
2  * Copyright (c) 2017 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 /**
7  * This is a fake HW device model which executes a test applicatio
8  * timed "task" each time a fake timer is triggered
9  */
10 
11 #include "bs_types.h"
12 #include "time_machine_if.h"
13 #include "irq_ctrl.h"
14 #include "NRF_HW_model_top.h"
15 
16 bs_time_t Timer_event_fw_test_ticker = TIME_NEVER;
17 
18 static uint8_t awake_cpu_asap = 0;
19 static bs_time_t Timer_event_fw_test_ticker_internal = TIME_NEVER;
20 static bs_time_t fw_test_ticker_tick_period = TIME_NEVER;
21 
bst_ticker_find_next_time()22 static void bst_ticker_find_next_time(){
23   if ( awake_cpu_asap == 1){
24     Timer_event_fw_test_ticker = tm_get_hw_time(); //We will awake it in this same microsecond
25   } else {
26     Timer_event_fw_test_ticker = Timer_event_fw_test_ticker_internal;
27   }
28 
29   nrf_hw_find_next_timer_to_trigger();
30 }
31 
32 /**
33  * Set the FW_test ticker to trigger periodically, with a period of <tick_period>
34  * Next trigger at <delta_time> us + current Hw time
35  */
bst_ticker_set_period(bs_time_t tick_period)36 void bst_ticker_set_period(bs_time_t tick_period){
37   fw_test_ticker_tick_period = tick_period;
38   Timer_event_fw_test_ticker_internal = tick_period + tm_get_hw_time();
39   bst_ticker_find_next_time();
40 }
41 
42 /**
43  * Set the next time the FW test ticker will trigger at <absolute_time> us
44  */
bst_ticker_set_next_tick_absolute(bs_time_t absolute_time)45 void bst_ticker_set_next_tick_absolute(bs_time_t absolute_time){
46   Timer_event_fw_test_ticker_internal = tm_abs_time_to_hw_time(absolute_time);
47   bst_ticker_find_next_time();
48 }
49 
50 /**
51  * Set the next time the FW test ticker will trigger
52  * at <delta_time> us + current Hw time
53  */
bst_ticker_set_next_tick_delta(bs_time_t delta_time)54 void bst_ticker_set_next_tick_delta(bs_time_t delta_time){
55   Timer_event_fw_test_ticker_internal = delta_time + tm_get_hw_time();
56   bst_ticker_find_next_time();
57 }
58 
bst_ticker_triggered(bs_time_t HW_time)59 void bst_ticker_triggered(bs_time_t HW_time){
60   if ( awake_cpu_asap == 1 ) {
61     awake_cpu_asap = 0;
62     hw_irq_ctrl_raise_im(PHONY_HARD_IRQ);
63   } else {
64     if ( fw_test_ticker_tick_period != TIME_NEVER ){
65       Timer_event_fw_test_ticker_internal = fw_test_ticker_tick_period + HW_time;
66     } else {
67       Timer_event_fw_test_ticker_internal = TIME_NEVER;
68     }
69     extern void bst_tick(bs_time_t time);
70     bst_tick(HW_time);
71   }
72   bst_ticker_find_next_time();
73 }
74 
75 /**
76  * Awake the MCU as soon as possible (in this same microsecond, in a following delta)
77  */
bst_awake_cpu_asap()78 void bst_awake_cpu_asap(){
79   awake_cpu_asap = 1;
80   bst_ticker_find_next_time();
81 }
82