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 ******************************************************************************/
31 #define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
32 #define TRNG_NULL_PARAM_CHK(para) \
35 return ERR_TRNG(EDRV_PARAMETER); \
46 extern int32_t target_get_trng(int32_t idx, uint32_t *base, uint32_t *irq);
48 static osr_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
50 /* Driver Capabilities */
51 static const trng_capabilities_t driver_capabilities = {
52 .lowper_mode = 0 /* low power mode */
59 osr_trng_reg_t *trng_reg = NULL;
61 static int32_t trng_disable_irq(void)
63 trng_reg->RBG_CR &= ~TRNG_IRQ_BIT;
67 static int32_t trng_enable(void)
69 trng_reg->RBG_CR |= TRNG_EN;
73 static int32_t trng_get_data(void)
75 int data = trng_reg->RBG_DR;
79 static int32_t trng_data_is_ready(void)
81 int flag = (trng_reg->RBG_FIFO_SR & TRNG_DATA_READY);
86 \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
87 \param[in] idx device id
88 \param[in] cb_event Pointer to \ref trng_event_cb_t
89 \return pointer to trng handle
91 trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
94 if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
98 /* obtain the trng information */
101 int32_t real_idx = target_get_trng(idx, &base, &irq);
103 if (real_idx != idx) {
107 osr_trng_priv_t *trng_priv = &trng_handle[idx];
108 trng_priv->base = base;
109 trng_priv->irq = irq;
111 /* initialize the trng context */
112 trng_reg = (osr_trng_reg_t *)(trng_priv->base);
113 trng_priv->cb = cb_event;
114 trng_priv->status.busy = 0;
115 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 osr_trng_priv_t *trng_priv = handle;
132 trng_priv->cb = NULL;
138 \brief Get driver capabilities.
139 \param[in] idx device id.
140 \return \ref trng_capabilities_t
142 //trng_capabilities_t csi_trng_get_capabilities(int32_t idx)
143 trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
146 if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
147 trng_capabilities_t ret;
148 memset(&ret, 0, sizeof(trng_capabilities_t));
151 return driver_capabilities;
155 \brief Get data from the TRNG.
156 \param[in] handle trng handle to operate.
157 \param[out] data Pointer to buffer with data get from TRNG
158 \param[in] num Number of data items to obtain
161 int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
163 TRNG_NULL_PARAM_CHK(handle);
164 TRNG_NULL_PARAM_CHK(data);
165 TRNG_NULL_PARAM_CHK(num);
167 osr_trng_priv_t *trng_priv = handle;
169 trng_priv->status.busy = 1U;
170 trng_priv->status.data_valid = 0U;
172 uint8_t left_len = (uint32_t)data & 0x3;
176 /* if the data addr is not aligned by word */
178 while (!trng_data_is_ready());
179 result = trng_get_data();
181 if (num > (4 - left_len)) {
182 memcpy(data, &result, 4 - left_len);
184 memcpy(data, &result, num);
185 trng_priv->status.busy = 0U;
186 trng_priv->status.data_valid = 1U;
189 //trng_priv->cb(0, TRNG_EVENT_DATA_GENERATE_COMPLETE);
190 trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
194 num -= (4 - left_len);
195 data += (4 - left_len);
198 uint32_t word_len = num >> 2;
199 left_len = num & 0x3;
201 /* obtain the data by word */
203 while (!trng_data_is_ready());
204 result = trng_get_data();
205 *(uint32_t *)data = result;
206 data = (void *)((uint32_t)data + 4);
209 /* if the num is not aligned by word */
211 while (!trng_data_is_ready());
212 result = trng_get_data();
213 memcpy(data, &result, left_len);
216 trng_priv->status.busy = 0U;
217 trng_priv->status.data_valid = 1U;
220 //trng_priv->cb(0, TRNG_EVENT_DATA_GENERATE_COMPLETE);
221 trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
228 \brief Get TRNG status.
229 \param[in] handle trng handle to operate.
230 \return TRNG status \ref trng_status_t
232 trng_status_t csi_trng_get_status(trng_handle_t handle)
234 if (handle == NULL) {
236 memset(&ret, 0, sizeof(trng_status_t));
239 osr_trng_priv_t *trng_priv = handle;
240 return trng_priv->status;