1 /* USER CODE BEGIN Header */
2 /**
3   ******************************************************************************
4   * @file    hw_rng.c
5   * @author  GPM WBL Application Team
6   * @brief   This file provides functions implementation for RNG Manager.
7   ******************************************************************************
8   * @attention
9   *
10   * Copyright (c) 2024 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   */
19 /* USER CODE END Header */
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include "hw_rng.h"
23 #include "stm32wb0x_ll_rng.h"
24 #include "stm32wb0x_ll_bus.h"
25 
26 /** @defgroup RNG_Manager  RNG Manager
27 * @{
28 */
29 
30 /** @defgroup RNG_Manager_TypesDefinitions Private Type Definitions
31 * @{
32 */
33 /**
34 * @}
35 */
36 
37 /** @defgroup RNG_Manager_Private_Defines Private Defines
38 * @{
39 */
40 /**
41 * @}
42 */
43 
44 /** @defgroup RNG_Manager_Private_Variables Private Variables
45 * @{
46 */
47 /**
48 * @}
49 */
50 
51 /** @defgroup RNG_Manager_External_Variables External Variables
52 * @{
53 */
54 /**
55 * @}
56 */
57 
58 /** @defgroup RNG_Manager_Public_Functions Public Functions
59 * @{
60 */
61 
HW_RNG_Init(void)62 HW_RNG_ResultStatus HW_RNG_Init(void)
63 {
64 #ifdef STM32WB09
65   /* Peripheral clock enable */
66   LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_RNG);
67 
68   uint32_t SamplingClockDivider = 0;
69 
70   /* Check that the divider value is equal to the one to configure. If not, it must redo the write and checking. */
71   while( LL_RNG_GetSamplingClockEnableDivider(RNG) != SamplingClockDivider)
72   {
73      /* While the new divider value is being resynchronized with the TRNG core clock domain, it is not possible to write another new value. */
74      LL_RNG_SetSamplingClockEnableDivider(RNG, SamplingClockDivider);
75   }
76 
77   /* Initialize random numbers generation */
78   LL_RNG_Enable(RNG);
79 
80   /* Wait for RNG enable operation */
81   while (LL_RNG_IsActiveFlag_DISABLED(RNG));
82 
83   /* Check if internal clock error occurs */
84   if (LL_RNG_IsActiveFlag_REVEAL_CLK_ERR(RNG))
85   {
86     return HW_RNG_ERROR;
87   }
88 #endif /* STM32WB09 */
89 
90 #if defined (STM32WB07) || defined (STM32WB06) || defined(STM32WB05)
91   /* Peripheral clock enable */
92   LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_RNG);
93 
94   /* Initialize random numbers generation */
95   LL_RNG_Enable(RNG);
96 
97   /* Wait for DRDY flag to be raised */
98   while (!LL_RNG_IsActiveFlag_RNGRDY(RNG));
99 
100   /* Check if error occurs */
101   if (  LL_RNG_IsActiveFlag_FAULT(RNG)  )
102   {
103     /* Clock or Seed Error detected. Set LED to blinking mode (Error type)*/
104     return HW_RNG_ERROR;
105   }
106 
107   /* Values of Generated Random numbers are now available in num array. */
108 
109 #endif /* STM32WB07 || STM32WB06 || STM32WB05*/
110   return HW_RNG_SUCCESS;
111 }
112 
HW_RNG_Deinit(void)113 HW_RNG_ResultStatus HW_RNG_Deinit(void)
114 {
115   /* Stop random numbers generation */
116   LL_RNG_Disable(RNG);
117   return HW_RNG_SUCCESS;
118 }
119 
120 /**
121  * @brief Provide a 16-bit true random number
122  * @param num: pointer to the random value returned
123  * @return error status: 0 = No error
124  */
HW_RNG_GetRandom16(uint16_t * num)125 HW_RNG_ResultStatus HW_RNG_GetRandom16(uint16_t* num)
126 {
127 #ifdef STM32WB09
128   /* Wait for VAL_READY signal */
129   while (!LL_RNG_IsActiveFlag_VAL_READY(RNG));
130 
131   *num = LL_RNG_READRANDDATA32(RNG);
132 
133 #endif /* STM32WB09 */
134 
135 #if defined (STM32WB07) || defined (STM32WB06) || defined(STM32WB05)
136   /* Wait for RNGRDY signal */
137   while (!LL_RNG_IsActiveFlag_RNGRDY(RNG));
138 
139   *num = (uint16_t)LL_RNG_ReadRandData16(RNG);
140 
141 #endif /* STM32WB07 || STM32WB06 || STM32WB05*/
142 
143   return HW_RNG_SUCCESS;
144 }
145 
146 /**
147  * @brief Provide a 32-bit true random number
148  * @param num: pointer to the random value returned
149  *
150  * @return error status: 0 = No error
151  */
HW_RNG_GetRandom32(uint32_t * num)152 HW_RNG_ResultStatus HW_RNG_GetRandom32(uint32_t* num)
153 {
154 #ifdef STM32WB09
155   /* Wait for VAL_READY signal */
156   while (!LL_RNG_IsActiveFlag_VAL_READY(RNG));
157 
158   *num = LL_RNG_READRANDDATA32(RNG);
159 #endif /* STM32WB09 */
160 
161 #if defined (STM32WB07) || defined (STM32WB06) || defined(STM32WB05)
162   uint16_t *num_16 = (uint16_t *) num;
163 
164   /* Wait for RNGRDY signal */
165   while (!LL_RNG_IsActiveFlag_RNGRDY(RNG));
166 
167   num_16[0] = (uint16_t)LL_RNG_ReadRandData16(RNG);
168 
169   /* Wait for RNGRDY signal */
170   while (!LL_RNG_IsActiveFlag_RNGRDY(RNG));
171 
172   num_16[1] = (uint16_t)LL_RNG_ReadRandData16(RNG);
173 #endif /* STM32WB07 || STM32WB06 || STM32WB05*/
174 
175   return HW_RNG_SUCCESS;
176 }
177 
178 /**
179 * @}
180 */
181 
182 /**
183 * @}
184 */
185