diff --git a/targets/stm32l442/Makefile b/targets/stm32l442/Makefile
index 67db61c..81993e0 100644
--- a/targets/stm32l442/Makefile
+++ b/targets/stm32l442/Makefile
@@ -2,7 +2,9 @@ CC=arm-none-eabi-gcc
CP=arm-none-eabi-objcopy
SZ=arm-none-eabi-size
-SRC=src/main.c src/init.c src/redirect.c src/flash.c src/startup_stm32l432xx.s src/system_stm32l4xx.c $(wildcard lib/*c)
+SRC=src/main.c src/init.c src/redirect.c src/flash.c src/rng.c \
+src/startup_stm32l432xx.s src/system_stm32l4xx.c $(wildcard lib/*c)
+
OBJ=$(SRC:.c=.o)
INC=-Isrc/ -Isrc/cmsis -Ilib/
LDSCRIPT=stm32l432xx.ld
@@ -18,7 +20,7 @@ HW=-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
CHIP=STM32L442xx
CFLAGS=$(INC) -c -D$(CHIP) -DUSE_FULL_LL_DRIVER -O0 -Wall -fdata-sections -ffunction-sections
-LDFLAGS=$(HW) -specs=nano.specs -specs=nosys.specs -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref -Wl,--gc-sections
+LDFLAGS=$(HW) -specs=nano.specs -specs=nosys.specs -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref -Wl,--gc-sections -u _printf_float
.PRECIOUS: %.o
@@ -39,7 +41,7 @@ all: $(TARGET).elf
$(CP) -O ihex $^ $(TARGET).hex
clean:
- rm -f *.o src/*.o src/*.elf *.elf
+ rm -f *.o src/*.o src/*.elf *.elf *.hex
flash: $(TARGET).hex
STM32_Programmer_CLI -c port=SWD -halt -d $(TARGET).hex -rst
diff --git a/targets/stm32l442/lib/stm32l4xx_ll_rng.c b/targets/stm32l442/lib/stm32l4xx_ll_rng.c
new file mode 100644
index 0000000..5ded9ba
--- /dev/null
+++ b/targets/stm32l442/lib/stm32l4xx_ll_rng.c
@@ -0,0 +1,162 @@
+/**
+ ******************************************************************************
+ * @file stm32l4xx_ll_rng.c
+ * @author MCD Application Team
+ * @brief RNG LL module driver.
+ ******************************************************************************
+ * @attention
+ *
+ *
© COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+#if defined(USE_FULL_LL_DRIVER)
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l4xx_ll_rng.h"
+#include "stm32l4xx_ll_bus.h"
+
+#ifdef USE_FULL_ASSERT
+#include "stm32_assert.h"
+#else
+#define assert_param(expr) ((void)0U)
+#endif
+
+/** @addtogroup STM32L4xx_LL_Driver
+ * @{
+ */
+
+#if defined (RNG)
+
+/** @addtogroup RNG_LL
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/** @addtogroup RNG_LL_Private_Macros
+ * @{
+ */
+#if defined(RNG_CR_CED)
+#define IS_LL_RNG_CED(__MODE__) (((__MODE__) == LL_RNG_CED_ENABLE) || \
+ ((__MODE__) == LL_RNG_CED_DISABLE))
+#endif /* defined(RNG_CR_CED) */
+
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup RNG_LL_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup RNG_LL_EF_Init
+ * @{
+ */
+
+/**
+ * @brief De-initialize RNG registers (Registers restored to their default values).
+ * @param RNGx RNG Instance
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RNG registers are de-initialized
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_RNG_DeInit(RNG_TypeDef *RNGx)
+{
+ /* Check the parameters */
+ assert_param(IS_RNG_ALL_INSTANCE(RNGx));
+
+ /* Enable RNG reset state */
+ LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_RNG);
+
+ /* Release RNG from reset state */
+ LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_RNG);
+
+ return (SUCCESS);
+}
+
+#if defined(RNG_CR_CED)
+/**
+ * @brief Initialize RNG registers according to the specified parameters in RNG_InitStruct.
+ * @param RNGx RNG Instance
+ * @param RNG_InitStruct: pointer to a LL_RNG_InitTypeDef structure
+ * that contains the configuration information for the specified RNG peripheral.
+ * @retval An ErrorStatus enumeration value:
+ * - SUCCESS: RNG registers are initialized according to RNG_InitStruct content
+ * - ERROR: not applicable
+ */
+ErrorStatus LL_RNG_Init(RNG_TypeDef *RNGx, LL_RNG_InitTypeDef *RNG_InitStruct)
+{
+ /* Check the parameters */
+ assert_param(IS_RNG_ALL_INSTANCE(RNGx));
+ assert_param(IS_LL_RNG_CED(RNG_InitStruct->ClockErrorDetection));
+
+ /* Clock Error Detection configuration */
+ MODIFY_REG(RNGx->CR, RNG_CR_CED, RNG_InitStruct->ClockErrorDetection);
+
+ return (SUCCESS);
+}
+
+/**
+ * @brief Set each @ref LL_RNG_InitTypeDef field to default value.
+ * @param RNG_InitStruct: pointer to a @ref LL_RNG_InitTypeDef structure
+ * whose fields will be set to default values.
+ * @retval None
+ */
+void LL_RNG_StructInit(LL_RNG_InitTypeDef *RNG_InitStruct)
+{
+ /* Set RNG_InitStruct fields to default values */
+ RNG_InitStruct->ClockErrorDetection = LL_RNG_CED_ENABLE;
+
+}
+#endif /* defined(RNG_CR_CED) */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined (RNG) */
+
+/**
+ * @}
+ */
+
+#endif /* USE_FULL_LL_DRIVER */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/targets/stm32l442/lib/stm32l4xx_ll_rng.h b/targets/stm32l442/lib/stm32l4xx_ll_rng.h
new file mode 100644
index 0000000..2c49eac
--- /dev/null
+++ b/targets/stm32l442/lib/stm32l4xx_ll_rng.h
@@ -0,0 +1,428 @@
+/**
+ ******************************************************************************
+ * @file stm32l4xx_ll_rng.h
+ * @author MCD Application Team
+ * @brief Header file of RNG LL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2017 STMicroelectronics
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32L4xx_LL_RNG_H
+#define __STM32L4xx_LL_RNG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l4xx.h"
+
+/** @addtogroup STM32L4xx_LL_Driver
+ * @{
+ */
+
+#if defined(RNG)
+
+/** @defgroup RNG_LL RNG
+ * @{
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup RNG_LL_ES_Init_Struct RNG Exported Init structures
+ * @{
+ */
+
+
+#if defined(RNG_CR_CED)
+/**
+ * @brief LL RNG Init Structure Definition
+ */
+typedef struct
+{
+ uint32_t ClockErrorDetection; /*!< Clock error detection.
+ This parameter can be one value of @ref RNG_LL_CED.
+
+ This parameter can be modified using unitary functions @ref LL_RNG_EnableClkErrorDetect(). */
+}LL_RNG_InitTypeDef;
+#endif /* defined(RNG_CR_CED) */
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup RNG_LL_Exported_Constants RNG Exported Constants
+ * @{
+ */
+
+#if defined(RNG_CR_CED)
+/** @defgroup RNG_LL_CED Clock Error Detection
+ * @{
+ */
+#define LL_RNG_CED_ENABLE 0x00000000U /*!< Clock error detection enabled */
+#define LL_RNG_CED_DISABLE RNG_CR_CED /*!< Clock error detection disabled */
+/**
+ * @}
+ */
+#endif /* defined(RNG_CR_CED) */
+
+
+/** @defgroup RNG_LL_EC_GET_FLAG Get Flags Defines
+ * @brief Flags defines which can be used with LL_RNG_ReadReg function
+ * @{
+ */
+#define LL_RNG_SR_DRDY RNG_SR_DRDY /*!< Register contains valid random data */
+#define LL_RNG_SR_CECS RNG_SR_CECS /*!< Clock error current status */
+#define LL_RNG_SR_SECS RNG_SR_SECS /*!< Seed error current status */
+#define LL_RNG_SR_CEIS RNG_SR_CEIS /*!< Clock error interrupt status */
+#define LL_RNG_SR_SEIS RNG_SR_SEIS /*!< Seed error interrupt status */
+/**
+ * @}
+ */
+
+/** @defgroup RNG_LL_EC_IT IT Defines
+ * @brief IT defines which can be used with LL_RNG_ReadReg and LL_RNG_WriteReg macros
+ * @{
+ */
+#define LL_RNG_CR_IE RNG_CR_IE /*!< RNG Interrupt enable */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/** @defgroup RNG_LL_Exported_Macros RNG Exported Macros
+ * @{
+ */
+
+/** @defgroup RNG_LL_EM_WRITE_READ Common Write and read registers Macros
+ * @{
+ */
+
+/**
+ * @brief Write a value in RNG register
+ * @param __INSTANCE__ RNG Instance
+ * @param __REG__ Register to be written
+ * @param __VALUE__ Value to be written in the register
+ * @retval None
+ */
+#define LL_RNG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
+
+/**
+ * @brief Read a value in RNG register
+ * @param __INSTANCE__ RNG Instance
+ * @param __REG__ Register to be read
+ * @retval Register value
+ */
+#define LL_RNG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup RNG_LL_Exported_Functions RNG Exported Functions
+ * @{
+ */
+/** @defgroup RNG_LL_EF_Configuration RNG Configuration functions
+ * @{
+ */
+
+/**
+ * @brief Enable Random Number Generation
+ * @rmtoll CR RNGEN LL_RNG_Enable
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_Enable(RNG_TypeDef *RNGx)
+{
+ SET_BIT(RNGx->CR, RNG_CR_RNGEN);
+}
+
+/**
+ * @brief Disable Random Number Generation
+ * @rmtoll CR RNGEN LL_RNG_Disable
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_Disable(RNG_TypeDef *RNGx)
+{
+ CLEAR_BIT(RNGx->CR, RNG_CR_RNGEN);
+}
+
+/**
+ * @brief Check if Random Number Generator is enabled
+ * @rmtoll CR RNGEN LL_RNG_IsEnabled
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsEnabled(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->CR, RNG_CR_RNGEN) == (RNG_CR_RNGEN));
+}
+
+#if defined(RNG_CR_CED)
+/**
+ * @brief Enable RNG Clock Error Detection
+ * @rmtoll CR CED LL_RNG_EnableClkErrorDetect
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_EnableClkErrorDetect(RNG_TypeDef *RNGx)
+{
+ CLEAR_BIT(RNGx->CR, RNG_CR_CED);
+}
+
+/**
+ * @brief Disable RNG Clock Error Detection
+ * @rmtoll CR CED LL_RNG_DisableClkErrorDetect
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_DisableClkErrorDetect(RNG_TypeDef *RNGx)
+{
+ SET_BIT(RNGx->CR, RNG_CR_CED);
+}
+
+/**
+ * @brief Check if RNG Clock Error Detection is enabled
+ * @rmtoll CR CED LL_RNG_IsEnabledClkErrorDetect
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsEnabledClkErrorDetect(RNG_TypeDef *RNGx)
+{
+ return (!(READ_BIT(RNGx->CR, RNG_CR_CED) == (RNG_CR_CED)));
+}
+#endif /* defined(RNG_CR_CED) */
+
+
+/**
+ * @}
+ */
+
+/** @defgroup RNG_LL_EF_FLAG_Management FLAG Management
+ * @{
+ */
+
+/**
+ * @brief Indicate if the RNG Data ready Flag is set or not
+ * @rmtoll SR DRDY LL_RNG_IsActiveFlag_DRDY
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_DRDY(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->SR, RNG_SR_DRDY) == (RNG_SR_DRDY));
+}
+
+/**
+ * @brief Indicate if the Clock Error Current Status Flag is set or not
+ * @rmtoll SR CECS LL_RNG_IsActiveFlag_CECS
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_CECS(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->SR, RNG_SR_CECS) == (RNG_SR_CECS));
+}
+
+/**
+ * @brief Indicate if the Seed Error Current Status Flag is set or not
+ * @rmtoll SR SECS LL_RNG_IsActiveFlag_SECS
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_SECS(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->SR, RNG_SR_SECS) == (RNG_SR_SECS));
+}
+
+/**
+ * @brief Indicate if the Clock Error Interrupt Status Flag is set or not
+ * @rmtoll SR CEIS LL_RNG_IsActiveFlag_CEIS
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_CEIS(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->SR, RNG_SR_CEIS) == (RNG_SR_CEIS));
+}
+
+/**
+ * @brief Indicate if the Seed Error Interrupt Status Flag is set or not
+ * @rmtoll SR SEIS LL_RNG_IsActiveFlag_SEIS
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsActiveFlag_SEIS(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->SR, RNG_SR_SEIS) == (RNG_SR_SEIS));
+}
+
+/**
+ * @brief Clear Clock Error interrupt Status (CEIS) Flag
+ * @rmtoll SR CEIS LL_RNG_ClearFlag_CEIS
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_ClearFlag_CEIS(RNG_TypeDef *RNGx)
+{
+ WRITE_REG(RNGx->SR, ~RNG_SR_CEIS);
+}
+
+/**
+ * @brief Clear Seed Error interrupt Status (SEIS) Flag
+ * @rmtoll SR SEIS LL_RNG_ClearFlag_SEIS
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_ClearFlag_SEIS(RNG_TypeDef *RNGx)
+{
+ WRITE_REG(RNGx->SR, ~RNG_SR_SEIS);
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RNG_LL_EF_IT_Management IT Management
+ * @{
+ */
+
+/**
+ * @brief Enable Random Number Generator Interrupt
+ * (applies for either Seed error, Clock Error or Data ready interrupts)
+ * @rmtoll CR IE LL_RNG_EnableIT
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_EnableIT(RNG_TypeDef *RNGx)
+{
+ SET_BIT(RNGx->CR, RNG_CR_IE);
+}
+
+/**
+ * @brief Disable Random Number Generator Interrupt
+ * (applies for either Seed error, Clock Error or Data ready interrupts)
+ * @rmtoll CR IE LL_RNG_DisableIT
+ * @param RNGx RNG Instance
+ * @retval None
+ */
+__STATIC_INLINE void LL_RNG_DisableIT(RNG_TypeDef *RNGx)
+{
+ CLEAR_BIT(RNGx->CR, RNG_CR_IE);
+}
+
+/**
+ * @brief Check if Random Number Generator Interrupt is enabled
+ * (applies for either Seed error, Clock Error or Data ready interrupts)
+ * @rmtoll CR IE LL_RNG_IsEnabledIT
+ * @param RNGx RNG Instance
+ * @retval State of bit (1 or 0).
+ */
+__STATIC_INLINE uint32_t LL_RNG_IsEnabledIT(RNG_TypeDef *RNGx)
+{
+ return (READ_BIT(RNGx->CR, RNG_CR_IE) == (RNG_CR_IE));
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup RNG_LL_EF_Data_Management Data Management
+ * @{
+ */
+
+/**
+ * @brief Return32-bit Random Number value
+ * @rmtoll DR RNDATA LL_RNG_ReadRandData32
+ * @param RNGx RNG Instance
+ * @retval Generated 32-bit random value
+ */
+__STATIC_INLINE uint32_t LL_RNG_ReadRandData32(RNG_TypeDef *RNGx)
+{
+ return (uint32_t)(READ_REG(RNGx->DR));
+}
+
+/**
+ * @}
+ */
+
+#if defined(USE_FULL_LL_DRIVER)
+/** @defgroup RNG_LL_EF_Init Initialization and de-initialization functions
+ * @{
+ */
+#if defined(RNG_CR_CED)
+ErrorStatus LL_RNG_Init(RNG_TypeDef *RNGx, LL_RNG_InitTypeDef *RNG_InitStruct);
+void LL_RNG_StructInit(LL_RNG_InitTypeDef *RNG_InitStruct);
+#endif /* defined(RNG_CR_CED) */
+ErrorStatus LL_RNG_DeInit(RNG_TypeDef *RNGx);
+
+/**
+ * @}
+ */
+#endif /* USE_FULL_LL_DRIVER */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* defined(RNG) */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32L4xx_LL_RNG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/targets/stm32l442/src/flash.h b/targets/stm32l442/src/flash.h
index 67db60e..e4841df 100644
--- a/targets/stm32l442/src/flash.h
+++ b/targets/stm32l442/src/flash.h
@@ -1,5 +1,5 @@
-#ifndef _FLASH_H_H
-#define _FLASH_H_H
+#ifndef _FLASH_H_
+#define _FLASH_H_
void flash_erase_page(uint8_t page);
void flash_write_dword(uint32_t addr, uint64_t data);
diff --git a/targets/stm32l442/src/init.c b/targets/stm32l442/src/init.c
index 524d34f..9d366da 100644
--- a/targets/stm32l442/src/init.c
+++ b/targets/stm32l442/src/init.c
@@ -11,6 +11,7 @@
#include "stm32l4xx_ll_usart.h"
#include "stm32l4xx_ll_bus.h"
#include "stm32l4xx_ll_tim.h"
+#include "stm32l4xx_ll_rng.h"
/* USER CODE BEGIN Includes */
@@ -30,6 +31,7 @@ static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM6_Init(void);
+static void MX_RNG_Init(void);
#define Error_Handler() _Error_Handler(__FILE__,__LINE__)
void _Error_Handler(char *file, int line);
@@ -63,6 +65,7 @@ void hw_init(void)
MX_TIM2_Init();
MX_TIM6_Init();
+ MX_RNG_Init();
TIM6->SR = 0;
__enable_irq();
@@ -299,3 +302,14 @@ static void MX_TIM6_Init(void)
// Start immediately
LL_TIM_EnableCounter(TIM6);
}
+
+/* RNG init function */
+static void MX_RNG_Init(void)
+{
+
+ /* Peripheral clock enable */
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_RNG);
+
+ LL_RNG_Enable(RNG);
+
+}
diff --git a/targets/stm32l442/src/main.c b/targets/stm32l442/src/main.c
index a403987..7dd5797 100644
--- a/targets/stm32l442/src/main.c
+++ b/targets/stm32l442/src/main.c
@@ -15,13 +15,14 @@
#include "app.h"
#include "flash.h"
+#include "rng.h"
#define Error_Handler() _Error_Handler(__FILE__,__LINE__)
#define LED_PIN_G LL_GPIO_PIN_0
#define LED_PIN_B LL_GPIO_PIN_1
#define LED_PIN_R LL_GPIO_PIN_2
-#define LED_PORT GPIOA
+#define LED_PORT GPIOA
void hw_init(void);
@@ -140,11 +141,22 @@ void TIM6_DAC_IRQHandler()
__65_seconds += 1;
}
+void dump_hex(uint8_t * b, int len)
+{
+ while(len--)
+ {
+ printf("%02x ", *b++);
+ }
+ printf("\r\n");
+}
+
int main(void)
{
uint8_t str[] = "YouCompleteMe: a code-completion engine for Vim";
- uint8_t buf[500];
+ uint8_t buf[5000];
uint32_t i = 0;
+ float ent;
+ float test = 1235.889944f;
hw_init();
printf("hello solo\r\n");
@@ -169,6 +181,12 @@ int main(void)
uint32_t t2 = millis();
printf("100 ms delay (%lu)\r\n",t2-t1);
+
+ ent = rng_test(64 * 1024);
+
+ printf("entropy of 64KB from RNG: %.6f\r\n", ent);
+ printf("test float: %.2f\r\n", test);
+
// Test PWM + weighting of RGB
test_colors();
diff --git a/targets/stm32l442/src/rng.c b/targets/stm32l442/src/rng.c
new file mode 100644
index 0000000..526a387
--- /dev/null
+++ b/targets/stm32l442/src/rng.c
@@ -0,0 +1,85 @@
+#include
+#include
+#include
+#include
+#include "stm32l4xx_ll_rng.h"
+
+#include "rng.h"
+
+int __errno = 0;
+
+void rng_get_bytes(uint8_t * dst, size_t sz)
+{
+ uint8_t r[8];
+ unsigned int i,j;
+ for (i = 0; i < sz; i += 4)
+ {
+ while( !LL_RNG_IsActiveFlag_DRDY(RNG) )
+ ;
+ *(uint32_t*)&r = LL_RNG_ReadRandData32(RNG);
+
+ if (RNG->SR & 0x66)
+ {
+ printf("Error RNG: %02lx\r\n", RNG->SR);
+ exit(1);
+ }
+
+ for (j = 0; j < 4; j++)
+ {
+ if ((i + j) > sz)
+ {
+ return;
+ }
+ dst[i + j] = r[j];
+ }
+ }
+}
+
+float shannon_entropy(float * p, size_t sz)
+{
+
+ unsigned int i;
+ float entropy = 0.0f;
+
+ for(i=0; i < sz; i++)
+ {
+ if (p[i] > 0.0)
+ {
+ entropy -= p[i] * (float) log( (double) p[i]);
+ }
+ }
+
+ entropy = entropy / (float) log ((double) 2.0);
+
+ return entropy;
+}
+
+// Measure shannon entropy of RNG
+float rng_test(size_t n)
+{
+ unsigned int i;
+ int sz = 0;
+ uint8_t buf[4];
+ int counts[256];
+ float p[256];
+
+ memset(counts, 0, sizeof(counts));
+
+ for(i=0; i < n; i+=4)
+ {
+ rng_get_bytes(buf, 4);
+ sz += 4;
+
+ counts[buf[0]]++;
+ counts[buf[1]]++;
+ counts[buf[2]]++;
+ counts[buf[3]]++;
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ p[i] = ((float)counts[i])/sz;
+ }
+
+ return shannon_entropy(p, 256);
+}
diff --git a/targets/stm32l442/src/rng.h b/targets/stm32l442/src/rng.h
new file mode 100644
index 0000000..d3060db
--- /dev/null
+++ b/targets/stm32l442/src/rng.h
@@ -0,0 +1,9 @@
+#ifndef _RNG_H_
+#define _RNG_H_
+#include
+
+void rng_get_bytes(uint8_t * dst, size_t sz);
+float shannon_entropy(float * p, size_t sz);
+float rng_test(size_t n);
+
+#endif