1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18
19 /********************************************************************************************************
20 * @file trng.c
21 *
22 * @brief This is the source file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 #include "trng.h"
28 #include "compiler.h"
29 /**********************************************************************************************************************
30 * local constants *
31 *********************************************************************************************************************/
32
33
34 /**********************************************************************************************************************
35 * local macro *
36 *********************************************************************************************************************/
37
38
39 /**********************************************************************************************************************
40 * local data type *
41 *********************************************************************************************************************/
42
43
44 /**********************************************************************************************************************
45 * global variable *
46 *********************************************************************************************************************/
47
48 _attribute_data_retention_sec_ unsigned int g_rnd_m_w = 0;
49 _attribute_data_retention_sec_ unsigned int g_rnd_m_z = 0;
50
51 /**********************************************************************************************************************
52 * local variable *
53 *********************************************************************************************************************/
54 /**********************************************************************************************************************
55 * local function prototype *
56 *********************************************************************************************************************/
57 /**********************************************************************************************************************
58 * global function implementation *
59 *********************************************************************************************************************/
60 /**
61 * @brief This function performs to get one random number.If chip in suspend TRNG module should be close.
62 * else its current will be larger.
63 * @return the value of one random number.
64 */
trng_init(void)65 void trng_init(void)
66 {
67 //TRNG module Reset clear
68 reg_rst2 |= FLD_RST2_TRNG;
69 //turn on TRNG clock
70 reg_clk_en2 |= FLD_CLK2_TRNG_EN;
71
72 reg_trng_cr0 &= ~(FLD_TRNG_CR0_RBGEN); //disable
73 reg_trng_rtcr = 0x00; //TCR_MSEL
74 reg_trng_cr0 |= (FLD_TRNG_CR0_RBGEN); //enable
75
76 while(!(reg_rbg_sr & FLD_RBG_SR_DRDY));
77 g_rnd_m_w = reg_rbg_dr; //get the random number
78 while(!(reg_rbg_sr & FLD_RBG_SR_DRDY));
79 g_rnd_m_z = reg_rbg_dr;
80
81 //Reset TRNG module
82 reg_rst2 &= (~FLD_RST2_TRNG);
83 //turn off TRNG module clock
84 reg_clk_en2 &= ~(FLD_CLK2_TRNG_EN);
85
86 reg_trng_cr0 &= ~(FLD_TRNG_CR0_RBGEN | FLD_TRNG_CR0_ROSEN0 | FLD_TRNG_CR0_ROSEN1 \
87 | FLD_TRNG_CR0_ROSEN2 | FLD_TRNG_CR0_ROSEN3);
88 }
89
90 /**
91 * @brief This function performs to get one random number.
92 * @return the value of one random number.
93 */
trng_rand(void)94 _attribute_ram_code_sec_noinline_ unsigned int trng_rand(void) //16M clock, code in flash 23us, code in sram 4us
95 {
96
97 g_rnd_m_w = 18000 * (g_rnd_m_w & 0xffff) + (g_rnd_m_w >> 16);
98 g_rnd_m_z = 36969 * (g_rnd_m_z & 0xffff) + (g_rnd_m_z >> 16);
99 unsigned int result = (g_rnd_m_z << 16) + g_rnd_m_w;
100
101 return (unsigned int)( result ^ stimer_get_tick() );
102 }
103
104