1 /*
2  * Copyright (c) 2017 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "NRF_RNG.h"
7 #include <string.h>
8 #include <stdbool.h>
9 #include "time_machine_if.h"
10 #include "NRF_HW_model_top.h"
11 #include "NRF_PPI.h"
12 #include "irq_ctrl.h"
13 #include "irq_sources.h"
14 #include "bs_rand_main.h"
15 
16 /*
17  * RNG — Random number generator
18  * http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52840.ps%2Frng.html&cp=2_0_0_24&anchor=concept_h35_c1l_cs
19  *
20  * Very rough model
21  */
22 
23 NRF_RNG_Type NRF_RNG_regs;
24 bs_time_t Timer_RNG = TIME_NEVER; //Time when the next random number will be ready
25 
26 static bool RNG_hw_started = false;
27 static bool RNG_INTEN = false; //interrupt enable
28 
29 /**
30  * Initialize the RNG model
31  */
nrg_rng_init()32 void nrg_rng_init(){
33   memset(&NRF_RNG_regs, 0, sizeof(NRF_RNG_regs));
34   RNG_hw_started = false;
35   RNG_INTEN = false;
36   Timer_RNG = TIME_NEVER;
37 }
38 
39 /**
40  * Clean up the RNG model before program exit
41  */
nrf_rng_clean_up()42 void nrf_rng_clean_up(){
43 
44 }
45 
46 /**
47  * TASK_START triggered handler
48  */
nrf_rng_task_start()49 void nrf_rng_task_start(){
50   if (RNG_hw_started) {
51     return;
52   }
53   RNG_hw_started = true;
54 
55   bs_time_t delay;
56   if ( NRF_RNG_regs.CONFIG ){ //Bias correction enabled
57     delay = 120 + 128;
58     /*
59      * The spec says that the delay is unpredictable yet it does not
60      * provide any indication of what kind of random distribution to
61      * expect => I just assume the value is always the average(?) they
62      * provide
63      */
64   } else {
65     delay = 30 + 128;
66   }
67   Timer_RNG = tm_get_hw_time() + delay;
68 
69   nrf_hw_find_next_timer_to_trigger();
70 }
71 
72 /**
73  * TASK_STOP triggered handler
74  */
nrf_rng_task_stop()75 void nrf_rng_task_stop(){
76   RNG_hw_started = false;
77   Timer_RNG = TIME_NEVER;
78   nrf_hw_find_next_timer_to_trigger();
79 }
80 
81 
nrf_rng_regw_sideeffects_TASK_START()82 void nrf_rng_regw_sideeffects_TASK_START(){
83   if ( NRF_RNG_regs.TASKS_START ) {
84     NRF_RNG_regs.TASKS_START = 0;
85     nrf_rng_task_start();
86   }
87 }
88 
nrf_rng_regw_sideeffects_TASK_STOP()89 void nrf_rng_regw_sideeffects_TASK_STOP(){
90   if ( NRF_RNG_regs.TASKS_STOP ) {
91     NRF_RNG_regs.TASKS_STOP = 0;
92     nrf_rng_task_stop();
93   }
94 }
95 
nrf_rng_regw_sideeffects_INTENSET()96 void nrf_rng_regw_sideeffects_INTENSET(){
97   if ( NRF_RNG_regs.INTENSET ) {
98     RNG_INTEN = true;
99   }
100 }
101 
nrf_rng_regw_sideeffects_INTENCLEAR()102 void nrf_rng_regw_sideeffects_INTENCLEAR(){
103   if ( NRF_RNG_regs.INTENCLR ) {
104     RNG_INTEN = false;
105     NRF_RNG_regs.INTENSET = 0;
106     NRF_RNG_regs.INTENCLR = 0;
107   }
108 }
109 
110 /**
111  * Handle any register side effect (by inspecting the registers states)
112  * (deprecated)
113  */
nrf_rng_regw_sideeffects()114 void nrf_rng_regw_sideeffects(){
115 
116   nrf_rng_regw_sideeffects_TASK_START();
117 
118   nrf_rng_regw_sideeffects_TASK_STOP();
119 
120   nrf_rng_regw_sideeffects_INTENSET();
121 
122   nrf_rng_regw_sideeffects_INTENCLEAR();
123 }
124 
125 /**
126  * Time has come when a new random number is ready
127  */
nrf_rng_timer_triggered()128 void nrf_rng_timer_triggered(){
129 
130   NRF_RNG_regs.VALUE = bs_random_uint32();
131   //A proper random number even if CONFIG is not set to correct the bias
132 
133   if ( NRF_RNG_regs.SHORTS == 0 ) {
134     //When the next value will be ready:
135     bs_time_t delay;
136     if ( NRF_RNG_regs.CONFIG ){ //Bias correction enabled
137       delay = 120;
138     } else {
139       delay = 30 ;
140     }
141     Timer_RNG = tm_get_hw_time() + delay;
142   } else {
143     Timer_RNG = TIME_NEVER;
144   }
145   nrf_hw_find_next_timer_to_trigger();
146 
147   NRF_RNG_regs.EVENTS_VALRDY = 1;
148   nrf_ppi_event(RNG_EVENTS_VALRDY);
149   if ( RNG_INTEN ){
150     hw_irq_ctrl_set_irq(NRF5_IRQ_RNG_IRQn);
151     //Note: there is no real need to delay the interrupt a delta
152   }
153 }
154