1 /* 2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 /** 16 **************************************************************************************** 17 * 18 * @file trng_api.c 19 * 20 * @brief TRNG API functions 21 * 22 **************************************************************************************** 23 */ 24 25 /* 26 * INCLUDE FILES 27 **************************************************************************************** 28 */ 29 #include "trng_api.h" 30 #include "reg_trng.h" 31 #include "reg_sysctrl.h" 32 #include "ll.h" 33 #include "dbg_assert.h" 34 35 #define __USE_TRNG_ISR 0 36 37 #if __USE_TRNG_ISR TRNG_IRQHandler(void)38void TRNG_IRQHandler(void) 39 { 40 // clear interrupt 41 unsigned int trng_data = CS_TRNG->trng_data; 42 trng_data = trng_data; // fix warning 43 ASSERT_WARN((CS_TRNG->trng_status & (TRNG_SSECSQ | TRNG_SSEISQ)) == 0x00UL); 44 } 45 #endif 46 trng_init(void)47void trng_init(void) 48 { 49 // clk en if required 50 cpusysctrl_pclkme_set(CSC_PCLKME_TRNG_EN_BIT); 51 #if __USE_TRNG_ISR 52 NVIC_SetPriority(TRNG_IRQn, __NVIC_PRIO_LOWEST); 53 NVIC_EnableIRQ(TRNG_IRQn); 54 #endif 55 } 56 trng_free(void)57void trng_free(void) 58 { 59 // clk dis 60 #if __USE_TRNG_ISR 61 NVIC_DisableIRQ(TRNG_IRQn); 62 #endif 63 } 64 trng_get_word(void)65unsigned int trng_get_word(void) 66 { 67 unsigned int data; 68 #if !(__USE_TRNG_ISR) 69 unsigned int status; 70 #endif 71 72 CS_TRNG->trng_en |= (TRNG_STRNGENQ | TRNG_STRNGIEQ); 73 74 #if __USE_TRNG_ISR 75 critical_section_start(); 76 do { 77 __WFI(); 78 } while (!(CS_TRNG->trng_status & TRNG_SDRDYQ)); 79 critical_section_end(); 80 data = CS_TRNG->trng_data; 81 82 #else 83 do { 84 __WFE(); 85 status = CS_TRNG->trng_status; 86 ASSERT_WARN((status & (TRNG_SSECSQ | TRNG_SSEISQ)) == 0x00UL); 87 } while (!(status & TRNG_SDRDYQ)); 88 // read data to clear trng int, make sure do it before ClearPendingIRQ 89 data = CS_TRNG->trng_data; 90 __DSB(); 91 NVIC_ClearPendingIRQ(TRNG_IRQn); 92 #endif 93 94 return data; 95 } 96