1 /**
2 *********************************************************************************
3 *
4 * @file ald_trng.c
5 * @brief TRNG module driver.
6 *
7 * @version V1.0
8 * @date 26 Jun 2019
9 * @author AE Team
10 * @note
11 * Change Logs:
12 * Date Author Notes
13 * 26 Jun 2019 AE Team The first version
14 *
15 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 *
19 * Licensed under the Apache License, Version 2.0 (the License); you may
20 * not use this file except in compliance with the License.
21 * You may obtain a copy of the License at
22 *
23 * www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 **********************************************************************************
31 */
32
33 #include "ald_conf.h"
34
35
36 /** @addtogroup ES32FXXX_ALD
37 * @{
38 */
39
40 /** @defgroup TRNG TRNG
41 * @brief TRNG module driver
42 * @{
43 */
44 #ifdef ALD_TRNG
45
46 /** @addtogroup CRYPT_Private_Functions CRYPT Private Functions
47 * @{
48 */
49 void trng_reset(trng_handle_t *hperh);
50 /**
51 * @}
52 */
53
54 /** @defgroup TRNG_Public_Functions TRNG Public Functions
55 * @{
56 */
57
58 /** @addtogroup TRNG_Public_Functions_Group1 Initialization functions
59 * @brief Initialization functions
60 *
61 * @verbatim
62 ==============================================================================
63 ##### Initialization functions #####
64 ==============================================================================
65 [..] This section provides functions allowing to initialize the TRNG:
66 (+) This parameters can be configured:
67 (++) Word Width
68 (++) Seed Type
69 (++) Seed
70 (++) Start Time
71 (++) Adjust parameter
72
73 @endverbatim
74 * @{
75 */
76
77
78 /**
79 * @brief Initializes the TRNG according to the specified
80 * parameters in the trng_init_t.
81 * @param hperh: Pointer to a trng_handle_t structure that contains
82 * the configuration information for the specified TRNG module.
83 * @retval Status, see @ref ald_status_t.
84 */
ald_trng_init(trng_handle_t * hperh)85 ald_status_t ald_trng_init(trng_handle_t *hperh)
86 {
87 uint32_t tmp = 0;
88
89 if (hperh == NULL)
90 return ERROR;
91
92 assert_param(IS_TRNG_DATA_WIDTH(hperh->init.data_width));
93 assert_param(IS_TRNG_SEED_TYPE(hperh->init.seed_type));
94 assert_param(IS_TRNG_ADJC(hperh->init.adjc));
95 assert_param(IS_FUNC_STATE(hperh->init.posten));
96 assert_param(IS_TRNG_T_START(hperh->init.t_start));
97
98 __LOCK(hperh);
99 trng_reset(hperh);
100
101 if (hperh->state == TRNG_STATE_RESET)
102 __UNLOCK(hperh);
103
104 tmp = TRNG->CR;
105
106 if (hperh->init.adjc == 0)
107 tmp = (0 << TRNG_CR_ADJM_POS);
108 else
109 tmp = (1 << TRNG_CR_ADJM_POS);
110
111 tmp |= ((1 << TRNG_CR_TRNGSEL_POS) | (hperh->init.data_width << TRNG_CR_DSEL_POSS) |
112 (hperh->init.seed_type << TRNG_CR_SDSEL_POSS) | (hperh->init.adjc << TRNG_CR_ADJC_POSS) |
113 (hperh->init.posten << TRNG_CR_POSTEN_MSK));
114
115 TRNG->CR = tmp;
116
117 WRITE_REG(TRNG->SEED, hperh->init.seed);
118 MODIFY_REG(TRNG->CFGR, TRNG_CFGR_TSTART_MSK, (hperh->init.t_start) << TRNG_CFGR_TSTART_POSS);
119
120 hperh->state = TRNG_STATE_READY;
121 __UNLOCK(hperh);
122 return OK;
123 }
124 /**
125 * @}
126 */
127
128 /** @addtogroup TRNG_Public_Functions_Group2 Peripheral Control functions
129 * @brief Peripheral Control functions
130 *
131 * @verbatim
132 ==============================================================================
133 ##### Peripheral Control functions #####
134 ==============================================================================
135 [..] This section provides functions allowing to:
136 (+) ald_trng_get_result() API can Get the result.
137 (+) ald_trng_interrupt_config() API can be helpful to configure TRNG interrupt source.
138 (+) ald_trng_get_it_status() API can get the status of interrupt source.
139 (+) ald_trng_get_status() API can get the status of SR register.
140 (+) ald_trng_get_flag_status() API can get the status of interrupt flag.
141 (+) ald_trng_clear_flag_status() API can clear interrupt flag.
142
143 @endverbatim
144 * @{
145 */
146
147 /**
148 * @brief Get the result.
149 * @param hperh: Pointer to a trng_handle_t structure that contains
150 * the configuration information for the specified TRNG module.
151 * @retval The resultl
152 */
ald_trng_get_result(trng_handle_t * hperh)153 uint32_t ald_trng_get_result(trng_handle_t *hperh)
154 {
155 hperh->state = TRNG_STATE_READY;
156 hperh->data = hperh->perh->DR;
157 return (uint32_t)hperh->perh->DR;
158 }
159
160 /**
161 * @brief Enable/disable the specified interrupts.
162 * @param hperh: Pointer to a trng_handle_t structure that contains
163 * the configuration information for the specified TRNG module.
164 * @param it: Specifies the interrupt sources to be enabled or disabled.
165 * This parameter can be one of the @ref trng_it_t.
166 * @param state: New state of the specified interrupts.
167 * This parameter can be:
168 * @arg ENABLE
169 * @arg DISABLE
170 * @retval None
171 */
ald_trng_interrupt_config(trng_handle_t * hperh,trng_it_t it,type_func_t state)172 void ald_trng_interrupt_config(trng_handle_t *hperh, trng_it_t it, type_func_t state)
173 {
174 assert_param(IS_TRNG_IT(it));
175 assert_param(IS_FUNC_STATE(state));
176
177 if (state)
178 SET_BIT(hperh->perh->IER, it);
179 else
180 CLEAR_BIT(hperh->perh->IER, it);
181
182 return;
183 }
184
185 /**
186 * @brief Get the status of SR register.
187 * @param hperh: Pointer to a trng_handle_t structure that contains
188 * the configuration information for the specified TRNG module.
189 * @param status: Specifies the TRNG status type.
190 * This parameter can be one of the @ref trng_status_t.
191 * @retval Status:
192 * - 0: RESET
193 * - 1: SET
194 */
ald_trng_get_status(trng_handle_t * hperh,trng_status_t status)195 flag_status_t ald_trng_get_status(trng_handle_t *hperh, trng_status_t status)
196 {
197 assert_param(IS_TRNG_STATUS(status));
198
199 if (READ_BIT(hperh->perh->SR, status))
200 return SET;
201
202 return RESET;
203 }
204
205 /**
206 * @brief Get the status of interrupt source.
207 * @param hperh: Pointer to a trng_handle_t structure that contains
208 * the configuration information for the specified TRNG module.
209 * @param it: Specifies the interrupt source.
210 * This parameter can be one of the @ref trng_it_t.
211 * @retval Status:
212 * - 0: RESET
213 * - 1: SET
214 */
ald_trng_get_it_status(trng_handle_t * hperh,trng_it_t it)215 it_status_t ald_trng_get_it_status(trng_handle_t *hperh, trng_it_t it)
216 {
217 assert_param(IS_TRNG_IT(it));
218
219 if (READ_BIT(hperh->perh->IER, it))
220 return SET;
221
222 return RESET;
223 }
224
225 /**
226 * @brief Get the status of interrupt flag.
227 * @param hperh: Pointer to a trng_handle_t structure that contains
228 * the configuration information for the specified TRNG module.
229 * @param flag: Specifies the interrupt flag.
230 * This parameter can be one of the @ref trng_flag_t.
231 * @retval Status:
232 * - 0: RESET
233 * - 1: SET
234 */
ald_trng_get_flag_status(trng_handle_t * hperh,trng_flag_t flag)235 flag_status_t ald_trng_get_flag_status(trng_handle_t *hperh, trng_flag_t flag)
236 {
237 assert_param(IS_TRNG_FLAG(flag));
238
239 if (READ_BIT(hperh->perh->IFR, flag))
240 return SET;
241
242 return RESET;
243 }
244
245 /**
246 * @brief Clear the interrupt flag.
247 * @param hperh: Pointer to a trng_handle_t structure that contains
248 * the configuration information for the specified TRNG module.
249 * @param flag: Specifies the interrupt flag.
250 * This parameter can be one of the @ref trng_flag_t.
251 * @retval None
252 */
ald_trng_clear_flag_status(trng_handle_t * hperh,trng_flag_t flag)253 void ald_trng_clear_flag_status(trng_handle_t *hperh, trng_flag_t flag)
254 {
255 assert_param(IS_TRNG_FLAG(flag));
256 WRITE_REG(hperh->perh->IFCR, flag);
257
258 return;
259 }
260
261 /**
262 * @brief Reset the TRNG peripheral.
263 * @param hperh: Pointer to a trng_handle_t structure that contains
264 * the configuration information for the specified TRNG module.
265 * @retval None
266 */
trng_reset(trng_handle_t * hperh)267 void trng_reset(trng_handle_t *hperh)
268 {
269 TRNG->CR = 0;
270 TRNG->SEED = 0;
271 TRNG->CFGR = 0x1FF0707;
272 TRNG->IER = 0;
273 TRNG->IFCR = 0xFFFFFFFF;
274
275 hperh->state = TRNG_STATE_READY;
276 __UNLOCK(hperh);
277 return;
278 }
279
280 /**
281 * @brief This function handles TRNG interrupt request.
282 * @param hperh: Pointer to a trng_handle_t structure that contains
283 * the configuration information for the specified TRNG module.
284 * @retval None
285 */
ald_trng_irq_handler(trng_handle_t * hperh)286 void ald_trng_irq_handler(trng_handle_t *hperh)
287 {
288 if (ald_trng_get_flag_status(hperh, TRNG_IF_SERR) == SET) {
289 hperh->state = TRNG_STATE_ERROR;
290 ald_trng_clear_flag_status(hperh, TRNG_IF_SERR);
291 if (hperh->err_cplt_cbk)
292 hperh->err_cplt_cbk(hperh);
293 return;
294 }
295
296 if (ald_trng_get_flag_status(hperh, TRNG_IF_DAVLD) == SET) {
297 hperh->data = hperh->perh->DR;
298 hperh->state = TRNG_STATE_READY;
299 ald_trng_clear_flag_status(hperh, TRNG_IF_DAVLD);
300 if (hperh->trng_cplt_cbk)
301 hperh->trng_cplt_cbk(hperh);
302 }
303
304 if (ald_trng_get_flag_status(hperh, TRNG_IF_START) == SET) {
305 hperh->state = TRNG_STATE_BUSY;
306 ald_trng_clear_flag_status(hperh, TRNG_IF_START);
307 if (hperh->init_cplt_cbk)
308 hperh->init_cplt_cbk(hperh);
309 }
310 }
311 /**
312 * @}
313 */
314 /**
315 * @}
316 */
317 #endif /* ALD_TRNG */
318 /**
319 * @}
320 */
321 /**
322 * @}
323 */
324