utzig closed pull request #1104: Add STM32 TRNG driver
URL: https://github.com/apache/mynewt-core/pull/1104
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/hw/bsp/nucleo-f767zi/include/bsp/stm32f7xx_hal_conf.h 
b/hw/bsp/nucleo-f767zi/include/bsp/stm32f7xx_hal_conf.h
index da2e39a6b..28a234e47 100644
--- a/hw/bsp/nucleo-f767zi/include/bsp/stm32f7xx_hal_conf.h
+++ b/hw/bsp/nucleo-f767zi/include/bsp/stm32f7xx_hal_conf.h
@@ -72,7 +72,6 @@
 #define HAL_MDIOS_MODULE_ENABLED
 #define HAL_PCD_MODULE_ENABLED
 #define HAL_HCD_MODULE_ENABLED
-#define HAL_RNG_MODULE_ENABLED   
 #define HAL_SAI_MODULE_ENABLED   
 #define HAL_SD_MODULE_ENABLED  
 #define HAL_SPDIFRX_MODULE_ENABLED
@@ -81,22 +80,23 @@
 #define HAL_WWDG_MODULE_ENABLED  
 */
 #define HAL_DMA_MODULE_ENABLED
-#define HAL_ETH_MODULE_ENABLED 
-#define HAL_FLASH_MODULE_ENABLED 
+#define HAL_ETH_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
 #define HAL_SRAM_MODULE_ENABLED
 #define HAL_GPIO_MODULE_ENABLED
 #define HAL_I2C_MODULE_ENABLED
-#define HAL_IWDG_MODULE_ENABLED 
+#define HAL_IWDG_MODULE_ENABLED
 #define HAL_LPTIM_MODULE_ENABLED
 #define HAL_PWR_MODULE_ENABLED
-#define HAL_QSPI_MODULE_ENABLED   
-#define HAL_RCC_MODULE_ENABLED 
+#define HAL_QSPI_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
 #define HAL_RTC_MODULE_ENABLED
-#define HAL_SPI_MODULE_ENABLED   
-#define HAL_TIM_MODULE_ENABLED   
-#define HAL_UART_MODULE_ENABLED 
-#define HAL_USART_MODULE_ENABLED 
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
 #define HAL_CORTEX_MODULE_ENABLED
+#define HAL_RNG_MODULE_ENABLED
 
 /* ########################## HSE/HSI Values adaptation ##################### 
*/
 /**
diff --git a/hw/bsp/nucleo-f767zi/src/hal_bsp.c 
b/hw/bsp/nucleo-f767zi/src/hal_bsp.c
index 1b3523f0d..b7e0d1e9d 100644
--- a/hw/bsp/nucleo-f767zi/src/hal_bsp.c
+++ b/hw/bsp/nucleo-f767zi/src/hal_bsp.c
@@ -20,6 +20,11 @@
 
 #include "os/mynewt.h"
 
+#if MYNEWT_VAL(TRNG)
+#include "trng/trng.h"
+#include "trng_stm32/trng_stm32.h"
+#endif
+
 #if MYNEWT_VAL(UART_0)
 #include <uart/uart.h>
 #include <uart_hal/uart_hal.h>
@@ -49,6 +54,10 @@
 
 #include "bsp/bsp.h"
 
+#if MYNEWT_VAL(TRNG)
+static struct trng_dev os_bsp_trng;
+#endif
+
 #if MYNEWT_VAL(UART_0)
 static struct uart_dev hal_uart0;
 
@@ -175,6 +184,12 @@ hal_bsp_init(void)
 
     hal_system_clock_start();
 
+#if MYNEWT_VAL(TRNG)
+    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
+                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
+    assert(rc == 0);
+#endif
+
 #if MYNEWT_VAL(UART_0)
     rc = os_dev_create((struct os_dev *) &hal_uart0, "uart0",
       OS_DEV_INIT_PRIMARY, 0, uart_hal_init, (void *)&uart_cfg[0]);
diff --git a/hw/bsp/nucleo-f767zi/src/system_stm32f7xx.c 
b/hw/bsp/nucleo-f767zi/src/system_stm32f7xx.c
index dbf98d654..55a38d922 100644
--- a/hw/bsp/nucleo-f767zi/src/system_stm32f7xx.c
+++ b/hw/bsp/nucleo-f767zi/src/system_stm32f7xx.c
@@ -64,6 +64,11 @@
   */
 
 #include "stm32f7xx.h"
+#include "stm32f7xx_hal_gpio_ex.h"
+#include "stm32f7xx_hal_flash.h"
+#include "stm32f7xx_hal_rcc.h"
+#include "stm32f7xx_hal_pwr.h"
+#include "stm32f7xx_hal_pwr_ex.h"
 #include "mcu/cmsis_nvic.h"
 
 #if !defined  (HSE_VALUE) 
@@ -134,6 +139,7 @@
 /** @addtogroup STM32F7xx_System_Private_FunctionPrototypes
   * @{
   */
+static void SystemClock_Config(void);
 
 /**
   * @}
@@ -175,6 +181,9 @@ void SystemInit(void)
   /* Disable all interrupts */
   RCC->CIR = 0x00000000;
 
+  /* Configure System Clock */
+  SystemClock_Config();
+
   /* Relocate the vector table */
   NVIC_Relocate();
 }
@@ -263,6 +272,56 @@ void SystemCoreClockUpdate(void)
   SystemCoreClock >>= tmp;
 }
 
+/** System Clock Configuration.
+ *
+ * Configures CPU to run at 168 MHz.
+ *
+ * ((16 MHz / 10) * 210) / 2 = 168 MHz
+ */
+void SystemClock_Config(void)
+{
+
+    RCC_OscInitTypeDef RCC_OscInitStruct;
+    RCC_ClkInitTypeDef RCC_ClkInitStruct;
+
+    SCB_EnableICache();
+
+    /**Configure the main internal regulator output voltage
+    */
+    __HAL_RCC_PWR_CLK_ENABLE();
+
+    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
+
+    /* Initializes the CPU, AHB and APB busses clocks */
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+    RCC_OscInitStruct.HSICalibrationValue = 16;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
+    RCC_OscInitStruct.PLL.PLLM = 10;
+    RCC_OscInitStruct.PLL.PLLN = 210;
+    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+    RCC_OscInitStruct.PLL.PLLQ = 2;
+    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+    {
+        /* TODO: Throw error */
+    }
+
+    /* Initializes the CPU, AHB and APB busses clocks */
+    RCC_ClkInitStruct.ClockType = \
+        RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | \
+        RCC_CLOCKTYPE_PCLK2;
+    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
+    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
+
+    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
+    {
+        /* TODO: Throw error */
+    }
+}
+
 /**
   * @}
   */
diff --git a/hw/bsp/olimex_stm32-e407_devboard/include/bsp/stm32f4xx_hal_conf.h 
b/hw/bsp/olimex_stm32-e407_devboard/include/bsp/stm32f4xx_hal_conf.h
index 0b0057f5b..12e645621 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/include/bsp/stm32f4xx_hal_conf.h
+++ b/hw/bsp/olimex_stm32-e407_devboard/include/bsp/stm32f4xx_hal_conf.h
@@ -75,7 +75,6 @@
 #define HAL_LTDC_MODULE_ENABLED
 #define HAL_PWR_MODULE_ENABLED
 #define HAL_RCC_MODULE_ENABLED
-#define HAL_RNG_MODULE_ENABLED
 #define HAL_RTC_MODULE_ENABLED
 /* #define HAL_SAI_MODULE_ENABLED */
 #define HAL_SD_MODULE_ENABLED
@@ -99,6 +98,7 @@
 #define HAL_IWDG_MODULE_ENABLED
 #define HAL_PWR_MODULE_ENABLED
 #define HAL_RCC_MODULE_ENABLED
+#define HAL_RNG_MODULE_ENABLED
 #define HAL_SPI_MODULE_ENABLED
 #define HAL_TIM_MODULE_ENABLED
 #define HAL_CORTEX_MODULE_ENABLED
diff --git a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c 
b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
index 09b25a29a..bda94dd5c 100644
--- a/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
+++ b/hw/bsp/olimex_stm32-e407_devboard/src/hal_bsp.c
@@ -25,6 +25,10 @@
 #include "stm32f4xx_hal_dma.h"
 #include "stm32f4xx_hal_adc.h"
 #include "flash_map/flash_map.h"
+#if MYNEWT_VAL(TRNG)
+#include "trng/trng.h"
+#include "trng_stm32/trng_stm32.h"
+#endif
 #if MYNEWT_VAL(UART_0)
 #include "uart/uart.h"
 #include "uart_hal/uart_hal.h"
@@ -48,6 +52,10 @@
 #include "mcu/stm32f4_bsp.h"
 #include "mcu/stm32f4xx_mynewt_hal.h"
 
+#if MYNEWT_VAL(TRNG)
+static struct trng_dev os_bsp_trng;
+#endif
+
 #if MYNEWT_VAL(UART_0)
 struct uart_dev hal_uart0;
 #endif
@@ -376,6 +384,13 @@ hal_bsp_init(void)
     int rc;
 
     (void)rc;
+
+#if MYNEWT_VAL(TRNG)
+    rc = os_dev_create(&os_bsp_trng.dev, "trng", OS_DEV_INIT_KERNEL,
+                       OS_DEV_INIT_PRIO_DEFAULT, stm32_trng_dev_init, NULL);
+    assert(rc == 0);
+#endif
+
 #if MYNEWT_VAL(SPI_0_MASTER)
     rc = hal_spi_init(0, &spi0_cfg, HAL_SPI_TYPE_MASTER);
     assert(rc == 0);
diff --git a/hw/drivers/trng/trng_stm32/include/trng_stm32/trng_stm32.h 
b/hw/drivers/trng/trng_stm32/include/trng_stm32/trng_stm32.h
new file mode 100644
index 000000000..7beaef5bd
--- /dev/null
+++ b/hw/drivers/trng/trng_stm32/include/trng_stm32/trng_stm32.h
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef __TRNG_STM32_H__
+#define __TRNG_STM32_H__
+
+#include "trng/trng.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int stm32_trng_dev_init(struct os_dev *dev, void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TRNG_STM32_H__ */
diff --git a/hw/drivers/trng/trng_stm32/pkg.yml 
b/hw/drivers/trng/trng_stm32/pkg.yml
new file mode 100644
index 000000000..edd928a38
--- /dev/null
+++ b/hw/drivers/trng/trng_stm32/pkg.yml
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+pkg.name: hw/drivers/trng/trng_stm32
+pkg.description: TRNG driver for STM32
+pkg.author: "Apache Mynewt <d...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+
+pkg.apis:
+    - TRNG_HW_IMPL
+pkg.deps:
+   - hw/drivers/trng
diff --git a/hw/drivers/trng/trng_stm32/src/trng_stm32.c 
b/hw/drivers/trng/trng_stm32/src/trng_stm32.c
new file mode 100644
index 000000000..f300970ad
--- /dev/null
+++ b/hw/drivers/trng/trng_stm32/src/trng_stm32.c
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#include <string.h>
+#include "mcu/cmsis_nvic.h"
+#include "mcu/stm32_hal.h"
+#include "trng/trng.h"
+#include "trng_stm32/trng_stm32.h"
+
+static uint8_t rng_cache[ MYNEWT_VAL(STM32_TRNG_CACHE_LEN) ];
+static uint16_t rng_cache_out;
+static uint16_t rng_cache_in;
+
+static RNG_HandleTypeDef g_hrng;
+
+static void
+stm32_rng_start(void)
+{
+    __HAL_RNG_ENABLE(&g_hrng);
+    __HAL_RNG_ENABLE_IT(&g_hrng);
+}
+
+static void
+stm32_rng_stop(void)
+{
+    __HAL_RNG_DISABLE(&g_hrng);
+}
+
+static void
+stm32_rng_irq_handler(void)
+{
+    int8_t i;
+
+    HAL_RNG_IRQHandler(&g_hrng);
+    if (g_hrng.State == HAL_RNG_STATE_READY) {
+        for (i = 24; i >= 0; i -= 8) {
+            rng_cache[rng_cache_in++] = (g_hrng.RandomNumber >> i) & 0xff;
+
+            if (rng_cache_in >= sizeof(rng_cache)) {
+                rng_cache_in = 0;
+            }
+
+            if ((rng_cache_in + 1) % sizeof(rng_cache) == rng_cache_out) {
+                stm32_rng_stop();
+                return;
+            }
+        }
+    }
+    __HAL_RNG_ENABLE_IT(&g_hrng);
+}
+
+static size_t
+stm32_trng_read(struct trng_dev *trng, void *ptr, size_t size)
+{
+    os_sr_t sr;
+    size_t num_read;
+
+    OS_ENTER_CRITICAL(sr);
+
+    if (rng_cache_out <= rng_cache_in) {
+        size = min(size, rng_cache_in - rng_cache_out);
+        memcpy(ptr, &rng_cache[rng_cache_out], size);
+        num_read = size;
+    } else if (rng_cache_out + size <= sizeof(rng_cache)) {
+        memcpy(ptr, &rng_cache[rng_cache_out], size);
+        num_read = size;
+    } else {
+        num_read = sizeof(rng_cache) - rng_cache_out;
+        memcpy(ptr, &rng_cache[rng_cache_out], num_read);
+
+        size -= num_read;
+        ptr += num_read;
+
+        size = min(size, rng_cache_in);
+        memcpy(ptr, rng_cache, size);
+        num_read += size;
+    }
+
+    rng_cache_out += num_read;
+    rng_cache_out %= sizeof(rng_cache);
+
+    if (num_read > 0) {
+        stm32_rng_start();
+    }
+
+    OS_EXIT_CRITICAL(sr);
+
+    return num_read;
+}
+
+static uint32_t
+stm32_trng_get_u32(struct trng_dev *trng)
+{
+    union {
+        uint32_t v32;
+        uint8_t v8[4];
+    } val;
+    size_t num;
+
+    num = stm32_trng_read(trng, &val.v8, sizeof(val.v8));
+    while (num < sizeof(val.v8)) {
+        os_sched(NULL);
+        num += stm32_trng_read(trng, &val.v8[num], sizeof(val.v8) - num);
+    }
+
+    return val.v32;
+}
+
+static int
+stm32_trng_dev_open(struct os_dev *dev, uint32_t wait, void *arg)
+{
+    struct trng_dev *trng;
+
+    trng = (struct trng_dev *)dev;
+    assert(trng);
+
+    if (!(dev->od_flags & OS_DEV_F_STATUS_OPEN)) {
+        rng_cache_out = 0;
+        rng_cache_in = 0;
+
+        __HAL_RCC_RNG_CLK_ENABLE();
+
+        g_hrng.Instance = RNG;
+        g_hrng.State = HAL_RNG_STATE_BUSY;
+        HAL_RNG_Init(&g_hrng);
+
+        NVIC_SetPriority(RNG_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
+        NVIC_SetVector(RNG_IRQn, (uint32_t)stm32_rng_irq_handler);
+        NVIC_EnableIRQ(RNG_IRQn);
+
+        stm32_rng_start();
+    }
+
+    return 0;
+}
+
+int
+stm32_trng_dev_init(struct os_dev *dev, void *arg)
+{
+    struct trng_dev *trng;
+
+    trng = (struct trng_dev *)dev;
+    assert(trng);
+
+    OS_DEV_SETHANDLERS(dev, stm32_trng_dev_open, NULL);
+
+    trng->interface.get_u32 = stm32_trng_get_u32;
+    trng->interface.read = stm32_trng_read;
+
+    return 0;
+}
diff --git a/hw/drivers/trng/trng_stm32/syscfg.yml 
b/hw/drivers/trng/trng_stm32/syscfg.yml
new file mode 100644
index 000000000..e8fb84aba
--- /dev/null
+++ b/hw/drivers/trng/trng_stm32/syscfg.yml
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+# Package: hw/drivers/trng/trng_stm32
+
+syscfg.defs:
+    STM32_TRNG_CACHE_LEN:
+        description: 'Internal cache length, shall be power of 2'
+        value: 32
diff --git a/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h 
b/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h
index 0eb8ecec2..37f49fe96 100644
--- a/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f4xx/include/mcu/stm32_hal.h
@@ -71,6 +71,9 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_trng */
+#include "stm32f4xx_hal_rng.h"
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f4xx/syscfg.yml b/hw/mcu/stm/stm32f4xx/syscfg.yml
index ad8fb5427..0c92552df 100644
--- a/hw/mcu/stm/stm32f4xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f4xx/syscfg.yml
@@ -43,3 +43,7 @@ syscfg.defs:
         value:  0
         restrictions:
             - "!SPI_0_MASTER"
+
+    TRNG:
+        description: 'True Random Number Generator (RNG)'
+        value: 0
diff --git a/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h 
b/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h
index 3fa0ccb81..10241d44c 100644
--- a/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h
+++ b/hw/mcu/stm/stm32f7xx/include/mcu/stm32_hal.h
@@ -75,6 +75,9 @@ struct stm32_hal_spi_cfg {
 
 #define STM32_HAL_TIMER_MAX     (3)
 
+/* hal_trng */
+#include "stm32f7xx_hal_rng.h"
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/mcu/stm/stm32f7xx/syscfg.yml b/hw/mcu/stm/stm32f7xx/syscfg.yml
index 0a39551f5..d671e4bad 100644
--- a/hw/mcu/stm/stm32f7xx/syscfg.yml
+++ b/hw/mcu/stm/stm32f7xx/syscfg.yml
@@ -44,3 +44,7 @@ syscfg.defs:
     I2C_0:
         description: 'I2C (TWI) interface 0'
         value:  0
+
+    TRNG:
+        description: 'True Random Number Generator (RNG)'
+        value: 0


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to