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