diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 38e93248e4..32ba15bc7f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -309,7 +309,6 @@ config ARCH_CHIP_STM32F0 config ARCH_CHIP_STM32L0 bool "STMicro STM32 L0" select ARCH_CORTEXM0 - depends on EXPERIMENTAL ---help--- STMicro STM32L0 architectures (ARM Cortex-M0). diff --git a/arch/arm/src/stm32f0l0/Make.defs b/arch/arm/src/stm32f0l0/Make.defs index ca1261f344..bc6aa0cf5a 100644 --- a/arch/arm/src/stm32f0l0/Make.defs +++ b/arch/arm/src/stm32f0l0/Make.defs @@ -65,16 +65,18 @@ CMN_CSRCS += up_dumpnvic.c endif CHIP_ASRCS = -CHIP_CSRCS = stm32_clockconfig.c stm32_gpio.c stm32_irq.c # stm32_dma_v1.c -CHIP_CSRCS += stm32_lse.c stm32_lowputc.c stm32_serial.c stm32_start.c +CHIP_CSRCS = stm32_start.c stm32_gpio.c stm32_irq.c # stm32_dma_v1.c +CHIP_CSRCS += stm32_lse.c stm32_lowputc.c stm32_serial.c # Configuration-dependent STM32F0/L0 files -ifdef ($(CONFIG_ARCH_CHIP_STM32L0),y -CHIP_CSRCS += stm32l0_rcc.c +ifeq ($(CONFIG_ARCH_CHIP_STM32F0),y) +CHIP_CSRCS += stm32_clockconfig.c +else ifeq ($(CONFIG_ARCH_CHIP_STM32L0),y) +CHIP_CSRCS += stm32_rcc.c endif -ifdef ($(CONFIG_STM32F0L0_PWR),y +ifeq ($(CONFIG_STM32F0L0_PWR),y) CHIP_CSRCS += stm32_pwr.c endif diff --git a/arch/arm/src/stm32f0l0/hardware/stm32f0_pwr.h b/arch/arm/src/stm32f0l0/hardware/stm32f0_pwr.h index 15434bc2a6..9081a21ee7 100644 --- a/arch/arm/src/stm32f0l0/hardware/stm32f0_pwr.h +++ b/arch/arm/src/stm32f0l0/hardware/stm32f0_pwr.h @@ -48,6 +48,9 @@ * Pre-processor Definitions ************************************************************************************/ +#undef HAVE_PWR_WKUP2 1 +#undef HAVE_PWR_WKUP3 1 + /* Register Offsets *****************************************************************/ #define STM32_PWR_CR_OFFSET 0x0000 /* Power control register */ diff --git a/arch/arm/src/stm32f0l0/hardware/stm32l0_pwr.h b/arch/arm/src/stm32f0l0/hardware/stm32l0_pwr.h index 226e2f9d9f..ece00a1ecf 100644 --- a/arch/arm/src/stm32f0l0/hardware/stm32l0_pwr.h +++ b/arch/arm/src/stm32f0l0/hardware/stm32l0_pwr.h @@ -47,6 +47,9 @@ * Pre-processor Definitions ************************************************************************************/ +#define HAVE_PWR_WKUP2 1 +#define HAVE_PWR_WKUP3 1 + /* Register Offsets *****************************************************************/ #define STM32_PWR_CR_OFFSET 0x0000 /* Power control register */ diff --git a/arch/arm/src/stm32f0l0/stm32_dma.h b/arch/arm/src/stm32f0l0/stm32_dma.h index fe741fd597..2d5b0137cd 100644 --- a/arch/arm/src/stm32f0l0/stm32_dma.h +++ b/arch/arm/src/stm32f0l0/stm32_dma.h @@ -245,7 +245,7 @@ size_t stm32_dmaresidual(DMA_HANDLE handle); * ****************************************************************************/ -#ifdef CONFIG_STM32_DMACAPABLE +#ifdef CONFIG_STM32F0L0_DMACAPABLE bool stm32_dmacapable(uintptr_t maddr, uint32_t count, uint32_t ccr); #else # define stm32_dmacapable(maddr, count, ccr) (true) diff --git a/arch/arm/src/stm32f0l0/stm32_pwr.c b/arch/arm/src/stm32f0l0/stm32_pwr.c index f9a538d967..fd7c8dfd84 100644 --- a/arch/arm/src/stm32f0l0/stm32_pwr.c +++ b/arch/arm/src/stm32f0l0/stm32_pwr.c @@ -55,20 +55,7 @@ * Private Data ************************************************************************************/ -/* Wakeup Pin Definitions: See chip/stm32_pwr.h */ - -#undef HAVE_PWR_WKUP2 -#undef HAVE_PWR_WKUP3 - -#if defined(CONFIG_STM32_STM32F30XX) -# define HAVE_PWR_WKUP2 1 -#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F33XX) || \ - defined(CONFIG_STM32_STM32F37XX) -# define HAVE_PWR_WKUP2 1 -# define HAVE_PWR_WKUP3 1 -#endif - -/* Thr parts only support a single Wake-up pin do not include the numeric suffix +/* Parts only support a single Wake-up pin do not include the numeric suffix * in the naming. */ @@ -323,7 +310,7 @@ bool stm32_pwr_getwuf(void) * ************************************************************************************/ -#ifdef CONFIG_STM32_ENERGYLITE +#ifdef CONFIG_STM32F0L0_ENERGYLITE void stm32_pwr_setvos(uint16_t vos) { uint16_t regval; @@ -336,7 +323,7 @@ void stm32_pwr_setvos(uint16_t vos) * 4. Poll VOSF bit of in PWR_CSR register. Wait until it is reset to 0. */ - while ((stm32_pwr_getreg32(STM32_PWR_CSR_OFFSET) & PWR_CSR_VOSF) != 0); + while ((stm32_pwr_getreg32(STM32_PWR_CSR_OFFSET) & PWR_CSR_VOSF) != 0) { } @@ -414,6 +401,6 @@ void stm32_pwr_disablepvd(void) stm32_pwr_modifyreg32(STM32_PWR_CR_OFFSET, PWR_CR_PVDE, 0); } -#endif /* CONFIG_STM32_ENERGYLITE */ +#endif /* CONFIG_STM32F0L0_ENERGYLITE */ #endif /* CONFIG_STM32F0L0_PWR */ diff --git a/arch/arm/src/stm32f0l0/stm32_pwr.h b/arch/arm/src/stm32f0l0/stm32_pwr.h index 83bc3b2c48..b137bc7a91 100644 --- a/arch/arm/src/stm32f0l0/stm32_pwr.h +++ b/arch/arm/src/stm32f0l0/stm32_pwr.h @@ -33,8 +33,8 @@ * ************************************************************************************/ -#ifndef __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32_PWR_H -#define __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32_PWR_H +#ifndef __ARCH_ARM_SRC_STM32F0L0_STM32_PWR_H +#define __ARCH_ARM_SRC_STM32F0L0_STM32_PWR_H /************************************************************************************ * Included Files @@ -181,7 +181,7 @@ bool stm32_pwr_getwuf(void); * ************************************************************************************/ -#ifdef CONFIG_STM32_ENERGYLITE +#ifdef CONFIG_STM32F0L0_ENERGYLITE void stm32_pwr_setvos(uint16_t vos); /************************************************************************************ @@ -223,7 +223,7 @@ void stm32_pwr_enablepvd(void); void stm32_pwr_disablepvd(void); -#endif /* CONFIG_STM32_ENERGYLITE */ +#endif /* CONFIG_STM32F0L0_ENERGYLITE */ #undef EXTERN #if defined(__cplusplus) @@ -231,4 +231,4 @@ void stm32_pwr_disablepvd(void); #endif #endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_STM32F0L0_HARDWARE_STM32_PWR_H */ +#endif /* __ARCH_ARM_SRC_STM32F0L0_STM32_PWR_H */ diff --git a/arch/arm/src/stm32f0l0/stm32_rcc.c b/arch/arm/src/stm32f0l0/stm32_rcc.c new file mode 100644 index 0000000000..272674e998 --- /dev/null +++ b/arch/arm/src/stm32f0l0/stm32_rcc.c @@ -0,0 +1,227 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0/stm32_rcc.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * 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 "up_internal.h" +#include "up_arch.h" + +#include "hardware/stm32_flash.h" +#include "hardware/stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 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. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Include chip-specific clocking initialization logic */ + +#if defined(CONFIG_ARCH_CHIP_STM32L0) +# include "stm32l0_rcc.c" +#else +# error "Unsupported STM32F0/L0 RCC" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_resetbkp + * + * Description: + * The RTC needs to reset the Backup Domain to change RTCSEL and resetting + * the Backup Domain renders to disabling the LSE as consequence. In order + * to avoid resetting the Backup Domain when we already configured LSE we + * will reset the Backup Domain early (here). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_STM32F0L0_RTC) && defined(CONFIG_STM32F0L0_PWR) +static inline void rcc_resetbkp(void) +{ + uint32_t regval; + + /* Check if the RTC is already configured */ + + stm32_pwr_initbkp(false); + + regval = getreg32(RTC_MAGIC_REG); + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) + { + stm32_pwr_enablebkp(true); + + /* We might be changing RTCSEL - to ensure such changes work, we must + * reset the backup domain (having backed up the RTC_MAGIC token) + */ + + modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_BDRST); + modifyreg32(STM32_RCC_BDCR, RCC_BDCR_BDRST, 0); + + stm32_pwr_enablebkp(false); + } +} +#else +# define rcc_resetbkp() +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_clockconfig + * + * Description: + * Called to establish the clock settings based on the values in board.h. + * This function (by default) will reset most everything, enable the PLL, + * and enable peripheral clocking for all peripherals enabled in the NuttX + * configuration file. + * + * If CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is defined, then clocking + * will be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void stm32_clockconfig(void) +{ + /* Make sure that we are starting in the reset state */ + + rcc_reset(); + + /* Reset backup domain if appropriate */ + + rcc_resetbkp(); + +#if defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32_stdclockconfig(); + +#endif + +#ifdef CONFIG_STM32F0L0_SYSCFG_IOCOMPENSATION + /* Enable I/O Compensation */ + + stm32_iocompensation(); +#endif + + /* Enable peripheral clocking */ + + rcc_enableperipherals(); +} + +/************************************************************************************ + * Name: stm32_clockenable + * + * Description: + * Re-enable the clock and restore the clock settings based on settings in board.h. + * This function is only available to support low-power modes of operation: When + * re-awakening from deep-sleep modes, it is necessary to re-enable/re-start the + * PLL + * + * This functional performs a subset of the operations performed by + * stm32_clockconfig(): It does not reset any devices, and it does not reset the + * currenlty enabled peripheral clocks. + * + * If CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is defined, then clocking will + * be enabled by an externally provided, board-specific function called + * stm32_board_clockconfig(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ************************************************************************************/ + +#ifdef CONFIG_PM +void stm32_clockenable(void) +{ +#if defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) + /* Invoke Board Custom Clock Configuration */ + + stm32_board_clockconfig(); + +#else + /* Invoke standard, fixed clock configuration based on definitions in board.h */ + + stm32_stdclockconfig(); + +#endif +} +#endif diff --git a/arch/arm/src/stm32f0l0/stm32l0_rcc.c b/arch/arm/src/stm32f0l0/stm32l0_rcc.c index 934f9cd89e..4a015bbd1a 100644 --- a/arch/arm/src/stm32f0l0/stm32l0_rcc.c +++ b/arch/arm/src/stm32f0l0/stm32l0_rcc.c @@ -37,6 +37,8 @@ * Included Files ****************************************************************************/ +#include "stm32_pwr.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/