• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2   ****************************************************************************************
3   * @file    app_rng.c
4   * @author  BLE Driver Team
5   * @brief   HAL APP module driver.
6   ****************************************************************************************
7   * @attention
8   #####Copyright (c) 2019 GOODIX
9    All rights reserved.
10 
11    Redistribution and use in source and binary forms, with or without
12    modification, are permitted provided that the following conditions are met:
13    * Redistributions of source code must retain the above copyright
14     notice, this list of conditions and the following disclaimer.
15    * Redistributions in binary form must reproduce the above copyright
16      notice, this list of conditions and the following disclaimer in the
17      documentation and/or other materials provided with the distribution.
18    * Neither the name of GOODIX nor the names of its contributors may be used
19      to endorse or promote products derived from this software without
20      specific prior written permission.
21 
22    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25    ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32    POSSIBILITY OF SUCH DAMAGE.
33   ****************************************************************************************
34   */
35 
36 /*
37  * INCLUDE FILES
38  *****************************************************************************************
39  */
40 #include "string.h"
41 #include "platform_sdk.h"
42 #include "app_pwr_mgmt.h"
43 #include "app_systick.h"
44 #include "app_rng.h"
45 
46 #ifdef HAL_RNG_MODULE_ENABLED
47 
48 /*
49  * DEFINES
50  *****************************************************************************************
51  */
52 
53 #ifdef ENV_RTOS_USE_MUTEX
54 
55 #define APP_RNG_DRV_SYNC_MUTEX_LOCK     app_driver_mutex_pend(s_rng_env.mutex_sync, MUTEX_WAIT_FOREVER)
56 #define APP_RNG_DRV_SYNC_MUTEX_UNLOCK   app_driver_mutex_post(s_rng_env.mutex_sync)
57 
58 #define APP_RNG_DRV_ASYNC_MUTEX_LOCK    app_driver_mutex_pend(s_rng_env.mutex_async, MUTEX_WAIT_FOREVER)
59 #define APP_RNG_DRV_ASYNC_MUTEX_UNLOCK  app_driver_mutex_post(s_rng_env.mutex_async)
60 
61 #endif
62 
63 /*
64  * STRUCT DEFINE
65  *****************************************************************************************
66  */
67 
68 /**@brief App rng state types. */
69 typedef enum {
70     APP_RNG_INVALID = 0,
71     APP_RNG_ACTIVITY,
72 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
73     APP_RNG_SLEEP,
74 #endif
75 } app_rng_state_t;
76 
77 struct rng_env_t {
78     app_rng_evt_handler_t   evt_handler;
79     rng_handle_t            handle;
80     app_rng_type_t          ues_type;
81     app_rng_state_t         rng_state;
82 #ifdef ENV_RTOS_USE_SEMP
83     APP_DRV_SEM_DECL(sem_rx);
84 #endif
85 
86 #ifdef ENV_RTOS_USE_MUTEX
87     APP_DRV_MUTEX_DECL(mutex_sync);
88     APP_DRV_MUTEX_DECL(mutex_async);
89 #endif
90 };
91 
92 /*
93  * LOCAL FUNCTION DECLARATION
94  *****************************************************************************************
95  */
96 static bool rng_prepare_for_sleep(void);
97 static void rng_sleep_canceled(void);
98 static void rng_wake_up_ind(void);
99 
100 /*
101  * LOCAL VARIABLE DEFINITIONS
102  *****************************************************************************************
103  */
104 struct rng_env_t s_rng_env = {
105     .evt_handler = NULL,
106 #ifdef ENV_RTOS_USE_SEMP
107     .sem_rx = NULL,
108 #endif
109 #ifdef ENV_RTOS_USE_MUTEX
110     .mutex_sync = NULL,
111     .mutex_async = NULL,
112 #endif
113 };
114 static bool s_sleep_cb_registered_flag = false;
115 static int16_t s_rng_pwr_id;
116 
117 const static app_sleep_callbacks_t rng_sleep_cb = {
118     .app_prepare_for_sleep = rng_prepare_for_sleep,
119     .app_sleep_canceled = rng_sleep_canceled,
120     .app_wake_up_ind = rng_wake_up_ind
121 };
122 
123 /*
124  * LOCAL FUNCTION DEFINITIONS
125  *****************************************************************************************
126  */
rng_prepare_for_sleep(void)127 static bool rng_prepare_for_sleep(void)
128 {
129     hal_rng_state_t state;
130 
131     if (s_rng_env.rng_state == APP_RNG_ACTIVITY) {
132         state = hal_rng_get_state(&s_rng_env.handle);
133         if ((state != HAL_RNG_STATE_READY) && (state != HAL_RNG_STATE_RESET)) {
134             return false;
135         }
136 
137         GLOBAL_EXCEPTION_DISABLE();
138         hal_rng_suspend_reg(&s_rng_env.handle);
139         GLOBAL_EXCEPTION_ENABLE();
140 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
141         s_rng_env.rng_state = APP_RNG_SLEEP;
142 #endif
143     }
144 
145     return true;
146 }
147 
rng_sleep_canceled(void)148 static void rng_sleep_canceled(void)
149 {
150 }
151 
rng_wake_up_ind(void)152 SECTION_RAM_CODE static void rng_wake_up_ind(void)
153 {
154 #ifndef APP_DRIVER_WAKEUP_CALL_FUN
155     if (s_rng_env.rng_state == APP_RNG_ACTIVITY) {
156         GLOBAL_EXCEPTION_DISABLE();
157         hal_rng_resume_reg(&s_rng_env.handle);
158         GLOBAL_EXCEPTION_ENABLE();
159         if (s_rng_env.ues_type == APP_RNG_TYPE_INTERRUPT) {
160             hal_nvic_clear_pending_irq(RNG_IRQn);
161             hal_nvic_enable_irq(RNG_IRQn);
162         }
163     }
164 #endif
165 }
166 
167 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
rng_wake_up(void)168 static void rng_wake_up(void)
169 {
170     if (s_rng_env.rng_state == APP_RNG_SLEEP) {
171         GLOBAL_EXCEPTION_DISABLE();
172         hal_rng_resume_reg(&s_rng_env.handle);
173         GLOBAL_EXCEPTION_ENABLE();
174         if (s_rng_env.ues_type == APP_RNG_TYPE_INTERRUPT) {
175             hal_nvic_clear_pending_irq(RNG_IRQn);
176             hal_nvic_enable_irq(RNG_IRQn);
177         }
178         s_rng_env.rng_state = APP_RNG_ACTIVITY;
179     }
180 }
181 #endif
182 
app_rng_event_call(rng_handle_t * p_rng,app_rng_evt_type_t evt_type,uint32_t random32bit)183 static void app_rng_event_call(rng_handle_t *p_rng, app_rng_evt_type_t evt_type, uint32_t random32bit)
184 {
185     app_rng_evt_t rng_evt = {APP_RNG_EVT_ERROR, 0x0};
186 
187     if (p_rng->p_instance == RNG) {
188         rng_evt.type = evt_type;
189         rng_evt.random_data = random32bit;
190     }
191 
192 #ifdef  ENV_RTOS_USE_SEMP
193     app_driver_sem_post_from_isr(s_rng_env.sem_rx);
194 #endif
195 
196     if (s_rng_env.evt_handler != NULL) {
197         s_rng_env.evt_handler(&rng_evt);
198     }
199 }
200 
201 /*
202  * GLOBAL FUNCTION DEFINITIONS
203  ****************************************************************************************
204  */
app_rng_init(app_rng_params_t * p_params,app_rng_evt_handler_t evt_handler)205 uint16_t app_rng_init(app_rng_params_t *p_params, app_rng_evt_handler_t evt_handler)
206 {
207     hal_status_t  hal_err_code = HAL_OK;
208     app_drv_err_t app_err_code = APP_DRV_SUCCESS;
209 
210     if (p_params == NULL) {
211         return APP_DRV_ERR_POINTER_NULL;
212     }
213 
214 #ifdef  ENV_RTOS_USE_SEMP
215     if (s_rng_env.sem_rx == NULL) {
216         app_err_code = app_driver_sem_init(&s_rng_env.sem_rx);
217         APP_DRV_ERR_CODE_CHECK(app_err_code);
218     }
219 #endif
220 
221 #ifdef ENV_RTOS_USE_MUTEX
222     if (s_rng_env.mutex_async == NULL) {
223         app_err_code = app_driver_mutex_init(&s_rng_env.mutex_async);
224         APP_DRV_ERR_CODE_CHECK(app_err_code);
225     }
226     if (s_rng_env.mutex_sync == NULL) {
227         app_err_code = app_driver_mutex_init(&s_rng_env.mutex_sync);
228         APP_DRV_ERR_CODE_CHECK(app_err_code);
229     }
230 #endif
231 
232     app_systick_init();
233 
234     if (p_params->use_type == APP_RNG_TYPE_INTERRUPT) {
235         hal_nvic_clear_pending_irq(RNG_IRQn);
236         hal_nvic_enable_irq(RNG_IRQn);
237     }
238 
239     s_rng_env.ues_type = p_params->use_type;
240     s_rng_env.evt_handler = evt_handler;
241 
242     memcpy_s(&s_rng_env.handle.init, sizeof (s_rng_env.handle.init), &p_params->init, sizeof(rng_init_t));
243     s_rng_env.handle.p_instance = RNG;
244     hal_err_code = hal_rng_deinit(&s_rng_env.handle);
245     APP_DRV_ERR_CODE_CHECK(hal_err_code);
246 
247     hal_err_code = hal_rng_init(&s_rng_env.handle);
248     APP_DRV_ERR_CODE_CHECK(hal_err_code);
249 
250     if (s_sleep_cb_registered_flag == false) { // register sleep callback
251         s_sleep_cb_registered_flag = true;
252         s_rng_pwr_id = pwr_register_sleep_cb(&rng_sleep_cb, APP_DRIVER_RNG_WAPEUP_PRIORITY);
253         if (s_rng_pwr_id < 0) {
254             return APP_DRV_ERR_INVALID_PARAM;
255         }
256     }
257 
258     s_rng_env.rng_state = APP_RNG_ACTIVITY;
259 
260     return app_err_code;
261 }
262 
app_rng_deinit(void)263 uint16_t app_rng_deinit(void)
264 {
265     hal_status_t  hal_err_code;
266 
267     if (s_rng_env.rng_state == APP_RNG_INVALID) {
268         return APP_DRV_ERR_INVALID_ID;
269     }
270 
271 #ifdef  ENV_RTOS_USE_SEMP
272     if (s_rng_env.sem_rx != NULL) {
273         app_driver_sem_deinit(s_rng_env.sem_rx);
274         s_rng_env.sem_rx = NULL;
275     }
276 #endif
277 
278 #ifdef ENV_RTOS_USE_MUTEX
279     if (s_rng_env.mutex_sync != NULL) {
280         app_driver_mutex_deinit(s_rng_env.mutex_sync);
281         s_rng_env.mutex_sync = NULL;
282     }
283     if (s_rng_env.mutex_async != NULL) {
284         app_driver_mutex_deinit(s_rng_env.mutex_async);
285         s_rng_env.mutex_async = NULL;
286     }
287 #endif
288 
289     hal_nvic_disable_irq(RNG_IRQn);
290     s_rng_env.rng_state = APP_RNG_INVALID;
291 
292     GLOBAL_EXCEPTION_DISABLE();
293     pwr_unregister_sleep_cb(s_rng_pwr_id);
294     s_sleep_cb_registered_flag = false;
295     GLOBAL_EXCEPTION_ENABLE();
296 
297     app_systick_deinit();
298 
299     hal_err_code = hal_rng_deinit(&s_rng_env.handle);
300     HAL_ERR_CODE_CHECK(hal_err_code);
301 
302     return APP_DRV_SUCCESS;
303 }
304 
app_rng_gen_sync(uint16_t * p_seed,uint32_t * p_random32bit)305 uint16_t app_rng_gen_sync(uint16_t *p_seed, uint32_t *p_random32bit)
306 {
307     hal_status_t err_code;
308 
309     if (s_rng_env.rng_state == APP_RNG_INVALID ||
310             p_seed == NULL ||
311             p_random32bit == NULL) {
312         return APP_DRV_ERR_INVALID_PARAM;
313     }
314 
315 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
316     rng_wake_up();
317 #endif
318 
319     err_code = hal_rng_generate_random_number(&s_rng_env.handle, p_seed, p_random32bit);
320     if (err_code != HAL_OK) {
321         return (uint16_t)err_code;
322     }
323 
324     return APP_DRV_SUCCESS;
325 }
326 
327 #ifdef  ENV_RTOS_USE_SEMP
app_rng_gen_sem_sync(uint16_t * p_seed)328 uint16_t app_rng_gen_sem_sync(uint16_t *p_seed)
329 {
330     hal_status_t err_code;
331 
332 #ifdef ENV_RTOS_USE_MUTEX
333     APP_RNG_DRV_ASYNC_MUTEX_LOCK;
334 #endif
335 
336     if (s_rng_env.rng_state == APP_RNG_INVALID ||
337             s_rng_env.ues_type == APP_RNG_TYPE_POLLING ||
338             p_seed == NULL) {
339 #ifdef ENV_RTOS_USE_MUTEX
340         APP_RNG_DRV_ASYNC_MUTEX_UNLOCK;
341 #endif
342         return APP_DRV_ERR_INVALID_PARAM;
343     }
344 
345 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
346     rng_wake_up();
347 #endif
348 
349     err_code = hal_rng_generate_random_number_it(&s_rng_env.handle, p_seed);
350     if (err_code != HAL_OK) {
351 #ifdef ENV_RTOS_USE_MUTEX
352         APP_RNG_DRV_ASYNC_MUTEX_UNLOCK;
353 #endif
354         return (uint16_t)err_code;
355     }
356 
357     app_driver_sem_pend(s_rng_env.sem_rx, OS_WAIT_FOREVER);
358 
359 #ifdef ENV_RTOS_USE_MUTEX
360     APP_RNG_DRV_ASYNC_MUTEX_UNLOCK;
361 #endif
362 
363     return APP_DRV_SUCCESS;
364 }
365 #endif
366 
app_rng_gen_async(uint16_t * p_seed)367 uint16_t app_rng_gen_async(uint16_t *p_seed)
368 {
369     hal_status_t err_code;
370 
371     if (s_rng_env.rng_state == APP_RNG_INVALID ||
372             s_rng_env.ues_type == APP_RNG_TYPE_POLLING ||
373             p_seed == NULL) {
374         return APP_DRV_ERR_INVALID_PARAM;
375     }
376 
377 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
378     rng_wake_up();
379 #endif
380 
381     err_code = hal_rng_generate_random_number_it(&s_rng_env.handle, p_seed);
382     if (err_code != HAL_OK) {
383         return (uint16_t)err_code;
384     }
385 
386     return APP_DRV_SUCCESS;
387 }
388 
app_rng_get_handle(void)389 rng_handle_t *app_rng_get_handle(void)
390 {
391     if (s_rng_env.rng_state == APP_RNG_INVALID) {
392         return NULL;
393     }
394 
395 #ifdef APP_DRIVER_WAKEUP_CALL_FUN
396     rng_wake_up();
397 #endif
398 
399     return &s_rng_env.handle;
400 }
401 
hal_rng_ready_data_callback(rng_handle_t * p_rng,uint32_t random32bit)402 void hal_rng_ready_data_callback(rng_handle_t *p_rng, uint32_t random32bit)
403 {
404     app_rng_event_call(p_rng, APP_RNG_EVT_DONE, random32bit);
405 }
406 
RNG_IRQHandler(void)407 SECTION_RAM_CODE void RNG_IRQHandler(void)
408 {
409 #if FLASH_PROTECT_PRIORITY
410     platform_interrupt_protection_push();
411 #endif
412     hal_rng_irq_handler(&s_rng_env.handle);
413 #if FLASH_PROTECT_PRIORITY
414     platform_interrupt_protection_pop();
415 #endif
416 }
417 
418 #endif
419