123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /*
- * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /******************************************************************************
- * @file ck_trng.c
- * @brief CSI Source File for TRNG Driver
- * @version V1.0
- * @date 02. June 2017
- ******************************************************************************/
- #include <stdbool.h>
- #include <stdio.h>
- #include <string.h>
- #include "drv_trng.h"
- #include "ck_trng.h"
- #define ERR_TRNG(errno) (CSI_DRV_ERRNO_TRNG_BASE | errno)
- #define TRNG_NULL_PARAM_CHK(para) \
- do { \
- if (para == NULL) { \
- return ERR_TRNG(EDRV_PARAMETER); \
- } \
- } while (0)
- typedef struct {
- uint32_t base;
- trng_event_cb_t cb;
- trng_status_t status;
- } ck_trng_priv_t;
- static ck_trng_priv_t trng_handle[CONFIG_TRNG_NUM];
- /* Driver Capabilities */
- static const trng_capabilities_t driver_capabilities = {
- .lowper_mode = 1 /* low power mode */
- };
- //
- // Functions
- //
- ck_trng_reg_t *trng_reg = NULL;
- static int32_t trng_enable(void)
- {
- trng_reg->TCR |= TRNG_EN;
- return 0;
- }
- static int32_t trng_get_data(void)
- {
- int data = trng_reg->TDR;
- return data;
- }
- static int32_t trng_data_is_ready(void)
- {
- int flag = (trng_reg->TCR & TRNG_DATA_READY);
- return flag;
- }
- int32_t __attribute__((weak)) target_get_trng_count(void)
- {
- return 0;
- }
- int32_t __attribute__((weak)) target_get_trng(int32_t idx, uint32_t *base)
- {
- return NULL;
- }
- /**
- \brief get trng handle count.
- \return trng handle count
- */
- int32_t csi_trng_get_instance_count(void)
- {
- return target_get_trng_count();
- }
- /**
- \brief Initialize TRNG Interface. 1. Initializes the resources needed for the TRNG interface 2.registers event callback function
- \param[in] idx must not exceed return value of csi_trng_get_instance_count()
- \param[in] cb_event Pointer to \ref trng_event_cb_t
- \return pointer to trng handle
- */
- trng_handle_t csi_trng_initialize(int32_t idx, trng_event_cb_t cb_event)
- {
- if (idx < 0 || idx >= CONFIG_TRNG_NUM) {
- return NULL;
- }
- /* obtain the trng information */
- uint32_t base = 0u;
- int32_t real_idx = target_get_trng(idx, &base);
- if (real_idx != idx) {
- return NULL;
- }
- ck_trng_priv_t *trng_priv = &trng_handle[idx];
- trng_priv->base = base;
- /* initialize the trng context */
- trng_reg = (ck_trng_reg_t *)(trng_priv->base);
- trng_priv->cb = cb_event;
- trng_priv->status.busy = 0;
- trng_priv->status.data_valid = 0;
- return (trng_handle_t)trng_priv;
- }
- /**
- \brief De-initialize TRNG Interface. stops operation and releases the software resources used by the interface
- \param[in] handle trng handle to operate.
- \return error code
- */
- int32_t csi_trng_uninitialize(trng_handle_t handle)
- {
- TRNG_NULL_PARAM_CHK(handle);
- ck_trng_priv_t *trng_priv = handle;
- trng_priv->cb = NULL;
- return 0;
- }
- /**
- \brief Get driver capabilities.
- \param[in] trng handle to operate.
- \return \ref trng_capabilities_t
- */
- trng_capabilities_t csi_trng_get_capabilities(trng_handle_t handle)
- {
- return driver_capabilities;
- }
- /**
- \brief Get data from the TRNG.
- \param[in] handle trng handle to operate.
- \param[out] data Pointer to buffer with data get from TRNG
- \param[in] num Number of data items to obtain
- \return error code
- */
- int32_t csi_trng_get_data(trng_handle_t handle, void *data, uint32_t num)
- {
- TRNG_NULL_PARAM_CHK(handle);
- TRNG_NULL_PARAM_CHK(data);
- TRNG_NULL_PARAM_CHK(num);
- ck_trng_priv_t *trng_priv = handle;
- trng_priv->status.busy = 1U;
- trng_priv->status.data_valid = 0U;
- uint8_t left_len = (uint32_t)data & 0x3;
- uint32_t result = 0;
- /* if the data addr is not aligned by word */
- if (left_len) {
- trng_enable();
- while (!trng_data_is_ready());
- result = trng_get_data();
- /* wait the data is ready */
- while (trng_data_is_ready());
- if (num > (4 - left_len)) {
- memcpy(data, &result, 4 - left_len);
- } else {
- memcpy(data, &result, num);
- trng_priv->status.busy = 0U;
- trng_priv->status.data_valid = 1U;
- if (trng_priv->cb) {
- trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
- }
- return 0;
- }
- num -= (4 - left_len);
- }
- uint32_t word_len = num >> 2;
- left_len = num & 0x3;
- /* obtain the data by word */
- while (word_len--) {
- trng_enable();
- while (!trng_data_is_ready());
- result = trng_get_data();
- while (trng_data_is_ready());
- *(uint32_t *)data = result;
- data += 4;
- }
- /* if the num is not aligned by word */
- if (left_len) {
- trng_enable();
- while (!trng_data_is_ready());
- result = trng_get_data();
- while (trng_data_is_ready());
- memcpy(data, &result, left_len);
- }
- trng_priv->status.busy = 0U;
- trng_priv->status.data_valid = 1U;
- if (trng_priv->cb) {
- trng_priv->cb(TRNG_EVENT_DATA_GENERATE_COMPLETE);
- }
- return 0;
- }
- /**
- \brief Get TRNG status.
- \param[in] handle trng handle to operate.
- \return TRNG status \ref trng_status_t
- */
- trng_status_t csi_trng_get_status(trng_handle_t handle)
- {
- ck_trng_priv_t *trng_priv = handle;
- return trng_priv->status;
- }
|