2 * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /******************************************************************************
19 * @brief CSI Source File for TRNG Driver
22 ******************************************************************************/
30 #define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
31 #define TRNG_NULL_PARAM_CHK(para) \
34 return ERR_TRNG(EDRV_PARAMETER); \
44 extern int32_t target_get_trng_count(void);
45 extern int32_t target_get_trng(int32_t idx, uint32_t *base);
47 static ck_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
49 /* Driver Capabilities */
50 static const trng_capabilities_t driver_capabilities = {
51 .lowper_mode = 1 /* low power mode */
54 extern int32_t target_get_trng(int32_t idx, uint32_t *base);
55 extern int32_t target_get_trng_count(void);
60 ck_trng_reg_t *trng_reg = NULL;
62 static int32_t trng_enable(void)
64 trng_reg->TCR |= TRNG_EN;
68 static int32_t trng_get_data(void)
70 int data = trng_reg->TDR;
74 static int32_t trng_data_is_ready(void)
76 int flag = (trng_reg->TCR & TRNG_DATA_READY);
81 \brief get trng handle count.
82 \return trng handle count
84 int32_t csi_trng_get_instance_count(void)
86 return target_get_trng_count();
90 \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
91 \param[in] idx must not exceed return value of csi_trng_get_instance_count()
92 \param[in] cb_event Pointer to \ref trng_event_cb_t
93 \return pointer to trng handle
95 trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
98 if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
102 /* obtain the trng information */
104 int32_t real_idx = target_get_trng(idx, &base);
106 if (real_idx != idx) {
110 ck_trng_priv_t *trng_priv = &trng_handle[idx];
111 trng_priv->base = base;
113 /* initialize the trng context */
114 trng_reg = (ck_trng_reg_t *)(trng_priv->base);
115 trng_priv->cb = cb_event;
116 trng_priv->status.busy = 0;
117 trng_priv->status.data_valid = 0;
119 return (trng_handle_t)trng_priv;
123 \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
124 \param[in] handle trng handle to operate.
127 int32_t csi_trng_uninitialize(trng_handle_t handle)
129 TRNG_NULL_PARAM_CHK(handle);
131 ck_trng_priv_t *trng_priv = handle;
132 trng_priv->cb = NULL;
138 \brief Get driver capabilities.
139 \param[in] trng handle to operate.
140 \return \ref trng_capabilities_t
142 trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
144 return driver_capabilities;
148 \brief Get data from the TRNG.
149 \param[in] handle trng handle to operate.
150 \param[out] data Pointer to buffer with data get from TRNG
151 \param[in] num Number of data items to obtain
154 int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
156 TRNG_NULL_PARAM_CHK(handle);
157 TRNG_NULL_PARAM_CHK(data);
158 TRNG_NULL_PARAM_CHK(num);
160 ck_trng_priv_t *trng_priv = handle;
162 trng_priv->status.busy = 1U;
163 trng_priv->status.data_valid = 0U;
165 uint8_t left_len = (uint32_t)data & 0x3;
168 /* if the data addr is not aligned by word */
171 while (!trng_data_is_ready());
172 result = trng_get_data();
173 /* wait the data is ready */
174 while (trng_data_is_ready());
176 if (num > (4 - left_len)) {
177 memcpy(data, &result, 4 - left_len);
179 memcpy(data, &result, num);
180 trng_priv->status.busy = 0U;
181 trng_priv->status.data_valid = 1U;
184 trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
188 num -= (4 - left_len);
189 data += (4 - left_len);
192 uint32_t word_len = num >> 2;
193 left_len = num & 0x3;
195 /* obtain the data by word */
198 while (!trng_data_is_ready());
199 result = trng_get_data();
200 while (trng_data_is_ready());
201 *(uint32_t *)data = result;
202 data = (void *)((uint32_t)data + 4);
205 /* if the num is not aligned by word */
208 while (!trng_data_is_ready());
209 result = trng_get_data();
210 while (trng_data_is_ready());
211 memcpy(data, &result, left_len);
214 trng_priv->status.busy = 0U;
215 trng_priv->status.data_valid = 1U;
218 trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
225 \brief Get TRNG status.
226 \param[in] handle trng handle to operate.
227 \return TRNG status \ref trng_status_t
229 trng_status_t csi_trng_get_status(trng_handle_t handle)
231 ck_trng_priv_t *trng_priv = handle;
232 return trng_priv->status;