diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f9fb1faabae..b1006f0bbd3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -510,13 +510,19 @@ config ARCH_CHIP_STM32L0 bool "STMicro STM32 L0" select ARCH_CORTEXM0 ---help--- - STMicro STM32L0 architectures (ARM Cortex-M0). + STMicro STM32L0 architectures (ARM Cortex-M0+). config ARCH_CHIP_STM32G0 bool "STMicro STM32 G0" select ARCH_CORTEXM0 ---help--- - STMicro STM32G0 architectures (ARM Cortex-M0). + STMicro STM32G0 architectures (ARM Cortex-M0+). + +config ARCH_CHIP_STM32C0 + bool "STMicro STM32 C0" + select ARCH_CORTEXM0 + ---help--- + STMicro STM32C0 architectures (ARM Cortex-M0+). config ARCH_CHIP_STM32F7 bool "STMicro STM32 F7" @@ -1178,7 +1184,7 @@ config ARCH_CHIP default "sam34" if ARCH_CHIP_SAM34 default "samv7" if ARCH_CHIP_SAMV7 default "stm32" if ARCH_CHIP_STM32 - default "stm32f0l0g0" if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0 + default "stm32f0l0g0" if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0 || ARCH_CHIP_STM32C0 default "stm32f7" if ARCH_CHIP_STM32F7 default "stm32h7" if ARCH_CHIP_STM32H7 default "stm32l4" if ARCH_CHIP_STM32L4 @@ -1657,7 +1663,7 @@ endif if ARCH_CHIP_STM32 source "arch/arm/src/stm32/Kconfig" endif -if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0 +if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0 || ARCH_CHIP_STM32C0 source "arch/arm/src/stm32f0l0g0/Kconfig" endif if ARCH_CHIP_STM32F7 diff --git a/arch/arm/include/stm32f0l0g0/chip.h b/arch/arm/include/stm32f0l0g0/chip.h index 8bdda88ff93..e6537e92b21 100644 --- a/arch/arm/include/stm32f0l0g0/chip.h +++ b/arch/arm/include/stm32f0l0g0/chip.h @@ -611,9 +611,108 @@ # define STM32_NRNG 1 /* One Random number generator (RNG) */ # define STM32_NCAP 24 /* Twenty-four Capacitive sensing channels */ # define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-E, H */ - +#elif defined(CONFIG_ARCH_CHIP_STM32C051XX) +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM16 4 /* Four 16-bit general up/down timers TIM3, TIM14, + * TIM16 and TIM17 */ +# define STM32_NGTIM32 1 /* One 32-bit general up/down timer TIM2 */ +# define STM32_NBTIM 0 /* No basic timers */ + /* One LPTIMER */ +# define STM32_NSPI 2 /* Two SPI modules SPI1-2 */ +# define STM32_NI2S 0 /* No I2S module */ +# define STM32_NI2C 2 /* Two I2C */ +# define STM32_NDMA 1 /* One DMA1, 5-channels */ +# define STM32_NUSART 2 /* Two USART modules, USART1-2 */ +# define STM32_NCAN 0 /* No CAN controllers */ +# define STM32_FDCAN 0 /* No FD CAN */ +# define STM32_NLCD 0 /* No LCD controller */ +# define STM32_NUSBDEV 0 /* No USB full-speed device controller */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NCEC 0 /* No HDMI-CEC controller */ +# define STM32_NADC 1 /* One 12-bit module */ +# define STM32_NDAC 0 /* No DAC channels */ +# define STM32_NCOMP 0 /* No Analog Comparators */ +# define STM32_NCRC 1 /* One CRC module */ +# define STM32_NRNG 0 /* No Random number generator (RNG) */ +# define STM32_NCAP 0 /* No Capacitive sensing channels */ +# define STM32_NPORTS 5 /* Five GPIO ports, GPIOA-D, F */ +#elif defined(CONFIG_ARCH_CHIP_STM32C071XX) +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM16 4 /* 16-bit general up/down timers TIM3, TIM14, + * TIM16 and TIM17 */ +# define STM32_NGTIM32 1 /* One 32-bit general up/down timer TIM2 */ +# define STM32_NBTIM 0 /* No basic timers */ + /* One LPTIMER */ +# define STM32_NSPI 2 /* Two SPI modules SPI1-2 */ +# define STM32_NI2S 0 /* No I2S module */ +# define STM32_NI2C 2 /* Two I2C */ +# define STM32_NDMA 1 /* One DMA1, 5-channels */ +# define STM32_NUSART 2 /* Two USART modules, USART1-2 */ +# define STM32_NCAN 0 /* No CAN controllers */ +# define STM32_FDCAN 0 /* No FD CAN */ +# define STM32_NLCD 0 /* No LCD controller */ +# define STM32_NUSBDEV 1 /* USB full-speed device controller */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NCEC 0 /* No HDMI-CEC controller */ +# define STM32_NADC 1 /* One 12-bit module */ +# define STM32_NDAC 0 /* No DAC channels */ +# define STM32_NCOMP 0 /* No Analog Comparators */ +# define STM32_NCRC 1 /* One CRC module */ +# define STM32_NRNG 0 /* No Random number generator (RNG) */ +# define STM32_NCAP 0 /* No Capacitive sensing channels */ +# define STM32_NPORTS 5 /* Five GPIO ports, GPIOA-D, F */ +#elif defined(CONFIG_ARCH_CHIP_STM32C091XX) +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM16 5 /* 16-bit general up/down timers TIM3, TIM14, + * TIM15, TIM16 and TIM17 */ +# define STM32_NGTIM32 1 /* One 32-bit general up/down timer TIM2 */ +# define STM32_NBTIM 0 /* No basic timers */ + /* One LPTIMER */ +# define STM32_NSPI 2 /* Two SPI modules SPI1-2 */ +# define STM32_NI2S 0 /* No I2S module */ +# define STM32_NI2C 2 /* Two I2C */ +# define STM32_NDMA 1 /* One DMA1, 5-channels */ +# define STM32_NUSART 4 /* Four USART modules, USART1-4 */ +# define STM32_NCAN 0 /* No CAN controllers */ +# define STM32_FDCAN 0 /* No FD CAN */ +# define STM32_NLCD 0 /* No LCD controller */ +# define STM32_NUSBDEV 1 /* USB full-speed device controller */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NCEC 0 /* No HDMI-CEC controller */ +# define STM32_NADC 1 /* One 12-bit module */ +# define STM32_NDAC 0 /* No DAC channels */ +# define STM32_NCOMP 0 /* No Analog Comparators */ +# define STM32_NCRC 1 /* One CRC module */ +# define STM32_NRNG 0 /* No Random number generator (RNG) */ +# define STM32_NCAP 0 /* No Capacitive sensing channels */ +# define STM32_NPORTS 5 /* Five GPIO ports, GPIOA-D, F */ +#elif defined(CONFIG_ARCH_CHIP_STM32C092XX) +# define STM32_NATIM 1 /* One advanced timers TIM1 */ +# define STM32_NGTIM16 5 /* 16-bit general up/down timers TIM3, TIM14, + * TIM15, TIM16 and TIM17 */ +# define STM32_NGTIM32 1 /* One 32-bit general up/down timer TIM2 */ +# define STM32_NBTIM 0 /* No basic timers */ + /* One LPTIMER */ +# define STM32_NSPI 2 /* Two SPI modules SPI1-2 */ +# define STM32_NI2S 0 /* No I2S module */ +# define STM32_NI2C 2 /* Two I2C */ +# define STM32_NDMA 1 /* One DMA1, 5-channels */ +# define STM32_NUSART 4 /* Four USART modules, USART1-4 */ +# define STM32_NCAN 0 /* No CAN controllers */ +# define STM32_FDCAN 1 /* One FD CAN */ +# define STM32_NLCD 0 /* No LCD controller */ +# define STM32_NUSBDEV 1 /* USB full-speed device controller */ +# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */ +# define STM32_NCEC 0 /* No HDMI-CEC controller */ +# define STM32_NADC 1 /* One 12-bit module */ +# define STM32_NDAC 0 /* No DAC channels */ +# define STM32_NCOMP 0 /* No Analog Comparators */ +# define STM32_NCRC 1 /* One CRC module */ +# define STM32_NRNG 0 /* No Random number generator (RNG) */ +# define STM32_NCAP 0 /* No Capacitive sensing channels */ +# define STM32_NPORTS 5 /* Five GPIO ports, GPIOA-D, F */ #else -# error "Unsupported STM32F0xx chip" +# error "Unsupported STM32 Cortex M0 chip" #endif /* NVIC priority levels *****************************************************/ diff --git a/arch/arm/include/stm32f0l0g0/irq.h b/arch/arm/include/stm32f0l0g0/irq.h index 1f2a7f9a393..d3ef578a8dd 100644 --- a/arch/arm/include/stm32f0l0g0/irq.h +++ b/arch/arm/include/stm32f0l0g0/irq.h @@ -74,6 +74,8 @@ # include #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include #else # error Unrecognized STM32 Cortex M0 family #endif diff --git a/arch/arm/include/stm32f0l0g0/stm32c0_irq.h b/arch/arm/include/stm32f0l0g0/stm32c0_irq.h new file mode 100644 index 00000000000..28b97f3ed92 --- /dev/null +++ b/arch/arm/include/stm32f0l0g0/stm32c0_irq.h @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/include/stm32f0l0g0/stm32c0_irq.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + ****************************************************************************/ + +/* This file should never be included directly but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32G0_IRQ_H +#define __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32G0_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Prototypes + ****************************************************************************/ + +/* IRQ numbers. The IRQ number corresponds vector number and hence map + * directly to bits in the NVIC. This does, however, waste several words of + * memory in the IRQ to handle mapping tables. + * + * Processor Exceptions (vectors 0-15). These common definitions can be + * found in nuttx/arch/arm/include/stm32f0l0g0/irq.h + */ + +#define STM32_IRQ_WWDG (STM32_IRQ_EXTINT + 0) /* 0: Window Watchdog interrupt */ +#define STM32_IRQ_PVM (STM32_IRQ_EXTINT + 1) /* 1: VDDIO2 monitor interrupt */ +#define STM32_IRQ_RTC (STM32_IRQ_EXTINT + 2) /* 2: RTC */ +#define STM32_IRQ_FLASH (STM32_IRQ_EXTINT + 3) /* 3: Flash */ +#define STM32_IRQ_RCC (STM32_IRQ_EXTINT + 4) /* 4: RCC */ +#define STM32_IRQ_EXTI0_1 (STM32_IRQ_EXTINT + 5) /* 5: EXTI0_1 */ +#define STM32_IRQ_EXTI2_3 (STM32_IRQ_EXTINT + 6) /* 6: EXTI2_3 */ +#define STM32_IRQ_EXTI4_15 (STM32_IRQ_EXTINT + 7) /* 7: EXTI4_15 */ +#define STM32_IRQ_USB (STM32_IRQ_EXTINT + 8) /* 8: USB global interrupt */ +#define STM32_IRQ_DMA1CH1 (STM32_IRQ_EXTINT + 9) /* 9: DMA1_CH1 */ +#define STM32_IRQ_DMA1CH2 (STM32_IRQ_EXTINT + 10) /* 10: DMA1_CH2 */ +#define STM32_IRQ_DMA1CH3 (STM32_IRQ_EXTINT + 10) /* 10: DMA1_CH3 */ +#define STM32_IRQ_DMA1CH4 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH4 */ +#define STM32_IRQ_DMA1CH5 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH5 */ +#define STM32_IRQ_DMA1CH6 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH6 */ +#define STM32_IRQ_DMA1CH7 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH7 */ +#define STM32_IRQ_DMAMUX (STM32_IRQ_EXTINT + 11) /* 11: DMAMUX */ +#define STM32_IRQ_ADC (STM32_IRQ_EXTINT + 12) /* 12: ADC */ +#define STM32_IRQ_TIM1_BRK (STM32_IRQ_EXTINT + 13) /* 13: TIM1_BRK_UP_TRG_COM */ +#define STM32_IRQ_TIM1_CC (STM32_IRQ_EXTINT + 14) /* 14: TIM1_CC */ +#define STM32_IRQ_TIM2 (STM32_IRQ_EXTINT + 15) /* 15: TIM2 */ +#define STM32_IRQ_TIM3 (STM32_IRQ_EXTINT + 16) /* 16: TIM3 */ +#define STM32_IRQ_TIM6 (STM32_IRQ_EXTINT + 17) /* 17: TIM6 */ +#define STM32_IRQ_TIM14 (STM32_IRQ_EXTINT + 19) /* 19: TIM14 */ +#define STM32_IRQ_TIM15 (STM32_IRQ_EXTINT + 20) /* 20: TIM15 */ +#define STM32_IRQ_TIM16 (STM32_IRQ_EXTINT + 21) /* 21: TIM16 */ +#define STM32_IRQ_TIM17 (STM32_IRQ_EXTINT + 22) /* 22: TIM17 */ +#define STM32_IRQ_I2C1 (STM32_IRQ_EXTINT + 23) /* 23: I2C1 */ +#define STM32_IRQ_I2C2 (STM32_IRQ_EXTINT + 24) /* 24: I2C2 */ +#define STM32_IRQ_SPI1 (STM32_IRQ_EXTINT + 25) /* 25: SPI1 */ +#define STM32_IRQ_SPI2 (STM32_IRQ_EXTINT + 26) /* 26: SPI2 */ +#define STM32_IRQ_USART1 (STM32_IRQ_EXTINT + 27) /* 27: USART1 */ +#define STM32_IRQ_USART2 (STM32_IRQ_EXTINT + 28) /* 28: USART2 */ +#define STM32_IRQ_USART3 (STM32_IRQ_EXTINT + 29) /* 29: USART3 */ +#define STM32_IRQ_USART4 (STM32_IRQ_EXTINT + 29) /* 29: USART4 */ +#define STM32_IRQ_FDCAN_IT0 (STM32_IRQ_EXTINT + 30) /* 30: FDCAN global interrupt 0 */ +#define STM32_IRQ_FDCAN_IT1 (STM32_IRQ_EXTINT + 31) /* 31: FDCAN global interrupt 1 */ + +#define STM32_IRQ_NEXTINT (32) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32G0_IRQ_H */ diff --git a/arch/arm/src/stm32f0l0g0/CMakeLists.txt b/arch/arm/src/stm32f0l0g0/CMakeLists.txt index 04bf3aa905d..0afcf2dd4ca 100644 --- a/arch/arm/src/stm32f0l0g0/CMakeLists.txt +++ b/arch/arm/src/stm32f0l0g0/CMakeLists.txt @@ -29,13 +29,16 @@ list( stm32_gpio.c stm32_exti_gpio.c stm32_irq.c - stm32_lse.c stm32_lowputc.c stm32_serial.c stm32_rcc.c) +if(CONFIG_STM32F0L0G0_RTC_LSECLOCK OR CONFIG_LCD_LSECLOCK) + list(APPEND SRCS stm32_lse.c) +endif() + if(CONFIG_STM32F0L0G0_DMA) - list(APPEND SRCS stm32_dma_v1.c) + list(APPEND SRCS stm32_dma.c) endif() if(CONFIG_STM32F0L0G0_PWR) diff --git a/arch/arm/src/stm32f0l0g0/Kconfig b/arch/arm/src/stm32f0l0g0/Kconfig index b6197adcd67..28a133b969f 100644 --- a/arch/arm/src/stm32f0l0g0/Kconfig +++ b/arch/arm/src/stm32f0l0g0/Kconfig @@ -10,7 +10,8 @@ choice default ARCH_CHIP_STM32F051R8 if ARCH_CHIP_STM32F0 default ARCH_CHIP_STM32L073RZ if ARCH_CHIP_STM32L0 default ARCH_CHIP_STM32G071RB if ARCH_CHIP_STM32G0 - depends on ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0 + default ARCH_CHIP_STM32C071RB if ARCH_CHIP_STM32C0 + depends on ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0 || ARCH_CHIP_STM32C0 config ARCH_CHIP_STM32F030C6 bool "STM32F030C6" @@ -713,7 +714,171 @@ config ARCH_CHIP_STM32L073RZ select ARCH_CHIP_STM32L073XX depends on ARCH_CHIP_STM32L0 -endchoice # ST STM32F0/L0 Chip Selection +config ARCH_CHIP_STM32C051D8 + bool "STM32C051D8" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051F6 + bool "STM32C051F6" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051F8 + bool "STM32C051F8" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051G6 + bool "STM32C051G6" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051G8 + bool "STM32C051G8" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051K6 + bool "STM32C051K6" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051K8 + bool "STM32C051K8" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051C6 + bool "STM32C051C6" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C051C8 + bool "STM32C051C8" + select ARCH_CHIP_STM32C051XX + +config ARCH_CHIP_STM32C071F8 + bool "STM32C071F8" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071FB + bool "STM32C071FB" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071G8 + bool "STM32C071G8" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071GB + bool "STM32C071GB" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071K8 + bool "STM32C071K8" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071KB + bool "STM32C071KB" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071C8 + bool "STM32C071C8" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071CB + bool "STM32C071CB" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071R8 + bool "STM32C071R8" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C071RB + bool "STM32C071RB" + select ARCH_CHIP_STM32C071XX + +config ARCH_CHIP_STM32C091FB + bool "STM32C091FB" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091FC + bool "STM32C091FC" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091EC + bool "STM32C091EC" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091GB + bool "STM32C091GB" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091GC + bool "STM32C091GC" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091KB + bool "STM32C091KB" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091KC + bool "STM32C091KC" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091CB + bool "STM32C091CB" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091CC + bool "STM32C091CC" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091RB + bool "STM32C091RB" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C091RC + bool "STM32C091RC" + select ARCH_CHIP_STM32C091XX + +config ARCH_CHIP_STM32C092FB + bool "STM32C092FB" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092FC + bool "STM32C092FC" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092EC + bool "STM32C092EC" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092GB + bool "STM32C092GB" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092GC + bool "STM32C092GC" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092KB + bool "STM32C092KB" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092KC + bool "STM32C092KC" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092CB + bool "STM32C092CB" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092CC + bool "STM32C092CC" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092RB + bool "STM32C092RB" + select ARCH_CHIP_STM32C092XX + +config ARCH_CHIP_STM32C092RC + bool "STM32C092RC" + select ARCH_CHIP_STM32C092XX + +endchoice # ST STM32F0/L0/G0/C0 Chip Selection choice prompt "Override Flash Size Designator" @@ -827,6 +992,16 @@ config STM32F0L0G0_STM32L0 select STM32F0L0G0_HAVE_IP_USART_V1 select STM32F0L0G0_HAVE_IP_EXTI_V1 +config STM32F0L0G0_STM32C0 + bool + default n + select STM32F0L0G0_HAVE_SPI2 + select STM32F0L0G0_HAVE_I2C2 + select STM32F0L0G0_HAVE_DMAMUX + select STM32F0L0G0_HAVE_ADC1_DMA + select STM32F0L0G0_HAVE_IP_USART_V2 + select STM32F0L0G0_HAVE_IP_EXTI_V2 + config STM32F0L0G0_STM32F03X bool default n @@ -919,6 +1094,28 @@ config ARCH_CHIP_STM32L073XX select STM32F0L0G0_HAVE_I2C3 select STM32F0L0G0_HAVE_USBDEV +config ARCH_CHIP_STM32C051XX + bool + select STM32F0L0G0_STM32C0 + +config ARCH_CHIP_STM32C071XX + bool + select STM32F0L0G0_STM32C0 + select STM32F0L0G0_HAVE_USBDEV + +config ARCH_CHIP_STM32C091XX + bool + select STM32F0L0G0_STM32C0 + select STM32F0L0G0_HAVE_USART3 + select STM32F0L0G0_HAVE_USART4 + +config ARCH_CHIP_STM32C092XX + bool + select STM32F0L0G0_STM32C0 + select STM32F0L0G0_HAVE_USART3 + select STM32F0L0G0_HAVE_USART4 + select STM32F0L0G0_HAVE_FDCAN + config STM32F0L0G0_DFU bool "DFU bootloader" default n @@ -1142,6 +1339,10 @@ config STM32F0L0G0_HAVE_OPAMP4 bool default n +config STM32F0L0G0_HAVE_FDCAN + bool + default n + # These are STM32 peripherals IP blocks config STM32F0L0G0_HAVE_IP_USART_V1 @@ -1165,7 +1366,6 @@ config STM32F0L0G0_HAVE_IP_EXTI_V2 config STM32F0L0G0_ADC1 bool "ADC1" default n - depends on EXPERIMENTAL select STM32F0L0G0_ADC config STM32F0L0G0_COMP1 diff --git a/arch/arm/src/stm32f0l0g0/Make.defs b/arch/arm/src/stm32f0l0g0/Make.defs index 18b36818491..c2e8d049f3d 100644 --- a/arch/arm/src/stm32f0l0g0/Make.defs +++ b/arch/arm/src/stm32f0l0g0/Make.defs @@ -23,10 +23,14 @@ include armv6-m/Make.defs CHIP_CSRCS = stm32_start.c stm32_gpio.c stm32_exti_gpio.c stm32_irq.c -CHIP_CSRCS += stm32_lse.c stm32_lowputc.c stm32_serial.c stm32_rcc.c +CHIP_CSRCS += stm32_lowputc.c stm32_serial.c stm32_rcc.c + +ifneq ($(CONFIG_STM32F0L0G0_RTC_LSECLOCK)$(CONFIG_STM32F0L0G0_LCD_LSECLOCK),) +CHIP_CSRCS += stm32_lse.c +endif ifeq ($(CONFIG_STM32F0L0G0_DMA),y) -CHIP_CSRCS += stm32_dma_v1.c +CHIP_CSRCS += stm32_dma.c endif ifeq ($(CONFIG_STM32F0L0G0_PWR),y) diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_adc.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_adc.h index fc49038f193..87c07cb1d16 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_adc.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_adc.h @@ -185,14 +185,25 @@ /* ADC sample time register */ -#define ADC_SMPR_1p5 (0) /* 000: 1.5 cycles */ -#define ADC_SMPR_7p5 (1) /* 001: 7.5 cycles */ -#define ADC_SMPR_13p5 (2) /* 010: 13.5 cycles */ -#define ADC_SMPR_28p5 (3) /* 011: 28.5 cycles */ -#define ADC_SMPR_41p5 (4) /* 100: 41.5 cycles */ -#define ADC_SMPR_55p5 (5) /* 101: 55.5 cycles */ -#define ADC_SMPR_71p5 (6) /* 110: 71.5 cycles */ -#define ADC_SMPR_239p5 (7) /* 111: 239.5 cycles */ +#ifdef CONFIG_ARCH_CHIP_STM32C0 +# define ADC_SMPR_1p5 (0) /* 000: 1.5 cycles */ +# define ADC_SMPR_3p5 (1) /* 001: 3.5 cycles */ +# define ADC_SMPR_7p5 (2) /* 010: 7.5 cycles */ +# define ADC_SMPR_12p5 (3) /* 011: 12.5 cycles */ +# define ADC_SMPR_19p5 (4) /* 100: 19.5 cycles */ +# define ADC_SMPR_39p5 (5) /* 101: 39.5 cycles */ +# define ADC_SMPR_79p5 (6) /* 110: 79.5 cycles */ +# define ADC_SMPR_160p5 (7) /* 111: 160.5 cycles */ +#else +# define ADC_SMPR_1p5 (0) /* 000: 1.5 cycles */ +# define ADC_SMPR_7p5 (1) /* 001: 7.5 cycles */ +# define ADC_SMPR_13p5 (2) /* 010: 13.5 cycles */ +# define ADC_SMPR_28p5 (3) /* 011: 28.5 cycles */ +# define ADC_SMPR_41p5 (4) /* 100: 41.5 cycles */ +# define ADC_SMPR_55p5 (5) /* 101: 55.5 cycles */ +# define ADC_SMPR_71p5 (6) /* 110: 71.5 cycles */ +# define ADC_SMPR_239p5 (7) /* 111: 239.5 cycles */ +#endif #define ADC_SMPR_SMP1_SHIFT (0) /* Bits 0-2: Sampling time selection 1 */ #define ADC_SMPR_SMP1_MASK (7 << ADC_SMPR_SMP_SHIFT) diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_dma_v1.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_dma_v1.h index bfae9f3a37b..cdae49a53ee 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_dma_v1.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_dma_v1.h @@ -538,7 +538,7 @@ # define DMACHAN_USART5_TX_1 DMACHAN_SETTING(STM32_DMA1_CHAN7, 13) # define DMACHAN_USART5_TX_2 DMACHAN_SETTING(STM32_DMA1_CHAN3, 13) -#elif defined(CONFIG_ARCH_CHIP_STM32G0) +#elif defined(CONFIG_ARCH_CHIP_STM32G0) || defined(CONFIG_ARCH_CHIP_STM32C0) /* This family uses a DMAMUX */ #else diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_dmamux.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_dmamux.h index cd7a3ad8c10..31402fafbc0 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_dmamux.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_dmamux.h @@ -152,9 +152,11 @@ /* Import DMAMUX map */ #if defined(CONFIG_STM32F0L0G0_STM32G0) -# include "chip/stm32g0_dmamux.h" +# include "hardware/stm32g0_dmamux.h" +#elif defined(CONFIG_STM32F0L0G0_STM32C0) +# include "hardware/stm32c0_dmamux.h" #else -# error "Unsupported STM32 F0/L0/G0 sub family" +# error "Unsupported STM32 M0 sub family" #endif #endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32_DMAMUX_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_exti.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_exti.h index ba41b0d8288..82e7cff363d 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_exti.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_exti.h @@ -36,6 +36,8 @@ # include "hardware/stm32l0_exti.h" #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "hardware/stm32g0_exti.h" +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "hardware/stm32c0_exti.h" #else # error "Unrecognized STM32 M0 EXTI" #endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_flash.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_flash.h index ce87eae83ba..57193fbe896 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_flash.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_flash.h @@ -36,6 +36,8 @@ # include "hardware/stm32l0_flash.h" #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "hardware/stm32g0_flash.h" +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "hardware/stm32c0_flash.h" #else # error "Unsupported STM32 M0 FLASH" #endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_gpio.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_gpio.h index 82db5a959ba..11ecd42a32d 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_gpio.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_gpio.h @@ -33,6 +33,8 @@ # define STM32_GPIO_VERY_LOW_SPEED 1 /* Have very low speed operation (400KHz) */ #elif defined(CONFIG_ARCH_CHIP_STM32G0) # define STM32_GPIO_VERY_LOW_SPEED 1 /* Have very low speed operation */ +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# define STM32_GPIO_VERY_LOW_SPEED 1 /* Have very low speed operation */ #else # error "Unsupported STM32 M0 family" #endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_memorymap.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_memorymap.h index f5d77010c30..dba663e2a36 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_memorymap.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_memorymap.h @@ -40,6 +40,8 @@ # include "hardware/stm32l0_memorymap.h" #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "hardware/stm32g0_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "hardware/stm32c0_memorymap.h" #else # error "Unsupported STM32 M0 memory map" #endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_pinmap.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_pinmap.h index d74aec0ca23..fa4d2ccf200 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_pinmap.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_pinmap.h @@ -59,6 +59,8 @@ # include "hardware/stm32l0_pinmap.h" # elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "hardware/stm32g0_pinmap.h" +# elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "hardware/stm32c0_pinmap.h" # else # error "Unsupported STM32 M0 pin map" # endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_pwr.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_pwr.h index 77b0014d34b..bdb173a17cb 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_pwr.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_pwr.h @@ -36,6 +36,8 @@ # include "hardware/stm32l0_pwr.h" #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "hardware/stm32g0_pwr.h" +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "hardware/stm32c0_pwr.h" #else # error "Unsupported STM32 M0 PWR" #endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_rcc.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_rcc.h index 6a90b37d9c4..9242ac00ff6 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_rcc.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_rcc.h @@ -36,6 +36,8 @@ # include "hardware/stm32l0_rcc.h" #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "hardware/stm32g0_rcc.h" +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "hardware/stm32c0_rcc.h" #else # error "Unsupported STM32 M0 RCC" #endif diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32_spi.h b/arch/arm/src/stm32f0l0g0/hardware/stm32_spi.h index 583ed23f93b..0a058ebf094 100644 --- a/arch/arm/src/stm32f0l0g0/hardware/stm32_spi.h +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32_spi.h @@ -32,7 +32,9 @@ /* Select STM32 SPI IP core */ -#if defined(CONFIG_STM32F0L0G0_STM32F0) || defined(CONFIG_STM32F0L0G0_STM32G0) +#if defined(CONFIG_STM32F0L0G0_STM32F0) || \ + defined(CONFIG_STM32F0L0G0_STM32G0) || \ + defined(CONFIG_STM32F0L0G0_STM32C0) # define HAVE_IP_SPI_V2 #elif defined(CONFIG_STM32F0L0G0_STM32L0) # define HAVE_IP_SPI_V1 diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_dmamux.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_dmamux.h new file mode 100644 index 00000000000..1d91dc308bc --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_dmamux.h @@ -0,0 +1,57 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_dmamux.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_DMAMUX_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_DMAMUX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* DMAMUX1 mapping **********************************************************/ + +/* NOTE: DMAMUX1 channels 0 to 7 are connected to DMA1 channels 0 to 7 */ + +#define DMAMUX1_REQ_GEN0 (1) +#define DMAMUX1_REQ_GEN1 (2) +#define DMAMUX1_REQ_GEN2 (3) +#define DMAMUX1_REQ_GEN3 (4) +#define DMAMUX1_ADC1 (5) + +/* TODO: ... */ + +/* DMAP for DMA1 */ + +#define DMAMAP_DMA1_REQGEN0 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN0) +#define DMAMAP_DMA1_REQGEN1 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN1) +#define DMAMAP_DMA1_REQGEN2 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN2) +#define DMAMAP_DMA1_REQGEN3 DMAMAP_MAP(DMA1, DMAMUX1_REQ_GEN3) +#define DMAMAP_DMA1_ADC1 DMAMAP_MAP(DMA1, DMAMUX1_ADC1) + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_DMAMUX_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_exti.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_exti.h new file mode 100644 index 00000000000..800a7a4faff --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_exti.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_exti.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_EXTI_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_EXTI_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define STM32_NEXTI 18 +#define STM32_EXTI_MASK 0xffffffff + +#define STM32_EXTI_BIT(n) (1 << (n)) + +/* Register Offsets *********************************************************/ + +#define STM32_EXTI_RTSR1_OFFSET 0x0000 /* Rising Trigger selection register 1 */ +#define STM32_EXTI_FTSR1_OFFSET 0x0004 /* Falling Trigger selection register 1 */ +#define STM32_EXTI_SWIER1_OFFSET 0x0008 /* Software interrupt event register 1 */ +#define STM32_EXTI_RPR1_OFFSET 0x000c /* Rising edge pending register 1 */ +#define STM32_EXTI_FPR1_OFFSET 0x0010 /* Falling edge pending register 1 */ + +#define STM32_EXTI_EXTICR_OFFSET(p) (0x0060 + ((p) & 0x000c)) /* Registers are displaced by 4! */ +#define STM32_EXTI_EXTICR1_OFFSET 0x0060 /* External interrupt selection register 1 */ +#define STM32_EXTI_EXTICR2_OFFSET 0x0064 /* External interrupt selection register 2 */ +#define STM32_EXTI_EXTICR3_OFFSET 0x0068 /* External interrupt selection register 3 */ +#define STM32_EXTI_EXTICR4_OFFSET 0x006c /* External interrupt selection register 4 */ +#define STM32_EXTI_IMR1_OFFSET 0x0080 /* CPU wakeup with interrupt mask register 1 */ +#define STM32_EXTI_EMR1_OFFSET 0x0084 /* CPU wakeup with event mask register 1 */ +#define STM32_EXTI_IMR2_OFFSET 0x0090 /* CPU wakeup with interrupt mask register 2 */ +#define STM32_EXTI_EMR2_OFFSET 0x0094 /* CPU wakeup with event mask register 2 */ + +/* Register Addresses *******************************************************/ + +#define STM32_EXTI_RTSR1 (STM32_EXTI_BASE + STM32_EXTI_RTSR1_OFFSET) +#define STM32_EXTI_FTSR1 (STM32_EXTI_BASE + STM32_EXTI_FTSR1_OFFSET) +#define STM32_EXTI_SWIER1 (STM32_EXTI_BASE + STM32_EXTI_SWIER1_OFFSET) +#define STM32_EXTI_RPR1 (STM32_EXTI_BASE + STM32_EXTI_RPR1_OFFSET) +#define STM32_EXTI_FPR1 (STM32_EXTI_BASE + STM32_EXTI_FPR1_OFFSET) +#define STM32_EXTI_EXTICR(p) (STM32_EXTI_BASE + STM32_EXTI_EXTICR_OFFSET(p)) +#define STM32_EXTI_IMR1 (STM32_EXTI_BASE + STM32_EXTI_IMR1_OFFSET) +#define STM32_EXTI_EMR1 (STM32_EXTI_BASE + STM32_EXTI_EMR1_OFFSET) +#define STM32_EXTI_IMR2 (STM32_EXTI_BASE + STM32_EXTI_IMR2_OFFSET) +#define STM32_EXTI_EMR2 (STM32_EXTI_BASE + STM32_EXTI_EMR2_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* EXTI external interrupt configuration register 1-4 */ + +#define EXTI_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define EXTI_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define EXTI_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define EXTI_EXTICR_PORTD (3) /* 0011: PD[x] pin */ + /* 0100: Reserved */ +#define EXTI_EXTICR_PORTF (5) /* 0101: PF[x] pin */ + +#define EXTI_EXTICR_PORT_MASK (0xff) +#define EXTI_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 3) +#define EXTI_EXTICR_EXTI_MASK(g) (EXTI_EXTICR_PORT_MASK << (EXTI_EXTICR_EXTI_SHIFT(g))) + +/* TODO */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_EXTI_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_flash.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_flash.h new file mode 100644 index 00000000000..2d7480429db --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_flash.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_flash.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_FLASH_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_FLASH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_FLASH_ACR_OFFSET 0x0000 +#define STM32_FLASH_KEYR_OFFSET 0x0008 +#define STM32_FLASH_OPTKEYR_OFFSET 0x000c +#define STM32_FLASH_SR_OFFSET 0x0010 +#define STM32_FLASH_CR_OFFSET 0x0014 +#define STM32_FLASH_OPTR_OFFSET 0x0020 +#define STM32_FLASH_PCROP1ASE_OFFSET 0x0024 +#define STM32_FLASH_PCROP1AER_OFFSET 0x0028 +#define STM32_FLASH_WPR1AR_OFFSET 0x002c +#define STM32_FLASH_WPR1BR_OFFSET 0x0030 +#define STM32_FLASH_WPR1BSR_OFFSET 0x0034 +#define STM32_FLASH_PCROP1BER_OFFSET 0x0038 +#define STM32_FLASH_SECR_OFFSET 0x0080 + +/* Register Addresses *******************************************************/ + +#define STM32_FLASH_ACR (STM32_FLASHIF_BASE+STM32_FLASH_ACR_OFFSET) +#define STM32_FLASH_KEYR (STM32_FLASHIF_BASE+STM32_FLASH_KEYR_OFFSET) +#define STM32_FLASH_OPTKEYR (STM32_FLASHIF_BASE+STM32_FLASH_OPTKEYR_OFFSET) +#define STM32_FLASH_SR (STM32_FLASHIF_BASE+STM32_FLASH_SR_OFFSET) +#define STM32_FLASH_CR (STM32_FLASHIF_BASE+STM32_FLASH_CR_OFFSET) +#define STM32_FLASH_OPTR (STM32_FLASHIF_BASE+STM32_FLASH_OPTR_OFFSET) +#define STM32_FLASH_PCROP1ASE (STM32_FLASHIF_BASE+STM32_FLASH_PCROP1ASE_OFFSET) +#define STM32_FLASH_PCROP1AER (STM32_FLASHIF_BAER+STM32_FLASH_PCROP1AER_OFFSET) +#define STM32_FLASH_WPR1AR (STM32_FLASHIF_BASE+STM32_FLASH_WPR1AR_OFFSET) +#define STM32_FLASH_WPR1BR (STM32_FLASHIF_BASE+STM32_FLASH_WPR1BR_OFFSET) +#define STM32_FLASH_WPR1BSR (STM32_FLASHIF_BASE+STM32_FLASH_WPR1BSR_OFFSET) +#define STM32_FLASH_PCROP1BER (STM32_FLASHIF_BASE+STM32_FLASH_PCROP1BER_OFFSET) +#define STM32_FLASH_SECR (STM32_FLASHIF_BASE+STM32_FLASH_SECR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Flash Access Control Register (ACR) */ + +#define FLASH_ACR_LATENCY_SHIFT (0) /* Bits 0-2: Flash memory access latency*/ +#define FLASH_ACR_LATENCY_MASK (7 << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY(n) ((n) << FLASH_ACR_LATENCY_SHIFT) +# define FLASH_ACR_LATENCY_0 (0 << FLASH_ACR_LATENCY_SHIFT) /* 000: Zero wait states */ +# define FLASH_ACR_LATENCY_1 (1 << FLASH_ACR_LATENCY_SHIFT) /* 001: One wait state */ + + /* Bits 3-7: Reserved */ +#define FLASH_ACR_PRFTEN (1 << 8) /* Bit 8: Prefetch enable */ +#define FLASH_ACR_ICEN (1 << 9) /* Bit 9: Instruction cache enable */ + /* Bit 10:Reserved */ +#define FLASH_ACR_ICRST (1 << 11) /* Bit 11:Instruction cache reset */ + /* Bits 12-15: Reserved */ +#define FLASH_ACR_EMPTY (1 << 16) /* Bit 16: Main Flash memory area empty */ + /* Bit 17: Reserved */ +#define FLASH_ACR_DBGSWEN (1 << 18) /* Bit 18: Debug access software enable */ + /* Bits 19-31: Reserved */ + +/* TODO */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_FLASH_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_memorymap.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_memorymap.h new file mode 100644 index 00000000000..9744ca79f1d --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_memorymap.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_memorymap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_MEMORYMAP_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* ST32F05XF07X Address Blocks **********************************************/ + +#define STM32_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */ +#define STM32_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block */ +#define STM32_PERIPH_BASE 0x40000000 /* 0x40000000-0x5fffffff: 512Mb peripheral block */ + /* 0x60000000-0xdfffffff: Reserved */ +#define STM32_CORTEX_BASE 0xe0000000 /* 0xe0000000-0xffffffff: 512Mb Cortex-M0 block */ + +#define STM32_REGION_MASK 0xf0000000 +#define STM32_IS_SRAM(a) ((((uint32_t)(a)) & STM32_REGION_MASK) == STM32_SRAM_BASE) + +/* Code Base Addresses ******************************************************/ + +#define STM32_BOOT_BASE 0x00000000 /* 0x00000000-0x0001ffff: Aliased boot memory */ + /* 0x00020000-0x07ffffff: Reserved */ +#define STM32_FLASH_BASE 0x08000000 /* 0x08000000-0x0801ffff: FLASH memory */ + /* 0x08020000-0x1fffd7ff: Reserved */ +#define STM32_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff77ff: System memory */ +#define STM32_OPTION_BASE 0x1fff7800 /* 0x1fff7800-0x1fff7fff: Option bytes */ + +/* Peripheral Base Addresses ************************************************/ + +#define STM32_APB1_BASE 0x40000000 /* 0x40000000-0x4001ffff: APB1 */ +#define STM32_AHB_BASE 0x40020000 /* 0x40020000-0x400263ff: AHB */ +#define STM32_IOPORT_BASE 0x50000000 /* 0x50000000-0x50001fff: IOPORT */ + +/* APB1 Base Addresses ******************************************************/ + +#define STM32_TIM2_BASE 0x40000000 /* 0x40000000-0x400003ff TIM2 */ +#define STM32_TIM3_BASE 0x40000400 /* 0x40000400-0x400007ff TIM3 */ +#define STM32_TIM14_BASE 0x40002000 /* 0x40002000-0x400023ff TIM14 */ +#define STM32_RTC_BASE 0x40002800 /* 0x40002800-0x40002bff RTC */ +#define STM32_WWDG_BASE 0x40002c00 /* 0x40002c00-0x40002fff WWDG */ +#define STM32_IWDG_BASE 0x40003000 /* 0x40003000-0x400033ff IWDG */ +#define STM32_SPI2_BASE 0x40003800 /* 0x40003800-0x40003bff SPI2, or */ +#define STM32_USART2_BASE 0x40004400 /* 0x40004400-0x400047ff USART2 */ +#define STM32_USART3_BASE 0x40004800 /* 0x40004800-0x40004bff USART3 */ +#define STM32_USART4_BASE 0x40004c00 /* 0x40004c00-0x40004fff USART4 */ +#define STM32_I2C1_BASE 0x40005400 /* 0x40005400-0x400057ff I2C1 */ +#define STM32_I2C2_BASE 0x40005800 /* 0x40005800-0x40005bff I2C2 */ +#define STM32_USB_BASE 0x40005c00 /* 0x40005c00-0x40005fff USB */ +#define STM32_FDCAN1_BASE 0x40006400 /* 0x40006400-0x400067ff FDCAN1 */ +#define STM32_CRS_BASE 0x40006c00 /* 0x40006c00-0x40006fff CRS */ +#define STM32_PWR_BASE 0x40007000 /* 0x40007000-0x400073ff PWR */ +#define STM32_USBRAM_BASE 0x40009800 /* 0x40009800-0x40008fff USBRAM */ +#define STM32_FDCANSRAM_BASE 0x4000b800 /* 0x4000b800-0x4000cbff FDCAN scratch RAM */ +#define STM32_FDCANMRAM_BASE 0x4000b400 /* 0x4000b400-0x4000b7ff FDCAN message RAM */ +#define STM32_SYSCFG_BASE 0x40010000 /* 0x40010000-0x400103ff SYSCFG */ + /* EXTI ??? */ +#define STM32_ADC1_BASE 0x40012400 /* 0x40012400-0x400127ff ADC1 */ +#define STM32_TIM1_BASE 0x40012c00 /* 0x40012c00-0x40012fff TIM1 */ +#define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */ +#define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */ +#define STM32_TIM15_BASE 0x40014000 /* 0x40014000-0x400143ff TIM15 */ +#define STM32_TIM16_BASE 0x40014400 /* 0x40014400-0x400147ff TIM16 */ +#define STM32_TIM17_BASE 0x40014800 /* 0x40014800-0x40014bff TIM17 */ +#define STM32_DBGMCU_BASE 0x40015800 /* 0x40015800-0x40015bff DBGMCU */ + +/* AHB1 Base Addresses ******************************************************/ + +#define STM32_DMA1_BASE 0x40020000 /* 0x40020000-0x400203ff: DMA1 */ +#define STM32_DMAMUX1_BASE 0x40020800 /* 0x40020800-0x40020bff: DMAMUX */ +#define STM32_RCC_BASE 0x40021000 /* 0x40021000-0x400213ff: Reset and Clock control RCC */ +#define STM32_EXTI_BASE 0x40021800 /* 0x40021800-0x40021bff: EXTI */ +#define STM32_FLASHIF_BASE 0x40022000 /* 0x40022000-0x400223ff: Flash memory interface */ +#define STM32_CRC_BASE 0x40023000 /* 0x40023000-0x400233ff: CRC */ + +/* AHB2 Base Addresses ******************************************************/ + +#define STM32_GPIOA_BASE 0x50000000 /* 0x50000000-0x500003ff: GPIO Port A */ +#define STM32_GPIOB_BASE 0x50000400 /* 0x50000400-0x500007ff: GPIO Port B */ +#define STM32_GPIOC_BASE 0x50000800 /* 0x50000800-0x50000bff: GPIO Port C */ +#define STM32_GPIOD_BASE 0X50000C00 /* 0x50000c00-0x50000fff: GPIO Port D */ +#define STM32_GPIOF_BASE 0x50001400 /* 0x50001400-0x500017ff: GPIO Port F */ + +/* Cortex-M4 Base Addresses *************************************************/ + +/* Other registers -- see armv7-m/nvic.h for standard Cortex-M4 registers in + * this address range + */ + +#define STM32_SCS_BASE 0xe000e000 +#define STM32_DEBUGMCU_BASE 0xe0042000 + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_MEMORYMAP_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_pinmap.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_pinmap.h new file mode 100644 index 00000000000..04277439d3e --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_pinmap.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_pinmap.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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_STM32F0L0G0_HARDWARE_STM32C0_PINMAP_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_PINMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "stm32_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Alternate Pin Functions. + * + * Alternative pin selections are provided with a numeric suffix like _1, _2, + * etc. Drivers, however, will use the pin selection without the numeric + * suffix. Additional definitions are required in the board.h file. For + * example, if CAN1_RX connects via PA11 on some board, then the following + * definitions should appear in the board.h header file for that board: + * + * #define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 + * + * The driver will then automatically configure PB6 as the I2C1 SCL pin. + */ + +/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! + * Additional effort is required to select specific GPIO options such as + * frequency, open-drain/push-pull, and pull-up/down! Just the basics are + * defined for most pins in this file. + */ + +/* ADC */ + +#define GPIO_ADC1_IN0_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN0) +#define GPIO_ADC1_IN1_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN1) +#define GPIO_ADC1_IN2_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN2) +#define GPIO_ADC1_IN3_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN3) +#define GPIO_ADC1_IN4_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN4) +#define GPIO_ADC1_IN5_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN5) +#define GPIO_ADC1_IN6_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN6) +#define GPIO_ADC1_IN7_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN7) +#define GPIO_ADC1_IN8_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN8) + +#define GPIO_ADC1_IN11_0 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN4) +#define GPIO_ADC1_IN12_0 (GPIO_ANALOG | GPIO_PORTC | GPIO_PIN5) +#define GPIO_ADC1_IN13_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN13) +#define GPIO_ADC1_IN14_0 (GPIO_ANALOG | GPIO_PORTA | GPIO_PIN14) + +#define GPIO_ADC1_IN17_0 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN0) +#define GPIO_ADC1_IN18_0 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN1) +#define GPIO_ADC1_IN19_0 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN2) +#define GPIO_ADC1_IN20_0 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN10) +#define GPIO_ADC1_IN21_0 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN11) +#define GPIO_ADC1_IN22_0 (GPIO_ANALOG | GPIO_PORTB | GPIO_PIN12) + +/* USART */ + +#define GPIO_USART1_CTS_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN11) +#define GPIO_USART1_CTS_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN4) +#define GPIO_USART1_RTS_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN12) +#define GPIO_USART1_RTS_2 (GPIO_ALT | GPIO_AF4 | GPIO_PORTB | GPIO_PIN3) +#define GPIO_USART1_RX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN10) +#define GPIO_USART1_RX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF0 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN7) +#define GPIO_USART1_RX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN5) +#define GPIO_USART1_TX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN9) +#define GPIO_USART1_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF0 | GPIO_PUSHPULL | GPIO_PORTB | GPIO_PIN6) +#define GPIO_USART1_TX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTC | GPIO_PIN4) + +#define GPIO_USART2_CTS_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN0) +#define GPIO_USART2_CTS_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN3) +#define GPIO_USART2_RTS_1 (GPIO_ALT | GPIO_AF1 | GPIO_PORTA | GPIO_PIN1) +#define GPIO_USART2_RTS_2 (GPIO_ALT | GPIO_AF0 | GPIO_PORTD | GPIO_PIN4) +#define GPIO_USART2_RX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN3) +#define GPIO_USART2_RX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN15) +#define GPIO_USART2_RX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN6) +#define GPIO_USART2_TX_1 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN2) +#define GPIO_USART2_TX_2 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTA | GPIO_PIN14) +#define GPIO_USART2_TX_3 (GPIO_ALT | GPIO_PULLUP | GPIO_AF1 | GPIO_PUSHPULL | GPIO_PORTD | GPIO_PIN6) + +/* TODO: missing pinmaps */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_PINMAP_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_pwr.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_pwr.h new file mode 100644 index 00000000000..85f4b1658a4 --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_pwr.h @@ -0,0 +1,165 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_pwr.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_PWR_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_PWR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define STM32_PWR_CR1_OFFSET 0x0000 /* Power control register 1 */ +#define STM32_PWR_CR2_OFFSET 0x0004 /* Power control register 2 */ +#define STM32_PWR_CR3_OFFSET 0x0008 /* Power control register 3 */ +#define STM32_PWR_CR4_OFFSET 0x000C /* Power control register 4 */ +#define STM32_PWR_SR1_OFFSET 0x0010 /* Power status register 1 */ +#define STM32_PWR_SR2_OFFSET 0x0014 /* Power status register 2 */ +#define STM32_PWR_SCR_OFFSET 0x0018 /* Power status clear register */ +#define STM32_PWR_PUCRA_OFFSET 0x0020 /* Power Port A pull-up control register */ +#define STM32_PWR_PDCRA_OFFSET 0x0024 /* Power Port A pull-down control register */ +#define STM32_PWR_PUCRB_OFFSET 0x0028 /* Power Port B pull-up control register */ +#define STM32_PWR_PDCRB_OFFSET 0x002C /* Power Port B pull-down control register */ +#define STM32_PWR_PUCRC_OFFSET 0x0030 /* Power Port C pull-up control register */ +#define STM32_PWR_PDCRC_OFFSET 0x0034 /* Power Port C pull-down control register */ +#define STM32_PWR_PUCRD_OFFSET 0x0038 /* Power Port D pull-up control register */ +#define STM32_PWR_PDCRD_OFFSET 0x003C /* Power Port D pull-down control register */ +#define STM32_PWR_PUCRF_OFFSET 0x0048 /* Power Port F pull-up control register */ +#define STM32_PWR_PDCRF_OFFSET 0x004C /* Power Port F pull-down control register */ +#define STM32_PWR_PUCRG_OFFSET 0x0050 /* Power Port G pull-up control register */ +#define STM32_PWR_PDCRG_OFFSET 0x0054 /* Power Port G pull-down control register */ +#define STM32_PWR_PUCRH_OFFSET 0x0058 /* Power Port H pull-up control register */ +#define STM32_PWR_PDCRH_OFFSET 0x005C /* Power Port H pull-down control register */ +#define STM32_PWR_PUCRI_OFFSET 0x0060 /* Power Port I pull-up control register */ +#define STM32_PWR_PDCRI_OFFSET 0x0064 /* Power Port I pull-down control register */ + +/* Register Addresses *******************************************************/ + +#define STM32_PWR_CR1 (STM32_PWR_BASE+STM32_PWR_CR1_OFFSET) +#define STM32_PWR_CR2 (STM32_PWR_BASE+STM32_PWR_CR2_OFFSET) +#define STM32_PWR_CR3 (STM32_PWR_BASE+STM32_PWR_CR3_OFFSET) +#define STM32_PWR_CR4 (STM32_PWR_BASE+STM32_PWR_CR4_OFFSET) +#define STM32_PWR_SR1 (STM32_PWR_BASE+STM32_PWR_SR1_OFFSET) +#define STM32_PWR_SR2 (STM32_PWR_BASE+STM32_PWR_SR2_OFFSET) +#define STM32_PWR_SCR (STM32_PWR_BASE+STM32_PWR_SCR_OFFSET) +#define STM32_PWR_PUCRA (STM32_PWR_BASE+STM32_PWR_PUCRA_OFFSET) +#define STM32_PWR_PDCRA (STM32_PWR_BASE+STM32_PWR_PDCRA_OFFSET) +#define STM32_PWR_PUCRB (STM32_PWR_BASE+STM32_PWR_PUCRB_OFFSET) +#define STM32_PWR_PDCRB (STM32_PWR_BASE+STM32_PWR_PDCRB_OFFSET) +#define STM32_PWR_PUCRC (STM32_PWR_BASE+STM32_PWR_PUCRC_OFFSET) +#define STM32_PWR_PDCRC (STM32_PWR_BASE+STM32_PWR_PDCRC_OFFSET) +#define STM32_PWR_PUCRD (STM32_PWR_BASE+STM32_PWR_PUCRD_OFFSET) +#define STM32_PWR_PDCRD (STM32_PWR_BASE+STM32_PWR_PDCRD_OFFSET) +#define STM32_PWR_PUCRE (STM32_PWR_BASE+STM32_PWR_PUCRE_OFFSET) +#define STM32_PWR_PDCRE (STM32_PWR_BASE+STM32_PWR_PDCRE_OFFSET) +#define STM32_PWR_PUCRF (STM32_PWR_BASE+STM32_PWR_PUCRF_OFFSET) +#define STM32_PWR_PDCRF (STM32_PWR_BASE+STM32_PWR_PDCRF_OFFSET) +#define STM32_PWR_PUCRG (STM32_PWR_BASE+STM32_PWR_PUCRG_OFFSET) +#define STM32_PWR_PDCRG (STM32_PWR_BASE+STM32_PWR_PDCRG_OFFSET) +#define STM32_PWR_PUCRH (STM32_PWR_BASE+STM32_PWR_PUCRH_OFFSET) +#define STM32_PWR_PDCRH (STM32_PWR_BASE+STM32_PWR_PDCRH_OFFSET) +#define STM32_PWR_PUCRI (STM32_PWR_BASE+STM32_PWR_PUCRI_OFFSET) +#define STM32_PWR_PDCRI (STM32_PWR_BASE+STM32_PWR_PDCRI_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Power control register 1 */ + +#define PWR_CR1_LPMS_SHIFT (0) /* Bits 0-2: Low-power mode selection */ +#define PWR_CR1_LPMS_MASK (7 << PWR_CR1_LPMS_SHIFT) +# define PWR_CR1_LPMS_STOP1MR (0 << PWR_CR1_LPMS_SHIFT) /* Stop 1 mode with main regulator (MR) */ +# define PWR_CR1_LPMS_STOP1LPR (1 << PWR_CR1_LPMS_SHIFT) /* Stop 1 mode with low-power regulator (LPR) */ +# define PWR_CR1_LPMS_STOP2 (2 << PWR_CR1_LPMS_SHIFT) /* 010: Stop 2 mode */ +# define PWR_CR1_LPMS_STANDBY (3 << PWR_CR1_LPMS_SHIFT) /* 011: Standby mode */ +# define PWR_CR1_LPMS_SHUTDOWN (4 << PWR_CR1_LPMS_SHIFT) /* 1xx: Shutdown mode */ + +#define PWR_CR1_FPDSTOP (1 << 3) /* Bit 3: Flash memory powered down during Stop mode */ + /* Bit 4: Reserved */ +#define PWR_CR1_FPDLPSLP (1 << 5) /* Bit 5: Flash memory powered down during Low-power sleep mode */ + /* Bits 6-31: Reserved */ +#define PWR_CR1_DBP (1 << 8) /* Bit 8: Disable Backup domain write protection */ +#define PWR_CR1_VOS_SHIFT (9) /* Bits 9-10: Voltage scaling range selection */ +#define PWR_CR1_VOS_MASK (3 << PWR_CR1_VOS_SHIFT) +# define PWR_CR1_VOS_RANGE1 (1 << PWR_CR1_VOS_SHIFT) /* 01: Range 1 */ +# define PWR_CR1_VOS_RANGE2 (2 << PWR_CR1_VOS_SHIFT) /* 10: Range 2 */ + +#define PWR_CR1_LPR (1 << 14) /* Bit 14: Low-power run */ + +/* Power control register 2 */ + +#define PWR_CR2_VDDIO2_SHIFT (8) /* Bits 8-9: VDDIO2 supply voltage monitoring */ +#define PWR_CR2_VDDIO2_MASK (3 << PWR_CR2_PLS_SHIFT) + +/* Power control register 3 */ + +#define PWR_CR3_EWUP1 (1 << 0) /* Bit 0: Enable Wakeup pin WKUP1 */ +#define PWR_CR3_EWUP2 (1 << 1) /* Bit 1: Enable Wakeup pin WKUP2 */ +#define PWR_CR3_EWUP3 (1 << 2) /* Bit 2: Enable Wakeup pin WKUP3 */ +#define PWR_CR3_EWUP4 (1 << 3) /* Bit 3: Enable Wakeup pin WKUP4 */ +#define PWR_CR3_EWUP5 (1 << 4) /* Bit 4: Enable Wakeup pin WKUP5 */ +#define PWR_CR3_EWUP6 (1 << 5) /* Bit 5: Enable Wakeup pin WKUP6 */ +#define PWR_CR3_APC (1 << 10) /* Bit 10: Apply pull-up and pull-down configuration */ +#define PWR_CR3_EIWUL (1 << 15) /* Bit 15: Enable internal wakeup line */ + +/* Power control register 4 */ + +#define PWR_CR4_WP1 (1 << 0) /* Bit 0: Wakeup pin WKUP1 polarity */ +#define PWR_CR4_WP2 (1 << 1) /* Bit 1: Wakeup pin WKUP2 polarity */ +#define PWR_CR4_WP3 (1 << 2) /* Bit 2: Wakeup pin WKUP3 polarity */ +#define PWR_CR4_WP4 (1 << 3) /* Bit 3: Wakeup pin WKUP4 polarity */ +#define PWR_CR4_WP5 (1 << 4) /* Bit 4: Wakeup pin WKUP5 polarity */ +#define PWR_CR4_WP6 (1 << 5) /* Bit 5: Wakeup pin WKUP6 polarity */ + +/* Power status register 1 */ + +#define PWR_SR1_WUF1 (1 << 0) /* Bit 0: Wakeup flag 1 */ +#define PWR_SR1_WUF2 (1 << 1) /* Bit 1: Wakeup flag 2 */ +#define PWR_SR1_WUF3 (1 << 2) /* Bit 2: Wakeup flag 3 */ +#define PWR_SR1_WUF4 (1 << 3) /* Bit 3: Wakeup flag 4 */ +#define PWR_SR1_WUF5 (1 << 4) /* Bit 4: Wakeup flag 5 */ +#define PWR_SR1_WUF6 (1 << 5) /* Bit 5: Wakeup flag 6 */ +#define PWR_SR1_SBF (1 << 8) /* Bit 8: Standby flag */ +#define PWR_SR1_WUFI (1 << 15) /* Bit 15: Wakeup internal flag */ + +/* Power status register 2 */ + +#define PWR_SR2_FLASHRDY (1 << 7) /* Bit 7: Flash ready flag */ +#define PWR_SR2_VDDIO2 (1 << 13) /* Bit 13: VDDIO2 supply voltage monitoring output flag */ + +/* Power status clear register */ + +#define PWR_SCR_CWUF1 (1 << 0) /* Bit 0: Clear wakeup flag 1 */ +#define PWR_SCR_CWUF2 (1 << 1) /* Bit 1: Clear wakeup flag 2 */ +#define PWR_SCR_CWUF3 (1 << 2) /* Bit 2: Clear wakeup flag 3 */ +#define PWR_SCR_CWUF4 (1 << 3) /* Bit 3: Clear wakeup flag 4 */ +#define PWR_SCR_CWUF5 (1 << 4) /* Bit 4: Clear wakeup flag 5 */ +#define PWR_SCR_CSBF (1 << 8) /* Bit 8: Clear standby flag */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_PWR_H */ diff --git a/arch/arm/src/stm32f0l0g0/hardware/stm32c0_rcc.h b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_rcc.h new file mode 100644 index 00000000000..1affcfaf74e --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/hardware/stm32c0_rcc.h @@ -0,0 +1,368 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/hardware/stm32c0_rcc.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_RCC_H +#define __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_RCC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* NOTE: STM32C0 does not have separate APB1 and APB2 buses, but uses single + * APB bus, however, divided into two sets of registers. For compatibility + * with other families, we leave the register names as APB1xx and APB2yy. + */ + +/* Register Offsets *********************************************************/ + +#define STM32_RCC_CR_OFFSET 0x0000 /* Clock control register */ +#define STM32_RCC_ICSCR_OFFSET 0x0004 /* Internal clock sources calibration register */ +#define STM32_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */ +#define STM32_RCC_CRRCR_OFFSET 0x0014 /* Clock recovery RC register */ +#define STM32_RCC_CIER_OFFSET 0x0018 /* Clock Source Interrupt enable register */ +#define STM32_RCC_CIFR_OFFSET 0x001c /* Clock Source Interrupt Flag register */ +#define STM32_RCC_CICR_OFFSET 0x0020 /* Clock Source Interrupt Clear register */ +#define STM32_RCC_IOPRSTR_OFFSET 0x0024 /* GPIO reset register */ +#define STM32_RCC_AHBRSTR_OFFSET 0x0028 /* AHB peripheral reset register */ +#define STM32_RCC_APB1RSTR_OFFSET 0x002c /* APB Peripheral reset register 1 */ +#define STM32_RCC_APB2RSTR_OFFSET 0x0030 /* APB Peripheral reset register 2 */ +#define STM32_RCC_IOPENR_OFFSET 0x0034 /* GPIO clock enable register */ +#define STM32_RCC_AHBENR_OFFSET 0x0038 /* AHB Peripheral Clock enable register */ +#define STM32_RCC_APB1ENR_OFFSET 0x003c /* APB Peripheral Clock enable register 1 */ +#define STM32_RCC_APB2ENR_OFFSET 0x0040 /* APB Peripheral Clock enable register 2 */ +#define STM32_RCC_IOPSMEN_OFFSET 0x0044 /* GPIO clock enable in Sleep mode register */ +#define STM32_RCC_AHBSMENR_OFFSET 0x0048 /* AHB peripheral clock enable in Sleep mode register */ +#define STM32_RCC_APBSMENR1_OFFSET 0x004c /* APB peripheral clock enable in Sleep mode register 1 */ +#define STM32_RCC_APBSMENR2_OFFSET 0x0050 /* APB peripheral clock enable in Sleep mode register 2 */ +#define STM32_RCC_CCIPR1_OFFSET 0x0054 /* Clock configuration register 1 */ +#define STM32_RCC_CCIPR2_OFFSET 0x0058 /* Clock configuration register 2 */ +#define STM32_RCC_CSR1_OFFSET 0x005c /* Control/status register 1 */ +#define STM32_RCC_CSR2_OFFSET 0x0060 /* Control/status register 2*/ + +/* Register Addresses *******************************************************/ + +#define STM32_RCC_CR (STM32_RCC_BASE+STM32_RCC_CR_OFFSET) +#define STM32_RCC_ICSCR (STM32_RCC_BASE+STM32_RCC_ICSCR_OFFSET) +#define STM32_RCC_CFGR (STM32_RCC_BASE+STM32_RCC_CFGR_OFFSET) +#define STM32_RCC_CRRCR (STM32_RCC_BASE+STM32_RCC_CRRCR_OFFSET) +#define STM32_RCC_CIER (STM32_RCC_BASE+STM32_RCC_CIER_OFFSET) +#define STM32_RCC_CIFR (STM32_RCC_BASE+STM32_RCC_CIFR_OFFSET) +#define STM32_RCC_CICR (STM32_RCC_BASE+STM32_RCC_CICR_OFFSET) +#define STM32_RCC_IOPRSTR (STM32_RCC_BASE+STM32_RCC_IOPRSTR_OFFSET) +#define STM32_RCC_AHBRSTR (STM32_RCC_BASE+STM32_RCC_AHBRSTR_OFFSET) +#define STM32_RCC_APB1RSTR (STM32_RCC_BASE+STM32_RCC_APB1RSTR_OFFSET) +#define STM32_RCC_APB2RSTR (STM32_RCC_BASE+STM32_RCC_APB2RSTR_OFFSET) +#define STM32_RCC_IOPENR (STM32_RCC_BASE+STM32_RCC_IOPENR_OFFSET) +#define STM32_RCC_AHBENR (STM32_RCC_BASE+STM32_RCC_AHBENR_OFFSET) +#define STM32_RCC_APB1ENR (STM32_RCC_BASE+STM32_RCC_APB1ENR_OFFSET) +#define STM32_RCC_APB2ENR (STM32_RCC_BASE+STM32_RCC_APB2ENR_OFFSET) +#define STM32_RCC_IOPSMEN (STM32_RCC_BASE+STM32_RCC_IOPSMEN_OFFSET) +#define STM32_RCC_AHBSMENR (STM32_RCC_BASE+STM32_RCC_AHBSMENR_OFFSET) +#define STM32_RCC_APBSMENR1 (STM32_RCC_BASE+STM32_RCC_APBSMENR1_OFFSET) +#define STM32_RCC_APBSMENR2 (STM32_RCC_BASE+STM32_RCC_APBSMENR2_OFFSET) +#define STM32_RCC_CCIPR1 (STM32_RCC_BASE+STM32_RCC_CCIPR1_OFFSET) +#define STM32_RCC_CCIPR2 (STM32_RCC_BASE+STM32_RCC_CCIPR2_OFFSET) +#define STM32_RCC_CSR1 (STM32_RCC_BASE+STM32_RCC_CSR1_OFFSET) +#define STM32_RCC_CSR2 (STM32_RCC_BASE+STM32_RCC_CSR2_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +/* Clock control register */ + + /* Bits 0-1: Reserved */ + +#define RCC_CR_SYSDIV_SHIFT (2) /* Bit 2-4: Clock division factor for system clock */ +#define RCC_CR_HSIKERDIV_SHIFT (5) /* Bit 5-7: HSI48 kernel clock division factor */ +#define RCC_CR_HSION (1 << 8) /* Bit 8: Internal high speed clock enable */ +#define RCC_CR_HSIKERON (1 << 9) /* Bit 9: Internal high speed clock enable for some IP kernels */ +#define RCC_CR_HSIRDY (1 << 10) /* Bit 10: Internal high speed clock ready flag */ +#define RCC_CR_HSIDIV_SHIFT (11) /* Bit 11: Internal high speed clock divider */ +#define RCC_CR_HSIDIV_MASK (7 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSI (0 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId2 (1 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId4 (2 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId8 (3 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId16 (4 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId32 (5 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId64 (6 << RCC_CR_HSIDIV_SHIFT) +#define RCC_CR_HSIDIV_HSId128 (7 << RCC_CR_HSIDIV_SHIFT) + /* Bits 14-15: Reserved */ +#define RCC_CR_HSEON (1 << 16) /* Bit 16: External high speed clock enable */ +#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External high speed clock ready flag */ +#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External high speed clock bypass */ + +#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock security system enable */ + /* Bits 20-21: Reserved */ +#define RCC_CR_HSIUSB48ON (1 << 22) /* Bit 22: HSIUSB48 clock enable */ +#define RCC_CR_HSIUSB48RDY (1 << 23) /* Bit 23: HSIUSB48 clock ready flag */ + /* Bits 24-31: Reserved */ + +#define RCC_CR_RESET 0x00001540 + +/* Internal clock sources calibration register */ + +#define RCC_ICSCR_HSICAL_SHIFT (0) /* Bits 0-7: Internal high speed clock calibration */ +#define RCC_ICSCR_HSICAL_MASK (0xff << RCC_ICSCR_HSICAL_SHIFT) +#define RCC_ICSCR_HSITRIM_SHIFT (8) /* Bits 8-12: High speed internal clock trimming */ +#define RCC_ICSCR_HSITRIM_MASK (0x1f << RCC_ICSCR_HSITRIM_SHIFT) +#define RCC_ICSCR_MSIRANGE_SHIFT (13) /* Bits 13-15: MSI clock ranges */ +#define RCC_ICSCR_MSIRANGE_MASK (7 << RCC_ICSCR_MSIRANGE_SHIFT) +# define RCC_ICSCR_MSIRANGE_0 (0 << RCC_ICSCR_MSIRANGE_SHIFT) /* 000: Range 0 around 65.536 kHz */ +# define RCC_ICSCR_MSIRANGE_1 (1 << RCC_ICSCR_MSIRANGE_SHIFT) /* 001: Range 1 around 131.072 kHz */ +# define RCC_ICSCR_MSIRANGE_2 (2 << RCC_ICSCR_MSIRANGE_SHIFT) /* 010: Range 2 around 262.144 kHz */ +# define RCC_ICSCR_MSIRANGE_3 (3 << RCC_ICSCR_MSIRANGE_SHIFT) /* 011: Range 3 around 524.288 kHz */ +# define RCC_ICSCR_MSIRANGE_4 (4 << RCC_ICSCR_MSIRANGE_SHIFT) /* 100: Range 4 around 1.048 MHz */ +# define RCC_ICSCR_MSIRANGE_5 (5 << RCC_ICSCR_MSIRANGE_SHIFT) /* 101: Range 5 around 2.097 MHz (reset value) */ +# define RCC_ICSCR_MSIRANGE_6 (6 << RCC_ICSCR_MSIRANGE_SHIFT) /* 110: Range 6 around 4.194 MHz */ +#define RCC_ICSCR_MSICAL_SHIFT (16) /* Bits 16-23: MSI clock calibration */ +#define RCC_ICSCR_MSICAL_MASK (0xff << RCC_ICSCR_MSICAL_SHIFT) +#define RCC_ICSCR_MSITRIM_SHIFT (24) /* Bits 24-31: MSI clock trimming */ +#define RCC_ICSCR_MSITRIM_MASK (0xff << RCC_ICSCR_MSITRIM_SHIFT) + +#define RCC_ICSR_RSTVAL 0x0000b000 + +/* Clock recovery RC register */ + +#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) + /* Bits 16-31: Reserved */ + +/* Clock configuration register */ + +#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-2: System clock Switch */ +#define RCC_CFGR_SW_MASK (7 << RCC_CFGR_SW_SHIFT) +# define RCC_CFGR_SW_HSI (0 << RCC_CFGR_SW_SHIFT) /* 000: HSI selected as system clock */ +# define RCC_CFGR_SW_HSE (1 << RCC_CFGR_SW_SHIFT) /* 001: HSE selected as system clock */ +# define RCC_CFGR_SW_HSIUSB48 (2 << RCC_CFGR_SW_SHIFT) /* 010: HSIUSB48 selected as system clock */ +# define RCC_CFGR_SW_LSI (3 << RCC_CFGR_SW_SHIFT) /* 011: LSI selected as system clock */ +# define RCC_CFGR_SW_LSE (4 << RCC_CFGR_SW_SHIFT) /* 100: LSE selected as system clock */ +#define RCC_CFGR_SWS_SHIFT (3) /* Bits 2-3: System Clock Switch Status */ +#define RCC_CFGR_SWS_MASK (7 << RCC_CFGR_SWS_SHIFT) +# define RCC_CFGR_SWS_HSI (0 << RCC_CFGR_SWS_SHIFT) /* 000: HSI used as system clock */ +# define RCC_CFGR_SWS_HSE (1 << RCC_CFGR_SWS_SHIFT) /* 001: HSE used as system clock */ +# define RCC_CFGR_SWS_HSIUSB48 (2 << RCC_CFGR_SWS_SHIFT) /* 010: HSIUSB48 used as system clock */ +# define RCC_CFGR_SWS_LSI (3 << RCC_CFGR_SWS_SHIFT) /* 011: LSI used as system clock */ +# define RCC_CFGR_SWS_LSE (4 << RCC_CFGR_SWS_SHIFT) /* 100: LSE used as system clock */ + /* Bits 6-7: Reserved */ +#define RCC_CFGR_HPRE_SHIFT (8) /* Bits 8-11: AHB prescaler */ +#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT) +# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */ +# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */ +# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */ +# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */ +# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */ +# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */ +# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */ +# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */ +# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */ + +#define RCC_CFGR_PPRE_SHIFT (12) /* Bits 12-14: APB Low speed prescaler (APB) */ +#define RCC_CFGR_PPRE_MASK (7 << RCC_CFGR_PPRE_SHIFT) +# define RCC_CFGR_PPRE_HCLK (0 << RCC_CFGR_PPRE_SHIFT) /* 0xx: HCLK not divided */ +# define RCC_CFGR_PPRE_HCLKd2 (4 << RCC_CFGR_PPRE_SHIFT) /* 100: HCLK divided by 2 */ +# define RCC_CFGR_PPRE_HCLKd4 (5 << RCC_CFGR_PPRE_SHIFT) /* 101: HCLK divided by 4 */ +# define RCC_CFGR_PPRE_HCLKd8 (6 << RCC_CFGR_PPRE_SHIFT) /* 110: HCLK divided by 8 */ +# define RCC_CFGR_PPRE_HCLKd16 (7 << RCC_CFGR_PPRE_SHIFT) /* 111: HCLK divided by 16 */ + /* Bit 15: Reserved */ + /* TODO: MCO bits */ +#define RCC_CFGR_RESET 0x00000000 + +/* Clock Source Interrupt enable register */ + +#define RCC_CIER_LSIRDYF (1 << 0) /* Bit 0: LSI ready interrupt flag */ +#define RCC_CIER_LSERDYF (1 << 1) /* Bit 1: LSE ready interrupt flag */ +#define RCC_CIER_HSIUSB48RDYE (1 << 2) /* Bit 2: HSI48USB ready interrupt flag */ +#define RCC_CIER_HSIRDYF (1 << 3) /* Bit 3: HSI ready interrupt flag */ +#define RCC_CIER_HSERDYF (1 << 5) /* Bit 5: MSE ready interrupt flag */ + +/* Clock Source Interrupt Flag register */ + +#define RCC_CIFR_LSIRDYF (1 << 0) /* Bit 0: LSI ready interrupt flag */ +#define RCC_CIFR_LSERDYF (1 << 1) /* Bit 1: LSE ready interrupt flag */ +#define RCC_CIFR_HSIUSB48RDYE (1 << 2) /* Bit 2: HSI16 ready interrupt flag */ +#define RCC_CIFR_HSIRDYF (1 << 3) /* Bit 3: HSI ready interrupt flag */ +#define RCC_CIFR_HSERDYF (1 << 5) /* Bit 5: MSE ready interrupt flag */ + +/* Clock Source Interrupt Clear register */ + +#define RCC_CICR_LSIRDYF (1 << 0) /* Bit 0: LSI ready interrupt flag */ +#define RCC_CICR_LSERDYF (1 << 1) /* Bit 1: LSE ready interrupt flag */ +#define RCC_CICR_HSIUSB48RDYE (1 << 2) /* Bit 2: HSI16 ready interrupt flag */ +#define RCC_CICR_HSIRDYF (1 << 3) /* Bit 3: HSI ready interrupt flag */ +#define RCC_CICR_HSERDYF (1 << 5) /* Bit 5: MSE ready interrupt flag */ + +/* GPIO reset register */ + +#define RCC_IOPRSTR_IOPARST (1 << 0) /* Bit 0: IO port A reset */ +#define RCC_IOPRSTR_IOPBRST (1 << 1) /* Bit 1: IO port B reset */ +#define RCC_IOPRSTR_IOPCRST (1 << 2) /* Bit 2: IO port C reset */ +#define RCC_IOPRSTR_IOPDRST (1 << 3) /* Bit 3: IO port D reset */ +#define RCC_IOPRSTR_IOPFRST (1 << 5) /* Bit 5: IO port F reset */ + +/* AHB peripheral reset register */ + +#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-31: Reserved */ + +/* APB Peripheral reset register 1 */ + +#define RCC_APB1RSTR_TIM2RST (1 << 0) /* Bit 0: Timer 2 reset */ +#define RCC_APB1RSTR_TIM3RST (1 << 1) /* Bit 1: Timer 3 reset */ + /* Bits 2-11: Reserved */ +#define RCC_APB1RSTR_FDCANRST (1 << 11) /* Bit 11: FDCAN reset */ + /* Bit 12: Reserved */ +#define RCC_APB1RSTR_SPI2RST (1 << 14) /* Bit 14: SPI 2 reset */ +#define RCC_APB1RSTR_USBRST (1 << 15) /* Bit 15: USB reset */ +#define RCC_APB1RSTR_CRCRST (1 << 16) /* Bit 15: CRC reset */ +#define RCC_APB1RSTR_USART2RST (1 << 17) /* Bit 17: USART 2 reset */ +#define RCC_APB1RSTR_USART3RST (1 << 18) /* Bit 18: USART 3 reset */ +#define RCC_APB1RSTR_USART4RST (1 << 19) /* Bit 19: USART 4 reset */ + /* Bit 20: Reserved */ +#define RCC_APB1RSTR_I2C1RST (1 << 21) /* Bit 21: I2C 1 reset */ + /* Bits 22-26: Reserved */ +#define RCC_APB1RSTR_DBGRST (1 << 27) /* Bit 27: Debug interface reset */ +#define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ + /* Bits 29-31: Reserved */ + +/* APB Peripheral reset register 2 */ + +#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: SYSCFG reset */ + /* Bits 1-10: Reserved */ +#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 reset */ +#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */ + /* Bit 13: Reserved */ +#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ +#define RCC_APB2RSTR_TIM14RST (1 << 14) /* Bit 14: TIM14 reset */ +#define RCC_APB2RSTR_TIM15RST (1 << 15) /* Bit 15: TIM15 reset */ +#define RCC_APB2RSTR_TIM16RST (1 << 16) /* Bit 16: TIM16 reset */ +#define RCC_APB2RSTR_TIM17RST (1 << 17) /* Bit 17: TIM17 reset */ + /* Bit 19: Reserved */ +#define RCC_APB2RSTR_ADC1RST (1 << 20) /* Bit 20: ADC reset */ + /* Bits 21-31: Reserved */ + +/* GPIO clock enable register */ + +#define RCC_IOPENR_IOPAEN (1 << 0) /* Bit 0: IO port A clock enable */ +#define RCC_IOPENR_IOPBEN (1 << 1) /* Bit 1: IO port B clock enable */ +#define RCC_IOPENR_IOPCEN (1 << 2) /* Bit 2: IO port C clock enable */ +#define RCC_IOPENR_IOPDEN (1 << 3) /* Bit 3: IO port D clock enable */ +#define RCC_IOPENR_IOPFEN (1 << 5) /* Bit 5: IO port F clock enable */ + +/* AHB Peripheral Clock enable register */ + +#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-31: Reserved */ + +/* APB Peripheral Clock enable register 1 */ + +#define RCC_APB1ENR_TIM2EN (1 << 0) /* Bit 0: Timer 2 clock enable */ +#define RCC_APB1ENR_TIM3EN (1 << 1) /* Bit 1: Timer 3 clock enable */ + /* Bits 2-11: Reserved */ +#define RCC_APB1ENR_FDCANEN (1 << 11) /* Bit 11: FDCAN clock enable */ + /* Bit 12: Reserved */ +#define RCC_APB1ENR_SPI2EN (1 << 14) /* Bit 14: SPI 2 clock enable */ +#define RCC_APB1ENR_USBEN (1 << 15) /* Bit 15: USB clock enable */ +#define RCC_APB1ENR_CRCEN (1 << 16) /* Bit 15: CRC clock enable */ +#define RCC_APB1ENR_USART2EN (1 << 17) /* Bit 17: USART 2 clock enable */ +#define RCC_APB1ENR_USART3EN (1 << 18) /* Bit 18: USART 3 clock enable */ +#define RCC_APB1ENR_USART4EN (1 << 19) /* Bit 19: USART 4 clock enable */ + /* Bit 20: Reserved */ +#define RCC_APB1ENR_I2C1EN (1 << 21) /* Bit 21: I2C 1 clock enable */ + /* Bits 22-26: Reserved */ +#define RCC_APB1ENR_DBGEN (1 << 27) /* Bit 27: Debug interface clock enable */ +#define RCC_APB1ENR_PWREN (1 << 28) /* Bit 28: Power interface clock enable */ + /* Bits 29-31: Reserved */ + +/* APB Peripheral Clock enable register 2 */ + +#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: SYSCFG clock enable */ + /* Bits 1-10: Reserved */ +#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 clock enable */ +#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 clock enable */ + /* Bit 13: Reserved */ +#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 clock enable */ +#define RCC_APB2ENR_TIM14EN (1 << 14) /* Bit 14: TIM14 clock enable */ +#define RCC_APB2ENR_TIM15EN (1 << 15) /* Bit 15: TIM15 clock enable */ +#define RCC_APB2ENR_TIM16EN (1 << 16) /* Bit 16: TIM16 clock enable */ +#define RCC_APB2ENR_TIM17EN (1 << 17) /* Bit 17: TIM17 clock enable */ + /* Bit 19: Reserved */ +#define RCC_APB2ENR_ADC1EN (1 << 20) /* Bit 20: ADC clock enable */ + /* Bits 21-31: Reserved */ + +/* TODO: GPIO clock enable in Sleep mode register */ + +/* TODO: AHB peripheral clock enable in Sleep mode register */ + +/* TODO: APB1 peripheral clock enable in Sleep mode register */ + +/* Clock configuration register 1 */ + +#define RCC_CSR1_LSEON (1 << 0) /* Bit 0: LSE enable */ +#define RCC_CSR1_LSERDY (1 << 1) /* Bit 1: LSE ready */ +#define RCC_CSR1_LSEBPY (1 << 2) /* Bit 2: LSE bypass */ +#define RCC_CSR1_LSEDRV_SHIFT (1 << 3) /* Bit 3: LSE driving capability */ + /* Bit 4: Reserved */ +#define RCC_CSR1_CSSLSEON (1 << 5) /* Bit 5: CSS on LSE enable */ +#define RCC_CSR1_CSSLSED (1 << 6) /* Bit 6: CSS on LSE failure detection flag */ + /* Bit 7: Reserved */ +#define RCC_CSR1_RTCSEL_SHIFT (8) /* Bits 8-9: RTC clock source selection */ +#define RCC_CSR1_RTCSEL_MASK (3 << RCC_CSR1_RTCSEL_SHIFT) +# define RCC_CSR1_RTCSEL_NOCLK (0 << RCC_CSR1_RTCSEL_SHIFT) +# define RCC_CSR1_RTCSEL_LSE (1 << RCC_CSR1_RTCSEL_SHIFT) +# define RCC_CSR1_RTCSEL_LSI (2 << RCC_CSR1_RTCSEL_SHIFT) +# define RCC_CSR1_RTCSEL_HSEd32 (3 << RCC_CSR1_RTCSEL_SHIFT) + /* Bits 10-14: Reserved */ +#define RCC_CSR1_RTCEN (1 << 15) /* Bit 15: RTC clock enable */ +#define RCC_CSR1_RTCRST (1 << 16) /* Bit 16: RTC software reset */ + /* Bits 17-23: Reserved */ +#define RCC_CSR1_LSCOEN (1 << 24) /* Bit 24: Low-speed clock output (LSCO) enable */ +#define RCC_CSR1_LSCOSEL (1 << 25) /* Bit 25: Low-speed clock output selection */ + /* Bits 26-31: Reserved */ + +/* Clock configuration register 2 */ + +#define RCC_CSR2_LSION (1 << 0) /* Bit 0: LSI oscillator enable */ +#define RCC_CSR2_LSIRDY (1 << 1) /* Bit 1: LSI oscillator ready */ + /* Bits 2-22: Reserved */ +#define RCC_CSR2_RMVF (1 << 23) /* Bit 23: Remove reset flag */ + /* Bit 24: Reserved */ +#define RCC_CSR2_OBLRSTF (1 << 25) /* Bit 25: Options bytes loading reset flag */ +#define RCC_CSR2_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */ +#define RCC_CSR2_PORRSTF (1 << 27) /* Bit 27: POR/PDR reset flag */ +#define RCC_CSR2_SFTRSTF (1 << 28) /* Bit 28: software reset flag */ +#define RCC_CSR2_IWDGRSTF (1 << 29) /* Bit 29: IWDG reset flag */ +#define RCC_CSR2_WWDGRSTF (1 << 30) /* Bit 30: WWDG reset flag */ +#define RCC_CSR2_LPWRRSTF (1 << 31) /* Bit 31: Low-power reset flag */ + +#endif /* __ARCH_ARM_SRC_STM32F0L0G0_HARDWARE_STM32C0_RCC_H */ diff --git a/arch/arm/src/stm32f0l0g0/stm32_adc.c b/arch/arm/src/stm32f0l0g0/stm32_adc.c index 7ef424ba011..249cfdc6298 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_adc.c +++ b/arch/arm/src/stm32f0l0g0/stm32_adc.c @@ -59,8 +59,8 @@ #if defined(CONFIG_STM32F0L0G0_ADC1) -#if !defined(CONFIG_STM32F0L0G0_STM32L0) -# error Only L0 supported for now +#if defined(CONFIG_STM32F0L0G0_STM32F0) || defined(CONFIG_STM32F0L0G0_STM32G0) +# error Not tested #endif /* At the moment there is no proper implementation for timers external @@ -116,8 +116,13 @@ #endif #if defined(ADC_HAVE_DMA) || (ADC_MAX_SAMPLES == 1) -# define ADC_SMP1_DEFAULT ADC_SMPR_13p5 -# define ADC_SMP2_DEFAULT ADC_SMPR_13p5 +# ifdef ADC_SMPR_13p5 +# define ADC_SMP1_DEFAULT ADC_SMPR_13p5 +# define ADC_SMP2_DEFAULT ADC_SMPR_13p5 +# else +# define ADC_SMP1_DEFAULT ADC_SMPR_12p5 +# define ADC_SMP2_DEFAULT ADC_SMPR_12p5 +# endif #else /* Slow down sampling frequency */ # define ADC_SMP1_DEFAULT ADC_SMPR_239p5 # define ADC_SMP2_DEFAULT ADC_SMPR_239p5 @@ -134,7 +139,9 @@ * (ST manual) */ -#if defined(CONFIG_STM32F0L0G0_STM32F0) || defined(CONFIG_STM32F0L0G0_STM32L0) +#if defined(CONFIG_STM32F0L0G0_STM32F0) || \ + defined(CONFIG_STM32F0L0G0_STM32L0) || \ + defined(CONFIG_STM32F0L0G0_STM32C0) # define ADC_CHANNELS_NUMBER 19 #else # error "Not supported" diff --git a/arch/arm/src/stm32f0l0g0/stm32_adc.h b/arch/arm/src/stm32f0l0g0/stm32_adc.h index ff2b0ed7c37..f620c4cf1ec 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_adc.h +++ b/arch/arm/src/stm32f0l0g0/stm32_adc.h @@ -94,9 +94,9 @@ # define ADC1_EXTSEL_T2TRGO ADC12_CFGR1_EXTSEL_TRG2 # define ADC1_EXTSEL_T3TRGO ADC12_CFGR1_EXTSEL_TRG3 # define ADC1_EXTSEL_T15TRGO ADC12_CFGR1_EXTSEL_TRG4 -# define ADC1_EXTSEL_T6TRGO ADC12_CFGR1_EXTSEL_TRG5 - /* TRG6 reserved */ + /* TRG5 and TRG6 reserved */ # define ADC1_EXTSEL_EXTI11 ADC12_CFGR1_EXTSEL_TRG7 +#elif defined(CONFIG_STM32F0L0G0_STM32C0) #else # error #endif diff --git a/arch/arm/src/stm32f0l0g0/stm32_dma.c b/arch/arm/src/stm32f0l0g0/stm32_dma.c new file mode 100644 index 00000000000..4d60de3763b --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/stm32_dma.c @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/stm32_dma.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32F0L0G0_HAVE_DMAMUX) +# include "stm32_dma_v1mux.c" +#else +# include "stm32_dma_v1.c" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ diff --git a/arch/arm/src/stm32f0l0g0/stm32_dma.h b/arch/arm/src/stm32f0l0g0/stm32_dma.h index 971f537f9ed..0d6d729a0cc 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_dma.h +++ b/arch/arm/src/stm32f0l0g0/stm32_dma.h @@ -32,6 +32,10 @@ #include "hardware/stm32_dma_v1.h" +#ifdef CONFIG_STM32F0L0G0_HAVE_DMAMUX +# include "hardware/stm32_dmamux.h" +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ diff --git a/arch/arm/src/stm32f0l0g0/stm32_dma_v1.c b/arch/arm/src/stm32f0l0g0/stm32_dma_v1.c index ce947303137..6197ffb6761 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_dma_v1.c +++ b/arch/arm/src/stm32f0l0g0/stm32_dma_v1.c @@ -52,7 +52,7 @@ */ #ifdef CONFIG_STM32F0L0G0_HAVE_DMAMUX -# error DMAMUX not supported yet +# error DMAMUX not supported here. Look at stm32_dma_v1mux.c #endif /**************************************************************************** diff --git a/arch/arm/src/stm32f0l0g0/stm32_dma_v1mux.c b/arch/arm/src/stm32f0l0g0/stm32_dma_v1mux.c new file mode 100644 index 00000000000..2f354348ba5 --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/stm32_dma_v1mux.c @@ -0,0 +1,1441 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/stm32_dma_v1mux.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + ****************************************************************************/ + +/* Ported from arch/arm/src/stm32/stm32_dma_v1mux.c */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "arm_internal.h" +#include "sched/sched.h" +#include "stm32_dma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DMAMUX_NUM 1 +#define DMA_CONTROLLERS 2 + +#ifdef CONFIG_STM32F0L0G0_DMA1 +# if defined(CONFIG_ARCH_CHIP_STM32C0) +# define DMA1_NCHAN 5 +# define DMA2_NCHAN 0 +# else +# error +# endif +#else +# define DMA1_NCHAN 0 +# define DMA2_NCHAN 0 +#endif + +#define DMA1_FIRST (0) +#define DMA1_LAST (DMA1_FIRST+DMA1_NCHAN) +#define DMA2_FIRST (DMA1_LAST) +#define DMA2_LAST (DMA2_FIRST+DMA2_NCHAN) + +/* All available DMA channels */ + +#define DMA_NCHANNELS (DMA1_NCHAN + DMA2_NCHAN) + +/* DMAMUX channels */ + +#if defined(CONFIG_ARCH_CHIP_STM32C0) +# define DMAMUX_NCHANNELS 5 +#else +# error +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure described one DMAMUX device */ + +struct stm32_dmamux_s +{ + uint8_t id; /* DMAMUX id */ + uint8_t nchan; /* DMAMUX channels */ + uint32_t base; /* DMAMUX base address */ +}; + +typedef const struct stm32_dmamux_s *DMA_MUX; + +/* This structure describes one DMA controller */ + +struct stm32_dma_s +{ + uint8_t first; /* Offset in stm32_dmach_s array */ + uint8_t nchan; /* Number of channels */ + uint8_t dmamux_offset; /* DMAMUX channel offset */ + uint32_t base; /* Base address */ + DMA_MUX dmamux; /* DMAMUX associated with controller */ +}; + +/* This structure describes one DMA channel (DMA1, DMA2) */ + +struct stm32_dmach_s +{ + bool used; /* Channel in use */ + uint8_t dmamux_req; /* Configured DMAMUX input request */ + uint8_t ctrl; /* DMA controller */ + uint8_t chan; /* DMA channel channel id */ + uint8_t irq; /* DMA channel IRQ number */ + uint8_t shift; /* IFCR bit shift value */ + uint32_t base; /* DMA register channel base address */ + dma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ +}; + +typedef struct stm32_dmach_s *DMA_CHANNEL; + +/* DMA operations */ + +struct stm32_dma_ops_s +{ + /* Disable the DMA transfer */ + + void (*dma_disable)(DMA_CHANNEL dmachan); + + /* DMA interrupt */ + + int (*dma_interrupt)(int irq, void *context, void *arg); + + /* Setup the DMA */ + + void (*dma_setup)(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr); + + /* Start the DMA */ + + void (*dma_start)(DMA_HANDLE handle, dma_callback_t callback, + void *arg, bool half); + + /* Read remaining DMA bytes */ + + size_t (*dma_residual)(DMA_HANDLE handle); + + /* Check the DMA configuration */ + + bool (*dma_capable)(uint32_t maddr, uint32_t count, uint32_t ccr); + +#ifdef CONFIG_DEBUG_DMA_INFO + /* Sample the DMA registers */ + + void (*dma_sample)(DMA_HANDLE handle, struct stm32_dmaregs_s *regs); + + /* Dump the DMA registers */ + + void (*dma_dump)(DMA_HANDLE handle, + const struct stm32_dmaregs_s *regs, + const char *msg); +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if defined(CONFIG_STM32F0L0G0_DMA1) || defined(CONFIG_STM32F0L0G0_DMA2) +static void stm32_dma12_disable(DMA_CHANNEL dmachan); +static int stm32_dma12_interrupt(int irq, void *context, void *arg); +static void stm32_dma12_setup(DMA_HANDLE handle, uint32_t paddr, + uint32_t maddr, size_t ntransfers, + uint32_t ccr); +static void stm32_dma12_start(DMA_HANDLE handle, dma_callback_t callback, + void *arg, bool half); +static size_t stm32_dma12_residual(DMA_HANDLE handle); +#ifdef CONFIG_DEBUG_DMA_INFO +static void stm32_dma12_sample(DMA_HANDLE handle, + struct stm32_dmaregs_s *regs); +static void stm32_dma12_dump(DMA_HANDLE handle, + const struct stm32_dmaregs_s *regs, + const char *msg); +#endif +#endif + +static uint32_t dmachan_getbase(DMA_CHANNEL dmachan); +static uint32_t dmabase_getreg(DMA_CHANNEL dmachan, uint32_t offset); +static void dmabase_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value); +static uint32_t dmachan_getreg(DMA_CHANNEL dmachan, uint32_t offset); +static void dmachan_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value); +static void dmamux_putreg(DMA_MUX dmamux, uint32_t offset, uint32_t value); +#ifdef CONFIG_DEBUG_DMA_INFO +static uint32_t dmamux_getreg(DMA_MUX dmamux, uint32_t offset); +static void stm32_dmamux_sample(DMA_MUX dmamux, uint8_t chan, + struct stm32_dmaregs_s *regs); +static void stm32_dmamux_dump(DMA_MUX dmamux, uint8_t channel, + const struct stm32_dmaregs_s *regs); +#endif +static DMA_CHANNEL stm32_dma_channel_get(uint8_t channel, + uint8_t controller); +static void stm32_gdma_limits_get(uint8_t controller, uint8_t *first, + uint8_t *last); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Operations specific to DMA controller */ + +static const struct stm32_dma_ops_s g_dma_ops[DMA_CONTROLLERS] = +{ +#ifdef CONFIG_STM32F0L0G0_DMA1 + /* 0 - DMA1 */ + + { + .dma_disable = stm32_dma12_disable, + .dma_interrupt = stm32_dma12_interrupt, + .dma_setup = stm32_dma12_setup, + .dma_start = stm32_dma12_start, + .dma_residual = stm32_dma12_residual, +#ifdef CONFIG_DEBUG_DMA_INFO + .dma_sample = stm32_dma12_sample, + .dma_dump = stm32_dma12_dump, +#endif + }, +#else + { + NULL + }, +#endif + +#ifdef CONFIG_STM32F0L0G0_DMA2 + /* 1 - DMA2 */ + + { + .dma_disable = stm32_dma12_disable, + .dma_interrupt = stm32_dma12_interrupt, + .dma_setup = stm32_dma12_setup, + .dma_start = stm32_dma12_start, + .dma_residual = stm32_dma12_residual, +#ifdef CONFIG_DEBUG_DMA_INFO + .dma_sample = stm32_dma12_sample, + .dma_dump = stm32_dma12_dump, +#endif + } +#else + { + NULL + } +#endif +}; + +/* This array describes the state of DMAMUX controller */ + +static const struct stm32_dmamux_s g_dmamux[DMAMUX_NUM] = +{ + { + .id = 1, + .nchan = DMAMUX_NCHANNELS, + .base = STM32_DMAMUX1_BASE + } +}; + +/* This array describes the state of each controller */ + +static const struct stm32_dma_s g_dma[DMA_NCHANNELS] = +{ +#ifdef CONFIG_STM32F0L0G0_DMA1 + /* 0 - DMA1 */ + + { + .base = STM32_DMA1_BASE, + .first = DMA1_FIRST, + .nchan = DMA1_NCHAN, + .dmamux = &g_dmamux[DMAMUX1], /* DMAMUX1 channels 0-6 */ + .dmamux_offset = 0 + }, +#endif + +#ifdef CONFIG_STM32F0L0G0_DMA2 + /* 1 - DMA2 */ + + { + .base = STM32_DMA2_BASE, + .first = DMA2_FIRST, + .nchan = DMA2_NCHAN, + .dmamux = &g_dmamux[DMAMUX1], /* DMAMUX1 channels 7-13 */ + .dmamux_offset = 7 + } +#endif +}; + +/* This array describes the state of each DMA channel. */ + +static struct stm32_dmach_s g_dmach[DMA_NCHANNELS] = +{ +#ifdef CONFIG_STM32F0L0G0_DMA1 + /* DMA1 */ + + { + .ctrl = DMA1, + .chan = 0, + .irq = STM32_IRQ_DMA1CH1, + .shift = DMA_CHAN_SHIFT(0), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(0), + }, + + { + .ctrl = DMA1, + .chan = 1, + .irq = STM32_IRQ_DMA1CH2, + .shift = DMA_CHAN_SHIFT(1), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(1), + }, + + { + .ctrl = DMA1, + .chan = 2, + .irq = STM32_IRQ_DMA1CH3, + .shift = DMA_CHAN_SHIFT(2), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(2), + }, + + { + .ctrl = DMA1, + .chan = 3, + .irq = STM32_IRQ_DMA1CH4, + .shift = DMA_CHAN_SHIFT(3), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(3), + }, + + { + .ctrl = DMA1, + .chan = 4, + .irq = STM32_IRQ_DMA1CH5, + .shift = DMA_CHAN_SHIFT(4), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(4), + }, + +# if DMA1_NCHAN > 5 + { + .ctrl = DMA1, + .chan = 5, + .irq = STM32_IRQ_DMA1CH6, + .shift = DMA_CHAN_SHIFT(5), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(5), + }, +# endif + +# if DMA1_NCHAN > 6 + { + .ctrl = DMA1, + .chan = 6, + .irq = STM32_IRQ_DMA1CH7, + .shift = DMA_CHAN_SHIFT(6), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(6), + }, +# endif + +# if DMA1_NCHAN > 7 + { + .ctrl = DMA1, + .chan = 7, + .irq = STM32_IRQ_DMA1CH8, + .shift = DMA_CHAN_SHIFT(7), + .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(7), + }, +# endif +#endif + +#ifdef CONFIG_STM32F0L0G0_DMA2 + /* DMA2 */ + + { + .ctrl = DMA2, + .chan = 0, + .irq = STM32_IRQ_DMA2CH1, + .shift = DMA_CHAN_SHIFT(0), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(0), + }, + + { + .ctrl = DMA2, + .chan = 1, + .irq = STM32_IRQ_DMA2CH2, + .shift = DMA_CHAN_SHIFT(1), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(1), + }, + + { + .ctrl = DMA2, + .chan = 2, + .irq = STM32_IRQ_DMA2CH3, + .shift = DMA_CHAN_SHIFT(2), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(2), + }, + + { + .ctrl = DMA2, + .chan = 3, + .irq = STM32_IRQ_DMA2CH4, + .shift = DMA_CHAN_SHIFT(3), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(3), + }, + + { + .ctrl = DMA2, + .chan = 4, + .irq = STM32_IRQ_DMA2CH5, + .shift = DMA_CHAN_SHIFT(4), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(4), + }, + +# if DMA2_NCHAN > 5 + { + .ctrl = DMA2, + .chan = 5, + .irq = STM32_IRQ_DMA2CH6, + .shift = DMA_CHAN_SHIFT(5), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(5), + }, +# endif + +# if DMA2_NCHAN > 6 + { + .ctrl = DMA2, + .chan = 6, + .irq = STM32_IRQ_DMA2CH7, + .shift = DMA_CHAN_SHIFT(6), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(6), + }, +# endif + +# if DMA2_NCHAN > 7 + { + .ctrl = DMA2, + .chan = 7, + .irq = STM32_IRQ_DMA2CH8, + .shift = DMA_CHAN_SHIFT(7), + .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(7), + }, +# endif +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * DMA register access functions + ****************************************************************************/ + +/**************************************************************************** + * Name: dmachan_getbase + * + * Description: + * Get base DMA address for dmachan + * + ****************************************************************************/ + +static uint32_t dmachan_getbase(DMA_CHANNEL dmachan) +{ + uint8_t controller = dmachan->ctrl; + + return g_dma[controller].base; +} + +/**************************************************************************** + * Name: dmabase_getreg + * + * Description: + * Get non-channel register from DMA controller + * + ****************************************************************************/ + +static uint32_t dmabase_getreg(DMA_CHANNEL dmachan, uint32_t offset) +{ + uint32_t dmabase = dmachan_getbase(dmachan); + + return getreg32(dmabase + offset); +} + +/**************************************************************************** + * Name: dmabase_putreg + * + * Description: + * Write to non-channel register in DMA controller + * + ****************************************************************************/ + +static void dmabase_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value) +{ + uint32_t dmabase = dmachan_getbase(dmachan); + + putreg32(value, dmabase + offset); +} + +/**************************************************************************** + * Name: dmachan_getreg + * + * Description: + * Get channel register. + * + ****************************************************************************/ + +static uint32_t dmachan_getreg(DMA_CHANNEL dmachan, uint32_t offset) +{ + return getreg32(dmachan->base + offset); +} + +/**************************************************************************** + * Name: dmachan_putreg + * + * Description: + * Write to channel register. + * + ****************************************************************************/ + +static void dmachan_putreg(DMA_CHANNEL dmachan, uint32_t offset, + uint32_t value) +{ + putreg32(value, dmachan->base + offset); +} + +/**************************************************************************** + * Name: dmamux_getreg + * + * Description: + * Write to DMAMUX + * + ****************************************************************************/ + +static void dmamux_putreg(DMA_MUX dmamux, uint32_t offset, uint32_t value) +{ + putreg32(value, dmamux->base + offset); +} + +/**************************************************************************** + * Name: dmamux_getreg + * + * Description: + * Get DMAMUX register. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static uint32_t dmamux_getreg(DMA_MUX dmamux, uint32_t offset) +{ + return getreg32(dmamux->base + offset); +} +#endif + +/**************************************************************************** + * Name: stm32_dma_channel_get + * + * Description: + * Get the g_dmach table entry associated with a given DMA controller + * and channel number. + * + ****************************************************************************/ + +static DMA_CHANNEL stm32_dma_channel_get(uint8_t channel, + uint8_t controller) +{ + uint8_t first = 0; + uint8_t nchan = 0; + + /* Get limits for g_dma array */ + + stm32_gdma_limits_get(controller, &first, &nchan); + + DEBUGASSERT(channel <= nchan); + + return &g_dmach[first + channel]; +} + +/**************************************************************************** + * Name: stm32_gdma_limits_get + * + * Description: + * Get g_dma array limits for a given DMA controller. + * + ****************************************************************************/ + +static void stm32_gdma_limits_get(uint8_t controller, uint8_t *first, + uint8_t *nchan) +{ + DEBUGASSERT(first != NULL); + DEBUGASSERT(nchan != NULL); + + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + *first = g_dma[controller].first; + *nchan = g_dma[controller].nchan; +} + +/**************************************************************************** + * DMA controller functions + ****************************************************************************/ + +#if defined(CONFIG_STM32F0L0G0_DMA1) || defined(CONFIG_STM32F0L0G0_DMA2) + +/**************************************************************************** + * Name: stm32_dma12_disable + * + * Description: + * Disable DMA channel (DMA1/DMA2) + * + ****************************************************************************/ + +static void stm32_dma12_disable(DMA_CHANNEL dmachan) +{ + uint32_t regval; + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + /* Disable all interrupts at the DMA controller */ + + regval = dmachan_getreg(dmachan, STM32_DMACHAN_CCR_OFFSET); + regval &= ~DMA_CCR_ALLINTS; + + /* Disable the DMA channel */ + + regval &= ~DMA_CCR_EN; + dmachan_putreg(dmachan, STM32_DMACHAN_CCR_OFFSET, regval); + + /* Clear pending channel interrupts */ + + dmabase_putreg(dmachan, STM32_DMA_IFCR_OFFSET, + DMA_ISR_CHAN_MASK(dmachan->chan)); +} + +/**************************************************************************** + * Name: stm32_dma12_interrupt + * + * Description: + * DMA channel interrupt handler + * + ****************************************************************************/ + +static int stm32_dma12_interrupt(int irq, void *context, void *arg) +{ + DMA_CHANNEL dmachan; + uint32_t isr; + uint8_t channel; + uint8_t controller; + + /* Get the channel and the controller that generated the interrupt */ + + if (0) + { + } +#ifdef CONFIG_STM32F0L0G0_DMA1 + else if (irq >= STM32_IRQ_DMA1CH1 && irq <= STM32_IRQ_DMA1CH7) + { + channel = irq - STM32_IRQ_DMA1CH1; + controller = DMA1; + } +#endif +#ifdef CONFIG_STM32F0L0G0_DMA2 + else if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH5) + { + channel = irq - STM32_IRQ_DMA2CH1; + controller = DMA2; + } + else if (irq >= STM32_IRQ_DMA2CH6 && irq <= STM32_IRQ_DMA2CH7) + { + channel = irq - STM32_IRQ_DMA2CH6 + (6 - 1); + controller = DMA2; + } +#endif + else + { + DEBUGPANIC(); + return OK; + } + + /* Get the channel structure from the stream and controller numbers */ + + dmachan = stm32_dma_channel_get(channel, controller); + + /* Get the interrupt status (for this channel only) */ + + isr = dmabase_getreg(dmachan, STM32_DMA_ISR_OFFSET) & + DMA_ISR_CHAN_MASK(dmachan->chan); + + /* Invoke the callback */ + + if (dmachan->callback) + { + dmachan->callback(dmachan, isr >> DMA_ISR_CHAN_SHIFT(dmachan->chan), + dmachan->arg); + } + + /* Clear the interrupts we are handling */ + + dmabase_putreg(dmachan, STM32_DMA_IFCR_OFFSET, isr); + + return OK; +} + +/**************************************************************************** + * Name: stm32_dma12_setup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +static void stm32_dma12_setup(DMA_HANDLE handle, uint32_t paddr, + uint32_t maddr, size_t ntransfers, + uint32_t ccr) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint32_t regval; + + DEBUGASSERT(handle != NULL); + DEBUGASSERT(ntransfers < 65536); + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + dmainfo("paddr: %08" PRIx32 " maddr: %08" PRIx32 + " ntransfers: %zd ccr: %08" PRIx32 "\n", + paddr, maddr, ntransfers, ccr); + +#ifdef CONFIG_STM32F0L0G0_DMACAPABLE + DEBUGASSERT(g_dma_ops[dmachan->ctrl].dma_capable(maddr, ntransfers, ccr)); +#endif + + /* Then DMA_CNDTRx register can only be modified if the DMA channel is + * disabled. + */ + + regval = dmachan_getreg(dmachan, STM32_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_EN); + dmachan_putreg(dmachan, STM32_DMACHAN_CCR_OFFSET, regval); + + /* Set the peripheral register address in the DMA_CPARx register. The data + * will be moved from/to this address to/from the memory after the + * peripheral event. + */ + + dmachan_putreg(dmachan, STM32_DMACHAN_CPAR_OFFSET, paddr); + + /* Set the memory address in the DMA_CMARx register. The data will be + * written to or read from this memory after the peripheral event. + */ + + dmachan_putreg(dmachan, STM32_DMACHAN_CMAR_OFFSET, maddr); + + /* Configure the total number of data to be transferred in the DMA_CNDTRx + * register. After each peripheral event, this value will be decremented. + */ + + dmachan_putreg(dmachan, STM32_DMACHAN_CNDTR_OFFSET, ntransfers); + + /* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx + * register. Configure data transfer direction, circular mode, peripheral + * & memory incremented mode, peripheral & memory data size, and interrupt + * after half and/or full transfer in the DMA_CCRx register. + */ + + regval = dmachan_getreg(dmachan, STM32_DMACHAN_CCR_OFFSET); + regval &= ~(DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | + DMA_CCR_CIRC | DMA_CCR_DIR); + ccr &= (DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK | + DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | + DMA_CCR_CIRC | DMA_CCR_DIR); + regval |= ccr; + dmachan_putreg(dmachan, STM32_DMACHAN_CCR_OFFSET, regval); +} + +/**************************************************************************** + * Name: stm32_dma12_start + * + * Description: + * Start the standard DMA transfer + ****************************************************************************/ + +static void stm32_dma12_start(DMA_HANDLE handle, dma_callback_t callback, + void *arg, bool half) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint32_t ccr; + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + /* Save the callback info. This will be invoked when the DMA completes */ + + dmachan->callback = callback; + dmachan->arg = arg; + + /* Activate the channel by setting the ENABLE bit in the DMA_CCRx register. + * As soon as the channel is enabled, it can serve any DMA request from the + * peripheral connected on the channel. + */ + + ccr = dmachan_getreg(dmachan, STM32_DMACHAN_CCR_OFFSET); + ccr |= DMA_CCR_EN; + + /* In normal mode, interrupt at either half or full completion. In circular + * mode, always interrupt on buffer wrap, and optionally interrupt at the + * halfway point. + */ + + if ((ccr & DMA_CCR_CIRC) == 0) + { + /* Once half of the bytes are transferred, the half-transfer flag + * (HTIF) is set and an interrupt is generated if the Half-Transfer + * Interrupt Enable bit (HTIE) is set. At the end of the transfer, + * the Transfer Complete Flag (TCIF) is set and an interrupt is + * generated if the Transfer Complete Interrupt Enable bit (TCIE) + * is set. + */ + + ccr |= (half ? (DMA_CCR_HTIE | DMA_CCR_TEIE) : + (DMA_CCR_TCIE | DMA_CCR_TEIE)); + } + else + { + /* In nonstop mode, when the transfer completes it immediately resets + * and starts again. The transfer-complete interrupt is thus always + * enabled, and the half-complete interrupt can be used in circular + * mode to determine when the buffer is half-full, or in + * double-buffered mode to determine when one of the two buffers + * is full. + */ + + ccr |= (half ? DMA_CCR_HTIE : 0) | DMA_CCR_TCIE | DMA_CCR_TEIE; + } + + dmachan_putreg(dmachan, STM32_DMACHAN_CCR_OFFSET, ccr); +} + +/**************************************************************************** + * Name: stm32_dma12_residual + ****************************************************************************/ + +static size_t stm32_dma12_residual(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + return dmachan_getreg(dmachan, STM32_DMACHAN_CNDTR_OFFSET); +} + +/**************************************************************************** + * Name: stm32_dma12_sample + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +void stm32_dma12_sample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + irqstate_t flags; + + flags = enter_critical_section(); + + regs->isr = dmabase_getreg(dmachan, STM32_DMA_ISR_OFFSET); + regs->ccr = dmachan_getreg(dmachan, STM32_DMACHAN_CCR_OFFSET); + regs->cndtr = dmachan_getreg(dmachan, STM32_DMACHAN_CNDTR_OFFSET); + regs->cpar = dmachan_getreg(dmachan, STM32_DMACHAN_CPAR_OFFSET); + regs->cmar = dmachan_getreg(dmachan, STM32_DMACHAN_CMAR_OFFSET); + + stm32_dmamux_sample(g_dma[dmachan->ctrl].dmamux, + dmachan->chan + g_dma[dmachan->ctrl].dmamux_offset, + regs); + + leave_critical_section(flags); +} +#endif + +/**************************************************************************** + * Name: stm32_dma12_dump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static void stm32_dma12_dump(DMA_HANDLE handle, + const struct stm32_dmaregs_s *regs, + const char *msg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + + DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2); + + uint32_t dmabase = dmachan_getbase(dmachan); + + dmainfo("DMA%d Registers: %s\n", + dmachan->ctrl + 1, + msg); + dmainfo(" ISR[%08x]: %08x\n", + dmabase + STM32_DMA_ISR_OFFSET, + regs->isr); + dmainfo(" CCR[%08x]: %08x\n", + dmachan->base + STM32_DMACHAN_CCR_OFFSET, + regs->ccr); + dmainfo(" CNDTR[%08x]: %08x\n", + dmachan->base + STM32_DMACHAN_CNDTR_OFFSET, + regs->cndtr); + dmainfo(" CPAR[%08x]: %08x\n", + dmachan->base + STM32_DMACHAN_CPAR_OFFSET, + regs->cpar); + dmainfo(" CMAR[%08x]: %08x\n", + dmachan->base + STM32_DMACHAN_CMAR_OFFSET, + regs->cmar); + + stm32_dmamux_dump(g_dma[dmachan->ctrl].dmamux, + dmachan->chan + g_dma[dmachan->ctrl].dmamux_offset, + regs); +} +#endif + +#endif /* CONFIG_STM32F0L0G0_DMA1 || CONFIG_STM32F0L0G0_DMA2 */ + +/**************************************************************************** + * Name: stm32_dmamux_sample + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static void stm32_dmamux_sample(DMA_MUX dmamux, uint8_t chan, + struct stm32_dmaregs_s *regs) +{ + regs->dmamux.ccr = dmamux_getreg(dmamux, STM32_DMAMUX_CXCR_OFFSET(chan)); + regs->dmamux.csr = dmamux_getreg(dmamux, STM32_DMAMUX_CSR_OFFSET); + regs->dmamux.rg0cr = dmamux_getreg(dmamux, STM32_DMAMUX_RG0CR_OFFSET); + regs->dmamux.rg1cr = dmamux_getreg(dmamux, STM32_DMAMUX_RG1CR_OFFSET); + regs->dmamux.rg2cr = dmamux_getreg(dmamux, STM32_DMAMUX_RG2CR_OFFSET); + regs->dmamux.rg3cr = dmamux_getreg(dmamux, STM32_DMAMUX_RG3CR_OFFSET); + regs->dmamux.rgsr = dmamux_getreg(dmamux, STM32_DMAMUX_RGSR_OFFSET); +} +#endif + +/**************************************************************************** + * Name: stm32_dmamux_dump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +static void stm32_dmamux_dump(DMA_MUX dmamux, uint8_t channel, + const struct stm32_dmaregs_s *regs) +{ + dmainfo("DMAMUX%d CH=%d\n", dmamux->id, channel); + dmainfo(" CCR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_CXCR_OFFSET(channel), + regs->dmamux.ccr); + dmainfo(" CSR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_CSR_OFFSET, regs->dmamux.csr); + dmainfo(" RG0CR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_RG0CR_OFFSET, regs->dmamux.rg0cr); + dmainfo(" RG1CR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_RG1CR_OFFSET, regs->dmamux.rg1cr); + dmainfo(" RG2CR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_RG2CR_OFFSET, regs->dmamux.rg2cr); + dmainfo(" RG3CR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_RG3CR_OFFSET, regs->dmamux.rg3cr); + dmainfo(" RGSR[%08x]: %08x\n", + dmamux->base + STM32_DMAMUX_RGSR_OFFSET, regs->dmamux.rgsr); +}; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_dma_initialize + * + * Description: + * Initialize the DMA subsystem (DMA1, DMA2) + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function arm_dma_initialize(void) +{ + DMA_CHANNEL dmachan; + uint8_t controller; + int channel; + + dmainfo("Initialize DMA\n"); + + /* Initialize DMA channels */ + + for (channel = 0; channel < DMA_NCHANNELS; channel++) + { + dmachan = &g_dmach[channel]; + + /* Initialize flag */ + + dmachan->used = false; + + /* Get DMA controller associated with channel */ + + controller = dmachan->ctrl; + + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + /* Attach standard DMA interrupt vectors */ + + irq_attach(dmachan->irq, g_dma_ops[controller].dma_interrupt, + dmachan); + + /* Disable the DMA channel */ + + g_dma_ops[controller].dma_disable(dmachan); + + /* Enable the IRQ at the NVIC (still disabled at the DMA controller) */ + + up_enable_irq(dmachan->irq); + } +} + +/**************************************************************************** + * Name: stm32_dmachannel + * + * Description: + * Allocate a DMA channel. This function gives the caller mutually + * exclusive access to the DMA channel specified by the 'dmamap' argument. + * It is common for both DMA controllers (DMA1 and DMA2). + * + * Input Parameters: + * dmamap - Identifies the stream/channel resource. For the STM32+, this + * is a bit-encoded value as provided by the DMAMAP_* definitions + * in hardware/stm32g4xxxx_dmamux.h + * + * Returned Value: + * On success, this function returns a non-NULL, void* DMA channel handle. + * NULL is returned on any failure. This function can fail only if no DMA + * channel is available. + * + * Assumptions: + * - The caller does not hold he DMA channel. + * - The caller can wait for the DMA channel to be freed if it is not + * available. + * + ****************************************************************************/ + +DMA_HANDLE stm32_dmachannel(unsigned int dmamap) +{ + DMA_CHANNEL dmachan; + uint8_t dmamux_req; + irqstate_t flags; + uint8_t controller; + uint8_t first = 0; + uint8_t nchan = 0; + int item = -1; + int i; + + /* Get DMA controller from encoded DMAMAP value */ + + controller = DMAMAP_CONTROLLER(dmamap); + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + /* Get DMAMUX channel from encoded DMAMAP value */ + + dmamux_req = DMAMAP_REQUEST(dmamap); + + /* Get g_dma array limits for given controller */ + + stm32_gdma_limits_get(controller, &first, &nchan); + + /* Find available channel for given controller */ + + flags = enter_critical_section(); + for (i = first; i < first + nchan; i += 1) + { + if (g_dmach[i].used == false) + { + item = i; + g_dmach[i].used = true; + g_dmach[i].dmamux_req = dmamux_req; + break; + } + } + + leave_critical_section(flags); + + dmainfo("ctrl=%d item=%d\n", controller, item); + + if (item == -1) + { + dmainfo("No available DMA chan for CTRL=%d\n", + controller); + + /* No available channel */ + + return NULL; + } + + /* Assign DMA item */ + + dmachan = &g_dmach[item]; + + dmainfo("Get g_dmach[%d] CTRL=%d CH=%d\n", i, controller, dmachan->chan); + + /* Be sure that we have proper DMA controller */ + + DEBUGASSERT(dmachan->ctrl == controller); + + return (DMA_HANDLE)dmachan; +} + +/**************************************************************************** + * Name: stm32_dmafree + * + * Description: + * Release a DMA channel and unmap DMAMUX if required. + * + * NOTE: The 'handle' used in this argument must NEVER be used again + * until stm32_dmachannel() is called again to re-gain access to the + * channel. + * + * Returned Value: + * None + * + * Assumptions: + * - The caller holds the DMA channel. + * - There is no DMA in progress + * + ****************************************************************************/ + +void stm32_dmafree(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller; + irqstate_t flags; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + dmainfo("Free g_dmach[%d] CTRL=%d CH=%d\n", dmachan - g_dmach, controller, + dmachan->chan); + UNUSED(controller); + + /* Release the channel */ + + flags = enter_critical_section(); + dmachan->used = false; + dmachan->dmamux_req = 0; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_dmasetup + * + * Description: + * Configure DMA before using + * + ****************************************************************************/ + +void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, + size_t ntransfers, uint32_t ccr) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + g_dma_ops[controller].dma_setup(handle, paddr, maddr, ntransfers, ccr); +} + +/**************************************************************************** + * Name: stm32_dmastart + * + * Description: + * Start the DMA transfer + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * - No DMA in progress + * + ****************************************************************************/ + +void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg, + bool half) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + DMA_MUX dmamux; + uint32_t regval; + uint8_t dmamux_chan; + uint8_t controller; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + /* Recommended channel configure procedure in reference manual: + * 1. Set and configure the DMA channel y, except enabling the channel y. + * 2. Set and configure the related DMAMUX y channel. + * 3. Last, activate the DMA channel y. + */ + + /* Get DMAMUX associated with DMA controller */ + + dmamux = g_dma[controller].dmamux; + dmamux_chan = dmachan->chan + g_dma[controller].dmamux_offset; + + /* DMAMUX Set DMA channel source */ + + regval = dmachan->dmamux_req << DMAMUX_CCR_DMAREQID_SHIFT; + dmamux_putreg(dmamux, STM32_DMAMUX_CXCR_OFFSET(dmamux_chan), regval); + + /* Enable DMA channel */ + + g_dma_ops[controller].dma_start(handle, callback, arg, half); +} + +/**************************************************************************** + * Name: stm32_dmastop + * + * Description: + * Cancel the DMA. After stm32_dmastop() is called, the DMA channel is + * reset and stm32_dmasetup() must be called before stm32_dmastart() + * can be called again + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +void stm32_dmastop(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + DMA_MUX dmamux; + uint8_t dmamux_chan; + uint8_t controller; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + /* Get DMAMUX associated with DMA controller */ + + dmamux = g_dma[controller].dmamux; + dmamux_chan = dmachan->chan + g_dma[controller].dmamux_offset; + + /* Disable DMA channel */ + + g_dma_ops[controller].dma_disable(dmachan); + + /* DMAMUX Clear DMA channel source */ + + dmamux_putreg(dmamux, STM32_DMAMUX_CXCR_OFFSET(dmamux_chan), 0); +} + +/**************************************************************************** + * Name: stm32_dmaresidual + * + * Description: + * Read the DMA bytes-remaining register. + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +size_t stm32_dmaresidual(DMA_HANDLE handle) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + return g_dma_ops[controller].dma_residual(handle); +} + +/**************************************************************************** + * Name: stm32_dmacapable + * + * Description: + * Check if the DMA controller can transfer data to/from given memory + * address. This depends on the internal connections in the ARM bus matrix + * of the processor. Note that this only applies to memory addresses, it + * will return false for any peripheral address. + * + * Input Parameters: + * cfg - DMA transfer configuration + * + * Returned Value: + * True, if transfer is possible. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32F0L0G0_DMACAPABLE +bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr) +{ + unsigned int msize_shift; + uint32_t transfer_size; + uint32_t mend; + + /* Verify that the address conforms to the memory transfer size. + * Transfers to/from memory performed by the DMA controller are + * required to be aligned to their size. + * + * Datasheet 3.13 claims + * "Access to Flash, SRAM, APB and AHB peripherals as source + * and destination" + */ + + switch (ccr & DMA_CCR_MSIZE_MASK) + { + case DMA_CCR_MSIZE_8BITS: + msize_shift = 0; + break; + + case DMA_CCR_MSIZE_16BITS: + msize_shift = 1; + break; + + case DMA_CCR_MSIZE_32BITS: + msize_shift = 2; + break; + + default: + return false; + } + + transfer_size = 1 << msize_shift; + + if ((maddr & (transfer_size - 1)) != 0) + { + return false; + } + + /* Verify that the transfer is to a memory region that supports DMA. */ + + mend = maddr + (count << msize_shift) - 1; + + if ((maddr & STM32_REGION_MASK) != (mend & STM32_REGION_MASK)) + { + return false; + } + + switch (maddr & STM32_REGION_MASK) + { + case STM32_PERIPH_BASE: + case STM32_SRAM_BASE: + case STM32_CODE_BASE: + + /* All RAM and flash is supported */ + + return true; + + default: + + /* Everything else is unsupported by DMA */ + + return false; + } +} +#endif + +/**************************************************************************** + * Name: stm32_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + g_dma_ops[controller].dma_sample(handle, regs); +} +#endif + +/**************************************************************************** + * Name: stm32_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by stm32_dmachannel() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA_INFO +void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, + const char *msg) +{ + DMA_CHANNEL dmachan = (DMA_CHANNEL)handle; + uint8_t controller; + + DEBUGASSERT(handle != NULL); + + /* Get DMA controller */ + + controller = dmachan->ctrl; + DEBUGASSERT(controller >= DMA1 && controller <= DMA2); + + dmainfo("DMA %d CH%d Registers: %s\n", dmachan->ctrl, dmachan->ctrl, msg); + + g_dma_ops[controller].dma_dump(handle, regs, msg); +} +#endif diff --git a/arch/arm/src/stm32f0l0g0/stm32_lse.c b/arch/arm/src/stm32f0l0g0/stm32_lse.c index 5d560839a59..472bf740457 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_lse.c +++ b/arch/arm/src/stm32f0l0g0/stm32_lse.c @@ -80,6 +80,18 @@ void stm32_rcc_enablelse(void) { } +#elif defined(CONFIG_ARCH_CHIP_STM32C0) + /* Enable the External Low-Speed (LSE) oscillator by setting the LSEON bit + * the RCC CSR1 register. + */ + + modifyreg32(STM32_RCC_CSR1, 0, RCC_CSR1_LSEON); + + /* Wait for the LSE clock to be ready */ + + while ((getreg32(STM32_RCC_CSR1) & RCC_CSR1_LSERDY) == 0) + { + } #endif /* Disable backup domain access if it was disabled on entry */ diff --git a/arch/arm/src/stm32f0l0g0/stm32_rcc.c b/arch/arm/src/stm32f0l0g0/stm32_rcc.c index 10b4adad393..49df30ceb77 100644 --- a/arch/arm/src/stm32f0l0g0/stm32_rcc.c +++ b/arch/arm/src/stm32f0l0g0/stm32_rcc.c @@ -73,6 +73,8 @@ # include "stm32l0_rcc.c" #elif defined(CONFIG_ARCH_CHIP_STM32G0) # include "stm32g0_rcc.c" +#elif defined(CONFIG_ARCH_CHIP_STM32C0) +# include "stm32c0_rcc.c" #else # error "Unsupported STM32F0/L0 RCC" #endif diff --git a/arch/arm/src/stm32f0l0g0/stm32c0_rcc.c b/arch/arm/src/stm32f0l0g0/stm32c0_rcc.c new file mode 100644 index 00000000000..3194b8ef68c --- /dev/null +++ b/arch/arm/src/stm32f0l0g0/stm32c0_rcc.c @@ -0,0 +1,495 @@ +/**************************************************************************** + * arch/arm/src/stm32f0l0g0/stm32c0_rcc.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * 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. Normally this is very fast, but I have + * seen at least one board that required this long, long timeout for + * the HSE to be ready. + */ + +#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rcc_reset + * + * Description: + * Put all RCC registers in reset state + * + ****************************************************************************/ + +static inline void rcc_reset(void) +{ + uint32_t regval; + + /* Reset CFGR register */ + + putreg32(RCC_CFGR_RESET, STM32_RCC_CFGR); + + /* Reset CR register */ + + putreg32(RCC_CR_RESET, STM32_RCC_CR); + + /* DBG clock enable */ + + regval = RCC_APB1ENR_DBGEN; + putreg32(regval, STM32_RCC_APB1ENR); +} + +/**************************************************************************** + * Name: rcc_enableio + * + * Description: + * Enable selected GPIO + * + ****************************************************************************/ + +static inline void rcc_enableio(void) +{ + uint32_t regval = 0; + + /* REVISIT: */ + + regval |= (RCC_IOPENR_IOPAEN | RCC_IOPENR_IOPBEN | RCC_IOPENR_IOPCEN | \ + RCC_IOPENR_IOPDEN | RCC_IOPENR_IOPFEN); + + putreg32(regval, STM32_RCC_IOPENR); /* Enable GPIO */ +} + +/**************************************************************************** + * Name: rcc_enableahb + * + * Description: + * Enable selected AHB peripherals + * + ****************************************************************************/ + +static inline void rcc_enableahb(void) +{ + uint32_t regval = 0; + + /* Set the appropriate bits in the AHBENR register to enabled the + * selected AHBENR peripherals. + */ + + regval = getreg32(STM32_RCC_AHBENR); + +#ifdef CONFIG_STM32F0L0G0_DMA1 + /* DMA 1 clock enable */ + + regval |= RCC_AHBENR_DMA1EN; +#endif + +#ifdef CONFIG_STM32F0L0G0_MIF + /* Memory interface clock enable */ + + regval |= RCC_AHBENR_MIFEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_CRC + /* CRC clock enable */ + + regval |= RCC_AHBENR_CRCEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_RNG + /* Random number generator clock enable */ + + regval |= RCC_AHBENR_RNGEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_AES + /* AES modules clock enable */ + + regval |= RCC_AHBENR_AESEN; +#endif + + putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ +} + +/**************************************************************************** + * Name: rcc_enableapb1 + * + * Description: + * Enable selected APB peripherals from the first APB register + * + ****************************************************************************/ + +static inline void rcc_enableapb1(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB1ENR register to enabled the + * selected APB peripherals. + */ + + regval = getreg32(STM32_RCC_APB1ENR); + +#ifdef CONFIG_STM32F0L0G0_TIM2 + /* Timer 2 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB1ENR_TIM2EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_TIM3 + /* Timer 3 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB1ENR_TIM3EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_FDCAN + /* FDCAN1 clock enable */ + + regval |= RCC_APB1ENR_FDCANEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_SPI2 + /* SPI 2 clock enable */ + + regval |= RCC_APB1ENR_SPI2EN; +#endif + +#ifdef CONFIG_STM32F0L0G0_USB + /* USB clock enable */ + + regval |= RCC_APB1ENR_USBEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_CRC + /* CRC clock enable */ + + regval |= RCC_APB1ENR_CRCEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_USART2 + /* USART 2 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB1ENR_USART2EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_USART3 + /* USART 3 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB1ENR_USART3EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_USART4 + /* USART 4 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB1ENR_USART4EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_I2C1 + /* I2C 1 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB1ENR_I2C1EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_PWR + /* Power interface clock enable */ + + regval |= RCC_APB1ENR_PWREN; +#endif + + putreg32(regval, STM32_RCC_APB1ENR); +} + +/**************************************************************************** + * Name: rcc_enableapb2 + * + * Description: + * Enable selected APB peripherals from the second APB register. + * + ****************************************************************************/ + +static inline void rcc_enableapb2(void) +{ + uint32_t regval; + + /* Set the appropriate bits in the APB2ENR register to enabled the + * selected APB peripherals. + */ + + regval = getreg32(STM32_RCC_APB2ENR); + +#ifdef CONFIG_STM32F0L0G0_SYSCFG + /* SYSCFG clock */ + + regval |= RCC_APB2ENR_SYSCFGEN; +#endif + +#ifdef CONFIG_STM32F0L0G0_TIM1 + /* TIM1 Timer clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB2ENR_TIM1EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_SPI1 + /* SPI 1 clock enable */ + + regval |= RCC_APB2ENR_SPI1EN; +#endif + +#ifdef CONFIG_STM32F0L0G0_USART1 + /* USART1 clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB2ENR_USART1EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_TIM14 + /* TIM14 Timer clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB2ENR_TIM14EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_TIM15 + /* TIM5 Timer clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB2ENR_TIM15EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_TIM16 + /* TIM16 Timer clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB2ENR_TIM16EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_TIM17 + /* TIM17 Timer clock enable */ + +#ifdef CONFIG_STM32F0L0G0_FORCEPOWER + regval |= RCC_APB2ENR_TIM17EN; +#endif +#endif + +#ifdef CONFIG_STM32F0L0G0_ADC1 + /* ADC 1 clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + + putreg32(regval, STM32_RCC_APB2ENR); +} + +/**************************************************************************** + * Name: stm32_rcc_enablehse + * + * Description: + * Enable the External High-Speed (HSE) Oscillator. + * + ****************************************************************************/ + +#if (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) +static inline bool stm32_rcc_enablehse(void) +{ + uint32_t regval; + volatile int32_t timeout; + + /* Enable External High-Speed Clock (HSE) */ + + regval = getreg32(STM32_RCC_CR); +#ifdef STM32_HSEBYP_ENABLE /* May be defined in board.h header file */ + regval |= RCC_CR_HSEBYP; /* Enable HSE clock bypass */ +#else + regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ +#endif + regval |= RCC_CR_HSEON; /* Enable HSE */ + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSE is ready (or until a timeout elapsed) */ + + for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) + { + /* Check if the HSERDY flag is set in the CR */ + + if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) + { + /* If so, then return TRUE */ + + return true; + } + } + + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or misconfiguration. + */ + + return false; +} +#endif + +/**************************************************************************** + * Name: stm32_stdclockconfig + * + * Description: + * Called to change to new clock based on settings in board.h. + * + ****************************************************************************/ + +#ifndef CONFIG_ARCH_BOARD_STM32F0G0L0_CUSTOM_CLOCKCONFIG +static void stm32_stdclockconfig(void) +{ + uint32_t regval; + uint32_t flash_ws; + + /* Flash wait states (latency) according to range and HCLK: + * + * - Flash 0WS if HCLK <= 24 + * - Flash 1WS if HCLK <= 48 + * + * Where HCLK = (SYSCLK / HPRE div) + */ + + if (STM32_HCLK_FREQUENCY <= 24000000) + { + flash_ws = FLASH_ACR_LATENCY_0; + } + else + { + flash_ws = FLASH_ACR_LATENCY_1; + } + + /* Enable the main source clock */ + +#if (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) + + /* System clock uses HSE */ + + if (!stm32_rcc_enablehse()) + { + /* In the case of a timeout starting the HSE, we really don't have a + * strategy. This is almost always a hardware failure or + * misconfiguration (for example, if no crystal is fitted on the board. + */ + + return; + } + +#elif (STM32_SYSCLK_SW == RCC_CFGR_SW_HSI) + + /* System clock uses HSI */ + + regval = getreg32(STM32_RCC_CR); /* Enable the HSI */ + regval |= RCC_CR_HSION; + + /* Configure HSI divider */ + + regval &= ~RCC_CR_HSIDIV_MASK; + regval |= STM32_RCC_HSIDIV; + + putreg32(regval, STM32_RCC_CR); + + /* Wait until the HSI clock is ready. Since this is an internal clock, no + * timeout is expected + */ + + while ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) == 0); + +#endif + + /* Configure FLASH wait states and enable prefetch */ + + regval = getreg32(STM32_FLASH_ACR); + regval &= ~FLASH_ACR_LATENCY_MASK; + regval |= (flash_ws & FLASH_ACR_LATENCY_MASK) | FLASH_ACR_PRFTEN; + putreg32(regval, STM32_FLASH_ACR); + + /* Set the HCLK source/divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_HPRE_MASK; + regval |= STM32_RCC_CFGR_HPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Set the PCLK divider */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_PPRE_MASK; + regval |= STM32_RCC_CFGR_PPRE; + putreg32(regval, STM32_RCC_CFGR); + + /* Select the system clock source */ + + regval = getreg32(STM32_RCC_CFGR); + regval &= ~RCC_CFGR_SW_MASK; + regval |= STM32_SYSCLK_SW; + putreg32(regval, STM32_RCC_CFGR); + + /* Wait until the selected source is used as the system clock source */ + + while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); +} +#endif + +/**************************************************************************** + * Name: rcc_enableperiphals + ****************************************************************************/ + +static inline void rcc_enableperipherals(void) +{ + rcc_enableio(); + rcc_enableahb(); + rcc_enableapb2(); + rcc_enableapb1(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/