1 /* 2 * Copyright (c) 2025 STMicroelectronics 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #include <zephyr/kernel.h> 7 #include <zephyr/device.h> 8 #include <stm32_ll_rng.h> 9 10 /** 11 * This driver supports two compatibles: 12 * - "st,stm32-rng" for TRNG with IRQ lines 13 * - "st,stm32-rng-noirq" for TRNG without IRQ lines 14 */ 15 #define IRQLESS_TRNG DT_HAS_COMPAT_STATUS_OKAY(st_stm32_rng_noirq) 16 17 #if IRQLESS_TRNG 18 #define DT_DRV_COMPAT st_stm32_rng_noirq 19 #define TRNG_GENERATION_DELAY K_NSEC(DT_INST_PROP_OR(0, generation_delay_ns, 0)) 20 #else /* !IRQLESS_TRNG */ 21 #define DT_DRV_COMPAT st_stm32_rng 22 #define IRQN DT_INST_IRQN(0) 23 #define IRQ_PRIO DT_INST_IRQ(0, priority) 24 #endif /* IRQLESS_TRNG */ 25 26 /* Cross-series LL compatibility wrappers */ ll_rng_enable_it(RNG_TypeDef * RNGx)27static inline void ll_rng_enable_it(RNG_TypeDef *RNGx) 28 { 29 /* Silence "unused" warning on IRQ-less hardware*/ 30 ARG_UNUSED(RNGx); 31 #if !IRQLESS_TRNG 32 # if defined(CONFIG_SOC_STM32WB09XX) 33 LL_RNG_EnableEnErrorIrq(RNGx); 34 LL_RNG_EnableEnFfFullIrq(RNGx); 35 # else 36 LL_RNG_EnableIT(RNGx); 37 # endif 38 #endif /* !IRQLESS_TRNG */ 39 } 40 ll_rng_is_active_seis(RNG_TypeDef * RNGx)41static inline uint32_t ll_rng_is_active_seis(RNG_TypeDef *RNGx) 42 { 43 #if defined(CONFIG_SOC_SERIES_STM32WB0X) 44 # if defined(CONFIG_SOC_STM32WB09XX) 45 return LL_RNG_IsActiveFlag_ENTROPY_ERR(RNGx); 46 # else 47 return LL_RNG_IsActiveFlag_FAULT(RNGx); 48 # endif 49 #else 50 return LL_RNG_IsActiveFlag_SEIS(RNGx); 51 #endif /* CONFIG_SOC_SERIES_STM32WB0X */ 52 } 53 ll_rng_clear_seis(RNG_TypeDef * RNGx)54static inline void ll_rng_clear_seis(RNG_TypeDef *RNGx) 55 { 56 #if defined(CONFIG_SOC_SERIES_STM32WB0X) 57 # if defined(CONFIG_SOC_STM32WB09XX) 58 LL_RNG_SetResetHealthErrorFlags(RNGx, 1); 59 # else 60 LL_RNG_ClearFlag_FAULT(RNGx); 61 # endif 62 #else 63 LL_RNG_ClearFlag_SEIS(RNGx); 64 #endif /* CONFIG_SOC_SERIES_STM32WB0X */ 65 } 66 ll_rng_is_active_secs(RNG_TypeDef * RNGx)67static inline uint32_t ll_rng_is_active_secs(RNG_TypeDef *RNGx) 68 { 69 #if !defined(CONFIG_SOC_SERIES_STM32WB0X) 70 return LL_RNG_IsActiveFlag_SECS(RNGx); 71 #else 72 /** 73 * STM32WB0x RNG has no equivalent of SECS. 74 * Since this flag is always checked in conjunction 75 * with FAULT (the SEIS equivalent), returning 0 is OK. 76 */ 77 return 0; 78 #endif /* !CONFIG_SOC_SERIES_STM32WB0X */ 79 } 80 ll_rng_is_active_drdy(RNG_TypeDef * RNGx)81static inline uint32_t ll_rng_is_active_drdy(RNG_TypeDef *RNGx) 82 { 83 #if defined(CONFIG_SOC_SERIES_STM32WB0X) 84 # if defined(CONFIG_SOC_STM32WB09XX) 85 return LL_RNG_IsActiveFlag_VAL_READY(RNGx); 86 # else 87 return LL_RNG_IsActiveFlag_RNGRDY(RNGx); 88 # endif 89 #else 90 return LL_RNG_IsActiveFlag_DRDY(RNGx); 91 #endif /* CONFIG_SOC_SERIES_STM32WB0X */ 92 } 93 ll_rng_read_rand_data(RNG_TypeDef * RNGx)94static inline uint16_t ll_rng_read_rand_data(RNG_TypeDef *RNGx) 95 { 96 #if defined(CONFIG_SOC_SERIES_STM32WB0X) 97 # if defined(CONFIG_SOC_STM32WB09XX) 98 return (uint16_t)LL_RNG_GetRndVal(RNGx); 99 # else 100 return LL_RNG_ReadRandData16(RNGx); 101 # endif 102 #else 103 return (uint16_t)LL_RNG_ReadRandData32(RNGx); 104 #endif /* CONFIG_SOC_SERIES_STM32WB0X */ 105 } 106