From a5250662fa6765d27c3696d425c476173faf1afc Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Fri, 17 May 2019 18:46:30 +0000 Subject: [PATCH] Merged in raiden00/nuttx_lora/lora (pull request #872) Port AES and RND to STM32 M0 + some improvements arch/arm/src/stm32f0l0/stm32_rng.c: change the function names to use the stm32_rng prefix arch/arm/src/stm32f0l0/stm32_usbdev.c: move HSI48 enable to stm32xx_rcc.c arch/arm/src/stm32f0l0: add support for AES arch/arm/src/stm32f0l0: add support for RND arch/arm/src/stm32f0l0: add HSI48 support for L0 Approved-by: Gregory Nutt --- arch/arm/include/stm32f0l0/chip.h | 6 + arch/arm/src/stm32/stm32_aes.c | 3 +- arch/arm/src/stm32/stm32_rng.c | 32 +- arch/arm/src/stm32f0l0/Kconfig | 27 ++ arch/arm/src/stm32f0l0/Make.defs | 8 + arch/arm/src/stm32f0l0/hardware/stm32_aes.h | 114 ++++++ arch/arm/src/stm32f0l0/hardware/stm32_rng.h | 78 ++++ arch/arm/src/stm32f0l0/hardware/stm32f0_rcc.h | 2 + arch/arm/src/stm32f0l0/hardware/stm32l0_rcc.h | 132 +++---- .../src/stm32f0l0/hardware/stm32l0_syscfg.h | 16 + arch/arm/src/stm32f0l0/stm32_aes.c | 342 ++++++++++++++++++ arch/arm/src/stm32f0l0/stm32_aes.h | 63 ++++ arch/arm/src/stm32f0l0/stm32_hsi48.c | 45 ++- arch/arm/src/stm32f0l0/stm32_hsi48.h | 3 +- arch/arm/src/stm32f0l0/stm32_rcc.c | 12 + arch/arm/src/stm32f0l0/stm32_rng.c | 337 +++++++++++++++++ arch/arm/src/stm32f0l0/stm32_usbdev.c | 7 - arch/arm/src/stm32f0l0/stm32f0_rcc.c | 26 ++ arch/arm/src/stm32f0l0/stm32l0_rcc.c | 90 ++++- configs/b-l072z-lrwan1/include/board.h | 8 + configs/nucleo-l073rz/include/board.h | 8 + 21 files changed, 1245 insertions(+), 114 deletions(-) create mode 100644 arch/arm/src/stm32f0l0/hardware/stm32_aes.h create mode 100644 arch/arm/src/stm32f0l0/hardware/stm32_rng.h create mode 100644 arch/arm/src/stm32f0l0/stm32_aes.c create mode 100644 arch/arm/src/stm32f0l0/stm32_aes.h create mode 100644 arch/arm/src/stm32f0l0/stm32_rng.c diff --git a/arch/arm/include/stm32f0l0/chip.h b/arch/arm/include/stm32f0l0/chip.h index fa9446b728..8a79f75538 100644 --- a/arch/arm/include/stm32f0l0/chip.h +++ b/arch/arm/include/stm32f0l0/chip.h @@ -57,6 +57,7 @@ # define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */ # define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */ # define STM32_NI2C 2 /* Two I2C modules */ +# define STM32_NDMA 1 /* 1 DMA1, 7-channels */ # define STM32_NUSART 2 /* Two USARTs modules */ # define STM32_NCAN 0 /* No CAN controllers */ # define STM32_NUSBDEV 1 /* One USB full-speed device controller */ @@ -82,6 +83,7 @@ # define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */ # define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */ # define STM32_NI2C 2 /* Two I2C modules */ +# define STM32_NDMA 1 /* 1 DMA1, 7-channels */ # define STM32_NUSART 4 /* Four USARTs module */ # define STM32_NCAN 1 /* One CAN controller */ # define STM32_NUSBDEV 1 /* One USB full-speed device controller */ @@ -109,6 +111,7 @@ # define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */ # define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */ # define STM32_NI2C 2 /* Two I2C modules */ +# define STM32_NDMA 1 /* 1 DMA1, 7-channels */ # define STM32_NUSART 4 /* Four USARTs module */ # define STM32_NCAN 1 /* One CAN controller */ # define STM32_NUSBDEV 1 /* One USB full-speed device controller */ @@ -136,6 +139,7 @@ # define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */ # define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */ # define STM32_NI2C 2 /* Two I2C modules */ +# define STM32_NDMA 1 /* 1 DMA1, 7-channels */ # define STM32_NUSART 4 /* Four USARTs module */ # define STM32_NCAN 1 /* One CAN controller */ # define STM32_NUSBDEV 1 /* One USB full-speed device controller */ @@ -163,6 +167,7 @@ # define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */ # define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */ # define STM32_NI2C 2 /* Two I2C modules */ +# define STM32_NDMA 2 /* DMA1, DMA2 */ # define STM32_NUSART 6 /* Six USARTs modules */ # define STM32_NCAN 1 /* One CAN controller */ # define STM32_NUSBDEV 0 /* No USB full-speed device controller */ @@ -191,6 +196,7 @@ # define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */ # define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */ # define STM32_NI2C 2 /* Two I2C modules */ +# define STM32_NDMA 2 /* DMA1, DMA2 */ # define STM32_NUSART 8 /* Eight USARTs modules */ # define STM32_NCAN 1 /* One CAN controller */ # define STM32_NUSBDEV 0 /* No USB full-speed device controller */ diff --git a/arch/arm/src/stm32/stm32_aes.c b/arch/arm/src/stm32/stm32_aes.c index d72ab695af..5c46040e01 100644 --- a/arch/arm/src/stm32/stm32_aes.c +++ b/arch/arm/src/stm32/stm32_aes.c @@ -167,8 +167,7 @@ static void stm32aes_encryptblock(FAR void *block_out, FAR const void *block_in) in++; putreg32(*in, STM32_AES_DINR); - while (!(getreg32(STM32_AES_SR) & AES_SR_CCF)) - ; + while (!(getreg32(STM32_AES_SR) & AES_SR_CCF)); stm32aes_ccfc(); *out = getreg32(STM32_AES_DOUTR); diff --git a/arch/arm/src/stm32/stm32_rng.c b/arch/arm/src/stm32/stm32_rng.c index 15925563e8..5a81ac3fcb 100644 --- a/arch/arm/src/stm32/stm32_rng.c +++ b/arch/arm/src/stm32/stm32_rng.c @@ -62,10 +62,10 @@ ****************************************************************************/ static int stm32_rng_initialize(void); -static int stm32_interrupt(int irq, void *context, FAR void *arg); -static void stm32_enable(void); -static void stm32_disable(void); -static ssize_t stm32_read(struct file *filep, char *buffer, size_t); +static int stm32_rng_interrupt(int irq, void *context, FAR void *arg); +static void stm32_rng_enable(void); +static void stm32_rng_disable(void); +static ssize_t stm32_rng_read(struct file *filep, char *buffer, size_t); /**************************************************************************** * Private Types @@ -91,7 +91,7 @@ static const struct file_operations g_rngops = { 0, /* open */ 0, /* close */ - stm32_read, /* read */ + stm32_rng_read, /* read */ 0, /* write */ 0, /* seek */ 0 /* ioctl */ @@ -121,7 +121,7 @@ static int stm32_rng_initialize(void) nxsem_init(&g_rngdev.rd_devsem, 0, 1); - if (irq_attach(STM32_IRQ_RNG, stm32_interrupt, NULL)) + if (irq_attach(STM32_IRQ_RNG, stm32_rng_interrupt, NULL)) { /* We could not attach the ISR to the interrupt */ @@ -142,10 +142,10 @@ static int stm32_rng_initialize(void) } /**************************************************************************** - * Name: stm32_enable + * Name: stm32_rng_enable ****************************************************************************/ -static void stm32_enable(void) +static void stm32_rng_enable(void) { uint32_t regval; @@ -157,10 +157,10 @@ static void stm32_enable(void) } /**************************************************************************** - * Name: stm32_disable + * Name: stm32_rng_disable ****************************************************************************/ -static void stm32_disable(void) +static void stm32_rng_disable(void) { uint32_t regval; regval = getreg32(STM32_RNG_CR); @@ -169,10 +169,10 @@ static void stm32_disable(void) } /**************************************************************************** - * Name: stm32_interrupt + * Name: stm32_rng_interrupt ****************************************************************************/ -static int stm32_interrupt(int irq, void *context, FAR void *arg) +static int stm32_rng_interrupt(int irq, void *context, FAR void *arg) { uint32_t rngsr; uint32_t data; @@ -233,7 +233,7 @@ static int stm32_interrupt(int irq, void *context, FAR void *arg) { /* Buffer filled, stop further interrupts. */ - stm32_disable(); + stm32_rng_disable(); nxsem_post(&g_rngdev.rd_readsem); } @@ -241,10 +241,10 @@ static int stm32_interrupt(int irq, void *context, FAR void *arg) } /**************************************************************************** - * Name: stm32_read + * Name: stm32_rng_read ****************************************************************************/ -static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen) +static ssize_t stm32_rng_read(struct file *filep, char *buffer, size_t buflen) { int ret; @@ -270,7 +270,7 @@ static ssize_t stm32_read(struct file *filep, char *buffer, size_t buflen) /* Enable RNG with interrupts */ - stm32_enable(); + stm32_rng_enable(); /* Wait until the buffer is filled */ diff --git a/arch/arm/src/stm32f0l0/Kconfig b/arch/arm/src/stm32f0l0/Kconfig index 5c8895276c..03df7059b7 100644 --- a/arch/arm/src/stm32f0l0/Kconfig +++ b/arch/arm/src/stm32f0l0/Kconfig @@ -714,6 +714,7 @@ config STM32F0L0_STM32L0 bool default n select STM32F0L0_ENERGYLITE + select STM32F0L0_HAVE_VREFINT select STM32F0L0_HAVE_ADC1_DMA config STM32F0L0_STM32F03X @@ -782,11 +783,15 @@ config STM32F0L0_ENERGYLITE config ARCH_CHIP_STM32L071XX bool select STM32F0L0_STM32L0 + select STM32F0L0_HAVE_RNG + select STM32F0L0_HAVE_HSI48 select STM32F0L0_HAVE_USART4 config ARCH_CHIP_STM32L072XX bool select STM32F0L0_STM32L0 + select STM32F0L0_HAVE_RNG + select STM32F0L0_HAVE_HSI48 select STM32F0L0_HAVE_USART4 select STM32F0L0_HAVE_USART5 select STM32F0L0_HAVE_I2C2 @@ -795,6 +800,8 @@ config ARCH_CHIP_STM32L072XX config ARCH_CHIP_STM32L073XX bool select STM32F0L0_STM32L0 + select STM32F0L0_HAVE_RNG + select STM32F0L0_HAVE_HSI48 select STM32F0L0_HAVE_USART4 select STM32F0L0_HAVE_USART5 select STM32F0L0_HAVE_SPI2 @@ -827,6 +834,14 @@ menu "STM32 Peripheral Support" # These "hidden" settings determine is a peripheral option is available for the # selection MCU +config STM32F0L0_HAVE_AES + bool + default n + +config STM32F0L0_HAVE_VREFINT + bool + default n + config STM32F0L0_HAVE_CCM bool default n @@ -1032,6 +1047,18 @@ config STM32F0L0_CAN1 select STM32F0L0_CAN depends on STM32F0L0_HAVE_CAN1 +config STM32F0L0_AES + bool "128-bit AES" + default n + depends on STM32F0L0_HAVE_AES + select CRYPTO_AES192_DISABLE if CRYPTO_ALGTEST + select CRYPTO_AES256_DISABLE if CRYPTO_ALGTEST + +config STM32F0L0_VREFINT + bool "Enable VREFINT" + default n + depends on STM32F0L0_HAVE_VREFINT + config STM32F0L0_CEC bool "CEC" default n diff --git a/arch/arm/src/stm32f0l0/Make.defs b/arch/arm/src/stm32f0l0/Make.defs index 39b964e4f3..45c8792ffa 100644 --- a/arch/arm/src/stm32f0l0/Make.defs +++ b/arch/arm/src/stm32f0l0/Make.defs @@ -113,3 +113,11 @@ endif ifeq ($(CONFIG_STM32F0L0_ADC),y) CHIP_CSRCS += stm32_adc.c endif + +ifeq ($(CONFIG_STM32F0L0_AES),y) +CHIP_CSRCS += stm32_aes.c +endif + +ifeq ($(CONFIG_STM32F0L0_RNG),y) +CHIP_CSRCS += stm32_rng.c +endif diff --git a/arch/arm/src/stm32f0l0/hardware/stm32_aes.h b/arch/arm/src/stm32f0l0/hardware/stm32_aes.h new file mode 100644 index 0000000000..2d583056bd --- /dev/null +++ b/arch/arm/src/stm32f0l0/hardware/stm32_aes.h @@ -0,0 +1,114 @@ +/******************************************************************************************** + * arch/arm/src/stm32f0l0/hardware/stm32_aes.h + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * 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 NuttX 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 OWNER 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. + * + ********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32_AES_H +#define __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32_AES_H + +/******************************************************************************************** + * Included Files + ********************************************************************************************/ + +#include + +#include "chip.h" + +/******************************************************************************************** + * Pre-processor Definitions + ********************************************************************************************/ + +/* AES register offsets *********************************************************************/ + +#define STM32_AES_CR_OFFSET 0x0000 /* Control Register */ +#define STM32_AES_SR_OFFSET 0x0004 /* Status Register */ +#define STM32_AES_DINR_OFFSET 0x0008 /* Data Input Register */ +#define STM32_AES_DOUTR_OFFSET 0x000C /* Data Output Register */ +#define STM32_AES_KEYR0_OFFSET 0x0010 /* AES Key Register 0 */ +#define STM32_AES_KEYR1_OFFSET 0x0014 /* AES Key Register 1 */ +#define STM32_AES_KEYR2_OFFSET 0x0018 /* AES Key Register 2 */ +#define STM32_AES_KEYR3_OFFSET 0x001C /* AES Key Register 3 */ +#define STM32_AES_IVR0_OFFSET 0x0020 /* AES Initialization Vector Register 0 */ +#define STM32_AES_IVR1_OFFSET 0x0024 /* AES Initialization Vector Register 1 */ +#define STM32_AES_IVR2_OFFSET 0x0028 /* AES Initialization Vector Register 2 */ +#define STM32_AES_IVR3_OFFSET 0x002C /* AES Initialization Vector Register 3 */ + +/* AES register addresses *******************************************************************/ + +#define STM32_AES_CR (STM32_AES_BASE + STM32_AES_CR_OFFSET) +#define STM32_AES_SR (STM32_AES_BASE + STM32_AES_SR_OFFSET) +#define STM32_AES_DINR (STM32_AES_BASE + STM32_AES_DINR_OFFSET) +#define STM32_AES_DOUTR (STM32_AES_BASE + STM32_AES_DOUTR_OFFSET) +#define STM32_AES_KEYR0 (STM32_AES_BASE + STM32_AES_KEYR0_OFFSET) +#define STM32_AES_KEYR1 (STM32_AES_BASE + STM32_AES_KEYR1_OFFSET) +#define STM32_AES_KEYR2 (STM32_AES_BASE + STM32_AES_KEYR2_OFFSET) +#define STM32_AES_KEYR3 (STM32_AES_BASE + STM32_AES_KEYR3_OFFSET) +#define STM32_AES_IVR0 (STM32_AES_BASE + STM32_AES_IVR0_OFFSET) +#define STM32_AES_IVR1 (STM32_AES_BASE + STM32_AES_IVR1_OFFSET) +#define STM32_AES_IVR2 (STM32_AES_BASE + STM32_AES_IVR2_OFFSET) +#define STM32_AES_IVR3 (STM32_AES_BASE + STM32_AES_IVR3_OFFSET) + +/* AES register bit definitions *************************************************************/ + +/* AES_CR register */ + +#define AES_CR_EN (1 << 0) /* AES Enable */ +#define AES_CR_DATATYPE (1 << 1) /* Data type selection */ +# define AES_CR_DATATYPE_LE (0x0 << 1) +# define AES_CR_DATATYPE_BE (0x2 << 1) + +#define AES_CR_MODE (1 << 3) /* AES Mode of operation */ +# define AES_CR_MODE_ENCRYPT (0x0 << 3) +# define AES_CR_MODE_KEYDERIV (0x1 << 3) +# define AES_CR_MODE_DECRYPT (0x2 << 3) +# define AES_CR_MODE_DECRYPT_KEYDERIV (0x3 << 3) + +#define AES_CR_CHMOD (1 << 5) /* AES Chaining Mode */ +# define AES_CR_CHMOD_ECB (0x0 << 5) +# define AES_CR_CHMOD_CBC (0x1 << 5) +# define AES_CR_CHMOD_CTR (0x2 << 5) + +#define AES_CR_CCFC (1 << 7) /* Computation Complete Flag Clear */ +#define AES_CR_ERRC (1 << 8) /* Error Clear */ +#define AES_CR_CCIE (1 << 9) /* Computation Complete Interrupt Enable */ +#define AES_CR_ERRIE (1 << 10) /* Error Interrupt Enable */ +#define AES_CR_DMAINEN (1 << 11) /* DMA Enable Input */ +#define AES_CR_DMAOUTEN (1 << 12) /* DMA Enable Output */ + +/* AES_SR register */ + +#define AES_SR_CCF (1 << 0) /* Computation Complete Flag */ +#define AES_SR_RDERR (1 << 1) /* Read Error Flag */ +#define AES_SR_WRERR (1 << 2) /* Write Error Flag */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32_AES_H */ diff --git a/arch/arm/src/stm32f0l0/hardware/stm32_rng.h b/arch/arm/src/stm32f0l0/hardware/stm32_rng.h new file mode 100644 index 0000000000..081c18a0fb --- /dev/null +++ b/arch/arm/src/stm32f0l0/hardware/stm32_rng.h @@ -0,0 +1,78 @@ +/************************************************************************************ + * arch/arm/src/stm32f0l0/hardware/stm32_rng.h + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * 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 NuttX 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 OWNER 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_STC_STM32F0L0_HARDWARE_STM32_RNG_H +#define __ARCH_ARM_STC_STM32F0L0_HARDWARE_STM32_RNG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_RNG_CR_OFFSET 0x0000 /* RNG Control Register */ +#define STM32_RNG_SR_OFFSET 0x0004 /* RNG Status Register */ +#define STM32_RNG_DR_OFFSET 0x0008 /* RNG Data Register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_RNG_CR (STM32_RNG_BASE+STM32_RNG_CR_OFFSET) +#define STM32_RNG_SR (STM32_RNG_BASE+STM32_RNG_SR_OFFSET) +#define STM32_RNG_DR (STM32_RNG_BASE+STM32_RNG_DR_OFFSET) + +/* Register Bitfield Definitions ****************************************************/ + +/* RNG Control Register */ + +#define RNG_CR_RNGEN (1 << 2) /* Bit 2: RNG enable */ +#define RNG_CR_IE (1 << 3) /* Bit 3: Interrupt enable */ +#define RNG_CR_CE (1 << 5) /* Bit 5: Clock error detection */ + +/* RNG Status Register */ + +#define RNG_SR_DRDY (1 << 0) /* Bit 0: Data ready */ +#define RNG_SR_CECS (1 << 1) /* Bit 1: Clock error current status */ +#define RNG_SR_SECS (1 << 2) /* Bit 2: Seed error current status */ +#define RNG_SR_CEIS (1 << 5) /* Bit 5: Clock error interrupt status */ +#define RNG_SR_SEIS (1 << 6) /* Bit 6: Seed error interrupt status */ + +#endif /* __ARCH_ARM_STC_STM32F0L0_HARDWARE_STM32_RNG_H */ diff --git a/arch/arm/src/stm32f0l0/hardware/stm32f0_rcc.h b/arch/arm/src/stm32f0l0/hardware/stm32f0_rcc.h index b21f2977df..dca713026e 100644 --- a/arch/arm/src/stm32f0l0/hardware/stm32f0_rcc.h +++ b/arch/arm/src/stm32f0l0/hardware/stm32f0_rcc.h @@ -363,6 +363,8 @@ # define RCC_CFGR3_USART1SW_HSI (3 << RCC_CFGR3_USART1SW_SHIFT) /* HSI is USART1 clock */ #define RCC_CFGR3_CECSW (1 << 6) /* Bit 6: HDMI CEC clock source selection */ #define RCC_CFGR3_USBSW (1 << 7) /* Bit 7: USB clock source selection */ +#define RCC_CFGR3_CLK48_HSI48 0 +#define RCC_CFGR3_CLK48_PLL (1 << 7) #define RCC_CFGR3_ADCSW (1 << 8) /* Bit 8: ADC clock source selection */ #define RCC_CFGR3_USART2SW_SHIFT (16) /* Bits 16-17: USART2 clock source selection */ #define RCC_CFGR3_USART2SW_MASK (3 << RCC_CFGR3_USART2SW_SHIFT) diff --git a/arch/arm/src/stm32f0l0/hardware/stm32l0_rcc.h b/arch/arm/src/stm32f0l0/hardware/stm32l0_rcc.h index f021edc850..efd050338b 100644 --- a/arch/arm/src/stm32f0l0/hardware/stm32l0_rcc.h +++ b/arch/arm/src/stm32f0l0/hardware/stm32l0_rcc.h @@ -139,9 +139,9 @@ /* Clock recovery RC register */ -#define RCC_CRRCR_HSI48ON (0) /* Bits 0: 48MHz HSI clock enable */ -#define RCC_CRRCR_HSI48RDY (1) /* Bits 1: 48MHz HSI clock ready */ -#define RCC_CRRCR_HSI48DIV6EN (2) /* Bits 2: 48MHz HSI clock divided by 6 output enable */ +#define RCC_CRRCR_HSI48ON (1 << 0) /* Bits 0: 48MHz HSI clock enable */ +#define RCC_CRRCR_HSI48RDY (1 << 1) /* Bits 1: 48MHz HSI clock ready */ +#define RCC_CRRCR_HSI48DIV6EN (1 << 2) /* Bits 2: 48MHz HSI clock divided by 6 output enable */ /* Bits 3-7: Reserved */ #define RCC_CRRCR_HSI48CAL_SHIFT (8) /* Bits 8: 48 MHz HSI reset calibration */ #define RCC_CRRCR_HSI48CAL_MASK (0xff << RCC_CRRCR_HSI48CAL_SHIFT) @@ -272,18 +272,18 @@ /* AHB peripheral reset register */ -#define RCC_AHBRSTR_DMA1RST (0) /* Bit 0: DMA 1 reset */ - /* Bits 1-7: Reserved */ -#define RCC_AHBRSTR_MIFRST (8) /* Bit 8: Memory interface reset */ - /* Bits 9-11: Reserved */ -#define RCC_AHBRSTR_CRCRST (12) /* Bit 12: Memory interface reset */ - /* Bits 13-15: Reserved */ -#define RCC_AHBRSTR_TSCRST (12) /* Bit 12: Touch sensing reset */ - /* Bits 17-19: Reserved */ -#define RCC_AHBRSTR_RNGRST (20) /* Bit 20: Random number generator module reset */ - /* Bits 21-23: Reserved */ -#define RCC_AHBRSTR_CRYPRST (24) /* Bit 24: Crypto module reset */ - /* Bits 25-31: Reserved */ +#define RCC_AHBRSTR_DMA1RST (1 << 0) /* Bit 0: DMA 1 reset */ + /* Bits 1-7: Reserved */ +#define RCC_AHBRSTR_MIFRST (1 << 8) /* Bit 8: Memory interface reset */ + /* Bits 9-11: Reserved */ +#define RCC_AHBRSTR_CRCRST (1 << 12) /* Bit 12: Memory interface reset */ + /* Bits 13-15: Reserved */ +#define RCC_AHBRSTR_TSCRST (1 << 12) /* Bit 12: Touch sensing reset */ + /* Bits 17-19: Reserved */ +#define RCC_AHBRSTR_RNGRST (1 << 20) /* Bit 20: Random number generator module reset */ + /* Bits 21-23: Reserved */ +#define RCC_AHBRSTR_AESRST (1 << 24) /* Bit 24: Crypto module (AES) reset */ + /* Bits 25-31: Reserved */ /* APB2 Peripheral reset register */ @@ -342,18 +342,18 @@ /* AHB Peripheral Clock enable register */ -#define RCC_AHBENR_DMA1EN (0) /* Bit 0: DMA 1 clock enable */ - /* Bits 1-7: Reserved */ -#define RCC_AHBENR_MIFEN (8) /* Bit 8: Memory interface clock enable */ - /* Bits 9-11: Reserved */ -#define RCC_AHBENR_CRCEN (12) /* Bit 12: Memory interface clock enable */ - /* Bits 13-15: Reserved */ -#define RCC_AHBENR_TSCEN (12) /* Bit 12: Touch sensing clock enable */ - /* Bits 17-19: Reserved */ -#define RCC_AHBENR_RNGEN (20) /* Bit 20: Random number generator module clock enable */ - /* Bits 21-23: Reserved */ -#define RCC_AHBENR_CRYPEN (24) /* Bit 24: Crypto module clock enable */ - /* Bits 25-31: Reserved */ +#define RCC_AHBENR_DMA1EN (1 << 0) /* Bit 0: DMA 1 clock enable */ + /* Bits 1-7: Reserved */ +#define RCC_AHBENR_MIFEN (1 << 8) /* Bit 8: Memory interface clock enable */ + /* Bits 9-11: Reserved */ +#define RCC_AHBENR_CRCEN (1 << 12) /* Bit 12: Memory interface clock enable */ + /* Bits 13-15: Reserved */ +#define RCC_AHBENR_TSCEN (1 << 12) /* Bit 12: Touch sensing clock enable */ + /* Bits 17-19: Reserved */ +#define RCC_AHBENR_RNGEN (1 << 20) /* Bit 20: Random number generator module clock enable */ + /* Bits 21-23: Reserved */ +#define RCC_AHBENR_AESEN (1 << 24) /* Bit 24: Crypto module (AES) clock enable */ + /* Bits 25-31: Reserved */ /* APB2 Peripheral Clock enable register */ @@ -412,18 +412,18 @@ /* AHB peripheral clock enable in Sleep mode register */ -#define RCC_AHBSMENR_DMA1SMEN (0) /* Bit 0: DMA 1 clock enable in Sleep mode */ - /* Bits 1-7: Reserved */ -#define RCC_AHBSMENR_MIFSMEN (8) /* Bit 8: Memory interface clock enable in Sleep mode */ - /* Bits 9-11: Reserved */ -#define RCC_AHBSMENR_CRCSMEN (12) /* Bit 12: Memory interface clock enable in Sleep mode */ - /* Bits 13-15: Reserved */ -#define RCC_AHBSMENR_TSCSMEN (12) /* Bit 12: Touch sensing clock enable in Sleep mode */ - /* Bits 17-19: Reserved */ -#define RCC_AHBSMENR_RNGSMEN (20) /* Bit 20: Random number generator module clock enable in Sleep mode */ - /* Bits 21-23: Reserved */ -#define RCC_AHBSMENR_CRYPSMEN (24) /* Bit 24: Crypto module clock enable in Sleep mode */ - /* Bits 25-31: Reserved */ +#define RCC_AHBSMENR_DMA1SMEN (1 << 0) /* Bit 0: DMA 1 clock enable in Sleep mode */ + /* Bits 1-7: Reserved */ +#define RCC_AHBSMENR_MIFSMEN (1 << 8) /* Bit 8: Memory interface clock enable in Sleep mode */ + /* Bits 9-11: Reserved */ +#define RCC_AHBSMENR_CRCSMEN (1 << 12) /* Bit 12: Memory interface clock enable in Sleep mode */ + /* Bits 13-15: Reserved */ +#define RCC_AHBSMENR_TSCSMEN (1 << 12) /* Bit 12: Touch sensing clock enable in Sleep mode */ + /* Bits 17-19: Reserved */ +#define RCC_AHBSMENR_RNGSMEN (1 << 20) /* Bit 20: Random number generator module clock enable in Sleep mode */ + /* Bits 21-23: Reserved */ +#define RCC_AHBSMENR_AESSMEN (1 << 24) /* Bit 24: Crypto module (AES) clock enable in Sleep mode */ + /* Bits 25-31: Reserved */ /* APB2 peripheral clock enable in Sleep mode register */ @@ -509,46 +509,46 @@ # define RCC_CCIPR_LPTIM1SEL_HSI16 (2 << RCC_CCIPR_LPTIM1SEL_SHIFT) # define RCC_CCIPR_LPTIM1SEL_LSE (3 << RCC_CCIPR_LPTIM1SEL_SHIFT) /* Bits 20-25: Reserved */ -#define RCC_CCIPR_HSI48SEL_SHIFT (26) /* Bit 26: HSI48 clock source selection */ -#define RCC_CCIPR_HSI48SEL_MASK (1 << RCC_CCIPR_HSI48SEL_SHIFT) -# define RCC_CCIPR_HSI48SEL_PLL (0 << RCC_CCIPR_HSI48SEL_SHIFT) -# define RCC_CCIPR_HSI48SEL_RC48 (1 << RCC_CCIPR_HSI48SEL_SHIFT) +#define RCC_CCIPR_CLK48SEL_SHIFT (26) /* Bit 26: HSI48 clock source selection */ +#define RCC_CCIPR_CLK48SEL_MASK (1 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_PLL (0 << RCC_CCIPR_CLK48SEL_SHIFT) +# define RCC_CCIPR_CLK48SEL_HSI48 (1 << RCC_CCIPR_CLK48SEL_SHIFT) /* Bits 27-31: Reserved */ /* Control/status register */ -#define RCC_CSR_LSION (0) /* Bit 0: LSI enable */ -#define RCC_CSR_LSIRDY (1) /* Bit 1: ready */ - /* Bits 3-7: Reserved */ -#define RCC_CSR_LSEON (8) /* Bit 8: LSE enable */ -#define RCC_CSR_LSERDY (9) /* Bit 9: LSE ready */ -#define RCC_CSR_LSEBPY (10) /* Bit 10: LSE bypass */ -#define RCC_CSR_LSEDRV_SHIFT (11) /* Bits 11-12: LSE driving capability */ +#define RCC_CSR_LSION (1 << 0) /* Bit 0: LSI enable */ +#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: ready */ + /* Bits 3-7: Reserved */ +#define RCC_CSR_LSEON (1 << 8) /* Bit 8: LSE enable */ +#define RCC_CSR_LSERDY (1 << 9) /* Bit 9: LSE ready */ +#define RCC_CSR_LSEBPY (1 << 10) /* Bit 10: LSE bypass */ +#define RCC_CSR_LSEDRV_SHIFT (11) /* Bits 11-12: LSE driving capability */ #define RCC_CSR_LSEDRV_MASK (3 << RCC_CSR_LSEDRV_SHIFT) # define RCC_CSR_LSEDRV_LOW (0 << RCC_CSR_LSEDRV_SHIFT) # define RCC_CSR_LSEDRV_MEDLOW (1 << RCC_CSR_LSEDRV_SHIFT) # define RCC_CSR_LSEDRV_MEDHGIH (2 << RCC_CSR_LSEDRV_SHIFT) # define RCC_CSR_LSEDRV_HIGH (3 << RCC_CSR_LSEDRV_SHIFT) -#define RCC_CSR_CSSLSEON (13) /* Bit 13: CSS on LSE enable */ -#define RCC_CSR_CSSLSED (14) /* Bit 14: CSS on LSE failure detection flag */ - /* Bit 15: Reserved */ -#define RCC_CSR_RTCSEL_SHIFT (16) /* Bits 16-17: RTC clock source selection */ +#define RCC_CSR_CSSLSEON (1 << 13) /* Bit 13: CSS on LSE enable */ +#define RCC_CSR_CSSLSED (1 << 14) /* Bit 14: CSS on LSE failure detection flag */ + /* Bit 15: Reserved */ +#define RCC_CSR_RTCSEL_SHIFT (16) /* Bits 16-17: RTC clock source selection */ #define RCC_CSR_RTCSEL_MASK (3 << RCC_CSR_RTCSEL_SHIFT) # define RCC_CSR_RTCSEL_NOCLK (0 << RCC_CSR_RTCSEL_SHIFT) # define RCC_CSR_RTCSEL_LSE (1 << RCC_CSR_RTCSEL_SHIFT) # define RCC_CSR_RTCSEL_LSI (2 << RCC_CSR_RTCSEL_SHIFT) # define RCC_CSR_RTCSEL_HSE (3 << RCC_CSR_RTCSEL_SHIFT) -#define RCC_CSR_RTCEN (18) /* Bit 18: RTC clock enable */ -#define RCC_CSR_RTCRST (19) /* Bit 19: RTC software reset */ - /* Bits 20-22: Reserved */ -#define RCC_CSR_RMVF (23) /* Bit 23: Remove reset flag */ -#define RCC_CSR_FWRSTF (24) /* Bit 24: Firewall reset flag */ -#define RCC_CSR_OBLRSTF (25) /* Bit 25: Options bytes loading reset flag */ -#define RCC_CSR_PINRSTF (26) /* Bit 26: PIN reset flag */ -#define RCC_CSR_PORRSTF (27) /* Bit 27: POR/PDR reset flag */ -#define RCC_CSR_SFTRSTF (28) /* Bit 28: software reset flag */ -#define RCC_CSR_IWDGRSTF (29) /* Bit 29: IWDG reset flag */ -#define RCC_CSR_WWDGRSTF (30) /* Bit 30: WWDG reset flag */ -#define RCC_CSR_LPWRRSTF (31) /* Bit 31: Low-power reset flag */ +#define RCC_CSR_RTCEN (1 << 18) /* Bit 18: RTC clock enable */ +#define RCC_CSR_RTCRST (1 << 19) /* Bit 19: RTC software reset */ + /* Bits 20-22: Reserved */ +#define RCC_CSR_RMVF (1 << 23) /* Bit 23: Remove reset flag */ +#define RCC_CSR_FWRSTF (1 << 24) /* Bit 24: Firewall reset flag */ +#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Options bytes loading reset flag */ +#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: software reset flag */ +#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: IWDG reset flag */ +#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: WWDG reset flag */ +#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-power reset flag */ #endif /* __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32L0_RCC_H */ diff --git a/arch/arm/src/stm32f0l0/hardware/stm32l0_syscfg.h b/arch/arm/src/stm32f0l0/hardware/stm32l0_syscfg.h index f2680abaeb..60b4ff30c4 100644 --- a/arch/arm/src/stm32f0l0/hardware/stm32l0_syscfg.h +++ b/arch/arm/src/stm32f0l0/hardware/stm32l0_syscfg.h @@ -51,6 +51,7 @@ #define STM32_SYSCFG_CFGR1_OFFSET 0x0000 /* SYSCFG configuration register 1 */ #define STM32_SYSCFG_CFGR2_OFFSET 0x0004 /* SYSCFG configuration register 2 */ +#define STM32_SYSCFG_CFGR3_OFFSET 0x0020 /* SYSCFG configuration register 3 */ #define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */ #define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */ @@ -64,6 +65,7 @@ #define STM32_SYSCFG_CFGR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR1_OFFSET) #define STM32_SYSCFG_CFGR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR2_OFFSET) +#define STM32_SYSCFG_CFGR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_CFGR3_OFFSET) #define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p)) #define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET) @@ -81,6 +83,20 @@ /* TODO: SYSCFG configuration register 3 */ +#define SYSCFG_CFGR3_ENVREFINT (1 << 0) /* Bit 0: VREFINT enable and scaler control for COMP2 enable */ + /* Bits 1-3: Reserved */ +#define SYSCFG_CFGR3_SELVREFOUT_SHIFT (4) /* Bits 4-5: VREFINT_ADC connection */ +#define SYSCFG_CFGR3_SELVREFOUT_MASK (3 << SYSCFG_CFGR3_SELVREFOUT_SHIFT) + /* Bits 6-7: Reserved */ +#define SYSCFG_CFGR3_ENBUFVREFADC (1 << 8) /* Bit 8: VREFINT reference for ADC enable */ +#define SYSCFG_CFGR3_ENBUFSENSORADC (1 << 9) /* Bit 9: Temperature sensor reference for ADC enable */ + /* Bits 10-11: Reserved */ +#define SYSCFG_CFGR3_ENBUFVREFINTCOMP2 (1 << 12) /* Bit 12: VREFINT reference for COMP2 scaler enable */ +#define SYSCFG_CFGR3_ENBUFVREFINTHSI48 (1 << 13) /* Bit 13: VREFINT reference for HSI48 scaler enable */ + /* Bits 14-29: Reserved */ +#define SYSCFG_CFGR3_VREFINTRDYF (1 << 30) /* Bit 30: VREFINT ready flag */ +#define SYSCFG_CFGR3_REFLOCK (1 << 31) /* Bit 31: SYSCFG_CFG3 lock bit */ + /* SYSCFG external interrupt configuration register 1-4 */ #define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ diff --git a/arch/arm/src/stm32f0l0/stm32_aes.c b/arch/arm/src/stm32f0l0/stm32_aes.c new file mode 100644 index 0000000000..d5d892ba50 --- /dev/null +++ b/arch/arm/src/stm32f0l0/stm32_aes.c @@ -0,0 +1,342 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0/stm32_aes.c + * + * Copyright (C) 2015 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * 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 NuttX 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32_rcc.h" +#include "stm32_aes.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AES_BLOCK_SIZE 16 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void stm32aes_enable(bool on); +static void stm32aes_ccfc(void); +static void stm32aes_setkey(FAR const void *key, size_t key_len); +static void stm32aes_setiv(FAR const void *iv); +static void stm32aes_encryptblock(FAR void *block_out, + FAR const void *block_in); +static int stm32aes_setup_cr(int mode, int encrypt); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_stm32aes_lock; +static bool g_stm32aes_initdone = false; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void stm32aes_enable(bool on) +{ + uint32_t regval; + + regval = getreg32(STM32_AES_CR); + if (on) + { + regval |= AES_CR_EN; + } + else + { + regval &= ~AES_CR_EN; + } + + putreg32(regval, STM32_AES_CR); +} + +/* Clear AES_SR_CCF status register bit */ + +static void stm32aes_ccfc(void) +{ + uint32_t regval; + + regval = getreg32(STM32_AES_CR); + regval |= AES_CR_CCFC; + putreg32(regval, STM32_AES_CR); +} + +/* TODO: Handle other AES key lengths or fail if length is not valid */ + +static void stm32aes_setkey(FAR const void *key, size_t key_len) +{ + FAR uint32_t *in = (FAR uint32_t *)key; + + (void)key_len; + + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR3); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR2); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR1); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_KEYR0); +} + +static void stm32aes_setiv(FAR const void *iv) +{ + FAR uint32_t *in = (FAR uint32_t *)iv; + + putreg32(__builtin_bswap32(*in), STM32_AES_IVR3); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_IVR2); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_IVR1); + in++; + putreg32(__builtin_bswap32(*in), STM32_AES_IVR0); +} + +static void stm32aes_encryptblock(FAR void *block_out, FAR const void *block_in) +{ + FAR uint32_t *in = (FAR uint32_t *)block_in; + FAR uint32_t *out = (FAR uint32_t *)block_out; + + putreg32(*in, STM32_AES_DINR); + in++; + putreg32(*in, STM32_AES_DINR); + in++; + putreg32(*in, STM32_AES_DINR); + in++; + putreg32(*in, STM32_AES_DINR); + + while (!(getreg32(STM32_AES_SR) & AES_SR_CCF)); + stm32aes_ccfc(); + + *out = getreg32(STM32_AES_DOUTR); + out++; + *out = getreg32(STM32_AES_DOUTR); + out++; + *out = getreg32(STM32_AES_DOUTR); + out++; + *out = getreg32(STM32_AES_DOUTR); +} + +static int stm32aes_setup_cr(int mode, int encrypt) +{ + uint32_t regval = 0; + + regval |= AES_CR_DATATYPE_BE; + + switch (mode) + { + case AES_MODE_ECB: + regval |= AES_CR_CHMOD_ECB; + break; + + case AES_MODE_CBC: + regval |= AES_CR_CHMOD_CBC; + break; + + case AES_MODE_CTR: + regval |= AES_CR_CHMOD_CTR; + break; + + default: + return -EINVAL; + } + + if (encrypt) + { + regval |= AES_CR_MODE_ENCRYPT; + } + else + { + if (mode == AES_MODE_CTR) + { + regval |= AES_CR_MODE_DECRYPT; + } + else + { + regval |= AES_CR_MODE_DECRYPT_KEYDERIV; + } + } + + putreg32(regval, STM32_AES_CR); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int stm32_aesreset(void) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + + regval = getreg32(STM32_RCC_AHBRSTR); + regval |= RCC_AHBRSTR_AESRST; + putreg32(regval, STM32_RCC_AHBRSTR); + regval &= ~RCC_AHBRSTR_AESRST; + putreg32(regval, STM32_RCC_AHBRSTR); + + leave_critical_section(flags); + + return OK; +} + +int stm32_aesinitialize(void) +{ + uint32_t regval; + + nxsem_init(&g_stm32aes_lock, 0, 1); + + regval = getreg32(STM32_RCC_AHBENR); + regval |= RCC_AHBENR_AESEN; + putreg32(regval, STM32_RCC_AHBENR); + + stm32aes_enable(false); + + return OK; +} + +int stm32_aesuninitialize(void) +{ + uint32_t regval; + + stm32aes_enable(false); + + regval = getreg32(STM32_RCC_AHBENR); + regval &= ~RCC_AHBENR_AESEN; + putreg32(regval, STM32_RCC_AHBENR); + + nxsem_destroy(&g_stm32aes_lock); + + return OK; +} + +int aes_cypher(FAR void *out, FAR const void *in, uint32_t size, + FAR const void *iv, FAR const void *key, uint32_t keysize, + int mode, int encrypt) +{ + int ret = OK; + + /* Ensure initialization was done */ + + if (!g_stm32aes_initdone) + { + ret = stm32_aesinitialize(); + if (ret < 0) + { + return ret; /* AES init failed */ + } + + g_stm32aes_initdone = true; + } + + if ((size & (AES_BLOCK_SIZE-1)) != 0) + { + return -EINVAL; + } + + if (keysize != 16) + { + return -EINVAL; + } + + ret = nxsem_wait(&g_stm32aes_lock); + if (ret < 0) + { + return ret; + } + + /* AES must be disabled before changing mode, key or IV. */ + + stm32aes_enable(false); + ret = stm32aes_setup_cr(mode, encrypt); + if (ret < 0) + { + goto out; + } + + stm32aes_setkey(key, keysize); + if (iv != NULL) + { + stm32aes_setiv(iv); + } + + stm32aes_enable(true); + while (size) + { + stm32aes_encryptblock(out, in); + out = (FAR uint8_t *)out + AES_BLOCK_SIZE; + in = (FAR uint8_t *)in + AES_BLOCK_SIZE; + size -= AES_BLOCK_SIZE; + } + + stm32aes_enable(false); + +out: + nxsem_post(&g_stm32aes_lock); + return ret; +} diff --git a/arch/arm/src/stm32f0l0/stm32_aes.h b/arch/arm/src/stm32f0l0/stm32_aes.h new file mode 100644 index 0000000000..07501b564f --- /dev/null +++ b/arch/arm/src/stm32f0l0/stm32_aes.h @@ -0,0 +1,63 @@ +/************************************************************************************ + * arch/arm/src/stm32f0l0/stm32_aes.h + * + * Copyright (C) 2014 Haltian Ltd. All rights reserved. + * Author: Juha Niskanen + * + * 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 NuttX 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 OWNER 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F0L0_STM32_AES_H +#define __ARCH_ARM_SRC_STM32F0L0_STM32_AES_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + +#include "chip.h" + +#include "hardware/stm32_aes.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32F0L0_STM32_AES_H */ diff --git a/arch/arm/src/stm32f0l0/stm32_hsi48.c b/arch/arm/src/stm32f0l0/stm32_hsi48.c index 9dfd1a3e84..02479c2b0f 100644 --- a/arch/arm/src/stm32f0l0/stm32_hsi48.c +++ b/arch/arm/src/stm32f0l0/stm32_hsi48.c @@ -46,6 +46,22 @@ #include "stm32_hsi48.h" +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_ARCH_CHIP_STM32F0) +# define STM32_HSI48_REG STM32_RCC_CR2 +# define STM32_HSI48ON RCC_CR2_HSI48ON +# define STM32_HSI48RDY RCC_CR2_HSI48RDY +#elif defined(CONFIG_ARCH_CHIP_STM32L0) +# define STM32_HSI48_REG STM32_RCC_CRRCR +# define STM32_HSI48ON RCC_CRRCR_HSI48ON +# define STM32_HSI48RDY RCC_CRRCR_HSI48RDY +#else +# error "Unsupported STM32F0/L0 HSI48" +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -93,23 +109,20 @@ void stm32_enable_hsi48(enum syncsrc_e syncsrc) * enabled. */ - regval = getreg32(STM32_RCC_CR2); - regval |= RCC_CR2_HSI48ON; - putreg32(regval, STM32_RCC_CR2); - - if (syncsrc == SYNCSRC_USB) - { - /* Select the HSI48 as the USB clock source */ - - regval = getreg32(STM32_RCC_CFGR3); - regval &= ~RCC_CFGR3_USBSW; - putreg32(regval, STM32_RCC_CFGR3); - } + regval = getreg32(STM32_HSI48_REG); + regval |= STM32_HSI48ON; + putreg32(regval, STM32_HSI48_REG); /* Wait for the HSI48 clock to stabilize */ - while ((getreg32(STM32_RCC_CR2) & RCC_CR2_HSI48RDY) == 0); + while ((getreg32(STM32_HSI48_REG) & STM32_HSI48RDY) == 0); + /* Return if no synchronization */ + + if (syncsrc == SYNCSRC_NONE) + { + return; + } /* The CRS synchronization (SYNC) source, selectable through the CRS_CFGR * register, can be the signal from the external CRS_SYNC pin, the LSE @@ -167,9 +180,9 @@ void stm32_disable_hsi48(void) /* Disable the HSI48 clock */ - regval = getreg32(STM32_RCC_CR2); - regval &= ~RCC_CR2_HSI48ON; - putreg32(regval, STM32_RCC_CR2); + regval = getreg32(STM32_HSI48_REG); + regval &= ~STM32_HSI48ON; + putreg32(regval, STM32_HSI48_REG); /* Set other registers to the default settings. */ diff --git a/arch/arm/src/stm32f0l0/stm32_hsi48.h b/arch/arm/src/stm32f0l0/stm32_hsi48.h index b2f22e7942..bbf8cd9c69 100644 --- a/arch/arm/src/stm32f0l0/stm32_hsi48.h +++ b/arch/arm/src/stm32f0l0/stm32_hsi48.h @@ -51,7 +51,8 @@ enum syncsrc_e { - SYNCSRC_GPIO = 0, /* GPIO selected as SYNC signal source */ + SYNCSRC_NONE = 0, /* No SYNC signal */ + SYNCSRC_GPIO, /* GPIO selected as SYNC signal source */ SYNCSRC_LSE, /* LSE selected as SYNC signal source */ SYNCSRC_USB, /* USB SOF selected as SYNC signal source */ }; diff --git a/arch/arm/src/stm32f0l0/stm32_rcc.c b/arch/arm/src/stm32f0l0/stm32_rcc.c index 65a1e5c724..a7d32cf157 100644 --- a/arch/arm/src/stm32f0l0/stm32_rcc.c +++ b/arch/arm/src/stm32f0l0/stm32_rcc.c @@ -52,11 +52,23 @@ #include "hardware/stm32_flash.h" #include "stm32_gpio.h" #include "stm32_rcc.h" +#include "stm32_hsi48.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +#ifdef CONFIG_STM32F0L0_RNG +# ifndef STM32_USE_CLK48 +# error RNG requires CLK48 enabled +# endif +#endif +#ifdef CONFIG_STM32F0L0_USB +# ifndef STM32_USE_CLK48 +# error USB requires CLK48 enabled +# endif +#endif + /* Allow up to 100 milliseconds for the high speed clock to become ready. * that is a very long delay, but if the clock does not become ready we are * hosed anyway. diff --git a/arch/arm/src/stm32f0l0/stm32_rng.c b/arch/arm/src/stm32f0l0/stm32_rng.c new file mode 100644 index 0000000000..b0c34a874a --- /dev/null +++ b/arch/arm/src/stm32f0l0/stm32_rng.c @@ -0,0 +1,337 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0/stm32_rng.c + * + * Copyright (C) 2012 Max Holtzberg. All rights reserved. + * Author: Max Holtzberg + * + * 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 NuttX 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "up_arch.h" +#include "hardware/stm32_rng.h" +#include "up_internal.h" + +#if defined(CONFIG_STM32F0L0_RNG) +#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH) + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int stm32_rng_initialize(void); +static int stm32_rng_interrupt(int irq, void *context, FAR void *arg); +static void stm32_rng_enable(void); +static void stm32_rng_disable(void); +static ssize_t stm32_rng_read(struct file *filep, char *buffer, size_t); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rng_dev_s +{ + sem_t rd_devsem; /* Threads can only exclusively access the RNG */ + sem_t rd_readsem; /* To block until the buffer is filled */ + char *rd_buf; + size_t rd_buflen; + uint32_t rd_lastval; + bool rd_first; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct rng_dev_s g_rngdev; + +static const struct file_operations g_rngops = +{ + 0, /* open */ + 0, /* close */ + stm32_rng_read, /* read */ + 0, /* write */ + 0, /* seek */ + 0 /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , 0 /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , 0 /* unlink */ +#endif +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rng_initialize + ****************************************************************************/ + +static int stm32_rng_initialize(void) +{ + uint32_t regval; + + _info("Initializing RNG\n"); + + memset(&g_rngdev, 0, sizeof(struct rng_dev_s)); + + nxsem_init(&g_rngdev.rd_devsem, 0, 1); + + if (irq_attach(STM32_IRQ_RNG, stm32_rng_interrupt, NULL)) + { + /* We could not attach the ISR to the interrupt */ + + _info("Could not attach IRQ.\n"); + + return -EAGAIN; + } + + /* Enable interrupts */ + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_IE; + putreg32(regval, STM32_RNG_CR); + + up_enable_irq(STM32_IRQ_RNG); + + return OK; +} + +/**************************************************************************** + * Name: stm32_rng_enable + ****************************************************************************/ + +static void stm32_rng_enable(void) +{ + uint32_t regval; + + g_rngdev.rd_first = true; + + regval = getreg32(STM32_RNG_CR); + regval |= RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +/**************************************************************************** + * Name: stm32_rng_disable + ****************************************************************************/ + +static void stm32_rng_disable(void) +{ + uint32_t regval; + regval = getreg32(STM32_RNG_CR); + regval &= ~RNG_CR_RNGEN; + putreg32(regval, STM32_RNG_CR); +} + +/**************************************************************************** + * Name: stm32_rng_interrupt + ****************************************************************************/ + +static int stm32_rng_interrupt(int irq, void *context, FAR void *arg) +{ + uint32_t rngsr; + uint32_t data; + + rngsr = getreg32(STM32_RNG_SR); + + if ((rngsr & (RNG_SR_SEIS | RNG_SR_CEIS)) /* Check for error bits */ + || !(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ + { + /* This random value is not valid, we will try again. */ + + return OK; + } + + data = getreg32(STM32_RNG_DR); + + /* As required by the FIPS PUB (Federal Information Processing Standard + * Publication) 140-2, the first random number generated after setting the + * RNGEN bit should not be used, but saved for comparison with the next + * generated random number. Each subsequent generated random number has to be + * compared with the previously generated number. The test fails if any two + * compared numbers are equal (continuous random number generator test). + */ + + if (g_rngdev.rd_first) + { + g_rngdev.rd_first = false; + g_rngdev.rd_lastval = data; + return OK; + } + + if (g_rngdev.rd_lastval == data) + { + /* Two subsequent same numbers, we will try again. */ + + return OK; + } + + /* If we get here, the random number is valid. */ + + g_rngdev.rd_lastval = data; + + if (g_rngdev.rd_buflen >= 4) + { + g_rngdev.rd_buflen -= 4; + *(uint32_t *)&g_rngdev.rd_buf[g_rngdev.rd_buflen] = data; + } + else + { + while (g_rngdev.rd_buflen > 0) + { + g_rngdev.rd_buf[--g_rngdev.rd_buflen] = (char)data; + data >>= 8; + } + } + + if (g_rngdev.rd_buflen == 0) + { + /* Buffer filled, stop further interrupts. */ + + stm32_rng_disable(); + nxsem_post(&g_rngdev.rd_readsem); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_rng_read + ****************************************************************************/ + +static ssize_t stm32_rng_read(struct file *filep, char *buffer, size_t buflen) +{ + int ret; + + ret = nxsem_wait(&g_rngdev.rd_devsem); + if (ret < 0) + { + return ret; + } + + /* We've got the semaphore. */ + + /* Initialize the operation semaphore with 0 for blocking until the + * buffer is filled from interrupts. The readsem semaphore is used + * for signaling and, hence, should not have priority inheritance + * enabled. + */ + + nxsem_init(&g_rngdev.rd_readsem, 0, 0); + nxsem_setprotocol(&g_rngdev.rd_readsem, SEM_PRIO_NONE); + + g_rngdev.rd_buflen = buflen; + g_rngdev.rd_buf = buffer; + + /* Enable RNG with interrupts */ + + stm32_rng_enable(); + + /* Wait until the buffer is filled */ + + ret = nxsem_wait(&g_rngdev.rd_readsem); + + /* Free RNG for next use */ + + nxsem_post(&g_rngdev.rd_devsem); + return ret < 0 ? ret : buflen; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: devrandom_register + * + * Description: + * Initialize the RNG hardware and register the /dev/random driver. + * Must be called BEFORE devurandom_register. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_RANDOM +void devrandom_register(void) +{ + stm32_rng_initialize(); + (void)register_driver("/dev/random", &g_rngops, 0444, NULL); +} +#endif + +/**************************************************************************** + * Name: devurandom_register + * + * Description: + * Register /dev/urandom + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_DEV_URANDOM_ARCH +void devurandom_register(void) +{ +#ifndef CONFIG_DEV_RANDOM + stm32_rng_initialize(); +#endif + (void)register_driver("/dev/urandom", &g_rngops, 0444, NULL); +} +#endif + +#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */ +#endif /* CONFIG_STM32F0L0_RNG */ diff --git a/arch/arm/src/stm32f0l0/stm32_usbdev.c b/arch/arm/src/stm32f0l0/stm32_usbdev.c index 2cca8a24b5..a3d5ff037a 100644 --- a/arch/arm/src/stm32f0l0/stm32_usbdev.c +++ b/arch/arm/src/stm32f0l0/stm32_usbdev.c @@ -63,7 +63,6 @@ #include "up_internal.h" #include "hardware/stm32_rcc.h" #include "hardware/stm32_usbdev.h" -#include "stm32_hsi48.h" #include "stm32_gpio.h" #include "stm32_usbdev.h" @@ -3659,10 +3658,8 @@ void up_usbinitialize(void) /* Configure USB GPIO alternate function pins */ -#ifdef CONFIG_STM32F0L0_STM32F30XX (void)stm32_configgpio(GPIO_USB_DM); (void)stm32_configgpio(GPIO_USB_DP); -#endif /* Enable clocking to the USB peripheral */ @@ -3670,10 +3667,6 @@ void up_usbinitialize(void) regval &= ~RCC_APB1ENR_USBEN; putreg32(regval, STM32_RCC_APB1RSTR); - /* Enable HSI48 clocking to to support USB transfers */ - - stm32_enable_hsi48(SYNCSRC_USB); - /* Power up the USB controller, but leave it in the reset state */ stm32_hwsetup(priv); diff --git a/arch/arm/src/stm32f0l0/stm32f0_rcc.c b/arch/arm/src/stm32f0l0/stm32f0_rcc.c index 2d29296228..17e704b148 100644 --- a/arch/arm/src/stm32f0l0/stm32f0_rcc.c +++ b/arch/arm/src/stm32f0l0/stm32f0_rcc.c @@ -53,6 +53,18 @@ #include "hardware/stm32_flash.h" #include "hardware/stm32_gpio.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Determine if board wants to use HSI48 as 48 MHz oscillator. */ + +#if defined(CONFIG_STM32F0L0_HAVE_HSI48) && defined(STM32_USE_CLK48) +# if STM32_CLK48_SEL == RCC_CFGR3_CLK48_HSI48 +# define STM32_USE_HSI48 +# endif +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -490,6 +502,14 @@ static void stm32_stdclockconfig(void) regval |= RCC_CFGR_SW_PLL; putreg32(regval, STM32_RCC_CFGR); while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SW_MASK) != RCC_CFGR_SW_PLL); + +#ifdef STM32_USE_CLK48 + /* Select the HSI48 clock source (USB clock source) */ + + regval = getreg32(STM32_RCC_CFGR3); + regval |= STM32_CLK48_SEL; + putreg32(regval, STM32_RCC_CFGR3); +#endif } #endif @@ -503,4 +523,10 @@ static inline void rcc_enableperipherals(void) rcc_enableahb(); rcc_enableapb2(); rcc_enableapb1(); + +#ifdef STM32_USE_HSI48 + /* Enable HSI48 clocking to to support USB transfers or RNG */ + + stm32_enable_hsi48(STM32_HSI48_SYNCSRC); +#endif } diff --git a/arch/arm/src/stm32f0l0/stm32l0_rcc.c b/arch/arm/src/stm32f0l0/stm32l0_rcc.c index 723fa80836..b23ffbf084 100644 --- a/arch/arm/src/stm32f0l0/stm32l0_rcc.c +++ b/arch/arm/src/stm32f0l0/stm32l0_rcc.c @@ -39,6 +39,8 @@ #include "stm32_pwr.h" +#include "hardware/stm32_syscfg.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -55,6 +57,17 @@ #define HSE_DIVISOR RCC_CR_RTCPRE_HSEd8 +/* Determine if board wants to use HSI48 as 48 MHz oscillator. */ + +#if defined(CONFIG_STM32F0L0_HAVE_HSI48) && defined(STM32_USE_CLK48) +# if STM32_CLK48_SEL == RCC_CCIPR_CLK48SEL_HSI48 +# define STM32_USE_HSI48 +# ifndef CONFIG_STM32F0L0_VREFINT +# error VREFINT must be enabled if HSI48 used +# endif +# endif +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -158,12 +171,6 @@ static inline void rcc_enableahb(void) regval |= RCC_AHBENR_RNGEN; #endif -#ifdef CONFIG_STM32F0L0_CRYP - /* Cryptographic modules clock enable */ - - regval |= RCC_AHBENR_CRYPEN; -#endif - putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ } @@ -393,6 +400,32 @@ static inline void rcc_enableapb2(void) putreg32(regval, STM32_RCC_APB2ENR); } +/**************************************************************************** + * Name: rcc_enableccip + * + * Description: + * Set peripherals independent clock configuration. + * + ****************************************************************************/ + +static inline void rcc_enableccip(void) +{ + uint32_t regval; + + /* Certain peripherals have no clock selected even when their enable bit is + * set. Set some defaults in the CCIPR register so those peripherals + * will at least have a clock. + */ + + regval = getreg32(STM32_RCC_CCIPR); + +#if defined(STM32_USE_CLK48) + regval |= STM32_CLK48_SEL; +#endif + + putreg32(regval, STM32_RCC_CCIPR); +} + /**************************************************************************** * Name: stm32_rcc_enablehse * @@ -712,6 +745,41 @@ static void stm32_stdclockconfig(void) stm32_rcc_enablelse(); #endif + +} +#endif + +/**************************************************************************** + * Name: vrefint_enable + * + * Description: + * Enable and configure internal voltage reference (VREFINT) + * + ****************************************************************************/ + +#ifdef CONFIG_STM32F0L0_VREFINT +static void vrefint_enable(void) +{ + uint32_t regval = 0; + + /* The HSI48 requires VREFINT and its reference to HSI48 */ + + regval = getreg32(STM32_SYSCFG_CFGR3); + + /* Enable VREFINT */ + + regval |= SYSCFG_CFGR3_ENVREFINT; + putreg32(regval, STM32_SYSCFG_CFGR3); + +#ifdef STM32_USE_HSI48 + /* Enable VREFINT reference to HSI48 */ + + regval |= SYSCFG_CFGR3_ENBUFVREFINTHSI48; +#endif + + /* Wait for VREFINT ready */ + + while ((getreg32(STM32_SYSCFG_CFGR3) & SYSCFG_CFGR3_VREFINTRDYF) == 0); } #endif @@ -721,10 +789,20 @@ static void stm32_stdclockconfig(void) static inline void rcc_enableperipherals(void) { + rcc_enableccip(); rcc_enableio(); rcc_enableahb(); rcc_enableapb2(); rcc_enableapb1(); +#ifdef CONFIG_STM32F0L0_VREFINT + vrefint_enable(); +#endif + +#ifdef STM32_USE_HSI48 + /* Enable HSI48 clocking to to support USB transfers or RNG */ + + stm32_enable_hsi48(STM32_HSI48_SYNCSRC); +#endif } /**************************************************************************** diff --git a/configs/b-l072z-lrwan1/include/board.h b/configs/b-l072z-lrwan1/include/board.h index e6f35afae0..0e093532b1 100644 --- a/configs/b-l072z-lrwan1/include/board.h +++ b/configs/b-l072z-lrwan1/include/board.h @@ -98,6 +98,14 @@ #define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd2 #define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) +/* 48MHz clock configuration */ + +#if defined(CONFIG_STM32F0L0_USB) || defined(CONFIG_STM32F0L0_RNG) +# define STM32_USE_CLK48 1 +# define STM32_CLK48_SEL RCC_CCIPR_CLK48SEL_HSI48 +# define STM32_HSI48_SYNCSRC SYNCSRC_NONE +#endif + /* TODO: timers */ /* LED definitions **********************************************************/ diff --git a/configs/nucleo-l073rz/include/board.h b/configs/nucleo-l073rz/include/board.h index 62d0e6fc09..9c268d241b 100644 --- a/configs/nucleo-l073rz/include/board.h +++ b/configs/nucleo-l073rz/include/board.h @@ -99,6 +99,14 @@ #define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd2 #define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/2) +/* 48MHz clock configuration */ + +#if defined(CONFIG_STM32F0L0_USB) || defined(CONFIG_STM32F0L0_RNG) +# define STM32_USE_CLK48 1 +# define STM32_CLK48_SEL RCC_CCIPR_CLK48SEL_HSI48 +# define STM32_HSI48_SYNCSRC SYNCSRC_NONE +#endif + /* TODO: timers */ /* LED definitions **********************************************************/