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