diff --git a/.github/workflows/build-AT32-eval.yaml b/.github/workflows/build-AT32-eval.yaml new file mode 100644 index 0000000000..28a269efc7 --- /dev/null +++ b/.github/workflows/build-AT32-eval.yaml @@ -0,0 +1,58 @@ +name: Firmware at GHA + +on: [ push, pull_request ] + +jobs: + build-firmware: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + # Build machines don't have arm-none-eabi gcc, so let's download it and put it on the path + - name: Download & Install GCC + if: ${{ env.skip != 'true' }} + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' + run: | + tools/provide_gcc.sh + echo "::add-path::`pwd`/gcc-arm-none-eabi/bin" + + - name: 1. Compile AT32 USB testhal + run: | + cd testhal/AT32/AT32F4xx/USB_CDC_IAD + make -j + + - name: Attach USB_CDC_IAD + if: always() + uses: actions/upload-artifact@v3 + with: + name: USB_CDC_IAD binaries + path: testhal/AT32/AT32F4xx/USB_CDC_IAD/build/ch*.* + + - name: 2. Compile AT32F435 demo + run: | + cd demos/STM32/RT-AT32F435-ARTERY144 + make -j + + - name: Attach RT-AT32F435-ARTERY144 + if: always() + uses: actions/upload-artifact@v3 + with: + name: RT-AT32F435-ARTERY144 binaries + path: demos/STM32/RT-AT32F435-ARTERY144/build/ch*.* + + - name: 3. Compile AT32 ADC testhal + run: | + cd testhal/AT32/AT32F4xx/ADC + make -j + + - name: Attach ADC + if: always() + uses: actions/upload-artifact@v3 + with: + name: ADC binaries + path: testhal/AT32/AT32F4xx/ADC/build/ch*.* + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..631c8555f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.dep +build diff --git a/demos/STM32/RT-AT32F435-ARTERY144/.gdbinit b/demos/STM32/RT-AT32F435-ARTERY144/.gdbinit new file mode 100644 index 0000000000..43297efd44 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/.gdbinit @@ -0,0 +1,7 @@ +target extended-remote localhost:3333 +file build/ch.elf +#file build-openblt/openblt_microrusefi.elf +load +set breakpoint auto-hw on +set remote hardware-breakpoint-limit 8 +set remote hardware-watchpoint-limit 4 diff --git a/demos/STM32/RT-AT32F435-ARTERY144/Makefile b/demos/STM32/RT-AT32F435-ARTERY144/Makefile new file mode 100644 index 0000000000..c6b2316f1d --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/Makefile @@ -0,0 +1,189 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data. +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO). +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = yes +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x400 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# Enables the use of FPU (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = no +endif + +# FPU-related options. +ifeq ($(USE_FPU_OPT),) + USE_FPU_OPT = -mfloat-abi=$(USE_FPU) -mfpu=fpv4-sp-d16 +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, target, sources and paths +# + +# Define project name here +PROJECT = ch + +# Target settings. +MCU = cortex-m4 + +# Imported source files and paths. +CHIBIOS := ../../.. +CONFDIR := ./cfg +BUILDDIR := ./build +DEPDIR := ./.dep + +# Licensing files. +include $(CHIBIOS)/os/license/license.mk +# Startup files. +include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f4xx.mk +# HAL-OSAL files (optional). +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx/platform.mk +include $(CHIBIOS)/os/hal/boards/AT_START_F435/board.mk +include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk +# Auto-build files in ./source recursively. +include $(CHIBIOS)/tools/mk/autobuild.mk +# Other files (optional). +include $(CHIBIOS)/test/lib/test.mk +include $(CHIBIOS)/test/rt/rt_test.mk +include $(CHIBIOS)/test/oslib/oslib_test.mk + +# Define linker script file here +LDSCRIPT= $(STARTUPLD)/AT32F435ZMxx.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(ALLCSRC) \ + $(TESTSRC) \ + main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = $(ALLCPPSRC) + +# List ASM source files here. +ASMSRC = $(ALLASMSRC) + +# List ASM with preprocessor source files here. +ASMXSRC = $(ALLXASMSRC) + +# Inclusion directories. +INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC) + +# Define C warning options here. +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes + +# Define C++ warning options here. +CPPWARN = -Wall -Wextra -Wundef + +# +# Project, target, sources and paths +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user section +############################################################################## + +############################################################################## +# Common rules +# + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk +include $(RULESPATH)/arm-none-eabi.mk +include $(RULESPATH)/rules.mk + +# +# Common rules +############################################################################## + +############################################################################## +# Custom rules +# + +# +# Custom rules +############################################################################## diff --git a/demos/STM32/RT-AT32F435-ARTERY144/at32f4x.cfg b/demos/STM32/RT-AT32F435-ARTERY144/at32f4x.cfg new file mode 100644 index 0000000000..e8cd07a6d2 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/at32f4x.cfg @@ -0,0 +1,149 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# script for at32f4x family + +# +# stm32f4 devices support both JTAG and SWD transports. +# +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME at32f4x +} + +set _ENDIAN little + +# Work-area is a space in RAM used for flash programming +# By default use 32kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x8000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + if { [using_jtag] } { + # See STM Document RM0090 + # Section 38.6.3 - corresponds to Cortex-M4 r0p1 + set _CPUTAPID 0x4ba00477 + } { + set _CPUTAPID 0x2ba01477 + } +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +if {[using_jtag]} { + jtag newtap $_CHIPNAME bs -irlen 5 +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +# flash bank $_FLASHNAME artery 0 0 0 0 $_TARGETNAME +flash bank $_FLASHNAME artery 0x080000000 0 0 0 $_TARGETNAME + +#flash bank $_CHIPNAME.otp artery 0x1fff7800 0 0 0 $_TARGETNAME + +if { [info exists QUADSPI] && $QUADSPI } { + set a [llength [flash list]] + set _QSPINAME $_CHIPNAME.qspi + flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000 +} + +# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz +# +# Since we may be running of an RC oscilator, we crank down the speed a +# bit more to be on the safe side. Perhaps superstition, but if are +# running off a crystal, we can run closer to the limit. Note +# that there can be a pretty wide band where things are more or less stable. +adapter speed 2000 + +adapter srst delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +$_TARGETNAME configure -event examine-end { + # Enable debug during low power modes (uses more power) + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP + mmw 0xE0042004 0x00000007 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP + mmw 0xE0042008 0x00001800 0 +} + +tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000 + +lappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu +proc _proc_pre_enable_$_CHIPNAME.tpiu {_chipname} { + targets $_chipname.cpu + + if { [$_chipname.tpiu cget -protocol] eq "sync" } { + switch [$_chipname.tpiu cget -port-width] { + 1 { + # Set TRACE_IOEN; TRACE_MODE to sync 1 bit; GPIOE[2-3] to AF0 + mmw 0xE0042004 0x00000060 0x000000c0 + mmw 0x40021020 0x00000000 0x0000ff00 + mmw 0x40021000 0x000000a0 0x000000f0 + mmw 0x40021008 0x000000f0 0x00000000 + } + 2 { + # Set TRACE_IOEN; TRACE_MODE to sync 2 bit; GPIOE[2-4] to AF0 + mmw 0xE0042004 0x000000a0 0x000000c0 + mmw 0x40021020 0x00000000 0x000fff00 + mmw 0x40021000 0x000002a0 0x000003f0 + mmw 0x40021008 0x000003f0 0x00000000 + } + 4 { + # Set TRACE_IOEN; TRACE_MODE to sync 4 bit; GPIOE[2-6] to AF0 + mmw 0xE0042004 0x000000e0 0x000000c0 + mmw 0x40021020 0x00000000 0x0fffff00 + mmw 0x40021000 0x00002aa0 0x00003ff0 + mmw 0x40021008 0x00003ff0 0x00000000 + } + } + } else { + # Set TRACE_IOEN; TRACE_MODE to async + mmw 0xE0042004 0x00000020 0x000000c0 + } +} + +$_CHIPNAME.tpiu configure -event pre-enable "_proc_pre_enable_$_CHIPNAME.tpiu $_CHIPNAME" + +$_TARGETNAME configure -event reset-init { + # Configure PLL to boost clock to HSI x 4 (64 MHz) + mww 0x40023804 0x08012008 ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P) + mww 0x40023C00 0x00000102 ;# FLASH_ACR = PRFTBE | 2(Latency) + mmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON + sleep 10 ;# Wait for PLL to lock + mmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2 + mmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL + + # Boost JTAG frequency + adapter speed 8000 +} + +$_TARGETNAME configure -event reset-start { + # Reduce speed since CPU speed will slow down to 16MHz with the reset + adapter speed 2000 +} diff --git a/demos/STM32/RT-AT32F435-ARTERY144/cfg/chconf.h b/demos/STM32/RT-AT32F435-ARTERY144/cfg/chconf.h new file mode 100644 index 0000000000..a51b09f4db --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/cfg/chconf.h @@ -0,0 +1,840 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file rt/templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_6_1_ + +/*===========================================================================*/ +/** + * @name System settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Handling of instances. + * @note If enabled then threads assigned to various instances can + * interact each other using the same synchronization objects. + * If disabled then each OS instance is a separate world, no + * direct interactions are handled by the OS. + */ +#if !defined(CH_CFG_SMP_MODE) +#define CH_CFG_SMP_MODE FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_ST_RESOLUTION) +#define CH_CFG_ST_RESOLUTION 32 +#endif + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_CFG_ST_FREQUENCY) +#define CH_CFG_ST_FREQUENCY 10000 +#endif + +/** + * @brief Time intervals data size. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_INTERVALS_SIZE) +#define CH_CFG_INTERVALS_SIZE 32 +#endif + +/** + * @brief Time types data size. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#define CH_CFG_TIME_TYPES_SIZE 32 +#endif + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#if !defined(CH_CFG_ST_TIMEDELTA) +#define CH_CFG_ST_TIMEDELTA 2 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#if !defined(CH_CFG_TIME_QUANTUM) +#define CH_CFG_TIME_QUANTUM 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#if !defined(CH_CFG_NO_IDLE_THREAD) +#define CH_CFG_NO_IDLE_THREAD FALSE +#endif + +/** + * @brief Kernel hardening level. + * @details This option is the level of functional-safety checks enabled + * in the kerkel. The meaning is: + * - 0: No checks, maximum performance. + * - 1: Reasonable checks. + * - 2: All checks. + * . + */ +#if !defined(CH_CFG_HARDENING_LEVEL) +#define CH_CFG_HARDENING_LEVEL 0 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#define CH_CFG_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TM) +#define CH_CFG_USE_TM TRUE +#endif + +/** + * @brief Time Stamps APIs. + * @details If enabled then the time stamps APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TIMESTAMP) +#define CH_CFG_USE_TIMESTAMP TRUE +#endif + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_REGISTRY) +#define CH_CFG_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_WAITEXIT) +#define CH_CFG_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_SEMAPHORES) +#define CH_CFG_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MUTEXES) +#define CH_CFG_USE_MUTEXES TRUE +#endif + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_CONDVARS) +#define CH_CFG_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_EVENTS) +#define CH_CFG_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MESSAGES) +#define CH_CFG_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#if !defined(CH_CFG_USE_DYNAMIC) +#define CH_CFG_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name OSLIB options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_MAILBOXES) +#define CH_CFG_USE_MAILBOXES TRUE +#endif + +/** + * @brief Memory checks APIs. + * @details If enabled then the memory checks APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCHECKS) +#define CH_CFG_USE_MEMCHECKS TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCORE) +#define CH_CFG_USE_MEMCORE TRUE +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#if !defined(CH_CFG_MEMCORE_SIZE) +#define CH_CFG_MEMCORE_SIZE 0 +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_CFG_USE_HEAP) +#define CH_CFG_USE_HEAP TRUE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMPOOLS) +#define CH_CFG_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS TRUE +#endif + +/** + * @brief Pipes APIs. + * @details If enabled then the pipes APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_PIPES) +#define CH_CFG_USE_PIPES TRUE +#endif + +/** + * @brief Objects Caches APIs. + * @details If enabled then the objects caches APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_CACHES) +#define CH_CFG_USE_OBJ_CACHES TRUE +#endif + +/** + * @brief Delegate threads APIs. + * @details If enabled then the delegate threads APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_DELEGATES) +#define CH_CFG_USE_DELEGATES TRUE +#endif + +/** + * @brief Jobs Queues APIs. + * @details If enabled then the jobs queues APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_JOBS) +#define CH_CFG_USE_JOBS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Objects factory options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Objects Factory APIs. + * @details If enabled then the objects factory APIs are included in the + * kernel. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_CFG_USE_FACTORY) +#define CH_CFG_USE_FACTORY TRUE +#endif + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#endif + +/** + * @brief Enables the registry of generic objects. + */ +#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#endif + +/** + * @brief Enables factory for generic buffers. + */ +#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/** + * @brief Enables factory for mailboxes. + */ +#if !defined(CH_CFG_FACTORY_MAILBOXES) +#define CH_CFG_FACTORY_MAILBOXES TRUE +#endif + +/** + * @brief Enables factory for objects FIFOs. + */ +#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#endif + +/** + * @brief Enables factory for Pipes. + */ +#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_PIPES TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_STATISTICS) +#define CH_DBG_STATISTICS FALSE +#endif + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) +#define CH_DBG_ENABLE_CHECKS FALSE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) +#define CH_DBG_ENABLE_ASSERTS FALSE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_MASK) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#define CH_DBG_ENABLE_STACK_CHECK FALSE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) +#define CH_DBG_FILL_THREADS FALSE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#if !defined(CH_DBG_THREADS_PROFILING) +#define CH_DBG_THREADS_PROFILING FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System structure extension. + * @details User fields added to the end of the @p ch_system_t structure. + */ +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add system custom fields here.*/ + +/** + * @brief System initialization hook. + * @details User initialization code added to the @p chSysInit() function + * just before interrupts are enabled globally. + */ +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add system initialization code here.*/ \ +} + +/** + * @brief OS instance structure extension. + * @details User fields added to the end of the @p os_instance_t structure. + */ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ + /* Add OS instance custom fields here.*/ + +/** + * @brief OS instance initialization hook. + * + * @param[in] oip pointer to the @p os_instance_t structure + */ +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ + /* Add OS instance initialization code here.*/ \ +} + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p _thread_init() function. + * + * @note It is invoked from within @p _thread_init() and implicitly from all + * the threads creation APIs. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + * + * @param[in] ntp thread being switched in + * @param[in] otp thread being switched out + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** + * @brief Runtime Faults Collection Unit hook. + * @details This hook is invoked each time new faults are collected and stored. + */ +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ + /* Faults handling code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/demos/STM32/RT-AT32F435-ARTERY144/cfg/halconf.h b/demos/STM32/RT-AT32F435-ARTERY144/cfg/halconf.h new file mode 100644 index 0000000000..6dba798842 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/cfg/halconf.h @@ -0,0 +1,553 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#define _CHIBIOS_HAL_CONF_ +#define _CHIBIOS_HAL_CONF_VER_7_1_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the cryptographic subsystem. + */ +#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__) +#define HAL_USE_CRY FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EFlash subsystem. + */ +#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__) +#define HAL_USE_EFL FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL TRUE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the TRNG subsystem. + */ +#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__) +#define HAL_USE_TRNG FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB FALSE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/** + * @brief Enables the WSPI subsystem. + */ +#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) +#define HAL_USE_WSPI FALSE +#endif + +/*===========================================================================*/ +/* PAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS FALSE +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) +#define PAL_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/** + * @brief Enforces the driver to use direct callbacks rather than OSAL events. + */ +#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__) +#define CAN_ENFORCE_USE_CALLBACKS FALSE +#endif + +/*===========================================================================*/ +/* CRY driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + +/*===========================================================================*/ +/* DAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the zero-copy API. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Timeout before assuming a failure while waiting for card idle. + * @note Time is in milliseconds. + */ +#if !defined(MMC_IDLE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define MMC_IDLE_TIMEOUT_MS 1000 +#endif + +/** + * @brief Mutual exclusion on the SPI bus. + */ +#if !defined(MMC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define MMC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief OCR initialization constant for V20 cards. + */ +#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__) +#define SDC_INIT_OCR_V20 0x50FF8000U +#endif + +/** + * @brief OCR initialization constant for non-V20 cards. + */ +#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__) +#define SDC_INIT_OCR 0x80100000U +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SIO driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SIO_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SIO_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Support for thread synchronization API. + */ +#if !defined(SIO_USE_SYNCHRONIZATION) || defined(__DOXYGEN__) +#define SIO_USE_SYNCHRONIZATION TRUE +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Inserts an assertion on function errors before returning. + */ +#if !defined(SPI_USE_ASSERT_ON_ERROR) || defined(__DOXYGEN__) +#define SPI_USE_ASSERT_ON_ERROR TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* WSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__) +#define WSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define WSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/demos/STM32/RT-AT32F435-ARTERY144/cfg/mcuconf.h b/demos/STM32/RT-AT32F435-ARTERY144/cfg/mcuconf.h new file mode 100644 index 0000000000..c8f2ca54e5 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/cfg/mcuconf.h @@ -0,0 +1,407 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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 MCUCONF_H +#define MCUCONF_H + +/* + * STM32F4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#define STM32F4xx_MCUCONF +#define STM32F437_MCUCONF + +/* + * Config pll clock resource + * common frequency config list: pll source selected hick or hext (8mhz) + * _________________________________________________________________________________________________ + * | | | | | | | | | | | + * |pll(mhz)| 288 | 252 | 216 | 192 | 180 | 144 | 108 | 72 | 36 | + * |________|_________|_________|_________|_________|_________|_________|_________|_________________| + * | | | | | | | | | | | + * |pll_ns | 144 | 126 | 108 | 96 | 90 | 72 | 108 | 72 | 72 | + * | | | | | | | | | | | + * |pll_ms | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + * | | | | | | | | | | | + * |pll_fr | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_8 | FR_8 | FR_16| + * |________|_________|_________|_________|_________|_________|_________|_________|________|________| + * + * if pll clock source selects hext with other frequency values, or configure pll to other + * frequency values, please use the at32 new clock configuration tool for configuration. + */ + +#if 0 +/* Defaults for 96MHz from DS */ +#define STM32_PLLM_VALUE 2 +#define STM32_PLLN_VALUE 192 +#define STM32_PLLP_VALUE 8 +#define STM32_PPRE1 STM32_PPRE1_DIV1 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV1 /* max 144 MHz */ +#endif + +#if 0 +/* 144 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 72 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV1 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV1 /* max 144 MHz */ +#endif + +#if 0 +/* 216 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 108 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV2 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV2 /* max 144 MHz */ +#endif + +#if 1 +/* 288 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 144 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV2 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV2 /* max 144 MHz */ +#endif + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_BKPRAM_ENABLE FALSE +#define STM32_HSI_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED TRUE +#define STM32_LSE_ENABLED FALSE +#define STM32_CLOCK48_REQUIRED TRUE +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_RTCSEL STM32_RTCSEL_LSI +#define STM32_RTCPRE_VALUE 8 +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI16_PRIORITY 6 +#define STM32_IRQ_EXTI17_PRIORITY 15 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_PRIORITY 15 +#define STM32_IRQ_EXTI22_PRIORITY 15 + +#define STM32_IRQ_TIM1_BRK_TIM9_PRIORITY 7 +#define STM32_IRQ_TIM1_UP_TIM10_PRIORITY 7 +#define STM32_IRQ_TIM1_TRGCO_TIM11_PRIORITY 7 +#define STM32_IRQ_TIM1_CC_PRIORITY 7 +#define STM32_IRQ_TIM2_PRIORITY 7 +#define STM32_IRQ_TIM3_PRIORITY 7 +#define STM32_IRQ_TIM4_PRIORITY 7 +#define STM32_IRQ_TIM5_PRIORITY 7 +#define STM32_IRQ_TIM6_PRIORITY 7 +#define STM32_IRQ_TIM7_PRIORITY 7 +#define STM32_IRQ_TIM8_BRK_TIM12_PRIORITY 7 +#define STM32_IRQ_TIM8_UP_TIM13_PRIORITY 7 +#define STM32_IRQ_TIM8_TRGCO_TIM14_PRIORITY 7 +#define STM32_IRQ_TIM8_CC_PRIORITY 7 + +#define STM32_IRQ_USART1_PRIORITY 12 +#define STM32_IRQ_USART2_PRIORITY 12 +#define STM32_IRQ_USART3_PRIORITY 12 +#define STM32_IRQ_UART4_PRIORITY 12 +#define STM32_IRQ_UART5_PRIORITY 12 +#define STM32_IRQ_USART6_PRIORITY 12 +#define STM32_IRQ_UART7_PRIORITY 12 +#define STM32_IRQ_UART8_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4 +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_USE_ADC2 FALSE +#define STM32_ADC_USE_ADC3 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#define STM32_ADC_IRQ_PRIORITY 6 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6 +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6 +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_USE_CAN2 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 +#define STM32_CAN_CAN2_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM5 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM8 FALSE +#define STM32_GPT_USE_TIM9 FALSE +#define STM32_GPT_USE_TIM10 FALSE +#define STM32_GPT_USE_TIM11 FALSE +#define STM32_GPT_USE_TIM12 FALSE +#define STM32_GPT_USE_TIM13 FALSE +#define STM32_GPT_USE_TIM14 FALSE + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C2_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C2_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * I2S driver system settings. + */ +#define STM32_I2S_USE_SPI2 FALSE +#define STM32_I2S_USE_SPI3 FALSE +#define STM32_I2S_SPI2_IRQ_PRIORITY 10 +#define STM32_I2S_SPI3_IRQ_PRIORITY 10 +#define STM32_I2S_SPI2_DMA_PRIORITY 1 +#define STM32_I2S_SPI3_DMA_PRIORITY 1 +#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM5 FALSE +#define STM32_ICU_USE_TIM8 FALSE +#define STM32_ICU_USE_TIM9 FALSE +#define STM32_ICU_USE_TIM10 FALSE +#define STM32_ICU_USE_TIM11 FALSE +#define STM32_ICU_USE_TIM12 FALSE +#define STM32_ICU_USE_TIM13 FALSE +#define STM32_ICU_USE_TIM14 FALSE + +/* + * MAC driver system settings. + */ +#define STM32_MAC_TRANSMIT_BUFFERS 2 +#define STM32_MAC_RECEIVE_BUFFERS 4 +#define STM32_MAC_BUFFERS_SIZE 1522 +#define STM32_MAC_PHY_TIMEOUT 100 +#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE +#define STM32_MAC_ETH1_IRQ_PRIORITY 13 +#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM5 FALSE +#define STM32_PWM_USE_TIM8 FALSE +#define STM32_PWM_USE_TIM9 FALSE +#define STM32_PWM_USE_TIM10 FALSE +#define STM32_PWM_USE_TIM11 FALSE +#define STM32_PWM_USE_TIM12 FALSE +#define STM32_PWM_USE_TIM13 FALSE +#define STM32_PWM_USE_TIM14 FALSE + +/* + * RTC driver system settings. + */ +#define STM32_RTC_PRESA_VALUE 32 +#define STM32_RTC_PRESS_VALUE 1024 +#define STM32_RTC_CR_INIT 0 +#define STM32_RTC_TAMPCR_INIT 0 + +/* + * SDC driver system settings. + */ +#define STM32_SDC_SDIO_DMA_PRIORITY 3 +#define STM32_SDC_SDIO_IRQ_PRIORITY 9 +#define STM32_SDC_WRITE_TIMEOUT_MS 1000 +#define STM32_SDC_READ_TIMEOUT_MS 1000 +#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 +#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 TRUE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USE_USART6 FALSE + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_USE_SPI4 FALSE +#define STM32_SPI_USE_SPI5 FALSE +#define STM32_SPI_USE_SPI6 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_SPI_SPI6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI4_DMA_PRIORITY 1 +#define STM32_SPI_SPI5_DMA_PRIORITY 1 +#define STM32_SPI_SPI6_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_SPI4_IRQ_PRIORITY 10 +#define STM32_SPI_SPI5_IRQ_PRIORITY 10 +#define STM32_SPI_SPI6_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USE_UART4 FALSE +#define STM32_UART_USE_UART5 FALSE +#define STM32_UART_USE_USART6 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_UART4_DMA_PRIORITY 0 +#define STM32_UART_UART5_DMA_PRIORITY 0 +#define STM32_UART_USART6_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_OTG1 FALSE +#define STM32_USB_USE_OTG2 FALSE +#define STM32_USB_OTG1_IRQ_PRIORITY 14 +#define STM32_USB_OTG2_IRQ_PRIORITY 14 +#define STM32_USB_OTG1_RX_FIFO_SIZE 512 +#define STM32_USB_OTG2_RX_FIFO_SIZE 1024 +#define STM32_USB_HOST_WAKEUP_DURATION 2 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +#endif /* MCUCONF_H */ diff --git a/demos/STM32/RT-AT32F435-ARTERY144/gdb.sh b/demos/STM32/RT-AT32F435-ARTERY144/gdb.sh new file mode 100755 index 0000000000..d6f6f2b183 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/gdb.sh @@ -0,0 +1,5 @@ +#!/bin/sh +#../../toolchain/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gdb $* +#../../toolchain/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb $* + +arm-none-eabi-gdb $* diff --git a/demos/STM32/RT-AT32F435-ARTERY144/main.c b/demos/STM32/RT-AT32F435-ARTERY144/main.c new file mode 100644 index 0000000000..38af6bf32a --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/main.c @@ -0,0 +1,83 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ch.h" +#include "hal.h" +#include "rt_test_root.h" +#include "oslib_test_root.h" + +/* + * This is a periodic thread that does absolutely nothing except flashing + * a LED. + */ +static THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { + + (void)arg; + chRegSetThreadName("blinker"); + while (true) { + palSetLine(LINE_LED1); + chThdSleepMilliseconds(50); + palSetLine(LINE_LED2); + chThdSleepMilliseconds(50); + palSetLine(LINE_LED3); + chThdSleepMilliseconds(200); + palClearLine(LINE_LED1); + chThdSleepMilliseconds(50); + palClearLine(LINE_LED2); + chThdSleepMilliseconds(50); + palClearLine(LINE_LED3); + chThdSleepMilliseconds(200); + } +} + +/* + * Application entry point. + */ +int main(void) { + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* + * Activates the serial driver 3 using the driver default configuration. + */ + sdStart(&SD1, NULL); + + /* + * Creates the example thread. + */ + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL); + + /* + * Normal main() thread activity, in this demo it does nothing except + * sleeping in a loop and check the button state. + */ + while (true) { + if (palReadLine(LINE_BUTTON)) { + test_execute((BaseSequentialStream *)&SD1, &rt_test_suite); + test_execute((BaseSequentialStream *)&SD1, &oslib_test_suite); + } + chThdSleepMilliseconds(500); + } +} diff --git a/demos/STM32/RT-AT32F435-ARTERY144/openocd_artery.sh b/demos/STM32/RT-AT32F435-ARTERY144/openocd_artery.sh new file mode 100755 index 0000000000..083b787bc6 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/openocd_artery.sh @@ -0,0 +1,3 @@ +#!/bin/sh +openocd -f interface/cmsis-dap.cfg -f ./at32f4x.cfg -c '$_TARGETNAME configure -rtos auto' $* + diff --git a/demos/STM32/RT-AT32F435-ARTERY144/openocd_artery_flash.sh b/demos/STM32/RT-AT32F435-ARTERY144/openocd_artery_flash.sh new file mode 100755 index 0000000000..01c963f5e4 --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/openocd_artery_flash.sh @@ -0,0 +1,8 @@ +#!/bin/sh +openocd -f interface/cmsis-dap.cfg -f ./at32f4x.cfg \ + -c "init" \ + -c "halt" \ + -c "flash write_image erase build/ch.elf" \ + -c "flash verify_image build/ch.elf" \ + -c "reset" \ + -c "exit" diff --git a/demos/STM32/RT-AT32F435-ARTERY144/readme.txt b/demos/STM32/RT-AT32F435-ARTERY144/readme.txt new file mode 100644 index 0000000000..ac2a9e4a3c --- /dev/null +++ b/demos/STM32/RT-AT32F435-ARTERY144/readme.txt @@ -0,0 +1,28 @@ +***************************************************************************** +** ChibiOS/RT port for ARM-Cortex-M4 AT32F435. ** +***************************************************************************** + +** TARGET ** + +The demo runs on an Artery AT-START-F435 board. + +** The Demo ** + +The demo flashes the board LEDs using a thread, by pressing the button located +on the board the test procedure is activated with output on the serial port +SD3 (USART3, mapped on STLink v2-1 Virtual COM Port). + +** Build Procedure ** + +The demo has been tested by using the free Codesourcery GCC-based toolchain +and YAGARTO. just modify the TRGT line in the makefile in order to use +different GCC toolchains. + +** Notes ** + +Some files used by the demo are not part of ChibiOS/RT but are copyright of +ST Microelectronics and are licensed under a different license. +Also note that not all the files present in the ST library are distributed +with ChibiOS/RT, you can find the whole library on the ST web site: + + http://www.st.com diff --git a/os/common/ext/Artery/AT32F4xx/at32f435xx.h b/os/common/ext/Artery/AT32F4xx/at32f435xx.h new file mode 100644 index 0000000000..44e54490e1 --- /dev/null +++ b/os/common/ext/Artery/AT32F4xx/at32f435xx.h @@ -0,0 +1,17026 @@ +/** + ****************************************************************************** + * @file stm32f437xx.h + * @author MCD Application Team + * @version V2.6.1 + * @date 14-February-2017 + * @brief CMSIS STM32F437xx Device Peripheral Access Layer Header File. + * + * This file contains: + * - Data structures and the address mapping for all peripherals + * - peripherals registers declarations and bits definition + * - Macros to access peripheral’s registers hardware + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS_Device + * @{ + */ + +/** @addtogroup stm32f437xx + * @{ + */ + +#ifndef __AT32F435xx_H +#define __AT32F435xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ +#define __CM4_REV 0x0001U /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1U /*!< STM32F4XX provides an MPU */ +#define __NVIC_PRIO_BITS 4U /*!< STM32F4XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1U /*!< FPU present */ + +/** + * @} + */ + +/** @addtogroup Peripheral_interrupt_number_definition + * @{ + */ + +/** + * @brief STM32F4XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum +{ +/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ +/****** STM32 specific Interrupt Numbers **********************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ + DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ + DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ + DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ + DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ + DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ + DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ + ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ + CAN1_TX_IRQn = 19, /*!< CAN1 TX Interrupt */ + CAN1_RX0_IRQn = 20, /*!< CAN1 RX0 Interrupt */ + CAN1_RX1_IRQn = 21, /*!< CAN1 RX1 Interrupt */ + CAN1_SCE_IRQn = 22, /*!< CAN1 SCE Interrupt */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + USART3_IRQn = 39, /*!< USART3 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + TIM8_BRK_TIM12_IRQn = 43, /*!< TIM8 Break Interrupt and TIM12 global interrupt */ + TIM8_UP_TIM13_IRQn = 44, /*!< TIM8 Update Interrupt and TIM13 global interrupt */ + TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ + TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare global interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FMC_IRQn = 48, /*!< FMC global Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + UART4_IRQn = 52, /*!< UART4 global Interrupt */ + UART5_IRQn = 53, /*!< UART5 global Interrupt */ + TIM6_DAC_IRQn = 54, /*!< TIM6 global and DAC1&2 underrun error interrupts */ + TIM7_IRQn = 55, /*!< TIM7 global interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + ETH_IRQn = 61, /*!< Ethernet global Interrupt */ + ETH_WKUP_IRQn = 62, /*!< Ethernet Wakeup through EXTI line Interrupt */ + CAN2_TX_IRQn = 63, /*!< CAN2 TX Interrupt */ + CAN2_RX0_IRQn = 64, /*!< CAN2 RX0 Interrupt */ + CAN2_RX1_IRQn = 65, /*!< CAN2 RX1 Interrupt */ + CAN2_SCE_IRQn = 66, /*!< CAN2 SCE Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + OTG_HS_EP1_OUT_IRQn = 74, /*!< USB OTG HS End Point 1 Out global interrupt */ + OTG_HS_EP1_IN_IRQn = 75, /*!< USB OTG HS End Point 1 In global interrupt */ + OTG_HS_WKUP_IRQn = 76, /*!< USB OTG HS Wakeup through EXTI interrupt */ + OTG_HS_IRQn = 77, /*!< USB OTG HS global interrupt */ + DCMI_IRQn = 78, /*!< DCMI global interrupt */ + CRYP_IRQn = 79, /*!< CRYP crypto global interrupt */ + HASH_RNG_IRQn = 80, /*!< Hash and Rng global interrupt */ + FPU_IRQn = 81, /*!< FPU global interrupt */ + UART7_IRQn = 82, /*!< UART7 global interrupt */ + UART8_IRQn = 83, /*!< UART8 global interrupt */ + SPI4_IRQn = 84, /*!< SPI4 global Interrupt */ + SPI5_IRQn = 85, /*!< SPI5 global Interrupt */ + SPI6_IRQn = 86, /*!< SPI6 global Interrupt */ + SAI1_IRQn = 87, /*!< SAI1 global Interrupt */ + DMA2D_IRQn = 90 /*!< DMA2D global Interrupt */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#include "system_at32f4xx.h" +#include + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __IO uint32_t CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + + +/** + * @brief Controller Area Network TxMailBox + */ + +typedef struct +{ + __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ + __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ + __IO uint32_t TDLR; /*!< CAN mailbox data low register */ + __IO uint32_t TDHR; /*!< CAN mailbox data high register */ +} CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ + +typedef struct +{ + __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ + __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ + __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ + __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ +} CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ + +typedef struct +{ + __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ + __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ +} CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ + +typedef struct +{ + __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ + __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ + __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ + __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ + __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ + __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ + __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ + __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ + uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ + uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ + __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ + __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ + uint32_t RESERVED2; /*!< Reserved, 0x208 */ + __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ + uint32_t RESERVED3; /*!< Reserved, 0x210 */ + __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ + uint32_t RESERVED4; /*!< Reserved, 0x218 */ + __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ +} CAN_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DCMI + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DCMI control register 1, Address offset: 0x00 */ + __IO uint32_t SR; /*!< DCMI status register, Address offset: 0x04 */ + __IO uint32_t RISR; /*!< DCMI raw interrupt status register, Address offset: 0x08 */ + __IO uint32_t IER; /*!< DCMI interrupt enable register, Address offset: 0x0C */ + __IO uint32_t MISR; /*!< DCMI masked interrupt status register, Address offset: 0x10 */ + __IO uint32_t ICR; /*!< DCMI interrupt clear register, Address offset: 0x14 */ + __IO uint32_t ESCR; /*!< DCMI embedded synchronization code register, Address offset: 0x18 */ + __IO uint32_t ESUR; /*!< DCMI embedded synchronization unmask register, Address offset: 0x1C */ + __IO uint32_t CWSTRTR; /*!< DCMI crop window start, Address offset: 0x20 */ + __IO uint32_t CWSIZER; /*!< DCMI crop window size, Address offset: 0x24 */ + __IO uint32_t DR; /*!< DCMI data register, Address offset: 0x28 */ +} DCMI_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA stream x configuration register */ + __IO uint32_t NDTR; /*!< DMA stream x number of data register */ + __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ + __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ + __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ + __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ +} DMA_Stream_TypeDef; + +typedef struct +{ + __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ + __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ + __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ + __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ +} DMA_TypeDef; + +/** + * @brief DMA2D Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA2D Control Register, Address offset: 0x00 */ + __IO uint32_t ISR; /*!< DMA2D Interrupt Status Register, Address offset: 0x04 */ + __IO uint32_t IFCR; /*!< DMA2D Interrupt Flag Clear Register, Address offset: 0x08 */ + __IO uint32_t FGMAR; /*!< DMA2D Foreground Memory Address Register, Address offset: 0x0C */ + __IO uint32_t FGOR; /*!< DMA2D Foreground Offset Register, Address offset: 0x10 */ + __IO uint32_t BGMAR; /*!< DMA2D Background Memory Address Register, Address offset: 0x14 */ + __IO uint32_t BGOR; /*!< DMA2D Background Offset Register, Address offset: 0x18 */ + __IO uint32_t FGPFCCR; /*!< DMA2D Foreground PFC Control Register, Address offset: 0x1C */ + __IO uint32_t FGCOLR; /*!< DMA2D Foreground Color Register, Address offset: 0x20 */ + __IO uint32_t BGPFCCR; /*!< DMA2D Background PFC Control Register, Address offset: 0x24 */ + __IO uint32_t BGCOLR; /*!< DMA2D Background Color Register, Address offset: 0x28 */ + __IO uint32_t FGCMAR; /*!< DMA2D Foreground CLUT Memory Address Register, Address offset: 0x2C */ + __IO uint32_t BGCMAR; /*!< DMA2D Background CLUT Memory Address Register, Address offset: 0x30 */ + __IO uint32_t OPFCCR; /*!< DMA2D Output PFC Control Register, Address offset: 0x34 */ + __IO uint32_t OCOLR; /*!< DMA2D Output Color Register, Address offset: 0x38 */ + __IO uint32_t OMAR; /*!< DMA2D Output Memory Address Register, Address offset: 0x3C */ + __IO uint32_t OOR; /*!< DMA2D Output Offset Register, Address offset: 0x40 */ + __IO uint32_t NLR; /*!< DMA2D Number of Line Register, Address offset: 0x44 */ + __IO uint32_t LWR; /*!< DMA2D Line Watermark Register, Address offset: 0x48 */ + __IO uint32_t AMTCR; /*!< DMA2D AHB Master Timer Configuration Register, Address offset: 0x4C */ + uint32_t RESERVED[236]; /*!< Reserved, 0x50-0x3FF */ + __IO uint32_t FGCLUT[256]; /*!< DMA2D Foreground CLUT, Address offset:400-7FF */ + __IO uint32_t BGCLUT[256]; /*!< DMA2D Background CLUT, Address offset:800-BFF */ +} DMA2D_TypeDef; + +/** + * @brief Ethernet MAC + */ + +typedef struct +{ + __IO uint32_t MACCR; + __IO uint32_t MACFFR; + __IO uint32_t MACHTHR; + __IO uint32_t MACHTLR; + __IO uint32_t MACMIIAR; + __IO uint32_t MACMIIDR; + __IO uint32_t MACFCR; + __IO uint32_t MACVLANTR; /* 8 */ + uint32_t RESERVED0[2]; + __IO uint32_t MACRWUFFR; /* 11 */ + __IO uint32_t MACPMTCSR; + uint32_t RESERVED1; + __IO uint32_t MACDBGR; + __IO uint32_t MACSR; /* 15 */ + __IO uint32_t MACIMR; + __IO uint32_t MACA0HR; + __IO uint32_t MACA0LR; + __IO uint32_t MACA1HR; + __IO uint32_t MACA1LR; + __IO uint32_t MACA2HR; + __IO uint32_t MACA2LR; + __IO uint32_t MACA3HR; + __IO uint32_t MACA3LR; /* 24 */ + uint32_t RESERVED2[40]; + __IO uint32_t MMCCR; /* 65 */ + __IO uint32_t MMCRIR; + __IO uint32_t MMCTIR; + __IO uint32_t MMCRIMR; + __IO uint32_t MMCTIMR; /* 69 */ + uint32_t RESERVED3[14]; + __IO uint32_t MMCTGFSCCR; /* 84 */ + __IO uint32_t MMCTGFMSCCR; + uint32_t RESERVED4[5]; + __IO uint32_t MMCTGFCR; + uint32_t RESERVED5[10]; + __IO uint32_t MMCRFCECR; + __IO uint32_t MMCRFAECR; + uint32_t RESERVED6[10]; + __IO uint32_t MMCRGUFCR; + uint32_t RESERVED7[334]; + __IO uint32_t PTPTSCR; + __IO uint32_t PTPSSIR; + __IO uint32_t PTPTSHR; + __IO uint32_t PTPTSLR; + __IO uint32_t PTPTSHUR; + __IO uint32_t PTPTSLUR; + __IO uint32_t PTPTSAR; + __IO uint32_t PTPTTHR; + __IO uint32_t PTPTTLR; + __IO uint32_t RESERVED8; + __IO uint32_t PTPTSSR; + uint32_t RESERVED9[565]; + __IO uint32_t DMABMR; + __IO uint32_t DMATPDR; + __IO uint32_t DMARPDR; + __IO uint32_t DMARDLAR; + __IO uint32_t DMATDLAR; + __IO uint32_t DMASR; + __IO uint32_t DMAOMR; + __IO uint32_t DMAIER; + __IO uint32_t DMAMFBOCR; + __IO uint32_t DMARSWTR; + uint32_t RESERVED10[8]; + __IO uint32_t DMACHTDR; + __IO uint32_t DMACHRDR; + __IO uint32_t DMACHTBAR; + __IO uint32_t DMACHRBAR; +} ETH_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ + __IO uint32_t OPTCR; /*!< FLASH option control register , Address offset: 0x14 */ + __IO uint32_t OPTCR1; /*!< FLASH option control register 1, Address offset: 0x18 */ +} FLASH_TypeDef; + +/** + * @brief Flexible Memory Controller + */ + +typedef struct +{ + __IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */ +} FMC_Bank1_TypeDef; + +/** + * @brief Flexible Memory Controller Bank1E + */ + +typedef struct +{ + __IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */ +} FMC_Bank1E_TypeDef; +/** + * @brief Flexible Memory Controller Bank2 + */ + +typedef struct +{ + __IO uint32_t PCR2; /*!< NAND Flash control register 2, Address offset: 0x60 */ + __IO uint32_t SR2; /*!< NAND Flash FIFO status and interrupt register 2, Address offset: 0x64 */ + __IO uint32_t PMEM2; /*!< NAND Flash Common memory space timing register 2, Address offset: 0x68 */ + __IO uint32_t PATT2; /*!< NAND Flash Attribute memory space timing register 2, Address offset: 0x6C */ + uint32_t RESERVED0; /*!< Reserved, 0x70 */ + __IO uint32_t ECCR2; /*!< NAND Flash ECC result registers 2, Address offset: 0x74 */ + uint32_t RESERVED1; /*!< Reserved, 0x78 */ + uint32_t RESERVED2; /*!< Reserved, 0x7C */ + __IO uint32_t PCR3; /*!< NAND Flash control register 3, Address offset: 0x80 */ + __IO uint32_t SR3; /*!< NAND Flash FIFO status and interrupt register 3, Address offset: 0x84 */ + __IO uint32_t PMEM3; /*!< NAND Flash Common memory space timing register 3, Address offset: 0x88 */ + __IO uint32_t PATT3; /*!< NAND Flash Attribute memory space timing register 3, Address offset: 0x8C */ + uint32_t RESERVED3; /*!< Reserved, 0x90 */ + __IO uint32_t ECCR3; /*!< NAND Flash ECC result registers 3, Address offset: 0x94 */ +} FMC_Bank2_3_TypeDef; + +/** + * @brief Flexible Memory Controller Bank4 + */ + +typedef struct +{ + __IO uint32_t PCR4; /*!< PC Card control register 4, Address offset: 0xA0 */ + __IO uint32_t SR4; /*!< PC Card FIFO status and interrupt register 4, Address offset: 0xA4 */ + __IO uint32_t PMEM4; /*!< PC Card Common memory space timing register 4, Address offset: 0xA8 */ + __IO uint32_t PATT4; /*!< PC Card Attribute memory space timing register 4, Address offset: 0xAC */ + __IO uint32_t PIO4; /*!< PC Card I/O space timing register 4, Address offset: 0xB0 */ +} FMC_Bank4_TypeDef; + +/** + * @brief Flexible Memory Controller Bank5_6 + */ + +typedef struct +{ + __IO uint32_t SDCR[2]; /*!< SDRAM Control registers , Address offset: 0x140-0x144 */ + __IO uint32_t SDTR[2]; /*!< SDRAM Timing registers , Address offset: 0x148-0x14C */ + __IO uint32_t SDCMR; /*!< SDRAM Command Mode register, Address offset: 0x150 */ + __IO uint32_t SDRTR; /*!< SDRAM Refresh Timer register, Address offset: 0x154 */ + __IO uint32_t SDSR; /*!< SDRAM Status register, Address offset: 0x158 */ +} FMC_Bank5_6_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ + __IO uint32_t CLR; /*!< GPIO port bit clear register, Address offset: 0x2c */ + uint32_t RESERVED[3]; /*!< Reserved, 0x30-0x38 */ + __IO uint32_t HDRV; /*!< GPIO huge current control register, Address offset: 0x3c */ + +} GPIO_TypeDef; + +/** + * @brief System configuration controller + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + __IO uint32_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + __IO uint32_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + __IO uint32_t DR; /*!< I2C Data register, Address offset: 0x10 */ + __IO uint32_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + __IO uint32_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + __IO uint32_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + __IO uint32_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + __IO uint32_t FLTR; /*!< I2C FLTR register, Address offset: 0x24 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ + __IO uint32_t LDOOV;/*!< LDO output voltage select register, Address offset: 0x08 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, 0x1C */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32_t RESERVED2; /*!< Reserved, 0x3C */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32_t RESERVED4; /*!< Reserved, 0x5C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + uint32_t RESERVED7[8]; /*!< Reserved, 0x80-0x9C */ + __IO uint32_t MISC1; /*!< Additional register 1 Address offset: 0xA0 */ + __IO uint32_t MISC2; /*!< Additional register 2 Address offset: 0xA4 */ + +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR;/*!< RTC alarm B sub second register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ +} RTC_TypeDef; + +/** + * @brief Serial Audio Interface + */ + +typedef struct +{ + __IO uint32_t GCR; /*!< SAI global configuration register, Address offset: 0x00 */ +} SAI_TypeDef; + +typedef struct +{ + __IO uint32_t CR1; /*!< SAI block x configuration register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< SAI block x configuration register 2, Address offset: 0x08 */ + __IO uint32_t FRCR; /*!< SAI block x frame configuration register, Address offset: 0x0C */ + __IO uint32_t SLOTR; /*!< SAI block x slot register, Address offset: 0x10 */ + __IO uint32_t IMR; /*!< SAI block x interrupt mask register, Address offset: 0x14 */ + __IO uint32_t SR; /*!< SAI block x status register, Address offset: 0x18 */ + __IO uint32_t CLRFR; /*!< SAI block x clear flag register, Address offset: 0x1C */ + __IO uint32_t DR; /*!< SAI block x data register, Address offset: 0x20 */ +} SAI_Block_TypeDef; + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __IO const uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __IO const uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __IO const uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __IO const uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __IO const uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __IO const uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __IO const uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __IO const uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + __IO uint32_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + __IO uint32_t SR; /*!< SPI status register, Address offset: 0x08 */ + __IO uint32_t DR; /*!< SPI data register, Address offset: 0x0C */ + __IO uint32_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + __IO uint32_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + __IO uint32_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + __IO uint32_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + __IO uint32_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ +} SPI_TypeDef; + + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ + __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + __IO uint32_t OR; /*!< TIM option register, Address offset: 0x50 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */ + __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @brief Crypto Processor + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CRYP control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< CRYP status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< CRYP data input register, Address offset: 0x08 */ + __IO uint32_t DOUT; /*!< CRYP data output register, Address offset: 0x0C */ + __IO uint32_t DMACR; /*!< CRYP DMA control register, Address offset: 0x10 */ + __IO uint32_t IMSCR; /*!< CRYP interrupt mask set/clear register, Address offset: 0x14 */ + __IO uint32_t RISR; /*!< CRYP raw interrupt status register, Address offset: 0x18 */ + __IO uint32_t MISR; /*!< CRYP masked interrupt status register, Address offset: 0x1C */ + __IO uint32_t K0LR; /*!< CRYP key left register 0, Address offset: 0x20 */ + __IO uint32_t K0RR; /*!< CRYP key right register 0, Address offset: 0x24 */ + __IO uint32_t K1LR; /*!< CRYP key left register 1, Address offset: 0x28 */ + __IO uint32_t K1RR; /*!< CRYP key right register 1, Address offset: 0x2C */ + __IO uint32_t K2LR; /*!< CRYP key left register 2, Address offset: 0x30 */ + __IO uint32_t K2RR; /*!< CRYP key right register 2, Address offset: 0x34 */ + __IO uint32_t K3LR; /*!< CRYP key left register 3, Address offset: 0x38 */ + __IO uint32_t K3RR; /*!< CRYP key right register 3, Address offset: 0x3C */ + __IO uint32_t IV0LR; /*!< CRYP initialization vector left-word register 0, Address offset: 0x40 */ + __IO uint32_t IV0RR; /*!< CRYP initialization vector right-word register 0, Address offset: 0x44 */ + __IO uint32_t IV1LR; /*!< CRYP initialization vector left-word register 1, Address offset: 0x48 */ + __IO uint32_t IV1RR; /*!< CRYP initialization vector right-word register 1, Address offset: 0x4C */ + __IO uint32_t CSGCMCCM0R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 0, Address offset: 0x50 */ + __IO uint32_t CSGCMCCM1R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 1, Address offset: 0x54 */ + __IO uint32_t CSGCMCCM2R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 2, Address offset: 0x58 */ + __IO uint32_t CSGCMCCM3R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 3, Address offset: 0x5C */ + __IO uint32_t CSGCMCCM4R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 4, Address offset: 0x60 */ + __IO uint32_t CSGCMCCM5R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 5, Address offset: 0x64 */ + __IO uint32_t CSGCMCCM6R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 6, Address offset: 0x68 */ + __IO uint32_t CSGCMCCM7R; /*!< CRYP GCM/GMAC or CCM/CMAC context swap register 7, Address offset: 0x6C */ + __IO uint32_t CSGCM0R; /*!< CRYP GCM/GMAC context swap register 0, Address offset: 0x70 */ + __IO uint32_t CSGCM1R; /*!< CRYP GCM/GMAC context swap register 1, Address offset: 0x74 */ + __IO uint32_t CSGCM2R; /*!< CRYP GCM/GMAC context swap register 2, Address offset: 0x78 */ + __IO uint32_t CSGCM3R; /*!< CRYP GCM/GMAC context swap register 3, Address offset: 0x7C */ + __IO uint32_t CSGCM4R; /*!< CRYP GCM/GMAC context swap register 4, Address offset: 0x80 */ + __IO uint32_t CSGCM5R; /*!< CRYP GCM/GMAC context swap register 5, Address offset: 0x84 */ + __IO uint32_t CSGCM6R; /*!< CRYP GCM/GMAC context swap register 6, Address offset: 0x88 */ + __IO uint32_t CSGCM7R; /*!< CRYP GCM/GMAC context swap register 7, Address offset: 0x8C */ +} CRYP_TypeDef; + +/** + * @brief HASH + */ + +typedef struct +{ + __IO uint32_t CR; /*!< HASH control register, Address offset: 0x00 */ + __IO uint32_t DIN; /*!< HASH data input register, Address offset: 0x04 */ + __IO uint32_t STR; /*!< HASH start register, Address offset: 0x08 */ + __IO uint32_t HR[5]; /*!< HASH digest registers, Address offset: 0x0C-0x1C */ + __IO uint32_t IMR; /*!< HASH interrupt enable register, Address offset: 0x20 */ + __IO uint32_t SR; /*!< HASH status register, Address offset: 0x24 */ + uint32_t RESERVED[52]; /*!< Reserved, 0x28-0xF4 */ + __IO uint32_t CSR[54]; /*!< HASH context swap registers, Address offset: 0x0F8-0x1CC */ +} HASH_TypeDef; + +/** + * @brief HASH_DIGEST + */ + +typedef struct +{ + __IO uint32_t HR[8]; /*!< HASH digest registers, Address offset: 0x310-0x32C */ +} HASH_DIGEST_TypeDef; + +/** + * @brief RNG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RNG control register, Address offset: 0x00 */ + __IO uint32_t SR; /*!< RNG status register, Address offset: 0x04 */ + __IO uint32_t DR; /*!< RNG data register, Address offset: 0x08 */ +} RNG_TypeDef; + +/** + * @brief USB_OTG_Core_Registers + */ +typedef struct +{ + __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register 000h */ + __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register 004h */ + __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register 008h */ + __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register 00Ch */ + __IO uint32_t GRSTCTL; /*!< Core Reset Register 010h */ + __IO uint32_t GINTSTS; /*!< Core Interrupt Register 014h */ + __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register 018h */ + __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register 01Ch */ + __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register 020h */ + __IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register 024h */ + __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register 028h */ + __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg 02Ch */ + uint32_t Reserved30[2]; /*!< Reserved 030h */ + __IO uint32_t GCCFG; /*!< General Purpose IO Register 038h */ + __IO uint32_t CID; /*!< User ID Register 03Ch */ + uint32_t Reserved40[48]; /*!< Reserved 0x40-0xFF */ + __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg 100h */ + __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO */ +} USB_OTG_GlobalTypeDef; + +/** + * @brief USB_OTG_device_Registers + */ +typedef struct +{ + __IO uint32_t DCFG; /*!< dev Configuration Register 800h */ + __IO uint32_t DCTL; /*!< dev Control Register 804h */ + __IO uint32_t DSTS; /*!< dev Status Register (RO) 808h */ + uint32_t Reserved0C; /*!< Reserved 80Ch */ + __IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask 810h */ + __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask 814h */ + __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg 818h */ + __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask 81Ch */ + uint32_t Reserved20; /*!< Reserved 820h */ + uint32_t Reserved9; /*!< Reserved 824h */ + __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register 828h */ + __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register 82Ch */ + __IO uint32_t DTHRCTL; /*!< dev threshold 830h */ + __IO uint32_t DIEPEMPMSK; /*!< dev empty msk 834h */ + __IO uint32_t DEACHINT; /*!< dedicated EP interrupt 838h */ + __IO uint32_t DEACHMSK; /*!< dedicated EP msk 83Ch */ + uint32_t Reserved40; /*!< dedicated EP mask 840h */ + __IO uint32_t DINEP1MSK; /*!< dedicated EP mask 844h */ + uint32_t Reserved44[15]; /*!< Reserved 844-87Ch */ + __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk 884h */ +} USB_OTG_DeviceTypeDef; + +/** + * @brief USB_OTG_IN_Endpoint-Specific_Register + */ +typedef struct +{ + __IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */ + uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h */ + __IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */ + uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch */ + __IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */ + __IO uint32_t DIEPDMA; /*!< IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h */ + __IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */ + uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch */ +} USB_OTG_INEndpointTypeDef; + +/** + * @brief USB_OTG_OUT_Endpoint-Specific_Registers + */ +typedef struct +{ + __IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h */ + uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h */ + __IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h */ + uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch */ + __IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h */ + __IO uint32_t DOEPDMA; /*!< dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h */ + uint32_t Reserved18[2]; /*!< Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch */ +} USB_OTG_OUTEndpointTypeDef; + +/** + * @brief USB_OTG_Host_Mode_Register_Structures + */ +typedef struct +{ + __IO uint32_t HCFG; /*!< Host Configuration Register 400h */ + __IO uint32_t HFIR; /*!< Host Frame Interval Register 404h */ + __IO uint32_t HFNUM; /*!< Host Frame Nbr/Frame Remaining 408h */ + uint32_t Reserved40C; /*!< Reserved 40Ch */ + __IO uint32_t HPTXSTS; /*!< Host Periodic Tx FIFO/ Queue Status 410h */ + __IO uint32_t HAINT; /*!< Host All Channels Interrupt Register 414h */ + __IO uint32_t HAINTMSK; /*!< Host All Channels Interrupt Mask 418h */ +} USB_OTG_HostTypeDef; + +/** + * @brief USB_OTG_Host_Channel_Specific_Registers + */ +typedef struct +{ + __IO uint32_t HCCHAR; /*!< Host Channel Characteristics Register 500h */ + __IO uint32_t HCSPLT; /*!< Host Channel Split Control Register 504h */ + __IO uint32_t HCINT; /*!< Host Channel Interrupt Register 508h */ + __IO uint32_t HCINTMSK; /*!< Host Channel Interrupt Mask Register 50Ch */ + __IO uint32_t HCTSIZ; /*!< Host Channel Transfer Size Register 510h */ + __IO uint32_t HCDMA; /*!< Host Channel DMA Address Register 514h */ + uint32_t Reserved[2]; /*!< Reserved */ +} USB_OTG_HostChannelTypeDef; + +/** + * @} + */ + +/** @addtogroup Peripheral_memory_map + * @{ + */ +#define FLASH_BASE 0x08000000U /*!< FLASH(up to 2 MB) base address in the alias region */ +#define CCMDATARAM_BASE 0x10000000U /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region */ +#define SRAM1_BASE 0x20000000U /*!< SRAM1(112 KB) base address in the alias region */ +#define SRAM2_BASE 0x2001C000U /*!< SRAM2(16 KB) base address in the alias region */ +#define SRAM3_BASE 0x20020000U /*!< SRAM3(64 KB) base address in the alias region */ +#define PERIPH_BASE 0x40000000U /*!< Peripheral base address in the alias region */ +#define BKPSRAM_BASE 0x40024000U /*!< Backup SRAM(4 KB) base address in the alias region */ +#define FMC_R_BASE 0xA0000000U /*!< FMC registers base address */ +#define SRAM1_BB_BASE 0x22000000U /*!< SRAM1(112 KB) base address in the bit-band region */ +#define SRAM2_BB_BASE 0x22380000U /*!< SRAM2(16 KB) base address in the bit-band region */ +#define SRAM3_BB_BASE 0x22400000U /*!< SRAM3(64 KB) base address in the bit-band region */ +#define PERIPH_BB_BASE 0x42000000U /*!< Peripheral base address in the bit-band region */ +#define BKPSRAM_BB_BASE 0x42480000U /*!< Backup SRAM(4 KB) base address in the bit-band region */ +#define FLASH_END 0x081FFFFFU /*!< FLASH end address */ +#define FLASH_OTP_BASE 0x1FFF7800U /*!< Base address of : (up to 528 Bytes) embedded FLASH OTP Area */ +#define FLASH_OTP_END 0x1FFF7A0FU /*!< End address of : (up to 528 Bytes) embedded FLASH OTP Area */ +#define CCMDATARAM_END 0x1000FFFFU /*!< CCM data RAM end address */ + +/* Legacy defines */ +#define SRAM_BASE SRAM1_BASE +#define SRAM_BB_BASE SRAM1_BB_BASE + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000U) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000U) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000U) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000U) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400U) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800U) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00U) +#define TIM6_BASE (APB1PERIPH_BASE + 0x1000U) +#define TIM7_BASE (APB1PERIPH_BASE + 0x1400U) +#define TIM12_BASE (APB1PERIPH_BASE + 0x1800U) +#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00U) +#define TIM14_BASE (APB1PERIPH_BASE + 0x2000U) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800U) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00U) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000U) +/* Reserved on AT32F435/7 */ +#define I2S2ext_BASE (APB1PERIPH_BASE + 0x3400U) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800U) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00U) +/* Reserved on AT32F435/7 */ +#define I2S3ext_BASE (APB1PERIPH_BASE + 0x4000U) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400U) +#define USART3_BASE (APB1PERIPH_BASE + 0x4800U) +#define UART4_BASE (APB1PERIPH_BASE + 0x4C00U) +#define UART5_BASE (APB1PERIPH_BASE + 0x5000U) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400U) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800U) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00U) +#define CAN1_BASE (APB1PERIPH_BASE + 0x6400U) +#define CAN2_BASE (APB1PERIPH_BASE + 0x6800U) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000U) +#define DAC_BASE (APB1PERIPH_BASE + 0x7400U) +#define UART7_BASE (APB1PERIPH_BASE + 0x7800U) +#define UART8_BASE (APB1PERIPH_BASE + 0x7C00U) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000U) +#define TIM8_BASE (APB2PERIPH_BASE + 0x0400U) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000U) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400U) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000U) +#define ADC2_BASE (APB2PERIPH_BASE + 0x2100U) +#define ADC3_BASE (APB2PERIPH_BASE + 0x2200U) +#define ADC123_COMMON_BASE (APB2PERIPH_BASE + 0x2300U) +/* Legacy define */ +#define ADC_BASE ADC123_COMMON_BASE +/* Reserved on AT32F435/7 */ +//#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00U) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000U) +#define SPI4_BASE (APB2PERIPH_BASE + 0x3400U) +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800U) +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00U) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4000U) +#define TIM10_BASE (APB2PERIPH_BASE + 0x4400U) +#define TIM11_BASE (APB2PERIPH_BASE + 0x4800U) +/* Only on AT32F435/7 */ +#define TIM20_BASE (APB2PERIPH_BASE + 0x4C00U) +#define SPI5_BASE (APB2PERIPH_BASE + 0x5000U) +#define SPI6_BASE (APB2PERIPH_BASE + 0x5400U) +#define SAI1_BASE (APB2PERIPH_BASE + 0x5800U) +#define SAI1_Block_A_BASE (SAI1_BASE + 0x004U) +#define SAI1_Block_B_BASE (SAI1_BASE + 0x024U) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000U) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400U) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800U) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00U) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000U) +#define GPIOF_BASE (AHB1PERIPH_BASE + 0x1400U) +#define GPIOG_BASE (AHB1PERIPH_BASE + 0x1800U) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00U) +#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000U) +#define GPIOJ_BASE (AHB1PERIPH_BASE + 0x2400U) +#define GPIOK_BASE (AHB1PERIPH_BASE + 0x2800U) + +/* Only on AT32F435/7 */ +#define EMAC_BAS (AHB1PERIPH_BASE + 0x8000U) +#define SDIO_BASE (AHB1PERIPH_BASE + 0xC400U) + +#define CRC_BASE (AHB1PERIPH_BASE + 0x3000U) +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800U) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00U) +#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000U) +#define DMA1_Stream0_BASE (DMA1_BASE + 0x010U) +#define DMA1_Stream1_BASE (DMA1_BASE + 0x028U) +#define DMA1_Stream2_BASE (DMA1_BASE + 0x040U) +#define DMA1_Stream3_BASE (DMA1_BASE + 0x058U) +#define DMA1_Stream4_BASE (DMA1_BASE + 0x070U) +#define DMA1_Stream5_BASE (DMA1_BASE + 0x088U) +#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0U) +#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8U) +#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400U) +#define DMA2_Stream0_BASE (DMA2_BASE + 0x010U) +#define DMA2_Stream1_BASE (DMA2_BASE + 0x028U) +#define DMA2_Stream2_BASE (DMA2_BASE + 0x040U) +#define DMA2_Stream3_BASE (DMA2_BASE + 0x058U) +#define DMA2_Stream4_BASE (DMA2_BASE + 0x070U) +#define DMA2_Stream5_BASE (DMA2_BASE + 0x088U) +#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0U) +#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8U) +#define ETH_BASE (AHB1PERIPH_BASE + 0x8000U) +#define ETH_MAC_BASE (ETH_BASE) +#define ETH_MMC_BASE (ETH_BASE + 0x0100U) +#define ETH_PTP_BASE (ETH_BASE + 0x0700U) +#define ETH_DMA_BASE (ETH_BASE + 0x1000U) +#define DMA2D_BASE (AHB1PERIPH_BASE + 0xB000U) + +/*!< AHB2 peripherals */ +#define DCMI_BASE (AHB2PERIPH_BASE + 0x50000U) +#define CRYP_BASE (AHB2PERIPH_BASE + 0x60000U) +#define HASH_BASE (AHB2PERIPH_BASE + 0x60400U) +#define HASH_DIGEST_BASE (AHB2PERIPH_BASE + 0x60710U) +#define RNG_BASE (AHB2PERIPH_BASE + 0x60800U) + +/*!< FMC Bankx registers base address */ +#define FMC_Bank1_R_BASE (FMC_R_BASE + 0x0000U) +#define FMC_Bank1E_R_BASE (FMC_R_BASE + 0x0104U) +#define FMC_Bank2_3_R_BASE (FMC_R_BASE + 0x0060U) +#define FMC_Bank4_R_BASE (FMC_R_BASE + 0x00A0U) +#define FMC_Bank5_6_R_BASE (FMC_R_BASE + 0x0140U) + + +/*!< Debug MCU registers base address */ +#define DBGMCU_BASE 0xE0042000U +/*!< USB registers base address */ +#define USB_OTG_FS2_PERIPH_BASE 0x40040000U +#define USB_OTG_FS1_PERIPH_BASE 0x50000000U + +#define USB_OTG_GLOBAL_BASE 0x000U +#define USB_OTG_DEVICE_BASE 0x800U +#define USB_OTG_IN_ENDPOINT_BASE 0x900U +#define USB_OTG_OUT_ENDPOINT_BASE 0xB00U +#define USB_OTG_EP_REG_SIZE 0x20U +#define USB_OTG_HOST_BASE 0x400U +#define USB_OTG_HOST_PORT_BASE 0x440U +#define USB_OTG_HOST_CHANNEL_BASE 0x500U +#define USB_OTG_HOST_CHANNEL_SIZE 0x20U +#define USB_OTG_PCGCCTL_BASE 0xE00U +#define USB_OTG_FIFO_BASE 0x1000U +#define USB_OTG_FIFO_SIZE 0x1000U + +#define UID_BASE 0x1FFF7A10U /*!< Unique device ID register base address */ +#define FLASHSIZE_BASE 0x1FFF7A22U /*!< FLASH Size register base address */ +#define PACKAGE_BASE 0x1FFF7BF0U /*!< Package size register base address */ +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define TIM6 ((TIM_TypeDef *) TIM6_BASE) +#define TIM7 ((TIM_TypeDef *) TIM7_BASE) +#define TIM12 ((TIM_TypeDef *) TIM12_BASE) +#define TIM13 ((TIM_TypeDef *) TIM13_BASE) +#define TIM14 ((TIM_TypeDef *) TIM14_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define I2S2ext ((SPI_TypeDef *) I2S2ext_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define I2S3ext ((SPI_TypeDef *) I2S3ext_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define USART3 ((USART_TypeDef *) USART3_BASE) +#define UART4 ((USART_TypeDef *) UART4_BASE) +#define UART5 ((USART_TypeDef *) UART5_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define CAN1 ((CAN_TypeDef *) CAN1_BASE) +#define CAN2 ((CAN_TypeDef *) CAN2_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define DAC1 ((DAC_TypeDef *) DAC_BASE) +#define DAC ((DAC_TypeDef *) DAC_BASE) /* Kept for legacy purpose */ +#define UART7 ((USART_TypeDef *) UART7_BASE) +#define UART8 ((USART_TypeDef *) UART8_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define TIM8 ((TIM_TypeDef *) TIM8_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define ADC2 ((ADC_TypeDef *) ADC2_BASE) +#define ADC3 ((ADC_TypeDef *) ADC3_BASE) +#define ADC123_COMMON ((ADC_Common_TypeDef *) ADC123_COMMON_BASE) +/* Legacy define */ +#define ADC ADC123_COMMON +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI4 ((SPI_TypeDef *) SPI4_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define SPI5 ((SPI_TypeDef *) SPI5_BASE) +#define SPI6 ((SPI_TypeDef *) SPI6_BASE) +#define SAI1 ((SAI_TypeDef *) SAI1_BASE) +#define SAI1_Block_A ((SAI_Block_TypeDef *)SAI1_Block_A_BASE) +#define SAI1_Block_B ((SAI_Block_TypeDef *)SAI1_Block_B_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOF ((GPIO_TypeDef *) GPIOF_BASE) +#define GPIOG ((GPIO_TypeDef *) GPIOG_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define GPIOI ((GPIO_TypeDef *) GPIOI_BASE) +#define GPIOJ ((GPIO_TypeDef *) GPIOJ_BASE) +#define GPIOK ((GPIO_TypeDef *) GPIOK_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) +#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) +#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) +#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) +#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) +#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) +#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) +#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) +#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) +#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) +#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) +#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) +#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) +#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) +#define ETH ((ETH_TypeDef *) ETH_BASE) +#define DMA2D ((DMA2D_TypeDef *)DMA2D_BASE) +#define DCMI ((DCMI_TypeDef *) DCMI_BASE) +#define CRYP ((CRYP_TypeDef *) CRYP_BASE) +#define HASH ((HASH_TypeDef *) HASH_BASE) +#define HASH_DIGEST ((HASH_DIGEST_TypeDef *) HASH_DIGEST_BASE) +#define RNG ((RNG_TypeDef *) RNG_BASE) +#define FMC_Bank1 ((FMC_Bank1_TypeDef *) FMC_Bank1_R_BASE) +#define FMC_Bank1E ((FMC_Bank1E_TypeDef *) FMC_Bank1E_R_BASE) +#define FMC_Bank2_3 ((FMC_Bank2_3_TypeDef *) FMC_Bank2_3_R_BASE) +#define FMC_Bank4 ((FMC_Bank4_TypeDef *) FMC_Bank4_R_BASE) +#define FMC_Bank5_6 ((FMC_Bank5_6_TypeDef *) FMC_Bank5_6_R_BASE) +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) +#define USB_OTG_FS1 ((USB_OTG_GlobalTypeDef *) USB_OTG_FS1_PERIPH_BASE) +#define USB_OTG_FS2 ((USB_OTG_GlobalTypeDef *) USB_OTG_FS2_PERIPH_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/* + * @brief Specific device feature definitions (not present on all devices in the STM32F4 serie) + */ +#define ADC_MULTIMODE_SUPPORT /*!
© COPYRIGHT(c) 2017 STMicroelectronics
+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx + * @{ + */ + +#ifndef __AT32F4xx_H +#define __AT32F4xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * @brief STM32 Family + */ +#if !defined (STM32F4) +#define STM32F4 +#endif /* STM32F4 */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ +#if !defined (STM32F405xx) && !defined (STM32F415xx) && !defined (STM32F407xx) && !defined (STM32F417xx) && \ + !defined (STM32F427xx) && !defined (STM32F437xx) && !defined (STM32F429xx) && !defined (STM32F439xx) && \ + !defined (STM32F401xC) && !defined (STM32F401xE) && !defined (STM32F410Tx) && !defined (STM32F410Cx) && \ + !defined (STM32F410Rx) && !defined (STM32F411xE) && !defined (STM32F446xx) && !defined (STM32F469xx) && \ + !defined (STM32F479xx) && !defined (STM32F412Cx) && !defined (STM32F412Rx) && !defined (STM32F412Vx) && \ + !defined (STM32F412Zx) && !defined (STM32F413xx) && !defined (STM32F423xx) + /* #define STM32F405xx */ /*!< STM32F405RG, STM32F405VG and STM32F405ZG Devices */ + /* #define STM32F415xx */ /*!< STM32F415RG, STM32F415VG and STM32F415ZG Devices */ + /* #define STM32F407xx */ /*!< STM32F407VG, STM32F407VE, STM32F407ZG, STM32F407ZE, STM32F407IG and STM32F407IE Devices */ + /* #define STM32F417xx */ /*!< STM32F417VG, STM32F417VE, STM32F417ZG, STM32F417ZE, STM32F417IG and STM32F417IE Devices */ + /* #define STM32F427xx */ /*!< STM32F427VG, STM32F427VI, STM32F427ZG, STM32F427ZI, STM32F427IG and STM32F427II Devices */ + /* #define STM32F437xx */ /*!< STM32F437VG, STM32F437VI, STM32F437ZG, STM32F437ZI, STM32F437IG and STM32F437II Devices */ + /* #define STM32F429xx */ /*!< STM32F429VG, STM32F429VI, STM32F429ZG, STM32F429ZI, STM32F429BG, STM32F429BI, STM32F429NG, + STM32F439NI, STM32F429IG and STM32F429II Devices */ + /* #define STM32F439xx */ /*!< STM32F439VG, STM32F439VI, STM32F439ZG, STM32F439ZI, STM32F439BG, STM32F439BI, STM32F439NG, + STM32F439NI, STM32F439IG and STM32F439II Devices */ + /* #define STM32F401xC */ /*!< STM32F401CB, STM32F401CC, STM32F401RB, STM32F401RC, STM32F401VB and STM32F401VC Devices */ + /* #define STM32F401xE */ /*!< STM32F401CD, STM32F401RD, STM32F401VD, STM32F401CE, STM32F401RE and STM32F401VE Devices */ + /* #define STM32F410Tx */ /*!< STM32F410T8 and STM32F410TB Devices */ + /* #define STM32F410Cx */ /*!< STM32F410C8 and STM32F410CB Devices */ + /* #define STM32F410Rx */ /*!< STM32F410R8 and STM32F410RB Devices */ + /* #define STM32F411xE */ /*!< STM32F411CC, STM32F411RC, STM32F411VC, STM32F411CE, STM32F411RE and STM32F411VE Devices */ + /* #define STM32F446xx */ /*!< STM32F446MC, STM32F446ME, STM32F446RC, STM32F446RE, STM32F446VC, STM32F446VE, STM32F446ZC, + and STM32F446ZE Devices */ + /* #define STM32F469xx */ /*!< STM32F469AI, STM32F469II, STM32F469BI, STM32F469NI, STM32F469AG, STM32F469IG, STM32F469BG, + STM32F469NG, STM32F469AE, STM32F469IE, STM32F469BE and STM32F469NE Devices */ + /* #define STM32F479xx */ /*!< STM32F479AI, STM32F479II, STM32F479BI, STM32F479NI, STM32F479AG, STM32F479IG, STM32F479BG + and STM32F479NG Devices */ + /* #define STM32F412Cx */ /*!< STM32F412CEU and STM32F412CGU Devices */ + /* #define STM32F412Zx */ /*!< STM32F412ZET, STM32F412ZGT, STM32F412ZEJ and STM32F412ZGJ Devices */ + /* #define STM32F412Vx */ /*!< STM32F412VET, STM32F412VGT, STM32F412VEH and STM32F412VGH Devices */ + /* #define STM32F412Rx */ /*!< STM32F412RET, STM32F412RGT, STM32F412REY and STM32F412RGY Devices */ + /* #define STM32F413xx */ /*!< STM32F413CH, STM32F413MH, STM32F413RH, STM32F413VH, STM32F413ZH, STM32F413CG, STM32F413MG, + STM32F413RG, STM32F413VG and STM32F413ZG Devices */ + /* #define STM32F423xx */ /*!< STM32F423CH, STM32F423RH, STM32F423VH and STM32F423ZH Devices */ +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ +#if !defined (USE_HAL_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_HAL_DRIVER */ +#endif /* USE_HAL_DRIVER */ + +/** + * @brief CMSIS version number V2.6.1 + */ +#define __STM32F4xx_CMSIS_VERSION_MAIN (0x02U) /*!< [31:24] main version */ +#define __STM32F4xx_CMSIS_VERSION_SUB1 (0x06U) /*!< [23:16] sub1 version */ +#define __STM32F4xx_CMSIS_VERSION_SUB2 (0x01U) /*!< [15:8] sub2 version */ +#define __STM32F4xx_CMSIS_VERSION_RC (0x00U) /*!< [7:0] release candidate */ +#define __STM32F4xx_CMSIS_VERSION ((__STM32F4xx_CMSIS_VERSION_MAIN << 24)\ + |(__STM32F4xx_CMSIS_VERSION_SUB1 << 16)\ + |(__STM32F4xx_CMSIS_VERSION_SUB2 << 8 )\ + |(__STM32F4xx_CMSIS_VERSION)) + +/** + * @} + */ + +/** @addtogroup Device_Included + * @{ + */ + +#if defined(AT32F435xx) || defined(AT32F437xx) + #include "at32f435xx.h" +#else + #error "Please select first the target AT32F4xx device used in your application (in at32f4xx.h file)" +#endif + +/** + * @} + */ + +/** @addtogroup Exported_types + * @{ + */ +typedef enum +{ + RESET = 0U, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + DISABLE = 0U, + ENABLE = !DISABLE +} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum +{ + ERROR = 0U, + SUCCESS = !ERROR +} ErrorStatus; + +/** + * @} + */ + + +/** @addtogroup Exported_macro + * @{ + */ +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) + +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) + +#define READ_BIT(REG, BIT) ((REG) & (BIT)) + +#define CLEAR_REG(REG) ((REG) = (0x0)) + +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) + +#define READ_REG(REG) ((REG)) + +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) + +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) + + +/** + * @} + */ + +#if defined (USE_HAL_DRIVER) + #include "stm32f4xx_hal.h" +#endif /* USE_HAL_DRIVER */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __AT32F4xx_H */ +/** + * @} + */ + +/** + * @} + */ + + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/os/common/ext/Artery/AT32F4xx/system_at32f4xx.h b/os/common/ext/Artery/AT32F4xx/system_at32f4xx.h new file mode 100644 index 0000000000..06309051c8 --- /dev/null +++ b/os/common/ext/Artery/AT32F4xx/system_at32f4xx.h @@ -0,0 +1,124 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.h + * @author MCD Application Team + * @version V2.6.1 + * @date 14-February-2017 + * @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32F4XX_H +#define __SYSTEM_STM32F4XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup STM32F4xx_System_Includes + * @{ + */ + +/** + * @} + */ + + +/** @addtogroup STM32F4xx_System_Exported_types + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetSysClockFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ +extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Functions + * @{ + */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32F4XX_H */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F435ZMxx.ld b/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F435ZMxx.ld new file mode 100644 index 0000000000..2c86aa055f --- /dev/null +++ b/os/common/startup/ARMCMx/compilers/GCC/ld/AT32F435ZMxx.ld @@ -0,0 +1,86 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/* + * AT32F435ZMxx with default settings memory setup. + * Note: Use of ram1 and ram2 is mutually exclusive with use of ram0. + */ +MEMORY +{ + flash0 (rx) : org = 0x08000000, len = 4032k + flash1 (rx) : org = 0x00000000, len = 0 + flash2 (rx) : org = 0x00000000, len = 0 + flash3 (rx) : org = 0x00000000, len = 0 + flash4 (rx) : org = 0x00000000, len = 0 + flash5 (rx) : org = 0x00000000, len = 0 + flash6 (rx) : org = 0x00000000, len = 0 + flash7 (rx) : org = 0x00000000, len = 0 + ram0 (wx) : org = 0x20000000, len = 64k + 320k /* SRAM1 + SRAM2 */ + ram1 (wx) : org = 0x20000000, len = 64k /* SRAM1 */ + ram2 (wx) : org = 0x20010000, len = 320k /* SRAM2 */ + ram3 (wx) : org = 0x20020000, len = 0 + ram4 (wx) : org = 0x10000000, len = 0 + ram5 (wx) : org = 0x40024000, len = 0 + ram6 (wx) : org = 0x00000000, len = 0 + ram7 (wx) : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk index 4f7178de5a..0eeee999f1 100644 --- a/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/rules.mk @@ -272,7 +272,7 @@ $(BUILDDIR)/lib$(PROJECT).a: $(OBJS) @echo Done clean: CLEAN_RULE_HOOK - @echo Cleaning + @echo Cleaning-GCC @echo - $(DEPDIR) @-rm -fR $(DEPDIR)/* $(BUILDDIR)/* 2>/dev/null @-if [ -d "$(DEPDIR)" ]; then rmdir -p --ignore-fail-on-non-empty $(subst ./,,$(DEPDIR)) 2>/dev/null; fi diff --git a/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f4xx.mk b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f4xx.mk new file mode 100644 index 0000000000..e33f7bcf6d --- /dev/null +++ b/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f4xx.mk @@ -0,0 +1,18 @@ +# List of the ChibiOS generic AT32F4xx startup and CMSIS files. +STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c + +STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.S \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.S + +STARTUPINC = $(CHIBIOS)/os/common/portability/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \ + $(CHIBIOS)/os/common/startup/ARMCMx/devices/AT32F4xx \ + $(CHIBIOS)/os/common/ext/ARM/CMSIS/Core/Include \ + $(CHIBIOS)/os/common/ext/Artery/AT32F4xx + +STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld + +# Shared variables +ALLXASMSRC += $(STARTUPASM) +ALLCSRC += $(STARTUPSRC) +ALLINC += $(STARTUPINC) diff --git a/os/common/startup/ARMCMx/devices/AT32F4xx/cmparams.h b/os/common/startup/ARMCMx/devices/AT32F4xx/cmparams.h new file mode 100644 index 0000000000..0b8b4e01ad --- /dev/null +++ b/os/common/startup/ARMCMx/devices/AT32F4xx/cmparams.h @@ -0,0 +1,88 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/cmparams.h + * @brief ARM Cortex-M4 parameters for the STM32F4xx. + * + * @defgroup ARMCMx_STM32F4xx STM32F4xx Specific Parameters + * @ingroup ARMCMx_SPECIFIC + * @details This file contains the Cortex-M4 specific parameters for the + * STM32F4xx platform. + * @{ + */ + +#ifndef CMPARAMS_H +#define CMPARAMS_H + +/** + * @brief Cortex core model. + */ +#define CORTEX_MODEL 4 + +/** + * @brief Floating Point unit presence. + */ +#define CORTEX_HAS_FPU 1 + +/** + * @brief Number of bits in priority masks. + */ +#define CORTEX_PRIORITY_BITS 4 + +/* If the device type is not externally defined, for example from the Makefile, + then a file named board.h is included. This file must contain a device + definition compatible with the vendor include file.*/ +#if !defined(AT32F435xx) && !defined(AT32F437xx) +#include "board.h" +#endif + +/** + * @brief Number of interrupt vectors. + * @note This number does not include the 16 system vectors and must be + * rounded to a multiple of 8. + */ +#define CORTEX_NUM_VECTORS 120 + +/* The following code is not processed when the file is included from an + asm module.*/ +#if !defined(_FROM_ASM_) + +/* Including the device CMSIS header. Note, we are not using the definitions + from this header because we need this file to be usable also from + assembler source files. We verify that the info matches instead.*/ +#include "at32f4xx.h" + +/*lint -save -e9029 [10.4] Signedness comes from external files, it is + unpredictable but gives no problems.*/ +#if CORTEX_MODEL != __CORTEX_M +#error "CMSIS __CORTEX_M mismatch" +#endif + +#if CORTEX_HAS_FPU != __FPU_PRESENT +#error "CMSIS __FPU_PRESENT mismatch" +#endif + +#if CORTEX_PRIORITY_BITS != __NVIC_PRIO_BITS +#error "CMSIS __NVIC_PRIO_BITS mismatch" +#endif +/*lint -restore*/ + +#endif /* !defined(_FROM_ASM_) */ + +#endif /* CMPARAMS_H */ + +/** @} */ diff --git a/os/hal/boards/AT_START_F435/board.c b/os/hal/boards/AT_START_F435/board.c new file mode 100644 index 0000000000..4041ccf612 --- /dev/null +++ b/os/hal/boards/AT_START_F435/board.c @@ -0,0 +1,266 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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 has been automatically generated using ChibiStudio board + * generator plugin. Do not edit manually. + */ + +#include "hal.h" +#include "stm32_gpio.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief Type of STM32 GPIO port setup. + */ +typedef struct { + uint32_t moder; + uint32_t otyper; + uint32_t ospeedr; + uint32_t pupdr; + uint32_t odr; + uint32_t afrl; + uint32_t afrh; +} gpio_setup_t; + +/** + * @brief Type of STM32 GPIO initialization data. + */ +typedef struct { +#if STM32_HAS_GPIOA || defined(__DOXYGEN__) + gpio_setup_t PAData; +#endif +#if STM32_HAS_GPIOB || defined(__DOXYGEN__) + gpio_setup_t PBData; +#endif +#if STM32_HAS_GPIOC || defined(__DOXYGEN__) + gpio_setup_t PCData; +#endif +#if STM32_HAS_GPIOD || defined(__DOXYGEN__) + gpio_setup_t PDData; +#endif +#if STM32_HAS_GPIOE || defined(__DOXYGEN__) + gpio_setup_t PEData; +#endif +#if STM32_HAS_GPIOF || defined(__DOXYGEN__) + gpio_setup_t PFData; +#endif +#if STM32_HAS_GPIOG || defined(__DOXYGEN__) + gpio_setup_t PGData; +#endif +#if STM32_HAS_GPIOH || defined(__DOXYGEN__) + gpio_setup_t PHData; +#endif +#if STM32_HAS_GPIOI || defined(__DOXYGEN__) + gpio_setup_t PIData; +#endif +#if STM32_HAS_GPIOJ || defined(__DOXYGEN__) + gpio_setup_t PJData; +#endif +#if STM32_HAS_GPIOK || defined(__DOXYGEN__) + gpio_setup_t PKData; +#endif +} gpio_config_t; + +/** + * @brief STM32 GPIO static initialization data. + */ +static const gpio_config_t gpio_default_config = { +#if STM32_HAS_GPIOA + {VAL_GPIOA_MODER, VAL_GPIOA_OTYPER, VAL_GPIOA_OSPEEDR, VAL_GPIOA_PUPDR, + VAL_GPIOA_ODR, VAL_GPIOA_AFRL, VAL_GPIOA_AFRH}, +#endif +#if STM32_HAS_GPIOB + {VAL_GPIOB_MODER, VAL_GPIOB_OTYPER, VAL_GPIOB_OSPEEDR, VAL_GPIOB_PUPDR, + VAL_GPIOB_ODR, VAL_GPIOB_AFRL, VAL_GPIOB_AFRH}, +#endif +#if STM32_HAS_GPIOC + {VAL_GPIOC_MODER, VAL_GPIOC_OTYPER, VAL_GPIOC_OSPEEDR, VAL_GPIOC_PUPDR, + VAL_GPIOC_ODR, VAL_GPIOC_AFRL, VAL_GPIOC_AFRH}, +#endif +#if STM32_HAS_GPIOD + {VAL_GPIOD_MODER, VAL_GPIOD_OTYPER, VAL_GPIOD_OSPEEDR, VAL_GPIOD_PUPDR, + VAL_GPIOD_ODR, VAL_GPIOD_AFRL, VAL_GPIOD_AFRH}, +#endif +#if STM32_HAS_GPIOE + {VAL_GPIOE_MODER, VAL_GPIOE_OTYPER, VAL_GPIOE_OSPEEDR, VAL_GPIOE_PUPDR, + VAL_GPIOE_ODR, VAL_GPIOE_AFRL, VAL_GPIOE_AFRH}, +#endif +#if STM32_HAS_GPIOF + {VAL_GPIOF_MODER, VAL_GPIOF_OTYPER, VAL_GPIOF_OSPEEDR, VAL_GPIOF_PUPDR, + VAL_GPIOF_ODR, VAL_GPIOF_AFRL, VAL_GPIOF_AFRH}, +#endif +#if STM32_HAS_GPIOG + {VAL_GPIOG_MODER, VAL_GPIOG_OTYPER, VAL_GPIOG_OSPEEDR, VAL_GPIOG_PUPDR, + VAL_GPIOG_ODR, VAL_GPIOG_AFRL, VAL_GPIOG_AFRH}, +#endif +#if STM32_HAS_GPIOH + {VAL_GPIOH_MODER, VAL_GPIOH_OTYPER, VAL_GPIOH_OSPEEDR, VAL_GPIOH_PUPDR, + VAL_GPIOH_ODR, VAL_GPIOH_AFRL, VAL_GPIOH_AFRH}, +#endif +#if STM32_HAS_GPIOI + {VAL_GPIOI_MODER, VAL_GPIOI_OTYPER, VAL_GPIOI_OSPEEDR, VAL_GPIOI_PUPDR, + VAL_GPIOI_ODR, VAL_GPIOI_AFRL, VAL_GPIOI_AFRH}, +#endif +#if STM32_HAS_GPIOJ + {VAL_GPIOJ_MODER, VAL_GPIOJ_OTYPER, VAL_GPIOJ_OSPEEDR, VAL_GPIOJ_PUPDR, + VAL_GPIOJ_ODR, VAL_GPIOJ_AFRL, VAL_GPIOJ_AFRH}, +#endif +#if STM32_HAS_GPIOK + {VAL_GPIOK_MODER, VAL_GPIOK_OTYPER, VAL_GPIOK_OSPEEDR, VAL_GPIOK_PUPDR, + VAL_GPIOK_ODR, VAL_GPIOK_AFRL, VAL_GPIOK_AFRH} +#endif +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void gpio_init(stm32_gpio_t *gpiop, const gpio_setup_t *config) { + + gpiop->OTYPER = config->otyper; + gpiop->OSPEEDR = config->ospeedr; + gpiop->PUPDR = config->pupdr; + gpiop->ODR = config->odr; + gpiop->AFRL = config->afrl; + gpiop->AFRH = config->afrh; + gpiop->MODER = config->moder; +} + +static void stm32_gpio_init(void) { + + /* Enabling GPIO-related clocks, the mask comes from the + registry header file.*/ + rccResetAHB1(STM32_GPIO_EN_MASK); + rccEnableAHB1(STM32_GPIO_EN_MASK, true); + + /* Initializing all the defined GPIO ports.*/ +#if STM32_HAS_GPIOA + gpio_init(GPIOA, &gpio_default_config.PAData); +#endif +#if STM32_HAS_GPIOB + gpio_init(GPIOB, &gpio_default_config.PBData); +#endif +#if STM32_HAS_GPIOC + gpio_init(GPIOC, &gpio_default_config.PCData); +#endif +#if STM32_HAS_GPIOD + gpio_init(GPIOD, &gpio_default_config.PDData); +#endif +#if STM32_HAS_GPIOE + gpio_init(GPIOE, &gpio_default_config.PEData); +#endif +#if STM32_HAS_GPIOF + gpio_init(GPIOF, &gpio_default_config.PFData); +#endif +#if STM32_HAS_GPIOG + gpio_init(GPIOG, &gpio_default_config.PGData); +#endif +#if STM32_HAS_GPIOH + gpio_init(GPIOH, &gpio_default_config.PHData); +#endif +#if STM32_HAS_GPIOI + gpio_init(GPIOI, &gpio_default_config.PIData); +#endif +#if STM32_HAS_GPIOJ + gpio_init(GPIOJ, &gpio_default_config.PJData); +#endif +#if STM32_HAS_GPIOK + gpio_init(GPIOK, &gpio_default_config.PKData); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Early initialization code. + * @details GPIO ports and system clocks are initialized before everything + * else. + */ +void __early_init(void) { + + stm32_gpio_init(); + stm32_clock_init(); +} + +#if HAL_USE_SDC || defined(__DOXYGEN__) +/** + * @brief SDC card detection. + */ +bool sdc_lld_is_card_inserted(SDCDriver *sdcp) { + + (void)sdcp; + /* CHTODO: Fill the implementation.*/ + return true; +} + +/** + * @brief SDC card write protection detection. + */ +bool sdc_lld_is_write_protected(SDCDriver *sdcp) { + + (void)sdcp; + /* CHTODO: Fill the implementation.*/ + return false; +} +#endif /* HAL_USE_SDC */ + +#if HAL_USE_MMC_SPI || defined(__DOXYGEN__) +/** + * @brief MMC_SPI card detection. + */ +bool mmc_lld_is_card_inserted(MMCDriver *mmcp) { + + (void)mmcp; + /* CHTODO: Fill the implementation.*/ + return true; +} + +/** + * @brief MMC_SPI card write protection detection. + */ +bool mmc_lld_is_write_protected(MMCDriver *mmcp) { + + (void)mmcp; + /* CHTODO: Fill the implementation.*/ + return false; +} +#endif + +/** + * @brief Board-specific initialization code. + * @note You can add your board-specific code here. + */ +void boardInit(void) { + +} diff --git a/os/hal/boards/AT_START_F435/board.h b/os/hal/boards/AT_START_F435/board.h new file mode 100644 index 0000000000..2cf0bf294c --- /dev/null +++ b/os/hal/boards/AT_START_F435/board.h @@ -0,0 +1,1673 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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 has been automatically generated using ChibiStudio board + * generator plugin. Do not edit manually. + */ + +#ifndef BOARD_H +#define BOARD_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/* + * Setup for STMicroelectronics STM32 Nucleo144-F429ZI board. + */ + +/* + * Board identifier. + */ +#define BOARD_AT_START_F435 +#define BOARD_NAME "Artery AT-START-F435 board" + +/* + * Board oscillators-related settings. + * NOTE: LSE not fitted. + */ +#if !defined(STM32_LSECLK) +#define STM32_LSECLK 0U +#endif + +#if !defined(STM32_HSECLK) +#define STM32_HSECLK 8000000U +#endif + +// AT-START-F435 has crystal/ceramic resonator +//#define STM32_HSE_BYPASS + +/* + * Board voltages. + * Required for performance limits calculation. + */ +#define STM32_VDD 300U + +/* + * MCU type as defined in the AT header. + */ +#define AT32F435xx + +/* + * IO pins assignments. + */ +/* TODO: */ +#define GPIOA_BUTTON 0U +#define GPIOA_TIM2_CH1 0U +#define GPIOA_RMII_REF_CLK 1U +#define GPIOA_RMII_MDIO 2U +#define GPIOA_ARD_A0 3U +#define GPIOA_ADC123_IN3 3U +#define GPIOA_ZIO_D24 4U +#define GPIOA_SPI3_NSS 4U +#define GPIOA_ARD_D13 5U +#define GPIOA_SPI1_SCK 5U +#define GPIOA_ARD_D12 6U +#define GPIOA_SPI1_MISO 6U +#define GPIOA_ARD_D11 7U +#define GPIOA_SPI1_MOSI 7U +#define GPIOA_ZIO_D71 7U +#define GPIOA_RMII_RX_DV 7U +#define GPIOA_USB_SOF 8U +#define GPIOA_USART1_TX 9U +#define GPIOA_USART1_RX 10U +#define GPIOA_OTG1_DM 11U +#define GPIOA_OTG2_DP 12U +#define GPIOA_SWDIO 13U +#define GPIOA_SWCLK 14U +#define GPIOA_ZIO_D20 15U +#define GPIOA_I2S3_WS 15U + +#define GPIOB_ZIO_D33 0U +#define GPIOB_TIM3_CH3 0U +#define GPIOB_LED1 0U +#define GPIOB_ZIO_A6 1U +#define GPIOB_ADC12_IN9 1U +#define GPIOB_ZIO_D27 2U +#define GPIOB_ZIO_D23 3U +#define GPIOB_I2S3_CK 3U +#define GPIOB_ZIO_D25 4U +#define GPIOB_SPI3_MISO 4U +#define GPIOB_ZIO_D22 5U +#define GPIOB_I2S3_SD 5U +#define GPIOB_ZIO_D26 6U +#define GPIOB_LED2 7U +#define GPIOB_ARD_D15 8U +#define GPIOB_I2C1_SCL 8U +#define GPIOB_ARD_D14 9U +#define GPIOB_I2C1_SDA 9U +#define GPIOB_ZIO_D36 10U +#define GPIOB_TIM2_CH3 10U +#define GPIOB_ZIO_D35 11U +#define GPIOB_TIM2_CH4 11U +#define GPIOB_OTG2_ID 12U +#define GPIOB_OTG2_VBUS 13U +#define GPIOB_OTG2_DP 14U +#define GPIOB_OTG2_DM 15U + +#define GPIOC_ARD_A1 0U +#define GPIOC_ADC123_IN10 0U +#define GPIOC_RMII_MDC 1U +#define GPIOC_ZIO_A7 2U +#define GPIOC_ADC123_IN12 2U +#define GPIOC_ARD_A2 3U +#define GPIOC_ADC123_IN13 3U +#define GPIOC_RMII_RXD0 4U +#define GPIOC_RMII_RXD1 5U +#define GPIOC_ZIO_D16 6U +#define GPIOC_I2S2_MCK 6U +#define GPIOC_ZIO_D21 7U +#define GPIOC_I2S3_MCK 7U +#define GPIOC_ZIO_D43 8U +#define GPIOC_SDMMC_D0 8U +#define GPIOC_ZIO_D44 9U +#define GPIOC_SDMMC_D1 9U +#define GPIOC_ZIO_D45 10U +#define GPIOC_SDMMC_D2 10U +#define GPIOC_ZIO_D46 11U +#define GPIOC_SDMMC_D3 11U +#define GPIOC_ZIO_D47 12U +#define GPIOC_SDMMC_CK 12U +#define GPIOC_BUTTON 13U +#define GPIOC_OSC32_IN 14U +#define GPIOC_OSC32_OUT 15U + +#define GPIOD_ZIO_D67 0U +#define GPIOD_CAN1_RX 0U +#define GPIOD_ZIO_D66 1U +#define GPIOD_CAN1_TX 1U +#define GPIOD_ZIO_D48 2U +#define GPIOD_SDMMC_CMD 2U +#define GPIOD_ZIO_D55 3U +#define GPIOD_USART2_CTS 3U +#define GPIOD_ZIO_D54 4U +#define GPIOD_USART2_RTS 4U +#define GPIOD_ZIO_D53 5U +#define GPIOD_USART2_TX 5U +#define GPIOD_ZIO_D52 6U +#define GPIOD_USART2_RX 6U +#define GPIOD_ZIO_D51 7U +#define GPIOD_USART2_SCLK 7U +#define GPIOD_USART3_RX 8U +#define GPIOD_STLK_RX 8U +#define GPIOD_USART3_TX 9U +#define GPIOD_STLK_TX 9U +#define GPIOD_PIN10 10U +#define GPIOD_ZIO_D30 11U +#define GPIOD_ZIO_D29 12U +#define GPIOD_LED0 13U +#define GPIOD_LED1 14U +#define GPIOD_LED2 15U + +#define GPIOE_ZIO_D34 0U +#define GPIOE_TIM4_ETR 0U +#define GPIOE_PIN1 1U +#define GPIOE_ZIO_D31 2U +#define GPIOE_ZIO_D56 2U +#define GPIOE_SAI1_MCLK_A 2U +#define GPIOE_ZIO_D60 3U +#define GPIOE_SAI1_SD_B 3U +#define GPIOE_ZIO_D57 4U +#define GPIOE_SAI1_FS_A 4U +#define GPIOE_ZIO_D58 5U +#define GPIOE_SAI1_SCK_A 5U +#define GPIOE_ZIO_D59 6U +#define GPIOE_SAI1_SD_A 6U +#define GPIOE_ZIO_D41 7U +#define GPIOE_TIM1_ETR 7U +#define GPIOE_ZIO_D42 8U +#define GPIOE_TIM1_CH1N 8U +#define GPIOE_ARD_D6 9U +#define GPIOE_TIM1_CH1 9U +#define GPIOE_ZIO_D40 10U +#define GPIOE_TIM1_CH2N 10U +#define GPIOE_ARD_D5 11U +#define GPIOE_TIM1_CH2 11U +#define GPIOE_ZIO_D39 12U +#define GPIOE_TIM1_CH3N 12U +#define GPIOE_ARD_D3 13U +#define GPIOE_TIM1_CH3 13U +#define GPIOE_ZIO_D38 14U +#define GPIOE_ZIO_D37 15U +#define GPIOE_TIM1_BKIN1 15U + +#define GPIOF_ZIO_D68 0U +#define GPIOF_I2C2_SDA 0U +#define GPIOF_ZIO_D69 1U +#define GPIOF_I2C2_SCL 1U +#define GPIOF_ZIO_D70 2U +#define GPIOF_I2C2_SMBA 2U +#define GPIOF_ARD_A3 3U +#define GPIOF_ADC3_IN9 3U +#define GPIOF_ZIO_A8 4U +#define GPIOF_ADC3_IN14 4U +#define GPIOF_ARD_A4 5U +#define GPIOF_ADC3_IN15 5U +#define GPIOF_PIN6 6U +#define GPIOF_ZIO_D62 7U +#define GPIOF_SAI1_MCLK_B 7U +#define GPIOF_ZIO_D61 8U +#define GPIOF_SAI1_SCK_B 8U +#define GPIOF_ZIO_D63 9U +#define GPIOF_SAI1_FS_B 9U +#define GPIOF_ARD_A5 10U +#define GPIOF_ADC3_IN8 10U +#define GPIOF_PIN11 11U +#define GPIOF_ARD_D8 12U +#define GPIOF_ARD_D7 13U +#define GPIOF_ARD_D4 14U +#define GPIOF_ARD_D2 15U + +#define GPIOG_ZIO_D65 0U +#define GPIOG_ZIO_D64 1U +#define GPIOG_ZIO_D49 2U +#define GPIOG_ZIO_D50 3U +#define GPIOG_PIN4 4U +#define GPIOG_PIN5 5U +#define GPIOG_USB_GPIO_OUT 6U +#define GPIOG_USB_GPIO_IN 7U +#define GPIOG_PIN8 8U +#define GPIOG_ARD_D0 9U +#define GPIOG_USART6_RX 9U +#define GPIOG_PIN10 10U +#define GPIOG_RMII_TX_EN 11U +#define GPIOG_PIN12 12U +#define GPIOG_RMII_TXD0 13U +#define GPIOG_ARD_D1 14U +#define GPIOG_USART6_TX 14U +#define GPIOG_PIN15 15U + +#define GPIOH_OSC_IN 0U +#define GPIOH_OSC_OUT 1U +#define GPIOH_PIN2 2U +#define GPIOH_PIN3 3U +#define GPIOH_PIN4 4U +#define GPIOH_PIN5 5U +#define GPIOH_PIN6 6U +#define GPIOH_PIN7 7U +#define GPIOH_PIN8 8U +#define GPIOH_PIN9 9U +#define GPIOH_PIN10 10U +#define GPIOH_PIN11 11U +#define GPIOH_PIN12 12U +#define GPIOH_PIN13 13U +#define GPIOH_PIN14 14U +#define GPIOH_PIN15 15U + +#define GPIOI_PIN0 0U +#define GPIOI_PIN1 1U +#define GPIOI_PIN2 2U +#define GPIOI_PIN3 3U +#define GPIOI_PIN4 4U +#define GPIOI_PIN5 5U +#define GPIOI_PIN6 6U +#define GPIOI_PIN7 7U +#define GPIOI_PIN8 8U +#define GPIOI_PIN9 9U +#define GPIOI_PIN10 10U +#define GPIOI_PIN11 11U +#define GPIOI_PIN12 12U +#define GPIOI_PIN13 13U +#define GPIOI_PIN14 14U +#define GPIOI_PIN15 15U + +#define GPIOJ_PIN0 0U +#define GPIOJ_PIN1 1U +#define GPIOJ_PIN2 2U +#define GPIOJ_PIN3 3U +#define GPIOJ_PIN4 4U +#define GPIOJ_PIN5 5U +#define GPIOJ_PIN6 6U +#define GPIOJ_PIN7 7U +#define GPIOJ_PIN8 8U +#define GPIOJ_PIN9 9U +#define GPIOJ_PIN10 10U +#define GPIOJ_PIN11 11U +#define GPIOJ_PIN12 12U +#define GPIOJ_PIN13 13U +#define GPIOJ_PIN14 14U +#define GPIOJ_PIN15 15U + +#define GPIOK_PIN0 0U +#define GPIOK_PIN1 1U +#define GPIOK_PIN2 2U +#define GPIOK_PIN3 3U +#define GPIOK_PIN4 4U +#define GPIOK_PIN5 5U +#define GPIOK_PIN6 6U +#define GPIOK_PIN7 7U +#define GPIOK_PIN8 8U +#define GPIOK_PIN9 9U +#define GPIOK_PIN10 10U +#define GPIOK_PIN11 11U +#define GPIOK_PIN12 12U +#define GPIOK_PIN13 13U +#define GPIOK_PIN14 14U +#define GPIOK_PIN15 15U + +/* + * IO lines assignments. + */ + +#define LINE_LED1 PAL_LINE(GPIOD, 13U) +#define LINE_LED2 PAL_LINE(GPIOD, 14U) +#define LINE_LED3 PAL_LINE(GPIOD, 15U) + +#define LINE_BUTTON PAL_LINE(GPIOA, 0U) + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/* + * I/O ports initial setup, this configuration is established soon after reset + * in the initialization code. + * Please refer to the STM32 Reference Manual for details. + */ +#define PIN_MODE_INPUT(n) (0U << ((n) * 2U)) +#define PIN_MODE_OUTPUT(n) (1U << ((n) * 2U)) +#define PIN_MODE_ALTERNATE(n) (2U << ((n) * 2U)) +#define PIN_MODE_ANALOG(n) (3U << ((n) * 2U)) +#define PIN_ODR_LOW(n) (0U << (n)) +#define PIN_ODR_HIGH(n) (1U << (n)) +#define PIN_OTYPE_PUSHPULL(n) (0U << (n)) +#define PIN_OTYPE_OPENDRAIN(n) (1U << (n)) +/* Normal */ +#define PIN_OSPEED_VERYLOW(n) (0U << ((n) * 2U)) +/* Normal */ +#define PIN_OSPEED_MEDIUM(n) (3U << ((n) * 2U)) +/* Large */ +#define PIN_OSPEED_HIGH(n) (1U << ((n) * 2U)) +#define PIN_PUPDR_FLOATING(n) (0U << ((n) * 2U)) +#define PIN_PUPDR_PULLUP(n) (1U << ((n) * 2U)) +#define PIN_PUPDR_PULLDOWN(n) (2U << ((n) * 2U)) +#define PIN_AFIO_AF(n, v) ((v) << (((n) % 8U) * 4U)) + +/* + * GPIOA setup: + * + * PA0 - ZIO_D32 TIM2_CH1 (input pullup). + * PA1 - RMII_REF_CLK (alternate 11). + * PA2 - RMII_MDIO (alternate 11). + * PA3 - ARD_A0 ADC123_IN3 (input pullup). + * PA4 - ZIO_D24 SPI3_NSS (input pullup). + * PA5 - ARD_D13 SPI1_SCK (input pullup). + * PA6 - ARD_D12 SPI1_MISO (input pullup). + * PA7 - ARD_D11 SPI1_MOSI ZIO_D71 RMII_RX_DV(alternate 11). + * PA8 - USB_SOF (alternate 10). + * PA9 - USB_VBUS (analog). + * PA10 - USB_ID (alternate 10). + * PA11 - USB_DM (alternate 10). + * PA12 - USB_DP (alternate 10). + * PA13 - SWDIO (alternate 0). + * PA14 - SWCLK (alternate 0). + * PA15 - ZIO_D20 I2S3_WS (input pullup). + */ +#define VAL_GPIOA_MODER (PIN_MODE_INPUT(GPIOA_BUTTON) | \ + PIN_MODE_ALTERNATE(GPIOA_RMII_REF_CLK) |\ + PIN_MODE_ALTERNATE(GPIOA_RMII_MDIO) | \ + PIN_MODE_INPUT(GPIOA_ARD_A0) | \ + PIN_MODE_INPUT(GPIOA_ZIO_D24) | \ + PIN_MODE_INPUT(GPIOA_ARD_D13) | \ + PIN_MODE_INPUT(GPIOA_ARD_D12) | \ + PIN_MODE_ALTERNATE(GPIOA_ARD_D11) | \ + PIN_MODE_ALTERNATE(GPIOA_USB_SOF) | \ + PIN_MODE_ALTERNATE(GPIOA_USART1_TX) | \ + PIN_MODE_ALTERNATE(GPIOA_USART1_RX) | \ + PIN_MODE_ALTERNATE(GPIOA_OTG1_DM) | \ + PIN_MODE_ALTERNATE(GPIOA_OTG2_DP) | \ + PIN_MODE_ALTERNATE(GPIOA_SWDIO) | \ + PIN_MODE_ALTERNATE(GPIOA_SWCLK) | \ + PIN_MODE_INPUT(GPIOA_ZIO_D20)) +#define VAL_GPIOA_OTYPER (PIN_OTYPE_PUSHPULL(GPIOA_BUTTON) | \ + PIN_OTYPE_PUSHPULL(GPIOA_RMII_REF_CLK) |\ + PIN_OTYPE_PUSHPULL(GPIOA_RMII_MDIO) | \ + PIN_OTYPE_PUSHPULL(GPIOA_ARD_A0) | \ + PIN_OTYPE_PUSHPULL(GPIOA_ZIO_D24) | \ + PIN_OTYPE_PUSHPULL(GPIOA_ARD_D13) | \ + PIN_OTYPE_PUSHPULL(GPIOA_ARD_D12) | \ + PIN_OTYPE_PUSHPULL(GPIOA_ARD_D11) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USB_SOF) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USART1_TX) | \ + PIN_OTYPE_PUSHPULL(GPIOA_USART1_RX) | \ + PIN_OTYPE_PUSHPULL(GPIOA_OTG1_DM) | \ + PIN_OTYPE_PUSHPULL(GPIOA_OTG2_DP) | \ + PIN_OTYPE_PUSHPULL(GPIOA_SWDIO) | \ + PIN_OTYPE_PUSHPULL(GPIOA_SWCLK) | \ + PIN_OTYPE_PUSHPULL(GPIOA_ZIO_D20)) +#define VAL_GPIOA_OSPEEDR (PIN_OSPEED_HIGH(GPIOA_BUTTON) | \ + PIN_OSPEED_HIGH(GPIOA_RMII_REF_CLK) | \ + PIN_OSPEED_HIGH(GPIOA_RMII_MDIO) | \ + PIN_OSPEED_HIGH(GPIOA_ARD_A0) | \ + PIN_OSPEED_HIGH(GPIOA_ZIO_D24) | \ + PIN_OSPEED_HIGH(GPIOA_ARD_D13) | \ + PIN_OSPEED_HIGH(GPIOA_ARD_D12) | \ + PIN_OSPEED_HIGH(GPIOA_ARD_D11) | \ + PIN_OSPEED_HIGH(GPIOA_USB_SOF) | \ + PIN_OSPEED_HIGH(GPIOA_USART1_TX) | \ + PIN_OSPEED_HIGH(GPIOA_USART1_RX) | \ + PIN_OSPEED_HIGH(GPIOA_OTG1_DM) | \ + PIN_OSPEED_HIGH(GPIOA_OTG2_DP) | \ + PIN_OSPEED_HIGH(GPIOA_SWDIO) | \ + PIN_OSPEED_HIGH(GPIOA_SWCLK) | \ + PIN_OSPEED_HIGH(GPIOA_ZIO_D20)) +#define VAL_GPIOA_PUPDR (PIN_PUPDR_FLOATING(GPIOA_BUTTON) | \ + PIN_PUPDR_FLOATING(GPIOA_RMII_REF_CLK) |\ + PIN_PUPDR_PULLUP(GPIOA_RMII_MDIO) | \ + PIN_PUPDR_PULLUP(GPIOA_ARD_A0) | \ + PIN_PUPDR_PULLUP(GPIOA_ZIO_D24) | \ + PIN_PUPDR_PULLUP(GPIOA_ARD_D13) | \ + PIN_PUPDR_PULLUP(GPIOA_ARD_D12) | \ + PIN_PUPDR_PULLUP(GPIOA_ARD_D11) | \ + PIN_PUPDR_FLOATING(GPIOA_USB_SOF) | \ + PIN_PUPDR_PULLUP(GPIOA_USART1_TX) | \ + PIN_PUPDR_PULLUP(GPIOA_USART1_RX) | \ + PIN_PUPDR_FLOATING(GPIOA_OTG1_DM) | \ + PIN_PUPDR_FLOATING(GPIOA_OTG2_DP) | \ + PIN_PUPDR_FLOATING(GPIOA_SWDIO) | \ + PIN_PUPDR_FLOATING(GPIOA_SWCLK) | \ + PIN_PUPDR_PULLUP(GPIOA_ZIO_D20)) +#define VAL_GPIOA_ODR (PIN_ODR_HIGH(GPIOA_BUTTON) | \ + PIN_ODR_HIGH(GPIOA_RMII_REF_CLK) | \ + PIN_ODR_HIGH(GPIOA_RMII_MDIO) | \ + PIN_ODR_HIGH(GPIOA_ARD_A0) | \ + PIN_ODR_HIGH(GPIOA_ZIO_D24) | \ + PIN_ODR_HIGH(GPIOA_ARD_D13) | \ + PIN_ODR_HIGH(GPIOA_ARD_D12) | \ + PIN_ODR_HIGH(GPIOA_ARD_D11) | \ + PIN_ODR_HIGH(GPIOA_USB_SOF) | \ + PIN_ODR_HIGH(GPIOA_USART1_TX) | \ + PIN_ODR_HIGH(GPIOA_USART1_RX) | \ + PIN_ODR_HIGH(GPIOA_OTG1_DM) | \ + PIN_ODR_HIGH(GPIOA_OTG2_DP) | \ + PIN_ODR_HIGH(GPIOA_SWDIO) | \ + PIN_ODR_HIGH(GPIOA_SWCLK) | \ + PIN_ODR_HIGH(GPIOA_ZIO_D20)) +#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_BUTTON, 0U) | \ + PIN_AFIO_AF(GPIOA_RMII_REF_CLK, 11U) | \ + PIN_AFIO_AF(GPIOA_RMII_MDIO, 11U) | \ + PIN_AFIO_AF(GPIOA_ARD_A0, 0U) | \ + PIN_AFIO_AF(GPIOA_ZIO_D24, 0U) | \ + PIN_AFIO_AF(GPIOA_ARD_D13, 0U) | \ + PIN_AFIO_AF(GPIOA_ARD_D12, 0U) | \ + PIN_AFIO_AF(GPIOA_ARD_D11, 11U)) +#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_USB_SOF, 10U) | \ + PIN_AFIO_AF(GPIOA_USART1_TX, 7U) | \ + PIN_AFIO_AF(GPIOA_USART1_RX, 7U) | \ + PIN_AFIO_AF(GPIOA_OTG1_DM, 10U) | \ + PIN_AFIO_AF(GPIOA_OTG2_DP, 10U) | \ + PIN_AFIO_AF(GPIOA_SWDIO, 0U) | \ + PIN_AFIO_AF(GPIOA_SWCLK, 0U) | \ + PIN_AFIO_AF(GPIOA_ZIO_D20, 0U)) + +/* + * GPIOB setup: + * + * PB0 - ZIO_D33 TIM3_CH3 LED1 (output pushpull maximum). + * PB1 - ZIO_A6 ADC12_IN9 (input pullup). + * PB2 - ZIO_D27 (input pullup). + * PB3 - ZIO_D23 I2S3_CK (input pullup). + * PB4 - ZIO_D25 SPI3_MISO (input pullup). + * PB5 - ZIO_D22 I2S3_SD (input pullup). + * PB6 - ZIO_D26 (input pullup). + * PB7 - LED2 (output pushpull maximum). + * PB8 - ARD_D15 I2C1_SCL (input pullup). + * PB9 - ARD_D14 I2C1_SDA (input pullup). + * PB10 - ZIO_D36 TIM2_CH3 (input pullup). + * PB11 - ZIO_D35 TIM2_CH4 (input pullup). + * PB12 - ZIO_D19 I2S2_WS (input pullup). + * PB13 - ZIO_D18 I2S2_CK RMII_TXD1 (alternate 11). + * PB14 - LED3 (output pushpull maximum). + * PB15 - ZIO_D17 I2S2_SD (input pullup). + */ +#define VAL_GPIOB_MODER (PIN_MODE_OUTPUT(GPIOB_ZIO_D33) | \ + PIN_MODE_INPUT(GPIOB_ZIO_A6) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D27) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D23) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D25) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D22) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D26) | \ + PIN_MODE_OUTPUT(GPIOB_LED2) | \ + PIN_MODE_INPUT(GPIOB_ARD_D15) | \ + PIN_MODE_INPUT(GPIOB_ARD_D14) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D36) | \ + PIN_MODE_INPUT(GPIOB_ZIO_D35) | \ + PIN_MODE_ALTERNATE(GPIOB_OTG2_ID) | \ + PIN_MODE_ALTERNATE(GPIOB_OTG2_VBUS) | \ + PIN_MODE_ALTERNATE(GPIOB_OTG2_DP) | \ + PIN_MODE_ALTERNATE(GPIOB_OTG2_DM)) +#define VAL_GPIOB_OTYPER (PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D33) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_A6) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D27) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D23) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D25) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D22) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D26) | \ + PIN_OTYPE_PUSHPULL(GPIOB_LED2) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ARD_D15) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ARD_D14) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D36) | \ + PIN_OTYPE_PUSHPULL(GPIOB_ZIO_D35) | \ + PIN_OTYPE_PUSHPULL(GPIOB_OTG2_ID) | \ + PIN_OTYPE_PUSHPULL(GPIOB_OTG2_VBUS) | \ + PIN_OTYPE_PUSHPULL(GPIOB_OTG2_DP) | \ + PIN_OTYPE_PUSHPULL(GPIOB_OTG2_DM)) +#define VAL_GPIOB_OSPEEDR (PIN_OSPEED_HIGH(GPIOB_ZIO_D33) | \ + PIN_OSPEED_HIGH(GPIOB_ZIO_A6) | \ + PIN_OSPEED_VERYLOW(GPIOB_ZIO_D27) | \ + PIN_OSPEED_HIGH(GPIOB_ZIO_D23) | \ + PIN_OSPEED_HIGH(GPIOB_ZIO_D25) | \ + PIN_OSPEED_HIGH(GPIOB_ZIO_D22) | \ + PIN_OSPEED_VERYLOW(GPIOB_ZIO_D26) | \ + PIN_OSPEED_HIGH(GPIOB_LED2) | \ + PIN_OSPEED_HIGH(GPIOB_ARD_D15) | \ + PIN_OSPEED_HIGH(GPIOB_ARD_D14) | \ + PIN_OSPEED_HIGH(GPIOB_ZIO_D36) | \ + PIN_OSPEED_HIGH(GPIOB_ZIO_D35) | \ + PIN_OSPEED_HIGH(GPIOB_OTG2_ID) | \ + PIN_OSPEED_HIGH(GPIOB_OTG2_VBUS) | \ + PIN_OSPEED_HIGH(GPIOB_OTG2_DP) | \ + PIN_OSPEED_HIGH(GPIOB_OTG2_DM)) +#define VAL_GPIOB_PUPDR (PIN_PUPDR_FLOATING(GPIOB_ZIO_D33) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_A6) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D27) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D23) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D25) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D22) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D26) | \ + PIN_PUPDR_FLOATING(GPIOB_LED2) | \ + PIN_PUPDR_PULLUP(GPIOB_ARD_D15) | \ + PIN_PUPDR_PULLUP(GPIOB_ARD_D14) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D36) | \ + PIN_PUPDR_PULLUP(GPIOB_ZIO_D35) | \ + PIN_PUPDR_PULLDOWN(GPIOB_OTG2_ID) | \ + PIN_PUPDR_PULLDOWN(GPIOB_OTG2_VBUS) | \ + PIN_PUPDR_FLOATING(GPIOB_OTG2_DP) | \ + PIN_PUPDR_FLOATING(GPIOB_OTG2_DM)) +#define VAL_GPIOB_ODR (PIN_ODR_LOW(GPIOB_ZIO_D33) | \ + PIN_ODR_HIGH(GPIOB_ZIO_A6) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D27) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D23) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D25) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D22) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D26) | \ + PIN_ODR_LOW(GPIOB_LED2) | \ + PIN_ODR_HIGH(GPIOB_ARD_D15) | \ + PIN_ODR_HIGH(GPIOB_ARD_D14) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D36) | \ + PIN_ODR_HIGH(GPIOB_ZIO_D35) | \ + PIN_ODR_HIGH(GPIOB_OTG2_ID) | \ + PIN_ODR_HIGH(GPIOB_OTG2_VBUS) | \ + PIN_ODR_HIGH(GPIOB_OTG2_DP) | \ + PIN_ODR_HIGH(GPIOB_OTG2_DM)) +#define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_ZIO_D33, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_A6, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D27, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D23, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D25, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D22, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D26, 0U) | \ + PIN_AFIO_AF(GPIOB_LED2, 0U)) +#define VAL_GPIOB_AFRH (PIN_AFIO_AF(GPIOB_ARD_D15, 0U) | \ + PIN_AFIO_AF(GPIOB_ARD_D14, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D36, 0U) | \ + PIN_AFIO_AF(GPIOB_ZIO_D35, 0U) | \ + PIN_AFIO_AF(GPIOB_OTG2_ID, 12U) | \ + PIN_AFIO_AF(GPIOB_OTG2_VBUS, 12U) | \ + PIN_AFIO_AF(GPIOB_OTG2_DP, 12U) | \ + PIN_AFIO_AF(GPIOB_OTG2_DM, 12U)) + +/* + * GPIOC setup: + * + * PC0 - ARD_A1 ADC123_IN10 (input pullup). + * PC1 - RMII_MDC (alternate 11). + * PC2 - ZIO_A7 ADC123_IN12 (input pullup). + * PC3 - ARD_A2 ADC123_IN13 (input pullup). + * PC4 - RMII_RXD0 (alternate 11). + * PC5 - RMII_RXD1 (alternate 11). + * PC6 - ZIO_D16 I2S2_MCK (input pullup). + * PC7 - ZIO_D21 I2S3_MCK (input pullup). + * PC8 - ZIO_D43 SDMMC_D0 (input pullup). + * PC9 - ZIO_D44 SDMMC_D1 (input pullup). + * PC10 - ZIO_D45 SDMMC_D2 (input pullup). + * PC11 - ZIO_D46 SDMMC_D3 (input pullup). + * PC12 - ZIO_D47 SDMMC_CK (input pullup). + * PC13 - BUTTON (input floating). + * PC14 - OSC32_IN (input floating). + * PC15 - OSC32_OUT (input floating). + */ +#define VAL_GPIOC_MODER (PIN_MODE_INPUT(GPIOC_ARD_A1) | \ + PIN_MODE_ALTERNATE(GPIOC_RMII_MDC) | \ + PIN_MODE_INPUT(GPIOC_ZIO_A7) | \ + PIN_MODE_INPUT(GPIOC_ARD_A2) | \ + PIN_MODE_ALTERNATE(GPIOC_RMII_RXD0) | \ + PIN_MODE_ALTERNATE(GPIOC_RMII_RXD1) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D16) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D21) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D43) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D44) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D45) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D46) | \ + PIN_MODE_INPUT(GPIOC_ZIO_D47) | \ + PIN_MODE_INPUT(GPIOC_BUTTON) | \ + PIN_MODE_INPUT(GPIOC_OSC32_IN) | \ + PIN_MODE_INPUT(GPIOC_OSC32_OUT)) +#define VAL_GPIOC_OTYPER (PIN_OTYPE_PUSHPULL(GPIOC_ARD_A1) | \ + PIN_OTYPE_PUSHPULL(GPIOC_RMII_MDC) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_A7) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ARD_A2) | \ + PIN_OTYPE_PUSHPULL(GPIOC_RMII_RXD0) | \ + PIN_OTYPE_PUSHPULL(GPIOC_RMII_RXD1) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D16) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D21) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D43) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D44) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D45) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D46) | \ + PIN_OTYPE_PUSHPULL(GPIOC_ZIO_D47) | \ + PIN_OTYPE_PUSHPULL(GPIOC_BUTTON) | \ + PIN_OTYPE_PUSHPULL(GPIOC_OSC32_IN) | \ + PIN_OTYPE_PUSHPULL(GPIOC_OSC32_OUT)) +#define VAL_GPIOC_OSPEEDR (PIN_OSPEED_HIGH(GPIOC_ARD_A1) | \ + PIN_OSPEED_HIGH(GPIOC_RMII_MDC) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_A7) | \ + PIN_OSPEED_HIGH(GPIOC_ARD_A2) | \ + PIN_OSPEED_HIGH(GPIOC_RMII_RXD0) | \ + PIN_OSPEED_HIGH(GPIOC_RMII_RXD1) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D16) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D21) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D43) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D44) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D45) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D46) | \ + PIN_OSPEED_HIGH(GPIOC_ZIO_D47) | \ + PIN_OSPEED_HIGH(GPIOC_BUTTON) | \ + PIN_OSPEED_VERYLOW(GPIOC_OSC32_IN) | \ + PIN_OSPEED_VERYLOW(GPIOC_OSC32_OUT)) +#define VAL_GPIOC_PUPDR (PIN_PUPDR_PULLUP(GPIOC_ARD_A1) | \ + PIN_PUPDR_FLOATING(GPIOC_RMII_MDC) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_A7) | \ + PIN_PUPDR_PULLUP(GPIOC_ARD_A2) | \ + PIN_PUPDR_FLOATING(GPIOC_RMII_RXD0) | \ + PIN_PUPDR_FLOATING(GPIOC_RMII_RXD1) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D16) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D21) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D43) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D44) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D45) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D46) | \ + PIN_PUPDR_PULLUP(GPIOC_ZIO_D47) | \ + PIN_PUPDR_FLOATING(GPIOC_BUTTON) | \ + PIN_PUPDR_FLOATING(GPIOC_OSC32_IN) | \ + PIN_PUPDR_FLOATING(GPIOC_OSC32_OUT)) +#define VAL_GPIOC_ODR (PIN_ODR_HIGH(GPIOC_ARD_A1) | \ + PIN_ODR_HIGH(GPIOC_RMII_MDC) | \ + PIN_ODR_HIGH(GPIOC_ZIO_A7) | \ + PIN_ODR_HIGH(GPIOC_ARD_A2) | \ + PIN_ODR_HIGH(GPIOC_RMII_RXD0) | \ + PIN_ODR_HIGH(GPIOC_RMII_RXD1) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D16) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D21) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D43) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D44) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D45) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D46) | \ + PIN_ODR_HIGH(GPIOC_ZIO_D47) | \ + PIN_ODR_HIGH(GPIOC_BUTTON) | \ + PIN_ODR_HIGH(GPIOC_OSC32_IN) | \ + PIN_ODR_HIGH(GPIOC_OSC32_OUT)) +#define VAL_GPIOC_AFRL (PIN_AFIO_AF(GPIOC_ARD_A1, 0U) | \ + PIN_AFIO_AF(GPIOC_RMII_MDC, 11U) | \ + PIN_AFIO_AF(GPIOC_ZIO_A7, 0U) | \ + PIN_AFIO_AF(GPIOC_ARD_A2, 0U) | \ + PIN_AFIO_AF(GPIOC_RMII_RXD0, 11U) | \ + PIN_AFIO_AF(GPIOC_RMII_RXD1, 11U) | \ + PIN_AFIO_AF(GPIOC_ZIO_D16, 0U) | \ + PIN_AFIO_AF(GPIOC_ZIO_D21, 0U)) +#define VAL_GPIOC_AFRH (PIN_AFIO_AF(GPIOC_ZIO_D43, 0U) | \ + PIN_AFIO_AF(GPIOC_ZIO_D44, 0U) | \ + PIN_AFIO_AF(GPIOC_ZIO_D45, 0U) | \ + PIN_AFIO_AF(GPIOC_ZIO_D46, 0U) | \ + PIN_AFIO_AF(GPIOC_ZIO_D47, 0U) | \ + PIN_AFIO_AF(GPIOC_BUTTON, 0U) | \ + PIN_AFIO_AF(GPIOC_OSC32_IN, 0U) | \ + PIN_AFIO_AF(GPIOC_OSC32_OUT, 0U)) + +/* + * GPIOD setup: + * + * PD0 - ZIO_D67 CAN1_RX (input pullup). + * PD1 - ZIO_D66 CAN1_TX (input pullup). + * PD2 - ZIO_D48 SDMMC_CMD (input pullup). + * PD3 - ZIO_D55 USART2_CTS (input pullup). + * PD4 - ZIO_D54 USART2_RTS (input pullup). + * PD5 - ZIO_D53 USART2_TX (input pullup). + * PD6 - ZIO_D52 USART2_RX (input pullup). + * PD7 - ZIO_D51 USART2_SCLK (input pullup). + * PD8 - USART3_RX STLK_RX (alternate 7). + * PD9 - USART3_TX STLK_TX (alternate 7). + * PD10 - PIN10 (input pullup). + * PD11 - ZIO_D30 (input pullup). + * PD12 - ZIO_D29 (input pullup). + * PD13 - ZIO_D28 (input pullup). + * PD14 - ARD_D10 SPI1_NSS (input pullup). + * PD15 - ARD_D9 TIM4_CH4 (input pullup). + */ +#define VAL_GPIOD_MODER (PIN_MODE_INPUT(GPIOD_ZIO_D67) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D66) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D48) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D55) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D54) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D53) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D52) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D51) | \ + PIN_MODE_ALTERNATE(GPIOD_USART3_RX) | \ + PIN_MODE_ALTERNATE(GPIOD_USART3_TX) | \ + PIN_MODE_INPUT(GPIOD_PIN10) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D30) | \ + PIN_MODE_INPUT(GPIOD_ZIO_D29) | \ + PIN_MODE_OUTPUT(GPIOD_LED0) | \ + PIN_MODE_OUTPUT(GPIOD_LED1) | \ + PIN_MODE_OUTPUT(GPIOD_LED2)) +#define VAL_GPIOD_OTYPER (PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D67) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D66) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D48) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D55) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D54) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D53) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D52) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D51) | \ + PIN_OTYPE_PUSHPULL(GPIOD_USART3_RX) | \ + PIN_OTYPE_PUSHPULL(GPIOD_USART3_TX) | \ + PIN_OTYPE_PUSHPULL(GPIOD_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D30) | \ + PIN_OTYPE_PUSHPULL(GPIOD_ZIO_D29) | \ + PIN_OTYPE_PUSHPULL(GPIOD_LED0) | \ + PIN_OTYPE_PUSHPULL(GPIOD_LED1) | \ + PIN_OTYPE_PUSHPULL(GPIOD_LED2)) +#define VAL_GPIOD_OSPEEDR (PIN_OSPEED_HIGH(GPIOD_ZIO_D67) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D66) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D48) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D55) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D54) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D53) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D52) | \ + PIN_OSPEED_HIGH(GPIOD_ZIO_D51) | \ + PIN_OSPEED_HIGH(GPIOD_USART3_RX) | \ + PIN_OSPEED_HIGH(GPIOD_USART3_TX) | \ + PIN_OSPEED_VERYLOW(GPIOD_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOD_ZIO_D30) | \ + PIN_OSPEED_VERYLOW(GPIOD_ZIO_D29) | \ + PIN_OSPEED_VERYLOW(GPIOD_LED0) | \ + PIN_OSPEED_VERYLOW(GPIOD_LED1) | \ + PIN_OSPEED_VERYLOW(GPIOD_LED2)) +#define VAL_GPIOD_PUPDR (PIN_PUPDR_PULLUP(GPIOD_ZIO_D67) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D66) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D48) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D55) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D54) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D53) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D52) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D51) | \ + PIN_PUPDR_FLOATING(GPIOD_USART3_RX) | \ + PIN_PUPDR_FLOATING(GPIOD_USART3_TX) | \ + PIN_PUPDR_PULLUP(GPIOD_PIN10) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D30) | \ + PIN_PUPDR_PULLUP(GPIOD_ZIO_D29) | \ + PIN_PUPDR_PULLUP(GPIOD_LED0) | \ + PIN_PUPDR_PULLUP(GPIOD_LED1) | \ + PIN_PUPDR_PULLUP(GPIOD_LED2)) +#define VAL_GPIOD_ODR (PIN_ODR_HIGH(GPIOD_ZIO_D67) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D66) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D48) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D55) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D54) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D53) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D52) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D51) | \ + PIN_ODR_HIGH(GPIOD_USART3_RX) | \ + PIN_ODR_HIGH(GPIOD_USART3_TX) | \ + PIN_ODR_HIGH(GPIOD_PIN10) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D30) | \ + PIN_ODR_HIGH(GPIOD_ZIO_D29) | \ + PIN_ODR_HIGH(GPIOD_LED0) | \ + PIN_ODR_HIGH(GPIOD_LED1) | \ + PIN_ODR_HIGH(GPIOD_LED2)) +#define VAL_GPIOD_AFRL (PIN_AFIO_AF(GPIOD_ZIO_D67, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D66, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D48, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D55, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D54, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D53, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D52, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D51, 0U)) +#define VAL_GPIOD_AFRH (PIN_AFIO_AF(GPIOD_USART3_RX, 7U) | \ + PIN_AFIO_AF(GPIOD_USART3_TX, 7U) | \ + PIN_AFIO_AF(GPIOD_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D30, 0U) | \ + PIN_AFIO_AF(GPIOD_ZIO_D29, 0U) | \ + PIN_AFIO_AF(GPIOD_LED0, 0U) | \ + PIN_AFIO_AF(GPIOD_LED1, 0U) | \ + PIN_AFIO_AF(GPIOD_LED2, 0U)) + +/* + * GPIOE setup: + * + * PE0 - ZIO_D34 TIM4_ETR (input pullup). + * PE1 - PIN1 (input pullup). + * PE2 - ZIO_D31 ZIO_D56 SAI1_MCLK_A(input pullup). + * PE3 - ZIO_D60 SAI1_SD_B (input pullup). + * PE4 - ZIO_D57 SAI1_FS_A (input pullup). + * PE5 - ZIO_D58 SAI1_SCK_A (input pullup). + * PE6 - ZIO_D59 SAI1_SD_A (input pullup). + * PE7 - ZIO_D41 TIM1_ETR (input pullup). + * PE8 - ZIO_D42 TIM1_CH1N (input pullup). + * PE9 - ARD_D6 TIM1_CH1 (input pullup). + * PE10 - ZIO_D40 TIM1_CH2N (input pullup). + * PE11 - ARD_D5 TIM1_CH2 (input pullup). + * PE12 - ZIO_D39 TIM1_CH3N (input pullup). + * PE13 - ARD_D3 TIM1_CH3 (input pullup). + * PE14 - ZIO_D38 (input pullup). + * PE15 - ZIO_D37 TIM1_BKIN1 (input pullup). + */ +#define VAL_GPIOE_MODER (PIN_MODE_INPUT(GPIOE_ZIO_D34) | \ + PIN_MODE_INPUT(GPIOE_PIN1) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D31) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D60) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D57) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D58) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D59) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D41) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D42) | \ + PIN_MODE_INPUT(GPIOE_ARD_D6) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D40) | \ + PIN_MODE_INPUT(GPIOE_ARD_D5) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D39) | \ + PIN_MODE_INPUT(GPIOE_ARD_D3) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D38) | \ + PIN_MODE_INPUT(GPIOE_ZIO_D37)) +#define VAL_GPIOE_OTYPER (PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D34) | \ + PIN_OTYPE_PUSHPULL(GPIOE_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D31) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D60) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D57) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D58) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D59) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D41) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D42) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ARD_D6) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D40) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ARD_D5) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D39) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ARD_D3) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D38) | \ + PIN_OTYPE_PUSHPULL(GPIOE_ZIO_D37)) +#define VAL_GPIOE_OSPEEDR (PIN_OSPEED_HIGH(GPIOE_ZIO_D34) | \ + PIN_OSPEED_VERYLOW(GPIOE_PIN1) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D31) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D60) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D57) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D58) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D59) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D41) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D42) | \ + PIN_OSPEED_HIGH(GPIOE_ARD_D6) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D40) | \ + PIN_OSPEED_HIGH(GPIOE_ARD_D5) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D39) | \ + PIN_OSPEED_HIGH(GPIOE_ARD_D3) | \ + PIN_OSPEED_VERYLOW(GPIOE_ZIO_D38) | \ + PIN_OSPEED_HIGH(GPIOE_ZIO_D37)) +#define VAL_GPIOE_PUPDR (PIN_PUPDR_PULLUP(GPIOE_ZIO_D34) | \ + PIN_PUPDR_PULLUP(GPIOE_PIN1) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D31) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D60) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D57) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D58) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D59) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D41) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D42) | \ + PIN_PUPDR_PULLUP(GPIOE_ARD_D6) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D40) | \ + PIN_PUPDR_PULLUP(GPIOE_ARD_D5) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D39) | \ + PIN_PUPDR_PULLUP(GPIOE_ARD_D3) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D38) | \ + PIN_PUPDR_PULLUP(GPIOE_ZIO_D37)) +#define VAL_GPIOE_ODR (PIN_ODR_HIGH(GPIOE_ZIO_D34) | \ + PIN_ODR_HIGH(GPIOE_PIN1) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D31) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D60) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D57) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D58) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D59) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D41) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D42) | \ + PIN_ODR_HIGH(GPIOE_ARD_D6) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D40) | \ + PIN_ODR_HIGH(GPIOE_ARD_D5) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D39) | \ + PIN_ODR_HIGH(GPIOE_ARD_D3) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D38) | \ + PIN_ODR_HIGH(GPIOE_ZIO_D37)) +#define VAL_GPIOE_AFRL (PIN_AFIO_AF(GPIOE_ZIO_D34, 0U) | \ + PIN_AFIO_AF(GPIOE_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D31, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D60, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D57, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D58, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D59, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D41, 0U)) +#define VAL_GPIOE_AFRH (PIN_AFIO_AF(GPIOE_ZIO_D42, 0U) | \ + PIN_AFIO_AF(GPIOE_ARD_D6, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D40, 0U) | \ + PIN_AFIO_AF(GPIOE_ARD_D5, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D39, 0U) | \ + PIN_AFIO_AF(GPIOE_ARD_D3, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D38, 0U) | \ + PIN_AFIO_AF(GPIOE_ZIO_D37, 0U)) + +/* + * GPIOF setup: + * + * PF0 - ZIO_D68 I2C2_SDA (input pullup). + * PF1 - ZIO_D69 I2C2_SCL (input pullup). + * PF2 - ZIO_D70 I2C2_SMBA (input pullup). + * PF3 - ARD_A3 ADC3_IN9 (input pullup). + * PF4 - ZIO_A8 ADC3_IN14 (input pullup). + * PF5 - ARD_A4 ADC3_IN15 (input pullup). + * PF6 - PIN6 (input pullup). + * PF7 - ZIO_D62 SAI1_MCLK_B (input pullup). + * PF8 - ZIO_D61 SAI1_SCK_B (input pullup). + * PF9 - ZIO_D63 SAI1_FS_B (input pullup). + * PF10 - ARD_A5 ADC3_IN8 (input pullup). + * PF11 - PIN11 (input pullup). + * PF12 - ARD_D8 (input pullup). + * PF13 - ARD_D7 (input pullup). + * PF14 - ARD_D4 (input pullup). + * PF15 - ARD_D2 (input pullup). + */ +#define VAL_GPIOF_MODER (PIN_MODE_INPUT(GPIOF_ZIO_D68) | \ + PIN_MODE_INPUT(GPIOF_ZIO_D69) | \ + PIN_MODE_INPUT(GPIOF_ZIO_D70) | \ + PIN_MODE_INPUT(GPIOF_ARD_A3) | \ + PIN_MODE_INPUT(GPIOF_ZIO_A8) | \ + PIN_MODE_INPUT(GPIOF_ARD_A4) | \ + PIN_MODE_INPUT(GPIOF_PIN6) | \ + PIN_MODE_INPUT(GPIOF_ZIO_D62) | \ + PIN_MODE_INPUT(GPIOF_ZIO_D61) | \ + PIN_MODE_INPUT(GPIOF_ZIO_D63) | \ + PIN_MODE_INPUT(GPIOF_ARD_A5) | \ + PIN_MODE_INPUT(GPIOF_PIN11) | \ + PIN_MODE_INPUT(GPIOF_ARD_D8) | \ + PIN_MODE_INPUT(GPIOF_ARD_D7) | \ + PIN_MODE_INPUT(GPIOF_ARD_D4) | \ + PIN_MODE_INPUT(GPIOF_ARD_D2)) +#define VAL_GPIOF_OTYPER (PIN_OTYPE_PUSHPULL(GPIOF_ZIO_D68) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ZIO_D69) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ZIO_D70) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_A3) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ZIO_A8) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_A4) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ZIO_D62) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ZIO_D61) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ZIO_D63) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_A5) | \ + PIN_OTYPE_PUSHPULL(GPIOF_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_D8) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_D7) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_D4) | \ + PIN_OTYPE_PUSHPULL(GPIOF_ARD_D2)) +#define VAL_GPIOF_OSPEEDR (PIN_OSPEED_HIGH(GPIOF_ZIO_D68) | \ + PIN_OSPEED_HIGH(GPIOF_ZIO_D69) | \ + PIN_OSPEED_HIGH(GPIOF_ZIO_D70) | \ + PIN_OSPEED_HIGH(GPIOF_ARD_A3) | \ + PIN_OSPEED_HIGH(GPIOF_ZIO_A8) | \ + PIN_OSPEED_HIGH(GPIOF_ARD_A4) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN6) | \ + PIN_OSPEED_HIGH(GPIOF_ZIO_D62) | \ + PIN_OSPEED_HIGH(GPIOF_ZIO_D61) | \ + PIN_OSPEED_HIGH(GPIOF_ZIO_D63) | \ + PIN_OSPEED_HIGH(GPIOF_ARD_A5) | \ + PIN_OSPEED_VERYLOW(GPIOF_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOF_ARD_D8) | \ + PIN_OSPEED_VERYLOW(GPIOF_ARD_D7) | \ + PIN_OSPEED_VERYLOW(GPIOF_ARD_D4) | \ + PIN_OSPEED_VERYLOW(GPIOF_ARD_D2)) +#define VAL_GPIOF_PUPDR (PIN_PUPDR_PULLUP(GPIOF_ZIO_D68) | \ + PIN_PUPDR_PULLUP(GPIOF_ZIO_D69) | \ + PIN_PUPDR_PULLUP(GPIOF_ZIO_D70) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_A3) | \ + PIN_PUPDR_PULLUP(GPIOF_ZIO_A8) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_A4) | \ + PIN_PUPDR_PULLUP(GPIOF_PIN6) | \ + PIN_PUPDR_PULLUP(GPIOF_ZIO_D62) | \ + PIN_PUPDR_PULLUP(GPIOF_ZIO_D61) | \ + PIN_PUPDR_PULLUP(GPIOF_ZIO_D63) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_A5) | \ + PIN_PUPDR_PULLUP(GPIOF_PIN11) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_D8) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_D7) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_D4) | \ + PIN_PUPDR_PULLUP(GPIOF_ARD_D2)) +#define VAL_GPIOF_ODR (PIN_ODR_HIGH(GPIOF_ZIO_D68) | \ + PIN_ODR_HIGH(GPIOF_ZIO_D69) | \ + PIN_ODR_HIGH(GPIOF_ZIO_D70) | \ + PIN_ODR_HIGH(GPIOF_ARD_A3) | \ + PIN_ODR_HIGH(GPIOF_ZIO_A8) | \ + PIN_ODR_HIGH(GPIOF_ARD_A4) | \ + PIN_ODR_HIGH(GPIOF_PIN6) | \ + PIN_ODR_HIGH(GPIOF_ZIO_D62) | \ + PIN_ODR_HIGH(GPIOF_ZIO_D61) | \ + PIN_ODR_HIGH(GPIOF_ZIO_D63) | \ + PIN_ODR_HIGH(GPIOF_ARD_A5) | \ + PIN_ODR_HIGH(GPIOF_PIN11) | \ + PIN_ODR_HIGH(GPIOF_ARD_D8) | \ + PIN_ODR_HIGH(GPIOF_ARD_D7) | \ + PIN_ODR_HIGH(GPIOF_ARD_D4) | \ + PIN_ODR_HIGH(GPIOF_ARD_D2)) +#define VAL_GPIOF_AFRL (PIN_AFIO_AF(GPIOF_ZIO_D68, 0U) | \ + PIN_AFIO_AF(GPIOF_ZIO_D69, 0U) | \ + PIN_AFIO_AF(GPIOF_ZIO_D70, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_A3, 0U) | \ + PIN_AFIO_AF(GPIOF_ZIO_A8, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_A4, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOF_ZIO_D62, 0U)) +#define VAL_GPIOF_AFRH (PIN_AFIO_AF(GPIOF_ZIO_D61, 0U) | \ + PIN_AFIO_AF(GPIOF_ZIO_D63, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_A5, 0U) | \ + PIN_AFIO_AF(GPIOF_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_D8, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_D7, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_D4, 0U) | \ + PIN_AFIO_AF(GPIOF_ARD_D2, 0U)) + +/* + * GPIOG setup: + * + * PG0 - ZIO_D65 (input pullup). + * PG1 - ZIO_D64 (input pullup). + * PG2 - ZIO_D49 (input pullup). + * PG3 - ZIO_D50 (input pullup). + * PG4 - PIN4 (input pullup). + * PG5 - PIN5 (input pullup). + * PG6 - USB_GPIO_OUT (input pullup). + * PG7 - USB_GPIO_IN (input pullup). + * PG8 - PIN8 (input pullup). + * PG9 - ARD_D0 USART6_RX (input pullup). + * PG10 - PIN10 (input pullup). + * PG11 - RMII_TX_EN (alternate 11). + * PG12 - PIN12 (input pullup). + * PG13 - RMII_TXD0 (alternate 11). + * PG14 - ARD_D1 USART6_TX (input pullup). + * PG15 - PIN15 (input pullup). + */ +#define VAL_GPIOG_MODER (PIN_MODE_INPUT(GPIOG_ZIO_D65) | \ + PIN_MODE_INPUT(GPIOG_ZIO_D64) | \ + PIN_MODE_INPUT(GPIOG_ZIO_D49) | \ + PIN_MODE_INPUT(GPIOG_ZIO_D50) | \ + PIN_MODE_INPUT(GPIOG_PIN4) | \ + PIN_MODE_INPUT(GPIOG_PIN5) | \ + PIN_MODE_INPUT(GPIOG_USB_GPIO_OUT) | \ + PIN_MODE_INPUT(GPIOG_USB_GPIO_IN) | \ + PIN_MODE_INPUT(GPIOG_PIN8) | \ + PIN_MODE_INPUT(GPIOG_ARD_D0) | \ + PIN_MODE_INPUT(GPIOG_PIN10) | \ + PIN_MODE_ALTERNATE(GPIOG_RMII_TX_EN) | \ + PIN_MODE_INPUT(GPIOG_PIN12) | \ + PIN_MODE_ALTERNATE(GPIOG_RMII_TXD0) | \ + PIN_MODE_INPUT(GPIOG_ARD_D1) | \ + PIN_MODE_INPUT(GPIOG_PIN15)) +#define VAL_GPIOG_OTYPER (PIN_OTYPE_PUSHPULL(GPIOG_ZIO_D65) | \ + PIN_OTYPE_PUSHPULL(GPIOG_ZIO_D64) | \ + PIN_OTYPE_PUSHPULL(GPIOG_ZIO_D49) | \ + PIN_OTYPE_PUSHPULL(GPIOG_ZIO_D50) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOG_USB_GPIO_OUT) |\ + PIN_OTYPE_PUSHPULL(GPIOG_USB_GPIO_IN) |\ + PIN_OTYPE_PUSHPULL(GPIOG_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOG_ARD_D0) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOG_RMII_TX_EN) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOG_RMII_TXD0) | \ + PIN_OTYPE_PUSHPULL(GPIOG_ARD_D1) | \ + PIN_OTYPE_PUSHPULL(GPIOG_PIN15)) +#define VAL_GPIOG_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOG_ZIO_D65) | \ + PIN_OSPEED_VERYLOW(GPIOG_ZIO_D64) | \ + PIN_OSPEED_VERYLOW(GPIOG_ZIO_D49) | \ + PIN_OSPEED_VERYLOW(GPIOG_ZIO_D50) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN5) | \ + PIN_OSPEED_HIGH(GPIOG_USB_GPIO_OUT) | \ + PIN_OSPEED_HIGH(GPIOG_USB_GPIO_IN) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN8) | \ + PIN_OSPEED_HIGH(GPIOG_ARD_D0) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN10) | \ + PIN_OSPEED_HIGH(GPIOG_RMII_TX_EN) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN12) | \ + PIN_OSPEED_HIGH(GPIOG_RMII_TXD0) | \ + PIN_OSPEED_HIGH(GPIOG_ARD_D1) | \ + PIN_OSPEED_VERYLOW(GPIOG_PIN15)) +#define VAL_GPIOG_PUPDR (PIN_PUPDR_PULLUP(GPIOG_ZIO_D65) | \ + PIN_PUPDR_PULLUP(GPIOG_ZIO_D64) | \ + PIN_PUPDR_PULLUP(GPIOG_ZIO_D49) | \ + PIN_PUPDR_PULLUP(GPIOG_ZIO_D50) | \ + PIN_PUPDR_PULLUP(GPIOG_PIN4) | \ + PIN_PUPDR_PULLUP(GPIOG_PIN5) | \ + PIN_PUPDR_PULLUP(GPIOG_USB_GPIO_OUT) | \ + PIN_PUPDR_PULLUP(GPIOG_USB_GPIO_IN) | \ + PIN_PUPDR_PULLUP(GPIOG_PIN8) | \ + PIN_PUPDR_PULLUP(GPIOG_ARD_D0) | \ + PIN_PUPDR_PULLUP(GPIOG_PIN10) | \ + PIN_PUPDR_FLOATING(GPIOG_RMII_TX_EN) | \ + PIN_PUPDR_PULLUP(GPIOG_PIN12) | \ + PIN_PUPDR_FLOATING(GPIOG_RMII_TXD0) | \ + PIN_PUPDR_PULLUP(GPIOG_ARD_D1) | \ + PIN_PUPDR_PULLUP(GPIOG_PIN15)) +#define VAL_GPIOG_ODR (PIN_ODR_HIGH(GPIOG_ZIO_D65) | \ + PIN_ODR_HIGH(GPIOG_ZIO_D64) | \ + PIN_ODR_HIGH(GPIOG_ZIO_D49) | \ + PIN_ODR_HIGH(GPIOG_ZIO_D50) | \ + PIN_ODR_HIGH(GPIOG_PIN4) | \ + PIN_ODR_HIGH(GPIOG_PIN5) | \ + PIN_ODR_HIGH(GPIOG_USB_GPIO_OUT) | \ + PIN_ODR_HIGH(GPIOG_USB_GPIO_IN) | \ + PIN_ODR_HIGH(GPIOG_PIN8) | \ + PIN_ODR_HIGH(GPIOG_ARD_D0) | \ + PIN_ODR_HIGH(GPIOG_PIN10) | \ + PIN_ODR_HIGH(GPIOG_RMII_TX_EN) | \ + PIN_ODR_HIGH(GPIOG_PIN12) | \ + PIN_ODR_HIGH(GPIOG_RMII_TXD0) | \ + PIN_ODR_HIGH(GPIOG_ARD_D1) | \ + PIN_ODR_HIGH(GPIOG_PIN15)) +#define VAL_GPIOG_AFRL (PIN_AFIO_AF(GPIOG_ZIO_D65, 0U) | \ + PIN_AFIO_AF(GPIOG_ZIO_D64, 0U) | \ + PIN_AFIO_AF(GPIOG_ZIO_D49, 0U) | \ + PIN_AFIO_AF(GPIOG_ZIO_D50, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOG_USB_GPIO_OUT, 0U) | \ + PIN_AFIO_AF(GPIOG_USB_GPIO_IN, 0U)) +#define VAL_GPIOG_AFRH (PIN_AFIO_AF(GPIOG_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOG_ARD_D0, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOG_RMII_TX_EN, 11U) | \ + PIN_AFIO_AF(GPIOG_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOG_RMII_TXD0, 11U) | \ + PIN_AFIO_AF(GPIOG_ARD_D1, 0U) | \ + PIN_AFIO_AF(GPIOG_PIN15, 0U)) + +/* + * GPIOH setup: + * + * PH0 - OSC_IN (input floating). + * PH1 - OSC_OUT (input floating). + * PH2 - PIN2 (input pullup). + * PH3 - PIN3 (input pullup). + * PH4 - PIN4 (input pullup). + * PH5 - PIN5 (input pullup). + * PH6 - PIN6 (input pullup). + * PH7 - PIN7 (input pullup). + * PH8 - PIN8 (input pullup). + * PH9 - PIN9 (input pullup). + * PH10 - PIN10 (input pullup). + * PH11 - PIN11 (input pullup). + * PH12 - PIN12 (input pullup). + * PH13 - PIN13 (input pullup). + * PH14 - PIN14 (input pullup). + * PH15 - PIN15 (input pullup). + */ +#define VAL_GPIOH_MODER (PIN_MODE_INPUT(GPIOH_OSC_IN) | \ + PIN_MODE_INPUT(GPIOH_OSC_OUT) | \ + PIN_MODE_INPUT(GPIOH_PIN2) | \ + PIN_MODE_INPUT(GPIOH_PIN3) | \ + PIN_MODE_INPUT(GPIOH_PIN4) | \ + PIN_MODE_INPUT(GPIOH_PIN5) | \ + PIN_MODE_INPUT(GPIOH_PIN6) | \ + PIN_MODE_INPUT(GPIOH_PIN7) | \ + PIN_MODE_INPUT(GPIOH_PIN8) | \ + PIN_MODE_INPUT(GPIOH_PIN9) | \ + PIN_MODE_INPUT(GPIOH_PIN10) | \ + PIN_MODE_INPUT(GPIOH_PIN11) | \ + PIN_MODE_INPUT(GPIOH_PIN12) | \ + PIN_MODE_INPUT(GPIOH_PIN13) | \ + PIN_MODE_INPUT(GPIOH_PIN14) | \ + PIN_MODE_INPUT(GPIOH_PIN15)) +#define VAL_GPIOH_OTYPER (PIN_OTYPE_PUSHPULL(GPIOH_OSC_IN) | \ + PIN_OTYPE_PUSHPULL(GPIOH_OSC_OUT) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOH_PIN15)) +#define VAL_GPIOH_OSPEEDR (PIN_OSPEED_HIGH(GPIOH_OSC_IN) | \ + PIN_OSPEED_HIGH(GPIOH_OSC_OUT) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOH_PIN15)) +#define VAL_GPIOH_PUPDR (PIN_PUPDR_FLOATING(GPIOH_OSC_IN) | \ + PIN_PUPDR_FLOATING(GPIOH_OSC_OUT) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN2) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN3) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN4) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN5) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN6) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN7) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN8) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN9) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN10) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN11) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN12) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN13) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN14) | \ + PIN_PUPDR_PULLUP(GPIOH_PIN15)) +#define VAL_GPIOH_ODR (PIN_ODR_HIGH(GPIOH_OSC_IN) | \ + PIN_ODR_HIGH(GPIOH_OSC_OUT) | \ + PIN_ODR_HIGH(GPIOH_PIN2) | \ + PIN_ODR_HIGH(GPIOH_PIN3) | \ + PIN_ODR_HIGH(GPIOH_PIN4) | \ + PIN_ODR_HIGH(GPIOH_PIN5) | \ + PIN_ODR_HIGH(GPIOH_PIN6) | \ + PIN_ODR_HIGH(GPIOH_PIN7) | \ + PIN_ODR_HIGH(GPIOH_PIN8) | \ + PIN_ODR_HIGH(GPIOH_PIN9) | \ + PIN_ODR_HIGH(GPIOH_PIN10) | \ + PIN_ODR_HIGH(GPIOH_PIN11) | \ + PIN_ODR_HIGH(GPIOH_PIN12) | \ + PIN_ODR_HIGH(GPIOH_PIN13) | \ + PIN_ODR_HIGH(GPIOH_PIN14) | \ + PIN_ODR_HIGH(GPIOH_PIN15)) +#define VAL_GPIOH_AFRL (PIN_AFIO_AF(GPIOH_OSC_IN, 0U) | \ + PIN_AFIO_AF(GPIOH_OSC_OUT, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN7, 0U)) +#define VAL_GPIOH_AFRH (PIN_AFIO_AF(GPIOH_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOH_PIN15, 0U)) + +/* + * GPIOI setup: + * + * PI0 - PIN0 (input pullup). + * PI1 - PIN1 (input pullup). + * PI2 - PIN2 (input pullup). + * PI3 - PIN3 (input pullup). + * PI4 - PIN4 (input pullup). + * PI5 - PIN5 (input pullup). + * PI6 - PIN6 (input pullup). + * PI7 - PIN7 (input pullup). + * PI8 - PIN8 (input pullup). + * PI9 - PIN9 (input pullup). + * PI10 - PIN10 (input pullup). + * PI11 - PIN11 (input pullup). + * PI12 - PIN12 (input pullup). + * PI13 - PIN13 (input pullup). + * PI14 - PIN14 (input pullup). + * PI15 - PIN15 (input pullup). + */ +#define VAL_GPIOI_MODER (PIN_MODE_INPUT(GPIOI_PIN0) | \ + PIN_MODE_INPUT(GPIOI_PIN1) | \ + PIN_MODE_INPUT(GPIOI_PIN2) | \ + PIN_MODE_INPUT(GPIOI_PIN3) | \ + PIN_MODE_INPUT(GPIOI_PIN4) | \ + PIN_MODE_INPUT(GPIOI_PIN5) | \ + PIN_MODE_INPUT(GPIOI_PIN6) | \ + PIN_MODE_INPUT(GPIOI_PIN7) | \ + PIN_MODE_INPUT(GPIOI_PIN8) | \ + PIN_MODE_INPUT(GPIOI_PIN9) | \ + PIN_MODE_INPUT(GPIOI_PIN10) | \ + PIN_MODE_INPUT(GPIOI_PIN11) | \ + PIN_MODE_INPUT(GPIOI_PIN12) | \ + PIN_MODE_INPUT(GPIOI_PIN13) | \ + PIN_MODE_INPUT(GPIOI_PIN14) | \ + PIN_MODE_INPUT(GPIOI_PIN15)) +#define VAL_GPIOI_OTYPER (PIN_OTYPE_PUSHPULL(GPIOI_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOI_PIN15)) +#define VAL_GPIOI_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOI_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOI_PIN15)) +#define VAL_GPIOI_PUPDR (PIN_PUPDR_PULLUP(GPIOI_PIN0) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN1) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN2) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN3) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN4) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN5) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN6) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN7) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN8) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN9) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN10) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN11) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN12) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN13) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN14) | \ + PIN_PUPDR_PULLUP(GPIOI_PIN15)) +#define VAL_GPIOI_ODR (PIN_ODR_HIGH(GPIOI_PIN0) | \ + PIN_ODR_HIGH(GPIOI_PIN1) | \ + PIN_ODR_HIGH(GPIOI_PIN2) | \ + PIN_ODR_HIGH(GPIOI_PIN3) | \ + PIN_ODR_HIGH(GPIOI_PIN4) | \ + PIN_ODR_HIGH(GPIOI_PIN5) | \ + PIN_ODR_HIGH(GPIOI_PIN6) | \ + PIN_ODR_HIGH(GPIOI_PIN7) | \ + PIN_ODR_HIGH(GPIOI_PIN8) | \ + PIN_ODR_HIGH(GPIOI_PIN9) | \ + PIN_ODR_HIGH(GPIOI_PIN10) | \ + PIN_ODR_HIGH(GPIOI_PIN11) | \ + PIN_ODR_HIGH(GPIOI_PIN12) | \ + PIN_ODR_HIGH(GPIOI_PIN13) | \ + PIN_ODR_HIGH(GPIOI_PIN14) | \ + PIN_ODR_HIGH(GPIOI_PIN15)) +#define VAL_GPIOI_AFRL (PIN_AFIO_AF(GPIOI_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN7, 0U)) +#define VAL_GPIOI_AFRH (PIN_AFIO_AF(GPIOI_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOI_PIN15, 0U)) + +/* + * GPIOJ setup: + * + * PJ0 - PIN0 (input pullup). + * PJ1 - PIN1 (input pullup). + * PJ2 - PIN2 (input pullup). + * PJ3 - PIN3 (input pullup). + * PJ4 - PIN4 (input pullup). + * PJ5 - PIN5 (input pullup). + * PJ6 - PIN6 (input pullup). + * PJ7 - PIN7 (input pullup). + * PJ8 - PIN8 (input pullup). + * PJ9 - PIN9 (input pullup). + * PJ10 - PIN10 (input pullup). + * PJ11 - PIN11 (input pullup). + * PJ12 - PIN12 (input pullup). + * PJ13 - PIN13 (input pullup). + * PJ14 - PIN14 (input pullup). + * PJ15 - PIN15 (input pullup). + */ +#define VAL_GPIOJ_MODER (PIN_MODE_INPUT(GPIOJ_PIN0) | \ + PIN_MODE_INPUT(GPIOJ_PIN1) | \ + PIN_MODE_INPUT(GPIOJ_PIN2) | \ + PIN_MODE_INPUT(GPIOJ_PIN3) | \ + PIN_MODE_INPUT(GPIOJ_PIN4) | \ + PIN_MODE_INPUT(GPIOJ_PIN5) | \ + PIN_MODE_INPUT(GPIOJ_PIN6) | \ + PIN_MODE_INPUT(GPIOJ_PIN7) | \ + PIN_MODE_INPUT(GPIOJ_PIN8) | \ + PIN_MODE_INPUT(GPIOJ_PIN9) | \ + PIN_MODE_INPUT(GPIOJ_PIN10) | \ + PIN_MODE_INPUT(GPIOJ_PIN11) | \ + PIN_MODE_INPUT(GPIOJ_PIN12) | \ + PIN_MODE_INPUT(GPIOJ_PIN13) | \ + PIN_MODE_INPUT(GPIOJ_PIN14) | \ + PIN_MODE_INPUT(GPIOJ_PIN15)) +#define VAL_GPIOJ_OTYPER (PIN_OTYPE_PUSHPULL(GPIOJ_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOJ_PIN15)) +#define VAL_GPIOJ_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOJ_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOJ_PIN15)) +#define VAL_GPIOJ_PUPDR (PIN_PUPDR_PULLUP(GPIOJ_PIN0) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN1) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN2) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN3) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN4) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN5) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN6) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN7) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN8) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN9) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN10) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN11) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN12) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN13) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN14) | \ + PIN_PUPDR_PULLUP(GPIOJ_PIN15)) +#define VAL_GPIOJ_ODR (PIN_ODR_HIGH(GPIOJ_PIN0) | \ + PIN_ODR_HIGH(GPIOJ_PIN1) | \ + PIN_ODR_HIGH(GPIOJ_PIN2) | \ + PIN_ODR_HIGH(GPIOJ_PIN3) | \ + PIN_ODR_HIGH(GPIOJ_PIN4) | \ + PIN_ODR_HIGH(GPIOJ_PIN5) | \ + PIN_ODR_HIGH(GPIOJ_PIN6) | \ + PIN_ODR_HIGH(GPIOJ_PIN7) | \ + PIN_ODR_HIGH(GPIOJ_PIN8) | \ + PIN_ODR_HIGH(GPIOJ_PIN9) | \ + PIN_ODR_HIGH(GPIOJ_PIN10) | \ + PIN_ODR_HIGH(GPIOJ_PIN11) | \ + PIN_ODR_HIGH(GPIOJ_PIN12) | \ + PIN_ODR_HIGH(GPIOJ_PIN13) | \ + PIN_ODR_HIGH(GPIOJ_PIN14) | \ + PIN_ODR_HIGH(GPIOJ_PIN15)) +#define VAL_GPIOJ_AFRL (PIN_AFIO_AF(GPIOJ_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN7, 0U)) +#define VAL_GPIOJ_AFRH (PIN_AFIO_AF(GPIOJ_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOJ_PIN15, 0U)) + +/* + * GPIOK setup: + * + * PK0 - PIN0 (input pullup). + * PK1 - PIN1 (input pullup). + * PK2 - PIN2 (input pullup). + * PK3 - PIN3 (input pullup). + * PK4 - PIN4 (input pullup). + * PK5 - PIN5 (input pullup). + * PK6 - PIN6 (input pullup). + * PK7 - PIN7 (input pullup). + * PK8 - PIN8 (input pullup). + * PK9 - PIN9 (input pullup). + * PK10 - PIN10 (input pullup). + * PK11 - PIN11 (input pullup). + * PK12 - PIN12 (input pullup). + * PK13 - PIN13 (input pullup). + * PK14 - PIN14 (input pullup). + * PK15 - PIN15 (input pullup). + */ +#define VAL_GPIOK_MODER (PIN_MODE_INPUT(GPIOK_PIN0) | \ + PIN_MODE_INPUT(GPIOK_PIN1) | \ + PIN_MODE_INPUT(GPIOK_PIN2) | \ + PIN_MODE_INPUT(GPIOK_PIN3) | \ + PIN_MODE_INPUT(GPIOK_PIN4) | \ + PIN_MODE_INPUT(GPIOK_PIN5) | \ + PIN_MODE_INPUT(GPIOK_PIN6) | \ + PIN_MODE_INPUT(GPIOK_PIN7) | \ + PIN_MODE_INPUT(GPIOK_PIN8) | \ + PIN_MODE_INPUT(GPIOK_PIN9) | \ + PIN_MODE_INPUT(GPIOK_PIN10) | \ + PIN_MODE_INPUT(GPIOK_PIN11) | \ + PIN_MODE_INPUT(GPIOK_PIN12) | \ + PIN_MODE_INPUT(GPIOK_PIN13) | \ + PIN_MODE_INPUT(GPIOK_PIN14) | \ + PIN_MODE_INPUT(GPIOK_PIN15)) +#define VAL_GPIOK_OTYPER (PIN_OTYPE_PUSHPULL(GPIOK_PIN0) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN1) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN2) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN3) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN4) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN5) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN6) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN7) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN8) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN9) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN10) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN11) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN12) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN13) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN14) | \ + PIN_OTYPE_PUSHPULL(GPIOK_PIN15)) +#define VAL_GPIOK_OSPEEDR (PIN_OSPEED_VERYLOW(GPIOK_PIN0) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN1) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN2) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN3) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN4) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN5) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN6) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN7) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN8) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN9) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN10) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN11) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN12) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN13) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN14) | \ + PIN_OSPEED_VERYLOW(GPIOK_PIN15)) +#define VAL_GPIOK_PUPDR (PIN_PUPDR_PULLUP(GPIOK_PIN0) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN1) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN2) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN3) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN4) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN5) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN6) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN7) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN8) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN9) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN10) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN11) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN12) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN13) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN14) | \ + PIN_PUPDR_PULLUP(GPIOK_PIN15)) +#define VAL_GPIOK_ODR (PIN_ODR_HIGH(GPIOK_PIN0) | \ + PIN_ODR_HIGH(GPIOK_PIN1) | \ + PIN_ODR_HIGH(GPIOK_PIN2) | \ + PIN_ODR_HIGH(GPIOK_PIN3) | \ + PIN_ODR_HIGH(GPIOK_PIN4) | \ + PIN_ODR_HIGH(GPIOK_PIN5) | \ + PIN_ODR_HIGH(GPIOK_PIN6) | \ + PIN_ODR_HIGH(GPIOK_PIN7) | \ + PIN_ODR_HIGH(GPIOK_PIN8) | \ + PIN_ODR_HIGH(GPIOK_PIN9) | \ + PIN_ODR_HIGH(GPIOK_PIN10) | \ + PIN_ODR_HIGH(GPIOK_PIN11) | \ + PIN_ODR_HIGH(GPIOK_PIN12) | \ + PIN_ODR_HIGH(GPIOK_PIN13) | \ + PIN_ODR_HIGH(GPIOK_PIN14) | \ + PIN_ODR_HIGH(GPIOK_PIN15)) +#define VAL_GPIOK_AFRL (PIN_AFIO_AF(GPIOK_PIN0, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN1, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN2, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN3, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN4, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN5, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN6, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN7, 0U)) +#define VAL_GPIOK_AFRH (PIN_AFIO_AF(GPIOK_PIN8, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN9, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN10, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN11, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN12, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN13, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN14, 0U) | \ + PIN_AFIO_AF(GPIOK_PIN15, 0U)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(_FROM_ASM_) +#ifdef __cplusplus +extern "C" { +#endif + void boardInit(void); +#ifdef __cplusplus +} +#endif +#endif /* _FROM_ASM_ */ + +#endif /* BOARD_H */ diff --git a/os/hal/boards/AT_START_F435/board.mk b/os/hal/boards/AT_START_F435/board.mk new file mode 100644 index 0000000000..66ad71fab6 --- /dev/null +++ b/os/hal/boards/AT_START_F435/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/AT_START_F435/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/os/hal/boards/AT_START_F435 + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/os/hal/boards/AT_START_F435/cfg/board.chcfg b/os/hal/boards/AT_START_F435/cfg/board.chcfg new file mode 100644 index 0000000000..61298bdc11 --- /dev/null +++ b/os/hal/boards/AT_START_F435/cfg/board.chcfg @@ -0,0 +1,1458 @@ + + + + + resources/gencfg/processors/boards/stm32f4xx/templates + .. + 5.0.x + + STMicroelectronics STM32 Nucleo144-F429ZI + ST_NUCLEO144_F429ZI + + + + MII_LAN8742A_ID + RMII + + STM32F429xx + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/os/hal/boards/AT_START_F435/cfg/board.fmpp b/os/hal/boards/AT_START_F435/cfg/board.fmpp new file mode 100644 index 0000000000..41754c1414 --- /dev/null +++ b/os/hal/boards/AT_START_F435/cfg/board.fmpp @@ -0,0 +1,15 @@ +sourceRoot: ../../../../../tools/ftl/processors/boards/stm32f4xx/templates +outputRoot: .. +dataRoot: . + +freemarkerLinks: { + lib: ../../../../../tools/ftl/libs +} + +data : { + doc1:xml ( + board.chcfg + { + } + ) +} diff --git a/os/hal/ports/AT32/AT32F4xx/at32_isr.c b/os/hal/ports/AT32/AT32F4xx/at32_isr.c new file mode 100644 index 0000000000..f39c6f7b27 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/at32_isr.c @@ -0,0 +1,255 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/stm32_isr.c + * @brief STM32F4xx ISR handler code. + * + * @addtogroup STM32F4xx_ISR + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +#define exti_serve_irq(pr, channel) { \ + \ + if ((pr) & (1U << (channel))) { \ + _pal_isr_code(channel); \ + } \ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if (HAL_USE_PAL && (PAL_USE_WAIT || PAL_USE_CALLBACKS)) || defined(__DOXYGEN__) +#if !defined(STM32_DISABLE_EXTI0_HANDLER) +/** + * @brief EXTI[0] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector58) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & (1U << 0); + EXTI->PR = pr; + + exti_serve_irq(pr, 0); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if !defined(STM32_DISABLE_EXTI1_HANDLER) +/** + * @brief EXTI[1] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector5C) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & (1U << 1); + EXTI->PR = pr; + + exti_serve_irq(pr, 1); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if !defined(STM32_DISABLE_EXTI2_HANDLER) +/** + * @brief EXTI[2] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector60) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & (1U << 2); + EXTI->PR = pr; + + exti_serve_irq(pr, 2); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if !defined(STM32_DISABLE_EXTI3_HANDLER) +/** + * @brief EXTI[3] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector64) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & (1U << 3); + EXTI->PR = pr; + + exti_serve_irq(pr, 3); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if !defined(STM32_DISABLE_EXTI4_HANDLER) +/** + * @brief EXTI[4] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector68) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & (1U << 4); + EXTI->PR = pr; + + exti_serve_irq(pr, 4); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if !defined(STM32_DISABLE_EXTI5_9_HANDLER) +/** + * @brief EXTI[5]...EXTI[9] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(Vector9C) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & ((1U << 5) | (1U << 6) | (1U << 7) | (1U << 8) | + (1U << 9)); + EXTI->PR = pr; + + exti_serve_irq(pr, 5); + exti_serve_irq(pr, 6); + exti_serve_irq(pr, 7); + exti_serve_irq(pr, 8); + exti_serve_irq(pr, 9); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#if !defined(STM32_DISABLE_EXTI10_15_HANDLER) +/** + * @brief EXTI[10]...EXTI[15] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(VectorE0) { + uint32_t pr; + + OSAL_IRQ_PROLOGUE(); + + pr = EXTI->PR; + pr &= EXTI->IMR & ((1U << 10) | (1U << 11) | (1U << 12) | (1U << 13) | + (1U << 14) | (1U << 15)); + EXTI->PR = pr; + + exti_serve_irq(pr, 10); + exti_serve_irq(pr, 11); + exti_serve_irq(pr, 12); + exti_serve_irq(pr, 13); + exti_serve_irq(pr, 14); + exti_serve_irq(pr, 15); + + OSAL_IRQ_EPILOGUE(); +} +#endif + +#endif /* HAL_USE_PAL && (PAL_USE_WAIT || PAL_USE_CALLBACKS) */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enables IRQ sources. + * + * @notapi + */ +void irqInit(void) { + +#if HAL_USE_PAL + nvicEnableVector(EXTI0_IRQn, STM32_IRQ_EXTI0_PRIORITY); + nvicEnableVector(EXTI1_IRQn, STM32_IRQ_EXTI1_PRIORITY); + nvicEnableVector(EXTI2_IRQn, STM32_IRQ_EXTI2_PRIORITY); + nvicEnableVector(EXTI3_IRQn, STM32_IRQ_EXTI3_PRIORITY); + nvicEnableVector(EXTI4_IRQn, STM32_IRQ_EXTI4_PRIORITY); + nvicEnableVector(EXTI9_5_IRQn, STM32_IRQ_EXTI5_9_PRIORITY); + nvicEnableVector(EXTI15_10_IRQn, STM32_IRQ_EXTI10_15_PRIORITY); +#endif +} + +/** + * @brief Disables IRQ sources. + * + * @notapi + */ +void irqDeinit(void) { + +#if HAL_USE_PAL + nvicDisableVector(EXTI0_IRQn); + nvicDisableVector(EXTI1_IRQn); + nvicDisableVector(EXTI2_IRQn); + nvicDisableVector(EXTI3_IRQn); + nvicDisableVector(EXTI4_IRQn); + nvicDisableVector(EXTI9_5_IRQn); + nvicDisableVector(EXTI15_10_IRQn); +#endif +} + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/at32_isr.h b/os/hal/ports/AT32/AT32F4xx/at32_isr.h new file mode 100644 index 0000000000..70e50317f9 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/at32_isr.h @@ -0,0 +1,291 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/stm32_isr.h + * @brief STM32F4xx ISR handler header. + * + * @addtogroup STM32F4xx_ISR + * @{ + */ + +#ifndef STM32_ISR_H +#define STM32_ISR_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name ISRs suppressed in standard drivers + * @{ + */ +#define STM32_TIM1_SUPPRESS_ISR +#define STM32_TIM2_SUPPRESS_ISR +#define STM32_TIM3_SUPPRESS_ISR +#define STM32_TIM4_SUPPRESS_ISR +#define STM32_TIM5_SUPPRESS_ISR +#define STM32_TIM6_SUPPRESS_ISR +#define STM32_TIM7_SUPPRESS_ISR +#define STM32_TIM8_SUPPRESS_ISR +#define STM32_TIM9_SUPPRESS_ISR +#define STM32_TIM10_SUPPRESS_ISR +#define STM32_TIM11_SUPPRESS_ISR +#define STM32_TIM12_SUPPRESS_ISR +#define STM32_TIM13_SUPPRESS_ISR +#define STM32_TIM14_SUPPRESS_ISR + +#define STM32_USART1_SUPPRESS_ISR +#define STM32_USART2_SUPPRESS_ISR +#define STM32_USART3_SUPPRESS_ISR +#define STM32_UART4_SUPPRESS_ISR +#define STM32_UART5_SUPPRESS_ISR +#define STM32_USART6_SUPPRESS_ISR +#define STM32_UART7_SUPPRESS_ISR +#define STM32_UART8_SUPPRESS_ISR +#define STM32_UART9_SUPPRESS_ISR +#define STM32_UART10_SUPPRESS_ISR +/** @} */ + +/** + * @name ISR names and numbers + * @{ + */ +/* + * CAN units. + */ +#define STM32_CAN1_TX_HANDLER Vector8C +#define STM32_CAN1_RX0_HANDLER Vector90 +#define STM32_CAN1_RX1_HANDLER Vector94 +#define STM32_CAN1_SCE_HANDLER Vector98 +#define STM32_CAN2_TX_HANDLER Vector13C +#define STM32_CAN2_RX0_HANDLER Vector140 +#define STM32_CAN2_RX1_HANDLER Vector144 +#define STM32_CAN2_SCE_HANDLER Vector148 +#define STM32_CAN3_TX_HANDLER Vector168 +#define STM32_CAN3_RX0_HANDLER Vector16C +#define STM32_CAN3_RX1_HANDLER Vector170 +#define STM32_CAN3_SCE_HANDLER Vector174 + +#define STM32_CAN1_TX_NUMBER 19 +#define STM32_CAN1_RX0_NUMBER 20 +#define STM32_CAN1_RX1_NUMBER 21 +#define STM32_CAN1_SCE_NUMBER 22 +#define STM32_CAN2_TX_NUMBER 63 +#define STM32_CAN2_RX0_NUMBER 64 +#define STM32_CAN2_RX1_NUMBER 65 +#define STM32_CAN2_SCE_NUMBER 66 +#define STM32_CAN3_TX_NUMBER 74 +#define STM32_CAN3_RX0_NUMBER 75 +#define STM32_CAN3_RX1_NUMBER 76 +#define STM32_CAN3_SCE_NUMBER 77 + +/* + * EXTI unit. + */ +#define STM32_EXTI0_HANDLER Vector58 +#define STM32_EXTI1_HANDLER Vector5C +#define STM32_EXTI2_HANDLER Vector60 +#define STM32_EXTI3_HANDLER Vector64 +#define STM32_EXTI4_HANDLER Vector68 +#define STM32_EXTI5_9_HANDLER Vector9C +#define STM32_EXTI10_15_HANDLER VectorE0 +#define STM32_EXTI16_HANDLER Vector44 /* PVD */ +#define STM32_EXTI17_HANDLER VectorE4 /* RTC ALARM */ +#define STM32_EXTI18_HANDLER VectorE8 /* USB FS WAKEUP */ +#define STM32_EXTI19_HANDLER Vector138 /* ETH WAKEUP */ +#define STM32_EXTI20_HANDLER Vector170 /* USB HS WAKEUP */ +#define STM32_EXTI21_HANDLER Vector48 /* RTC TAMPER */ +#define STM32_EXTI22_HANDLER Vector4C /* RTC WAKEUP */ + +#define STM32_EXTI0_NUMBER 6 +#define STM32_EXTI1_NUMBER 7 +#define STM32_EXTI2_NUMBER 8 +#define STM32_EXTI3_NUMBER 9 +#define STM32_EXTI4_NUMBER 10 +#define STM32_EXTI5_9_NUMBER 23 +#define STM32_EXTI10_15_NUMBER 40 +#define STM32_EXTI16_NUMBER 1 +#define STM32_EXTI17_NUMBER 41 +#define STM32_EXTI18_NUMBER 42 +#define STM32_EXTI19_NUMBER 62 +#define STM32_EXTI20_NUMBER 76 +#define STM32_EXTI21_NUMBER 2 +#define STM32_EXTI22_NUMBER 3 + +/* + * I2C units. + */ +#define STM32_I2C1_EVENT_HANDLER VectorBC +#define STM32_I2C1_ERROR_HANDLER VectorC0 +#define STM32_I2C2_EVENT_HANDLER VectorC4 +#define STM32_I2C2_ERROR_HANDLER VectorC8 +#define STM32_I2C3_EVENT_HANDLER Vector160 +#define STM32_I2C3_ERROR_HANDLER Vector164 + +#define STM32_I2C1_EVENT_NUMBER 31 +#define STM32_I2C1_ERROR_NUMBER 32 +#define STM32_I2C2_EVENT_NUMBER 33 +#define STM32_I2C2_ERROR_NUMBER 34 +#define STM32_I2C3_EVENT_NUMBER 72 +#define STM32_I2C3_ERROR_NUMBER 73 + +/* + * OTG units. + */ +#define STM32_OTG1_HANDLER Vector14C +#define STM32_OTG2_HANDLER Vector174 +#define STM32_OTG2_EP1OUT_HANDLER Vector168 +#define STM32_OTG2_EP1IN_HANDLER Vector16C + +#define STM32_OTG1_NUMBER 67 +#define STM32_OTG2_NUMBER 77 +#define STM32_OTG2_EP1OUT_NUMBER 74 +#define STM32_OTG2_EP1IN_NUMBER 75 + +/* + * SDIO unit. + */ +#define STM32_SDIO_HANDLER Vector104 + +#define STM32_SDIO_NUMBER 49 + +/* + * TIM units. + */ +#define STM32_TIM1_BRK_TIM9_HANDLER VectorA0 +#define STM32_TIM1_UP_TIM10_HANDLER VectorA4 +#define STM32_TIM1_TRGCO_TIM11_HANDLER VectorA8 +#define STM32_TIM1_CC_HANDLER VectorAC +#define STM32_TIM2_HANDLER VectorB0 +#define STM32_TIM3_HANDLER VectorB4 +#define STM32_TIM4_HANDLER VectorB8 +#define STM32_TIM5_HANDLER Vector108 +#define STM32_TIM6_HANDLER Vector118 +#define STM32_TIM7_HANDLER Vector11C +#define STM32_TIM8_BRK_TIM12_HANDLER VectorEC +#define STM32_TIM8_UP_TIM13_HANDLER VectorF0 +#define STM32_TIM8_TRGCO_TIM14_HANDLER VectorF4 +#define STM32_TIM8_CC_HANDLER VectorF8 + +#define STM32_TIM1_BRK_TIM9_NUMBER 24 +#define STM32_TIM1_UP_TIM10_NUMBER 25 +#define STM32_TIM1_TRGCO_TIM11_NUMBER 26 +#define STM32_TIM1_CC_NUMBER 27 +#define STM32_TIM2_NUMBER 28 +#define STM32_TIM3_NUMBER 29 +#define STM32_TIM4_NUMBER 30 +#define STM32_TIM5_NUMBER 50 +#define STM32_TIM6_NUMBER 54 +#define STM32_TIM7_NUMBER 55 +#define STM32_TIM8_BRK_TIM12_NUMBER 43 +#define STM32_TIM8_UP_TIM13_NUMBER 44 +#define STM32_TIM8_TRGCO_TIM14_NUMBER 45 +#define STM32_TIM8_CC_NUMBER 46 + +/* + * LPTIM units. + */ +#define STM32_LPTIM1_HANDLER Vector1C4 + +#define STM32_LPTIM1_NUMBER 97 + +/* + * USART units. + */ +#define STM32_USART1_HANDLER VectorD4 +#define STM32_USART2_HANDLER VectorD8 +#define STM32_USART3_HANDLER VectorDC +#define STM32_UART4_HANDLER Vector110 +#define STM32_UART5_HANDLER Vector114 +#define STM32_USART6_HANDLER Vector15C +#define STM32_UART7_HANDLER Vector188 +#define STM32_UART8_HANDLER Vector18C +#define STM32_UART9_HANDLER Vector1A0 +#define STM32_UART10_HANDLER Vector1A4 + +#define STM32_USART1_NUMBER 37 +#define STM32_USART2_NUMBER 38 +#define STM32_USART3_NUMBER 39 +#define STM32_UART4_NUMBER 52 +#define STM32_UART5_NUMBER 53 +#define STM32_USART6_NUMBER 71 +#define STM32_UART7_NUMBER 82 +#define STM32_UART8_NUMBER 83 +#define STM32_UART9_NUMBER 88 +#define STM32_UART10_NUMBER 89 + +/* + * Ethernet + */ +#define ETH_IRQHandler Vector134 + +/* + * FSMC + */ +#define STM32_FSMC_HANDLER Vector100 + +#define STM32_FSMC_NUMBER 48 + +/* + * LTDC + */ +#define STM32_LTDC_EV_HANDLER Vector1A0 +#define STM32_LTDC_ER_HANDLER Vector1A4 + +#define STM32_LTDC_EV_NUMBER 88 +#define STM32_LTDC_ER_NUMBER 89 + +/* + * DMA2D + */ +#define STM32_DMA2D_HANDLER Vector1A8 + +#define STM32_DMA2D_NUMBER 90 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void irqInit(void); + void irqDeinit(void); +#ifdef __cplusplus +} +#endif + +#endif /* STM32_ISR_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/at32_rcc.h b/os/hal/ports/AT32/AT32F4xx/at32_rcc.h new file mode 100644 index 0000000000..56817fa935 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/at32_rcc.h @@ -0,0 +1,1667 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/stm32_rcc.h + * @brief RCC helper driver header. + * @note This file requires definitions from the ST header file + * @p stm32f4xx.h. + * + * @addtogroup STM32F4xx_RCC + * @{ + */ +#ifndef STM32_RCC_H +#define STM32_RCC_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Generic RCC operations + * @{ + */ +/** + * @brief Enables the clock of one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAPB1(mask, lp) { \ + RCC->APB1ENR |= (mask); \ + if (lp) \ + RCC->APB1LPENR |= (mask); \ + else \ + RCC->APB1LPENR &= ~(mask); \ + (void)RCC->APB1LPENR; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define rccDisableAPB1(mask) { \ + RCC->APB1ENR &= ~(mask); \ + RCC->APB1LPENR &= ~(mask); \ + (void)RCC->APB1LPENR; \ +} + +/** + * @brief Resets one or more peripheral on the APB1 bus. + * + * @param[in] mask APB1 peripherals mask + * + * @api + */ +#define rccResetAPB1(mask) { \ + RCC->APB1RSTR |= (mask); \ + RCC->APB1RSTR &= ~(mask); \ + (void)RCC->APB1RSTR; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define rccEnableAPB2(mask, lp) { \ + RCC->APB2ENR |= (mask); \ + if (lp) \ + RCC->APB2LPENR |= (mask); \ + else \ + RCC->APB2LPENR &= ~(mask); \ + (void)RCC->APB2LPENR; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define rccDisableAPB2(mask) { \ + RCC->APB2ENR &= ~(mask); \ + RCC->APB2LPENR &= ~(mask); \ + (void)RCC->APB2LPENR; \ +} + +/** + * @brief Resets one or more peripheral on the APB2 bus. + * + * @param[in] mask APB2 peripherals mask + * + * @api + */ +#define rccResetAPB2(mask) { \ + RCC->APB2RSTR |= (mask); \ + RCC->APB2RSTR &= ~(mask); \ + (void)RCC->APB2RSTR; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB1(mask, lp) { \ + RCC->AHB1ENR |= (mask); \ + if (lp) \ + RCC->AHB1LPENR |= (mask); \ + else \ + RCC->AHB1LPENR &= ~(mask); \ + (void)RCC->AHB1LPENR; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * + * @api + */ +#define rccDisableAHB1(mask) { \ + RCC->AHB1ENR &= ~(mask); \ + RCC->AHB1LPENR &= ~(mask); \ + (void)RCC->AHB1LPENR; \ +} + +/** + * @brief Resets one or more peripheral on the AHB1 bus. + * + * @param[in] mask AHB1 peripherals mask + * + * @api + */ +#define rccResetAHB1(mask) { \ + RCC->AHB1RSTR |= (mask); \ + RCC->AHB1RSTR &= ~(mask); \ + (void)RCC->AHB1RSTR; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB2(mask, lp) { \ + RCC->AHB2ENR |= (mask); \ + if (lp) \ + RCC->AHB2LPENR |= (mask); \ + else \ + RCC->AHB2LPENR &= ~(mask); \ + (void)RCC->AHB2LPENR; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * + * @api + */ +#define rccDisableAHB2(mask) { \ + RCC->AHB2ENR &= ~(mask); \ + RCC->AHB2LPENR &= ~(mask); \ + (void)RCC->AHB2LPENR; \ +} + +/** + * @brief Resets one or more peripheral on the AHB2 bus. + * + * @param[in] mask AHB2 peripherals mask + * + * @api + */ +#define rccResetAHB2(mask) { \ + RCC->AHB2RSTR |= (mask); \ + RCC->AHB2RSTR &= ~(mask); \ + (void)RCC->AHB2RSTR; \ +} + +/** + * @brief Enables the clock of one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableAHB3(mask, lp) { \ + RCC->AHB3ENR |= (mask); \ + if (lp) \ + RCC->AHB3LPENR |= (mask); \ + else \ + RCC->AHB3LPENR &= ~(mask); \ + (void)RCC->AHB3LPENR; \ +} + +/** + * @brief Disables the clock of one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * + * @api + */ +#define rccDisableAHB3(mask) { \ + RCC->AHB3ENR &= ~(mask); \ + RCC->AHB3LPENR &= ~(mask); \ + (void)RCC->AHB3LPENR; \ +} + +/** + * @brief Resets one or more peripheral on the AHB3 (FSMC) bus. + * + * @param[in] mask AHB3 peripherals mask + * + * @api + */ +#define rccResetAHB3(mask) { \ + RCC->AHB3RSTR |= (mask); \ + RCC->AHB3RSTR &= ~(mask); \ + (void)RCC->AHB3RSTR; \ +} +/** @} */ + +/** + * @name ADC peripherals specific RCC operations + * @{ + */ +/** + * @brief Resets ADC peripherals. + * + * @api + */ +#define rccResetADC() rccResetAPB2(RCC_APB2RSTR_ADCRST) + +/** + * @brief Enables the ADC1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC1(lp) rccEnableAPB2(RCC_APB2ENR_ADC1EN, lp) + +/** + * @brief Disables the ADC1 peripheral clock. + * + * @api + */ +#define rccDisableADC1() rccDisableAPB2(RCC_APB2ENR_ADC1EN) + +/** + * @brief Enables the ADC2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC2(lp) rccEnableAPB2(RCC_APB2ENR_ADC2EN, lp) + +/** + * @brief Disables the ADC2 peripheral clock. + * + * @api + */ +#define rccDisableADC2() rccDisableAPB2(RCC_APB2ENR_ADC2EN) + +/** + * @brief Enables the ADC3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableADC3(lp) rccEnableAPB2(RCC_APB2ENR_ADC3EN, lp) + +/** + * @brief Disables the ADC3 peripheral clock. + * + * @api + */ +#define rccDisableADC3() rccDisableAPB2(RCC_APB2ENR_ADC3EN) +/** @} */ + +/** + * @name DAC peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the DAC1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDAC1(lp) rccEnableAPB1(RCC_APB1ENR_DACEN, lp) + +/** + * @brief Disables the DAC1 peripheral clock. + * + * @api + */ +#define rccDisableDAC1() rccDisableAPB1(RCC_APB1ENR_DACEN) + +/** + * @brief Resets the DAC1 peripheral. + * + * @api + */ +#define rccResetDAC1() rccResetAPB1(RCC_APB1RSTR_DACRST) +/** @} */ + +/** + * @name DMA peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the DMA1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA1(lp) rccEnableAHB1(RCC_AHB1ENR_DMA1EN, lp) + +/** + * @brief Disables the DMA1 peripheral clock. + * + * @api + */ +#define rccDisableDMA1() rccDisableAHB1(RCC_AHB1ENR_DMA1EN) + +/** + * @brief Resets the DMA1 peripheral. + * + * @api + */ +#define rccResetDMA1() rccResetAHB1(RCC_AHB1RSTR_DMA1RST) + +/** + * @brief Enables the DMA2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA2(lp) rccEnableAHB1(RCC_AHB1ENR_DMA2EN, lp) + +/** + * @brief Disables the DMA2 peripheral clock. + * + * @api + */ +#define rccDisableDMA2() rccDisableAHB1(RCC_AHB1ENR_DMA2EN) + +/** + * @brief Resets the DMA2 peripheral. + * + * @api + */ +#define rccResetDMA2() rccResetAHB1(RCC_AHB1RSTR_DMA2RST) +/** @} */ + +/** + * @name BKPSRAM specific RCC operations + * @{ + */ +/** + * @brief Enables the BKPSRAM peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#ifdef RCC_AHB1ENR_BKPSRAMEN +#define rccEnableBKPSRAM(lp) rccEnableAHB1(RCC_AHB1ENR_BKPSRAMEN, lp) +#else +#define rccEnableBKPSRAM(lp) +#endif + +/** + * @brief Disables the BKPSRAM peripheral clock. + * + * @api + */ +#ifdef RCC_AHB1ENR_BKPSRAMEN +#define rccDisableBKPSRAM() rccDisableAHB1(RCC_AHB1ENR_BKPSRAMEN) +#else +#define rccDisableBKPSRAM() +#endif +/** @} */ + +/** + * @name PWR interface specific RCC operations + * @{ + */ +/** + * @brief Enables the PWR interface clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnablePWRInterface(lp) rccEnableAPB1(RCC_APB1ENR_PWREN, lp) + +/** + * @brief Disables PWR interface clock. + * + * @api + */ +#define rccDisablePWRInterface() rccDisableAPB1(RCC_APB1ENR_PWREN) + +/** + * @brief Resets the PWR interface. + * + * @api + */ +#define rccResetPWRInterface() rccResetAPB1(RCC_APB1RSTR_PWRRST) +/** @} */ + +/** + * @name CAN peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the CAN1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CAN1EN, lp) + +/** + * @brief Disables the CAN1 peripheral clock. + * + * @api + */ +#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CAN1EN) + +/** + * @brief Resets the CAN1 peripheral. + * + * @api + */ +#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CAN1RST) + +/** + * @brief Enables the CAN2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableCAN2(lp) rccEnableAPB1(RCC_APB1ENR_CAN2EN, lp) + +/** + * @brief Disables the CAN2 peripheral clock. + * + * @api + */ +#define rccDisableCAN2() rccDisableAPB1(RCC_APB1ENR_CAN2EN) + +/** + * @brief Resets the CAN2 peripheral. + * + * @api + */ +#define rccResetCAN2() rccResetAPB1(RCC_APB1RSTR_CAN2RST) + +/** + * @brief Resets the CAN3 peripheral. + * + * @api + */ +#define rccResetCAN3() rccResetAPB1(RCC_APB1RSTR_CAN3RST) + +/** + * @brief Enables the CAN3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableCAN3(lp) rccEnableAPB1(RCC_APB1ENR_CAN3EN, lp) + +/** + * @brief Disables the CAN3 peripheral clock. + * + * @api + */ +#define rccDisableCAN3() rccDisableAPB1(RCC_APB1ENR_CAN3EN) +/** @} */ + +/** + * @name ETH peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the ETH peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableETH(lp) rccEnableAHB1(RCC_AHB1ENR_ETHMACEN | \ + RCC_AHB1ENR_ETHMACTXEN | \ + RCC_AHB1ENR_ETHMACRXEN, lp) + +/** + * @brief Disables the ETH peripheral clock. + * + * @api + */ +#define rccDisableETH() rccDisableAHB1(RCC_AHB1ENR_ETHMACEN | \ + RCC_AHB1ENR_ETHMACTXEN | \ + RCC_AHB1ENR_ETHMACRXEN) + +/** + * @brief Resets the ETH peripheral. + * + * @api + */ +#define rccResetETH() rccResetAHB1(RCC_AHB1RSTR_ETHMACRST) +/** @} */ + +/** + * @name I2C peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the I2C1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C1(lp) rccEnableAPB1(RCC_APB1ENR_I2C1EN, lp) + +/** + * @brief Disables the I2C1 peripheral clock. + * + * @api + */ +#define rccDisableI2C1() rccDisableAPB1(RCC_APB1ENR_I2C1EN) + +/** + * @brief Resets the I2C1 peripheral. + * + * @api + */ +#define rccResetI2C1() rccResetAPB1(RCC_APB1RSTR_I2C1RST) + +/** + * @brief Enables the I2C2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C2(lp) rccEnableAPB1(RCC_APB1ENR_I2C2EN, lp) + +/** + * @brief Disables the I2C2 peripheral clock. + * + * @api + */ +#define rccDisableI2C2() rccDisableAPB1(RCC_APB1ENR_I2C2EN) + +/** + * @brief Resets the I2C2 peripheral. + * + * @api + */ +#define rccResetI2C2() rccResetAPB1(RCC_APB1RSTR_I2C2RST) + +/** + * @brief Enables the I2C3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableI2C3(lp) rccEnableAPB1(RCC_APB1ENR_I2C3EN, lp) + +/** + * @brief Disables the I2C3 peripheral clock. + * + * @api + */ +#define rccDisableI2C3() rccDisableAPB1(RCC_APB1ENR_I2C3EN) + +/** + * @brief Resets the I2C3 peripheral. + * + * @api + */ +#define rccResetI2C3() rccResetAPB1(RCC_APB1RSTR_I2C3RST) +/** @} */ + +/** + * @brief Enables the I2C4 peripheral clock. + * + * @api + */ +#define rccEnableI2C4() rccEnableAPB1(RCC_APB1ENR_FMPI2C1EN, lp) + +/** + * @brief Disables the I2C4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableI2C4(lp) rccDisableAPB1(RCC_APB1ENR_FMPI2C1EN, lp) + +/** + * @brief Resets the I2C4 peripheral. + * + * @api + */ +#define rccResetI2C4() rccResetAPB1(RCC_APB1RSTR_FMPI2C1RST) +/** @} */ + +/** + * @name OTG peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the OTG_FS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableOTG_FS(lp) rccEnableAHB2(RCC_AHB2ENR_OTGFSEN, lp) + +/** + * @brief Disables the OTG_FS peripheral clock. + * + * @api + */ +#define rccDisableOTG_FS() rccDisableAHB2(RCC_AHB2ENR_OTGFSEN) + +/** + * @brief Resets the OTG_FS peripheral. + * + * @api + */ +#define rccResetOTG_FS() rccResetAHB2(RCC_AHB2RSTR_OTGFSRST) + +/** + * @brief Enables the OTG_HS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableOTG_HS(lp) rccEnableAHB1(RCC_AHB1ENR_OTGHSEN, lp) + +/** + * @brief Disables the OTG_HS peripheral clock. + * + * @api + */ +#define rccDisableOTG_HS() rccDisableAHB1(RCC_AHB1ENR_OTGHSEN) + +/** + * @brief Resets the OTG_HS peripheral. + * + * @api + */ +#define rccResetOTG_HS() rccResetAHB1(RCC_AHB1RSTR_OTGHRST) + +/** + * @brief Enables the OTG_HS peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableOTG_HSULPI(lp) + +/** + * @brief Disables the OTG_HS peripheral clock. + * + * @api + */ +#define rccDisableOTG_HSULPI() +/** @} */ + +/** + * @name QUADSPI peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the QUADSPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableQUADSPI1(lp) rccEnableAHB3(RCC_AHB3ENR_QSPIEN, lp) + +/** + * @brief Disables the QUADSPI1 peripheral clock. + * + * @api + */ +#define rccDisableQUADSPI1() rccDisableAHB3(RCC_AHB3ENR_QSPIEN) + +/** + * @brief Resets the QUADSPI1 peripheral. + * + * @api + */ +#define rccResetQUADSPI1() rccResetAHB3(RCC_AHB3RSTR_QSPIRST) +/** @} */ + +/** + * @name SDIO peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the SDIO peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSDIO(lp) rccEnableAPB2(RCC_APB2ENR_SDIOEN, lp) + +/** + * @brief Disables the SDIO peripheral clock. + * + * @api + */ +#define rccDisableSDIO() rccDisableAPB2(RCC_APB2ENR_SDIOEN) + +/** + * @brief Resets the SDIO peripheral. + * + * @api + */ +#define rccResetSDIO() rccResetAPB2(RCC_APB2RSTR_SDIORST) +/** @} */ + +/** + * @name SPI peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the SPI1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI1(lp) rccEnableAPB2(RCC_APB2ENR_SPI1EN, lp) + +/** + * @brief Disables the SPI1 peripheral clock. + * + * @api + */ +#define rccDisableSPI1() rccDisableAPB2(RCC_APB2ENR_SPI1EN) + +/** + * @brief Resets the SPI1 peripheral. + * + * @api + */ +#define rccResetSPI1() rccResetAPB2(RCC_APB2RSTR_SPI1RST) + +/** + * @brief Enables the SPI2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI2(lp) rccEnableAPB1(RCC_APB1ENR_SPI2EN, lp) + +/** + * @brief Disables the SPI2 peripheral clock. + * + * @api + */ +#define rccDisableSPI2() rccDisableAPB1(RCC_APB1ENR_SPI2EN) + +/** + * @brief Resets the SPI2 peripheral. + * + * @api + */ +#define rccResetSPI2() rccResetAPB1(RCC_APB1RSTR_SPI2RST) + +/** + * @brief Enables the SPI3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI3(lp) rccEnableAPB1(RCC_APB1ENR_SPI3EN, lp) + +/** + * @brief Disables the SPI3 peripheral clock. + * + * @api + */ +#define rccDisableSPI3() rccDisableAPB1(RCC_APB1ENR_SPI3EN) + +/** + * @brief Resets the SPI3 peripheral. + * + * @api + */ +#define rccResetSPI3() rccResetAPB1(RCC_APB1RSTR_SPI3RST) + +/** + * @brief Enables the SPI4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI4(lp) rccEnableAPB2(RCC_APB2ENR_SPI4EN, lp) + +/** + * @brief Disables the SPI4 peripheral clock. + * + * @api + */ +#define rccDisableSPI4() rccDisableAPB2(RCC_APB2ENR_SPI4EN) + +/** + * @brief Resets the SPI4 peripheral. + * + * @api + */ +#define rccResetSPI4() rccResetAPB2(RCC_APB2RSTR_SPI4RST) + +/** + * @brief Enables the SPI5 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI5(lp) rccEnableAPB2(RCC_APB2ENR_SPI5EN, lp) + +/** + * @brief Disables the SPI5 peripheral clock. + * + * @api + */ +#define rccDisableSPI5() rccDisableAPB2(RCC_APB2ENR_SPI5EN) + +/** + * @brief Resets the SPI5 peripheral. + * + * @api + */ +#define rccResetSPI5() rccResetAPB2(RCC_APB2RSTR_SPI5RST) + +/** + * @brief Enables the SPI6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSPI6(lp) rccEnableAPB2(RCC_APB2ENR_SPI6EN, lp) + +/** + * @brief Disables the SPI6 peripheral clock. + * + * @api + */ +#define rccDisableSPI6() rccDisableAPB2(RCC_APB2ENR_SPI6EN) + +/** + * @brief Resets the SPI6 peripheral. + * + * @api + */ +#define rccResetSPI6() rccResetAPB2(RCC_APB2RSTR_SPI6RST) +/** @} */ + +/** + * @name TIM peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the TIM1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM1(lp) rccEnableAPB2(RCC_APB2ENR_TIM1EN, lp) + +/** + * @brief Disables the TIM1 peripheral clock. + * + * @api + */ +#define rccDisableTIM1() rccDisableAPB2(RCC_APB2ENR_TIM1EN) + +/** + * @brief Resets the TIM1 peripheral. + * + * @api + */ +#define rccResetTIM1() rccResetAPB2(RCC_APB2RSTR_TIM1RST) + +/** + * @brief Enables the TIM2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM2(lp) rccEnableAPB1(RCC_APB1ENR_TIM2EN, lp) + +/** + * @brief Disables the TIM2 peripheral clock. + * + * @api + */ +#define rccDisableTIM2() rccDisableAPB1(RCC_APB1ENR_TIM2EN) + +/** + * @brief Resets the TIM2 peripheral. + * + * @api + */ +#define rccResetTIM2() rccResetAPB1(RCC_APB1RSTR_TIM2RST) + +/** + * @brief Enables the TIM3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM3(lp) rccEnableAPB1(RCC_APB1ENR_TIM3EN, lp) + +/** + * @brief Disables the TIM3 peripheral clock. + * + * @api + */ +#define rccDisableTIM3() rccDisableAPB1(RCC_APB1ENR_TIM3EN) + +/** + * @brief Resets the TIM3 peripheral. + * + * @api + */ +#define rccResetTIM3() rccResetAPB1(RCC_APB1RSTR_TIM3RST) + +/** + * @brief Enables the TIM4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM4(lp) rccEnableAPB1(RCC_APB1ENR_TIM4EN, lp) + +/** + * @brief Disables the TIM4 peripheral clock. + * + * @api + */ +#define rccDisableTIM4() rccDisableAPB1(RCC_APB1ENR_TIM4EN) + +/** + * @brief Resets the TIM4 peripheral. + * + * @api + */ +#define rccResetTIM4() rccResetAPB1(RCC_APB1RSTR_TIM4RST) + +/** + * @brief Enables the TIM5 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM5(lp) rccEnableAPB1(RCC_APB1ENR_TIM5EN, lp) + +/** + * @brief Disables the TIM5 peripheral clock. + * + * @api + */ +#define rccDisableTIM5() rccDisableAPB1(RCC_APB1ENR_TIM5EN) + +/** + * @brief Resets the TIM5 peripheral. + * + * @api + */ +#define rccResetTIM5() rccResetAPB1(RCC_APB1RSTR_TIM5RST) + +/** + * @brief Enables the TIM6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM6(lp) rccEnableAPB1(RCC_APB1ENR_TIM6EN, lp) + +/** + * @brief Disables the TIM6 peripheral clock. + * + * @api + */ +#define rccDisableTIM6() rccDisableAPB1(RCC_APB1ENR_TIM6EN) + +/** + * @brief Resets the TIM6 peripheral. + * + * @api + */ +#define rccResetTIM6() rccResetAPB1(RCC_APB1RSTR_TIM6RST) + +/** + * @brief Enables the TIM7 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM7(lp) rccEnableAPB1(RCC_APB1ENR_TIM7EN, lp) + +/** + * @brief Disables the TIM7 peripheral clock. + * + * @api + */ +#define rccDisableTIM7() rccDisableAPB1(RCC_APB1ENR_TIM7EN) + +/** + * @brief Resets the TIM7 peripheral. + * + * @api + */ +#define rccResetTIM7() rccResetAPB1(RCC_APB1RSTR_TIM7RST) + +/** + * @brief Enables the TIM8 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM8(lp) rccEnableAPB2(RCC_APB2ENR_TIM8EN, lp) + +/** + * @brief Disables the TIM8 peripheral clock. + * + * @api + */ +#define rccDisableTIM8() rccDisableAPB2(RCC_APB2ENR_TIM8EN) + +/** + * @brief Resets the TIM8 peripheral. + * + * @api + */ +#define rccResetTIM8() rccResetAPB2(RCC_APB2RSTR_TIM8RST) + +/** + * @brief Enables the TIM9 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM9(lp) rccEnableAPB2(RCC_APB2ENR_TIM9EN, lp) + +/** + * @brief Disables the TIM9 peripheral clock. + * + * @api + */ +#define rccDisableTIM9() rccDisableAPB2(RCC_APB2ENR_TIM9EN) + +/** + * @brief Resets the TIM9 peripheral. + * + * @api + */ +#define rccResetTIM9() rccResetAPB2(RCC_APB2RSTR_TIM9RST) + +/** + * @brief Enables the TIM10 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM10(lp) rccEnableAPB2(RCC_APB2ENR_TIM10EN, lp) + +/** + * @brief Disables the TIM10 peripheral clock. + * + * @api + */ +#define rccDisableTIM10() rccDisableAPB2(RCC_APB2ENR_TIM10EN) + +/** + * @brief Resets the TIM10 peripheral. + * + * @api + */ +#define rccResetTIM10() rccResetAPB2(RCC_APB2RSTR_TIM10RST) + +/** + * @brief Enables the TIM11 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM11(lp) rccEnableAPB2(RCC_APB2ENR_TIM11EN, lp) + +/** + * @brief Disables the TIM11 peripheral clock. + * + * @api + */ +#define rccDisableTIM11() rccDisableAPB2(RCC_APB2ENR_TIM11EN) + +/** + * @brief Resets the TIM11 peripheral. + * + * @api + */ +#define rccResetTIM11() rccResetAPB2(RCC_APB2RSTR_TIM11RST) + +/** + * @brief Enables the TIM12 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM12(lp) rccEnableAPB1(RCC_APB1ENR_TIM12EN, lp) + +/** + * @brief Disables the TIM12 peripheral clock. + * + * @api + */ +#define rccDisableTIM12() rccDisableAPB1(RCC_APB1ENR_TIM12EN) + +/** + * @brief Resets the TIM12 peripheral. + * + * @api + */ +#define rccResetTIM12() rccResetAPB1(RCC_APB1RSTR_TIM12RST) + +/** + * @brief Enables the TIM13 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM13(lp) rccEnableAPB1(RCC_APB1ENR_TIM13EN, lp) + +/** + * @brief Disables the TIM13 peripheral clock. + * + * @api + */ +#define rccDisableTIM13() rccDisableAPB1(RCC_APB1ENR_TIM13EN) + +/** + * @brief Resets the TIM13 peripheral. + * + * @api + */ +#define rccResetTIM13() rccResetAPB1(RCC_APB1RSTR_TIM13RST) + +/** + * @brief Enables the TIM14 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableTIM14(lp) rccEnableAPB1(RCC_APB1ENR_TIM14EN, lp) + +/** + * @brief Disables the TIM14 peripheral clock. + * + * @api + */ +#define rccDisableTIM14() rccDisableAPB1(RCC_APB1ENR_TIM14EN) + +/** + * @brief Resets the TIM14 peripheral. + * + * @api + */ +#define rccResetTIM14() rccResetAPB1(RCC_APB1RSTR_TIM14RST) +/** @} */ + +/** + * @brief Enables the LPTIM1 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableLPTIM1(lp) rccEnableAPB1(RCC_APB1ENR_LPTIM1EN, lp) + +/** + * @brief Disables the LPTIM1 peripheral clock. + * + * @api + */ +#define rccDisableLPTIM1() rccDisableAPB1(RCC_APB1ENR_LPTIM1EN, lp) + +/** + * @brief Resets the LPTIM1 peripheral. + * + * @api + */ +#define rccResetLPTIM1() rccResetAPB1(RCC_APB1RSTR_LPTIM1RST) +/** @} */ + +/** + * @name USART/UART peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the USART1 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART1(lp) rccEnableAPB2(RCC_APB2ENR_USART1EN, lp) + +/** + * @brief Disables the USART1 peripheral clock. + * + * @api + */ +#define rccDisableUSART1() rccDisableAPB2(RCC_APB2ENR_USART1EN) + +/** + * @brief Resets the USART1 peripheral. + * + * @api + */ +#define rccResetUSART1() rccResetAPB2(RCC_APB2RSTR_USART1RST) + +/** + * @brief Enables the USART2 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART2(lp) rccEnableAPB1(RCC_APB1ENR_USART2EN, lp) + +/** + * @brief Disables the USART2 peripheral clock. + * + * @api + */ +#define rccDisableUSART2() rccDisableAPB1(RCC_APB1ENR_USART2EN) + +/** + * @brief Resets the USART2 peripheral. + * + * @api + */ +#define rccResetUSART2() rccResetAPB1(RCC_APB1RSTR_USART2RST) + +/** + * @brief Enables the USART3 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART3(lp) rccEnableAPB1(RCC_APB1ENR_USART3EN, lp) + +/** + * @brief Disables the USART3 peripheral clock. + * + * @api + */ +#define rccDisableUSART3() rccDisableAPB1(RCC_APB1ENR_USART3EN) + +/** + * @brief Resets the USART3 peripheral. + * + * @api + */ +#define rccResetUSART3() rccResetAPB1(RCC_APB1RSTR_USART3RST) + +/** + * @brief Enables the UART4 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART4(lp) rccEnableAPB1(RCC_APB1ENR_UART4EN, lp) + +/** + * @brief Disables the UART4 peripheral clock. + * + * @api + */ +#define rccDisableUART4() rccDisableAPB1(RCC_APB1ENR_UART4EN) + +/** + * @brief Resets the UART4 peripheral. + * + * @api + */ +#define rccResetUART4() rccResetAPB1(RCC_APB1RSTR_UART4RST) + +/** + * @brief Enables the UART5 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_UART5EN, lp) + +/** + * @brief Disables the UART5 peripheral clock. + * + * @api + */ +#define rccDisableUART5() rccDisableAPB1(RCC_APB1ENR_UART5EN) + +/** + * @brief Resets the UART5 peripheral. + * + * @api + */ +#define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_UART5RST) + +/** + * @brief Enables the USART6 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUSART6(lp) rccEnableAPB2(RCC_APB2ENR_USART6EN, lp) + +/** + * @brief Disables the USART6 peripheral clock. + * + * @api + */ +#define rccDisableUSART6() rccDisableAPB2(RCC_APB2ENR_USART6EN) + +/** + * @brief Resets the USART6 peripheral. + * + * @api + */ +#define rccResetUSART6() rccResetAPB2(RCC_APB2RSTR_USART6RST) + +/** + * @brief Enables the UART7 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART7(lp) rccEnableAPB1(RCC_APB1ENR_UART7EN, lp) + +/** + * @brief Disables the UART7 peripheral clock. + * + * @api + */ +#define rccDisableUART7() rccDisableAPB1(RCC_APB1ENR_UART7EN) + +/** + * @brief Resets the UART7 peripheral. + * + * @api + */ +#define rccResetUART7() rccResetAPB1(RCC_APB1RSTR_UART7RST) + +/** + * @brief Enables the UART8 peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART8(lp) rccEnableAPB1(RCC_APB1ENR_UART8EN, lp) + +/** + * @brief Disables the UART8 peripheral clock. + * + * @api + */ +#define rccDisableUART8() rccDisableAPB1(RCC_APB1ENR_UART8EN) + +/** + * @brief Resets the UART8 peripheral. + * + * @api + */ +#define rccResetUART8() rccResetAPB1(RCC_APB1RSTR_UART8RST) +/** @} */ + +/** + * @brief Enables the UART9 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART9(lp) rccEnableAPB2(RCC_APB2ENR_UART9EN, lp) + +/** + * @brief Disables the UART9 peripheral clock. + * + * @api + */ +#define rccDisableUART9() rccDisableAPB2(RCC_APB2ENR_UART9EN, lp) + +/** + * @brief Resets the UART9 peripheral. + * + * @api + */ +#define rccResetUART9() rccResetAPB2(RCC_APB2RSTR_UART9RST) +/** @} */ + +/** + * @brief Enables the UART10 peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableUART10(lp) rccEnableAPB2(RCC_APB2ENR_UART10EN, lp) + +/** + * @brief Disables the UART10 peripheral clock. + * + * @api + */ +#define rccDisableUART10(lp) rccDisableAPB2(RCC_APB2ENR_UART10EN, lp) + +/** + * @brief Resets the UART10 peripheral. + * + * @api + */ +#define rccResetUART10() rccResetAPB2(RCC_APB2RSTR_UART10RST) +/** @} */ + +/** + * @name LTDC peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the LTDC peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableLTDC(lp) rccEnableAPB2(RCC_APB2ENR_LTDCEN, lp) + +/** + * @brief Disables the LTDC peripheral clock. + * + * @api + */ +#define rccDisableLTDC() rccDisableAPB2(RCC_APB2ENR_LTDCEN) + +/** + * @brief Resets the LTDC peripheral. + * + * @api + */ +#define rccResetLTDC() rccResetAPB2(RCC_APB2RSTR_LTDCRST) + +/** + * @name DMA2D peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the DMA2D peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableDMA2D(lp) rccEnableAHB1(RCC_AHB1ENR_DMA2DEN, lp) + +/** + * @brief Disables the DMA2D peripheral clock. + * + * @api + */ +#define rccDisableDMA2D() rccDisableAHB1(RCC_AHB1ENR_DMA2DEN) + +/** + * @brief Resets the DMA2D peripheral. + * + * @api + */ +#define rccResetDMA2D() rccResetAHB1(RCC_AHB1RSTR_DMA2DRST) +/** @} */ + +/** + * @name CRC peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the CRC peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableCRC(lp) rccEnableAHB1(RCC_AHB1ENR_CRCEN, lp) + +/** + * @brief Disables the CRC peripheral clock. + * + * @api + */ +#define rccDisableCRC() rccDisableAHB1(RCC_AHB1ENR_CRCEN) + +/** + * @brief Resets the CRC peripheral. + * + * @api + */ +#define rccResetCRC() rccResetAHB1(RCC_AHB1RSTR_CRCRST) +/** @} */ + +/** + * @name FSMC peripherals specific RCC operations + * @{ + */ +/** + * @brief Enables the FSMC peripheral clock. + * + * @param[in] lp low power enable flag + * + * @api + */ +#if STM32_HAS_FSMC || defined(__DOXYGEN__) +#if STM32_FSMC_IS_FMC || defined(__DOXYGEN__) + #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp) +#else + #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FSMCEN, lp) +#endif +#endif + +/** + * @brief Disables the FSMC peripheral clock. + * + * @api + */ +#if STM32_HAS_FSMC || defined(__DOXYGEN__) +#if STM32_FSMC_IS_FMC || defined(__DOXYGEN__) + #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN) +#else + #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FSMCEN) +#endif +#endif + +/** + * @brief Resets the FSMC peripheral. + * + * @api + */ +#if STM32_HAS_FSMC || defined(__DOXYGEN__) +#if STM32_FSMC_IS_FMC || defined(__DOXYGEN__) + #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST) +#else + #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FSMCRST) +#endif +#endif +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +#endif /* STM32_RCC_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/at32_registry.h b/os/hal/ports/AT32/AT32F4xx/at32_registry.h new file mode 100644 index 0000000000..efc4c68cb2 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/at32_registry.h @@ -0,0 +1,457 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/stm32_registry.h + * @brief STM32F4xx capabilities registry. + * + * @addtogroup HAL + * @{ + */ + +#ifndef AT32_REGISTRY_H +#define AT32_REGISTRY_H + +#if defined(AT32F437xx) || defined(AT32F435xx) +#define STM32F427_437xx +#define STM32F4XX + +#else +#error "Artery AT32F4xx device not specified" +#endif + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +/** + * @name STM32F4xx/STM32F2xx capabilities + * @{ + */ + +/*===========================================================================*/ +/* Common. */ +/*===========================================================================*/ + +/* RNG attributes.*/ +#define STM32_HAS_RNG1 TRUE + +/* RTC attributes.*/ +#define STM32_HAS_RTC TRUE +#if !defined(STM32F2XX) +#define STM32_RTC_HAS_SUBSECONDS TRUE +#else +#define STM32_RTC_HAS_SUBSECONDS FALSE +#endif +#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE +#define STM32_RTC_NUM_ALARMS 2 +#define STM32_RTC_STORAGE_SIZE 80 +#define STM32_RTC_TAMP_STAMP_HANDLER Vector48 +#define STM32_RTC_WKUP_HANDLER Vector4C +#define STM32_RTC_ALARM_HANDLER VectorE4 +#define STM32_RTC_TAMP_STAMP_NUMBER 2 +#define STM32_RTC_WKUP_NUMBER 3 +#define STM32_RTC_ALARM_NUMBER 41 +#define STM32_RTC_ALARM_EXTI 17 +#define STM32_RTC_TAMP_STAMP_EXTI 21 +#define STM32_RTC_WKUP_EXTI 22 +#define STM32_RTC_IRQ_ENABLE() do { \ + nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI21_PRIORITY); \ + nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI22_PRIORITY); \ + nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \ +} while (false) + +/*===========================================================================*/ +/* AT32F435xx, AT32F437xx */ +/*===========================================================================*/ + +#if defined(STM32F429_439xx) || defined(STM32F427_437xx) + +/* Clock tree attributes.*/ +/* TODO: Artery! */ +#define STM32_HAS_RCC_PLLSAI FALSE +/* TODO: Artery! */ +#define STM32_HAS_RCC_PLLI2S FALSE +/* TODO: Artery! */ +#define STM32_HAS_RCC_DCKCFGR FALSE +#define STM32_HAS_RCC_DCKCFGR2 FALSE +#define STM32_HAS_RCC_I2SSRC TRUE +#define STM32_HAS_RCC_I2SPLLSRC FALSE +#define STM32_HAS_RCC_CK48MSEL FALSE +#define STM32_RCC_CK48MSEL_USES_I2S FALSE +#define STM32_TIMPRE_PRESCALE4 TRUE + +/* ADC attributes.*/ +#define STM32_ADC_HANDLER Vector88 +#define STM32_ADC_NUMBER 18 + +#define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_ADC1_DMA_CHN 0x00000000 + +#define STM32_HAS_ADC2 TRUE +#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_ADC2_DMA_CHN 0x00001100 + +#define STM32_HAS_ADC3 TRUE +#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 1)) +#define STM32_ADC3_DMA_CHN 0x00000022 + +#define STM32_HAS_ADC4 FALSE + +#define STM32_HAS_SDADC1 FALSE +#define STM32_HAS_SDADC2 FALSE +#define STM32_HAS_SDADC3 FALSE + +/* CAN attributes.*/ +#define STM32_HAS_CAN1 TRUE +#define STM32_HAS_CAN2 TRUE +#define STM32_HAS_CAN3 FALSE +#define STM32_CAN_MAX_FILTERS 28 + +/* DAC attributes.*/ +#define STM32_HAS_DAC1_CH1 TRUE +#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_DAC1_CH1_DMA_CHN 0x00700000 + +#define STM32_HAS_DAC1_CH2 TRUE +#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_DAC1_CH2_DMA_CHN 0x07000000 + +#define STM32_HAS_DAC2_CH1 FALSE +#define STM32_HAS_DAC2_CH2 FALSE + +/* DMA attributes.*/ +#define STM32_ADVANCED_DMA TRUE +#define STM32_DMA_CACHE_HANDLING FALSE +#define STM32_DMA_SUPPORTS_DMAMUX FALSE + +#define STM32_HAS_DMA1 TRUE +#define STM32_DMA1_CH0_HANDLER Vector6C +#define STM32_DMA1_CH1_HANDLER Vector70 +#define STM32_DMA1_CH2_HANDLER Vector74 +#define STM32_DMA1_CH3_HANDLER Vector78 +#define STM32_DMA1_CH4_HANDLER Vector7C +#define STM32_DMA1_CH5_HANDLER Vector80 +#define STM32_DMA1_CH6_HANDLER Vector84 +#define STM32_DMA1_CH7_HANDLER VectorFC +#define STM32_DMA1_CH0_NUMBER 11 +#define STM32_DMA1_CH1_NUMBER 12 +#define STM32_DMA1_CH2_NUMBER 13 +#define STM32_DMA1_CH3_NUMBER 14 +#define STM32_DMA1_CH4_NUMBER 15 +#define STM32_DMA1_CH5_NUMBER 16 +#define STM32_DMA1_CH6_NUMBER 17 +#define STM32_DMA1_CH7_NUMBER 47 + +#define STM32_HAS_DMA2 TRUE +#define STM32_DMA2_CH0_HANDLER Vector120 +#define STM32_DMA2_CH1_HANDLER Vector124 +#define STM32_DMA2_CH2_HANDLER Vector128 +#define STM32_DMA2_CH3_HANDLER Vector12C +#define STM32_DMA2_CH4_HANDLER Vector130 +#define STM32_DMA2_CH5_HANDLER Vector150 +#define STM32_DMA2_CH6_HANDLER Vector154 +#define STM32_DMA2_CH7_HANDLER Vector158 +#define STM32_DMA2_CH0_NUMBER 56 +#define STM32_DMA2_CH1_NUMBER 57 +#define STM32_DMA2_CH2_NUMBER 58 +#define STM32_DMA2_CH3_NUMBER 59 +#define STM32_DMA2_CH4_NUMBER 60 +#define STM32_DMA2_CH5_NUMBER 68 +#define STM32_DMA2_CH6_NUMBER 69 +#define STM32_DMA2_CH7_NUMBER 70 + +/* ETH attributes.*/ +#define STM32_HAS_ETH TRUE +#define STM32_ETH_HANDLER Vector134 +#define STM32_ETH_NUMBER 61 + +/* EXTI attributes.*/ +#define STM32_EXTI_NUM_LINES 23 +#define STM32_EXTI_IMR1_MASK 0x00000000U + +/* GPIO attributes.*/ +#define STM32_HAS_GPIOA TRUE +#define STM32_HAS_GPIOB TRUE +#define STM32_HAS_GPIOC TRUE +#define STM32_HAS_GPIOD TRUE +#define STM32_HAS_GPIOE TRUE +#define STM32_HAS_GPIOH TRUE +#define STM32_HAS_GPIOF TRUE +#define STM32_HAS_GPIOG TRUE +/* TODO: Artery AT32F435/7 */ +#define STM32_HAS_GPIOI FALSE +#define STM32_HAS_GPIOJ FALSE +#define STM32_HAS_GPIOK FALSE +#define STM32_GPIO_EN_MASK (RCC_AHB1ENR_GPIOAEN | \ + RCC_AHB1ENR_GPIOBEN | \ + RCC_AHB1ENR_GPIOCEN | \ + RCC_AHB1ENR_GPIODEN | \ + RCC_AHB1ENR_GPIOEEN | \ + RCC_AHB1ENR_GPIOFEN | \ + RCC_AHB1ENR_GPIOGEN | \ + RCC_AHB1ENR_GPIOHEN | \ + RCC_AHB1ENR_GPIOIEN) + +/* I2C attributes.*/ +#define STM32_HAS_I2C1 TRUE +#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 5)) +#define STM32_I2C1_RX_DMA_CHN 0x00100001 +#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\ + STM32_DMA_STREAM_ID_MSK(1, 6)) +#define STM32_I2C1_TX_DMA_CHN 0x11000000 + +#define STM32_HAS_I2C2 TRUE +#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\ + STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_I2C2_RX_DMA_CHN 0x00007700 +#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_I2C2_TX_DMA_CHN 0x70000000 + +#define STM32_HAS_I2C3 TRUE +#define STM32_I2C3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_I2C3_RX_DMA_CHN 0x00000300 +#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_I2C3_TX_DMA_CHN 0x00030000 + +#define STM32_HAS_I2C4 FALSE + +/* QUADSPI attributes.*/ +#define STM32_HAS_QUADSPI1 FALSE + +/* SDIO attributes.*/ +#define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 + +/* SPI attributes.*/ +#define STM32_HAS_SPI1 TRUE +#define STM32_SPI1_SUPPORTS_I2S FALSE +#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_SPI1_RX_DMA_CHN 0x00000303 +#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI1_TX_DMA_CHN 0x00303000 + +#define STM32_HAS_SPI2 TRUE +#define STM32_SPI2_SUPPORTS_I2S TRUE +#define STM32_SPI2_I2S_FULLDUPLEX TRUE +#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_SPI2_RX_DMA_CHN 0x00000000 +#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_SPI2_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI3 TRUE +#define STM32_SPI3_SUPPORTS_I2S TRUE +#define STM32_SPI3_I2S_FULLDUPLEX TRUE +#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\ + STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_SPI3_RX_DMA_CHN 0x00000000 +#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\ + STM32_DMA_STREAM_ID_MSK(1, 7)) +#define STM32_SPI3_TX_DMA_CHN 0x00000000 + +#define STM32_HAS_SPI4 TRUE +#define STM32_SPI4_SUPPORTS_I2S FALSE +#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\ + STM32_DMA_STREAM_ID_MSK(2, 3)) +#define STM32_SPI4_RX_DMA_CHN 0x00005004 +#define STM32_SPI4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 4)) +#define STM32_SPI4_TX_DMA_CHN 0x00050040 + +#define STM32_HAS_SPI5 TRUE +#define STM32_SPI5_SUPPORTS_I2S FALSE +#define STM32_SPI5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) | \ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI5_RX_DMA_CHN 0x00702000 +#define STM32_SPI5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) | \ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI5_TX_DMA_CHN 0x07020000 + +#define STM32_HAS_SPI6 TRUE +#define STM32_SPI6_SUPPORTS_I2S FALSE +#define STM32_SPI6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SPI6_RX_DMA_CHN 0x01000000 +#define STM32_SPI6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_SPI6_TX_DMA_CHN 0x00100000 + +/* TIM attributes.*/ +#define STM32_TIM_MAX_CHANNELS 4 + +#define STM32_HAS_TIM1 TRUE +#define STM32_TIM1_IS_32BITS FALSE +#define STM32_TIM1_CHANNELS 4 + +#define STM32_HAS_TIM2 TRUE +#define STM32_TIM2_IS_32BITS TRUE +#define STM32_TIM2_CHANNELS 4 + +#define STM32_HAS_TIM3 TRUE +#define STM32_TIM3_IS_32BITS FALSE +#define STM32_TIM3_CHANNELS 4 + +#define STM32_HAS_TIM4 TRUE +#define STM32_TIM4_IS_32BITS FALSE +#define STM32_TIM4_CHANNELS 4 + +#define STM32_HAS_TIM5 TRUE +#define STM32_TIM5_IS_32BITS TRUE +#define STM32_TIM5_CHANNELS 4 + +#define STM32_HAS_TIM6 TRUE +#define STM32_TIM6_IS_32BITS FALSE +#define STM32_TIM6_CHANNELS 0 + +#define STM32_HAS_TIM7 TRUE +#define STM32_TIM7_IS_32BITS FALSE +#define STM32_TIM7_CHANNELS 0 + +#define STM32_HAS_TIM8 TRUE +#define STM32_TIM8_IS_32BITS FALSE +#define STM32_TIM8_CHANNELS 4 + +#define STM32_HAS_TIM9 TRUE +#define STM32_TIM9_IS_32BITS FALSE +#define STM32_TIM9_CHANNELS 2 + +#define STM32_HAS_TIM10 TRUE +#define STM32_TIM10_IS_32BITS FALSE +#define STM32_TIM10_CHANNELS 1 + +#define STM32_HAS_TIM11 TRUE +#define STM32_TIM11_IS_32BITS FALSE +#define STM32_TIM11_CHANNELS 1 + +#define STM32_HAS_TIM12 TRUE +#define STM32_TIM12_IS_32BITS FALSE +#define STM32_TIM12_CHANNELS 2 + +#define STM32_HAS_TIM13 TRUE +#define STM32_TIM13_IS_32BITS FALSE +#define STM32_TIM13_CHANNELS 1 + +#define STM32_HAS_TIM14 TRUE +#define STM32_TIM14_IS_32BITS FALSE +#define STM32_TIM14_CHANNELS 1 + +#define STM32_HAS_TIM15 FALSE +#define STM32_HAS_TIM16 FALSE +#define STM32_HAS_TIM17 FALSE +#define STM32_HAS_TIM18 FALSE +#define STM32_HAS_TIM19 FALSE +#define STM32_HAS_TIM20 FALSE +#define STM32_HAS_TIM21 FALSE +#define STM32_HAS_TIM22 FALSE + +/* USART attributes.*/ +#define STM32_HAS_USART1 TRUE +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\ + STM32_DMA_STREAM_ID_MSK(2, 5)) +#define STM32_USART1_RX_DMA_CHN 0x00400400 +#define STM32_USART1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7) +#define STM32_USART1_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART2 TRUE +#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5) +#define STM32_USART2_RX_DMA_CHN 0x00400000 +#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_USART2_TX_DMA_CHN 0x04000000 + +#define STM32_HAS_USART3 TRUE +#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_USART3_RX_DMA_CHN 0x00000040 +#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\ + STM32_DMA_STREAM_ID_MSK(1, 4)) +#define STM32_USART3_TX_DMA_CHN 0x00074000 + +#define STM32_HAS_UART4 TRUE +#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2) +#define STM32_UART4_RX_DMA_CHN 0x00000400 +#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4) +#define STM32_UART4_TX_DMA_CHN 0x00040000 + +#define STM32_HAS_UART5 TRUE +#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART5_RX_DMA_CHN 0x00000004 +#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7) +#define STM32_UART5_TX_DMA_CHN 0x40000000 + +#define STM32_HAS_USART6 TRUE +#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\ + STM32_DMA_STREAM_ID_MSK(2, 2)) +#define STM32_USART6_RX_DMA_CHN 0x00000550 +#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 6) |\ + STM32_DMA_STREAM_ID_MSK(2, 7)) +#define STM32_USART6_TX_DMA_CHN 0x55000000 + +#define STM32_HAS_UART7 TRUE +#define STM32_UART7_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3) +#define STM32_UART7_RX_DMA_CHN 0x00005000 +#define STM32_UART7_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1) +#define STM32_UART7_TX_DMA_CHN 0x00000050 + +#define STM32_HAS_UART8 TRUE +#define STM32_UART8_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6) +#define STM32_UART8_RX_DMA_CHN 0x05000000 +#define STM32_UART8_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 0) +#define STM32_UART8_TX_DMA_CHN 0x00000005 + +#define STM32_HAS_UART9 FALSE +#define STM32_HAS_UART10 FALSE +#define STM32_HAS_LPUART1 FALSE + +/* USB attributes.*/ +#define STM32_OTG_STEPPING 2 +#define STM32_HAS_OTG1 TRUE +#define STM32_OTG1_ENDPOINTS 7 +#define STM32_HAS_OTG2 TRUE +#define STM32_OTG2_ENDPOINTS 7 + +#define STM32_HAS_USB FALSE + +/* IWDG attributes.*/ +#define STM32_HAS_IWDG TRUE +#define STM32_IWDG_IS_WINDOWED FALSE + +/* LTDC attributes.*/ +#define STM32_HAS_LTDC TRUE + +/* DMA2D attributes.*/ +#define STM32_HAS_DMA2D TRUE + +/* FSMC attributes.*/ +#define STM32_HAS_FSMC TRUE +#define STM32_FSMC_IS_FMC TRUE +#define STM32_FSMC_HANDLER Vector100 +#define STM32_FSMC_NUMBER 48 + +/* CRC attributes.*/ +#define STM32_HAS_CRC TRUE +#define STM32_CRC_PROGRAMMABLE FALSE + +#endif /* defined(STM32F429_439xx) || defined(STM32F427_437xx) */ + +#endif /* AT32_REGISTRY_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.c b/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.c new file mode 100644 index 0000000000..e03ecee1ba --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.c @@ -0,0 +1,936 @@ +/* + ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file hal_efl_lld.c + * @brief STM32F4xx Embedded Flash subsystem low level driver source. + * + * @addtogroup HAL_EFL + * @{ + */ + +#include + +#include "hal.h" + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define STM32_FLASH_LINE_SIZE (1 << STM32_FLASH_PSIZE) +#define STM32_FLASH_LINE_MASK (STM32_FLASH_LINE_SIZE - 1U) + +#define FLASH_PDKEY1 0x04152637U +#define FLASH_PDKEY2 0xFAFBFCFDU + +#define FLASH_KEY1 0x45670123U +#define FLASH_KEY2 0xCDEF89ABU + +#define FLASH_OPTKEY1 0x08192A3BU +#define FLASH_OPTKEY2 0x4C5D6E7FU + +#if !defined(FLASH_SR_OPERR) +#define FLASH_SR_OPERR FLASH_SR_SOP +#endif + +#if !defined(STM32_FLASH_DUAL_BANK_PERMANENT) +#define STM32_FLASH_DUAL_BANK_PERMANENT FALSE +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EFL1 driver identifier. + */ +EFlashDriver EFLD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +#if defined(STM32F413xx) || defined(STM32F412xx) || \ + defined(STM32F40_41xxx) || defined(__DOXYGEN__) + +/* Sector table for 1.5M device. */ +static const flash_sector_descriptor_t efl_lld_sect1[STM32_FLASH1_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 65536 + 3 * 131072, 131072}, /* Sector 8. */ + { 4 * 16384 + 65536 + 4 * 131072, 131072}, /* Sector 9. */ + { 4 * 16384 + 65536 + 5 * 131072, 131072}, /* Sector 10. */ + { 4 * 16384 + 65536 + 6 * 131072, 131072}, /* Sector 11. */ + { 4 * 16384 + 65536 + 7 * 131072, 131072}, /* Sector 12. */ + { 4 * 16384 + 65536 + 8 * 131072, 131072}, /* Sector 13. */ + { 4 * 16384 + 65536 + 9 * 131072, 131072}, /* Sector 14. */ + { 4 * 16384 + 65536 + 10 * 131072, 131072} /* Sector 15. */ +}; + +/* Sector table for 1M device. */ +static const flash_sector_descriptor_t efl_lld_sect2[STM32_FLASH2_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 65536 + 3 * 131072, 131072}, /* Sector 8. */ + { 4 * 16384 + 65536 + 4 * 131072, 131072}, /* Sector 9. */ + { 4 * 16384 + 65536 + 5 * 131072, 131072}, /* Sector 10. */ + { 4 * 16384 + 65536 + 6 * 131072, 131072} /* Sector 11. */ +}; + +/* The descriptors for 1.5M device. */ +static const flash_descriptor_t efl_lld_size1[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH1_SECTORS_TOTAL, + .sectors = efl_lld_sect1, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH1_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 1M device. */ +static const flash_descriptor_t efl_lld_size2[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH2_SECTORS_TOTAL, + .sectors = efl_lld_sect2, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH2_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* Table describing possible flash sizes and descriptors for this device. */ +static const efl_lld_size_t efl_lld_flash_sizes[] = { + { + .desc = efl_lld_size1 + }, + { + .desc = efl_lld_size2 + } +}; +#elif defined(STM32F401xx) || defined(STM32F411xx) || \ + defined(__DOXYGEN__) + +/* Sector table for 128k device. */ +static const flash_sector_descriptor_t efl_lld_sect1[STM32_FLASH1_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ +}; + +/* Sector table for 256k device. */ +static const flash_sector_descriptor_t efl_lld_sect2[STM32_FLASH2_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ +}; + +/* Sector table for 384k device. */ +static const flash_sector_descriptor_t efl_lld_sect3[STM32_FLASH3_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 65536 + 1 * 131072, 131072}, /* Sector 6. */ +}; + +/* Sector table for 512k device. */ +static const flash_sector_descriptor_t efl_lld_sect4[STM32_FLASH4_SECTORS_TOTAL] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 65536 + 2 * 131072, 131072}, /* Sector 7. */ +}; + +/* The descriptors for 128k device. */ +static const flash_descriptor_t efl_lld_size1[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH1_SECTORS_TOTAL, + .sectors = efl_lld_sect1, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH1_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 256k device. */ +static const flash_descriptor_t efl_lld_size2[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH2_SECTORS_TOTAL, + .sectors = efl_lld_sect2, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH2_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 384k device. */ +static const flash_descriptor_t efl_lld_size3[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH3_SECTORS_TOTAL, + .sectors = efl_lld_sect3, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH3_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 512k device. */ +static const flash_descriptor_t efl_lld_size4[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Single bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH4_SECTORS_TOTAL, + .sectors = efl_lld_sect4, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH4_SIZE * STM32_FLASH_SIZE_SCALE + } +}; + +/* Table describing possible flash sizes and descriptors for this device. */ +static const efl_lld_size_t efl_lld_flash_sizes[] = { + { + .desc = efl_lld_size1 + }, + { + .desc = efl_lld_size2 + }, + { + .desc = efl_lld_size3 + }, + { + .desc = efl_lld_size4 + } +}; +#elif defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(__DOXYGEN__) + +/* Sector table for 1M device in SBM. */ +static const flash_sector_descriptor_t efl_lld_sect_1m_sbm[STM32_FLASH_SECTORS_TOTAL_1M_SBM] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 1 * 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 1 * 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 1 * 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 131072}, /* Sector 8. */ + { 4 * 16384 + 1 * 65536 + 4 * 131072, 131072}, /* Sector 9. */ + { 4 * 16384 + 1 * 65536 + 5 * 131072, 131072}, /* Sector 10. */ + { 4 * 16384 + 1 * 65536 + 6 * 131072, 131072} /* Sector 11. */ +}; + +/* Sector table for 1M device in DBM. */ +static const flash_sector_descriptor_t efl_lld_sect_1m_dbm[STM32_FLASH_SECTORS_TOTAL_1M_DBM] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 1 * 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 1 * 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 1 * 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 0}, /* Invalid. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 12. */ + { 5 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 13. */ + { 6 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 14. */ + { 7 * 16384 + 1 * 65536 + 3 * 131072, 16384}, /* Sector 15. */ + { 8 * 16384 + 1 * 65536 + 3 * 131072, 65536}, /* Sector 16. */ + { 8 * 16384 + 2 * 65536 + 3 * 131072, 131072}, /* Sector 17. */ + { 8 * 16384 + 2 * 65536 + 4 * 131072, 131072}, /* Sector 18. */ + { 8 * 16384 + 2 * 65536 + 5 * 131072, 131072} /* Sector 19. */ +}; + +/* Sector table for 2M device banks. */ +static const flash_sector_descriptor_t efl_lld_sect_2m[STM32_FLASH_SECTORS_TOTAL_2M] = { + { 0, 16384}, /* Sector 0. */ + { 1 * 16384, 16384}, /* Sector 1. */ + { 2 * 16384, 16384}, /* Sector 2. */ + { 3 * 16384, 16384}, /* Sector 3. */ + { 4 * 16384, 65536}, /* Sector 4. */ + { 4 * 16384 + 1 * 65536, 131072}, /* Sector 5. */ + { 4 * 16384 + 1 * 65536 + 1 * 131072, 131072}, /* Sector 6. */ + { 4 * 16384 + 1 * 65536 + 2 * 131072, 131072}, /* Sector 7. */ + { 4 * 16384 + 1 * 65536 + 3 * 131072, 131072}, /* Sector 8. */ + { 4 * 16384 + 1 * 65536 + 4 * 131072, 131072}, /* Sector 9. */ + { 4 * 16384 + 1 * 65536 + 5 * 131072, 131072}, /* Sector 10. */ + { 4 * 16384 + 1 * 65536 + 6 * 131072, 131072}, /* Sector 11. */ + { 4 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 12. */ + { 5 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 13. */ + { 6 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 14. */ + { 7 * 16384 + 1 * 65536 + 7 * 131072, 16384}, /* Sector 15. */ + { 8 * 16384 + 1 * 65536 + 7 * 131072, 65536}, /* Sector 16. */ + { 8 * 16384 + 2 * 65536 + 7 * 131072, 131072}, /* Sector 17. */ + { 8 * 16384 + 2 * 65536 + 8 * 131072, 131072}, /* Sector 18. */ + { 8 * 16384 + 2 * 65536 + 9 * 131072, 131072}, /* Sector 19. */ + { 8 * 16384 + 2 * 65536 + 10 * 131072, 131072}, /* Sector 20. */ + { 8 * 16384 + 2 * 65536 + 11 * 131072, 131072}, /* Sector 21. */ + { 8 * 16384 + 2 * 65536 + 12 * 131072, 131072}, /* Sector 22. */ + { 8 * 16384 + 2 * 65536 + 13 * 131072, 131072} /* Sector 23. */ +}; + +/* The descriptors for 1M device. */ +static const flash_descriptor_t efl_lld_size_1m[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Bank 1 (SBM) organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_1M_SBM, + .sectors = efl_lld_sect_1m_sbm, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_1M * STM32_FLASH_SIZE_SCALE + }, + { /* Bank 1 & 2 (DBM) organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_1M_DBM, + .sectors = efl_lld_sect_1m_dbm, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_1M * STM32_FLASH_SIZE_SCALE + } +}; + +/* The descriptors for 2M device. */ +static const flash_descriptor_t efl_lld_size_2m[STM32_FLASH_NUMBER_OF_BANKS] = { + { /* Dual bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_2M, + .sectors = efl_lld_sect_2m, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_2M * STM32_FLASH_SIZE_SCALE + }, + { /* Dual bank organisation. */ + .attributes = FLASH_ATTR_ERASED_IS_ONE | + FLASH_ATTR_MEMORY_MAPPED, + .page_size = STM32_FLASH_LINE_SIZE, + .sectors_count = STM32_FLASH_SECTORS_TOTAL_2M, + .sectors = efl_lld_sect_2m, + .sectors_size = 0, + .address = (uint8_t *)FLASH_BASE, + .size = STM32_FLASH_SIZE_2M * STM32_FLASH_SIZE_SCALE + } +}; + +/* Table describing possible flash sizes and descriptors for this device. */ +static const efl_lld_size_t efl_lld_flash_sizes[] = { + { + .desc = efl_lld_size_1m + }, + { + .desc = efl_lld_size_2m + } +}; +#else +#error "This EFL driver does not support the selected device" +#endif + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void stm32_flash_lock(EFlashDriver *eflp) { + + eflp->flash->CR |= FLASH_CR_LOCK; +} + +static inline void stm32_flash_unlock(EFlashDriver *eflp) { + + eflp->flash->KEYR |= FLASH_KEY1; + eflp->flash->KEYR |= FLASH_KEY2; +} + +static inline void stm32_flash_enable_pgm(EFlashDriver *eflp) { + + /* Set parallelism. */ + eflp->flash->CR &= ~FLASH_CR_PSIZE; + eflp->flash->CR |= STM32_FLASH_PSIZE << FLASH_CR_PSIZE_Pos; + + /* Enable programming. */ + eflp->flash->CR |= FLASH_CR_PG; +} + +static inline void stm32_flash_disable_pgm(EFlashDriver *eflp) { + + eflp->flash->CR &= ~FLASH_CR_PG; +} + +static inline void stm32_flash_clear_status(EFlashDriver *eflp) { + + eflp->flash->SR = 0x0000FFFFU; +} + +static inline void stm32_flash_wait_busy(EFlashDriver *eflp) { + + /* Wait for busy bit clear.*/ + while ((eflp->flash->SR & FLASH_SR_BSY) != 0U) { + } +} + +static inline size_t stm32_flash_get_size(void) { + return *(uint16_t*)((uint32_t) STM32_FLASH_SIZE_REGISTER) * STM32_FLASH_SIZE_SCALE; +} + +static inline bool stm32_flash_dual_bank(EFlashDriver *eflp) { + +#if STM32_FLASH_NUMBER_OF_BANKS > 1 + return ((eflp->flash->OPTCR & FLASH_OPTCR_DB1M) != 0U || STM32_FLASH_DUAL_BANK_PERMANENT); +#endif + (void)eflp; + return false; +} + +static inline flash_error_t stm32_flash_check_errors(EFlashDriver *eflp) { + uint32_t sr = eflp->flash->SR; + + /* Clearing error conditions.*/ + eflp->flash->SR = sr & 0x0000FFFFU; + + /* Some errors are only caught by assertion.*/ + osalDbgAssert((sr & 0) == 0U, "unexpected flash error"); + + /* Decoding relevant errors.*/ + if ((sr & FLASH_SR_WRPERR) != 0U) { + return FLASH_ERROR_HW_FAILURE; + } + + if ((sr & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_OPERR)) != 0U) { + return eflp->state == FLASH_PGM ? FLASH_ERROR_PROGRAM : FLASH_ERROR_ERASE; + } + + return FLASH_NO_ERROR; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level Embedded Flash driver initialization. + * + * @notapi + */ +void efl_lld_init(void) { + + /* Driver initialization.*/ + eflObjectInit(&EFLD1); + EFLD1.flash = FLASH; + /* Find the size of the flash and set descriptor reference. */ + uint8_t i; + for (i = 0; i < (sizeof(efl_lld_flash_sizes) / sizeof(efl_lld_size_t)); i++) { + if (efl_lld_flash_sizes[i].desc->size == stm32_flash_get_size()) { + EFLD1.descriptor = efl_lld_flash_sizes[i].desc; + if (stm32_flash_dual_bank(&EFLD1)) { + /* Point to the dual bank descriptor. */ + EFLD1.descriptor++; + } + return; + } + } + osalDbgAssert(false, "invalid flash configuration"); +} + +/** + * @brief Configures and activates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_start(EFlashDriver *eflp) { + stm32_flash_unlock(eflp); + FLASH->CR = 0x00000000U; +} + +/** + * @brief Deactivates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_stop(EFlashDriver *eflp) { + + stm32_flash_lock(eflp); +} + +/** + * @brief Gets the flash descriptor structure. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return A flash device descriptor. + * @retval Pointer to single bank if DBM not enabled. + * @retval Pointer to bank1 if DBM enabled. + * + * @notapi + */ +const flash_descriptor_t *efl_lld_get_descriptor(void *instance) { + EFlashDriver *devp = (EFlashDriver *)instance; + return devp->descriptor; +} + +/** + * @brief Read operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be read + * @param[out] rp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_READ if the read operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); + + const flash_descriptor_t *bank = efl_lld_get_descriptor(instance); + osalDbgCheck((size_t)offset + n <= (size_t)bank->size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No reading while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Clearing error status bits.*/ + stm32_flash_clear_status(devp); + + /* Actual read implementation.*/ + memcpy((void *)rp, (const void *)efl_lld_get_descriptor(instance)->address + + offset, n); + +#if defined(FLASH_CR_RDERR) + /* Checking for errors after reading.*/ + if ((devp->flash->SR & FLASH_SR_RDERR) != 0U) { + err = FLASH_ERROR_READ; + } +#endif + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; + +} + +/** + * @brief Program operation. + * @note Successive write operations are possible without the need of + * an erase when changing bits from one to zero. Writing one requires + * an erase operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be programmed + * @param[in] pp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_PROGRAM if the program operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { + EFlashDriver *devp = (EFlashDriver *)instance; + const flash_descriptor_t *bank = efl_lld_get_descriptor(instance); + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)bank->size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No programming while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_PGM; + + /* Clearing error status bits.*/ + stm32_flash_clear_status(devp); + + /* Enabling PGM mode in the controller.*/ + stm32_flash_enable_pgm(devp); + + /* Actual program implementation.*/ + while (n > 0U) { + volatile uint32_t *address; + + /* Create an array of sufficient size to hold line(s). */ + union { + uint32_t w[STM32_FLASH_LINE_SIZE / sizeof(uint32_t)]; + uint16_t h[STM32_FLASH_LINE_SIZE / sizeof(uint16_t)]; + uint8_t b[STM32_FLASH_LINE_SIZE / sizeof(uint8_t)]; + } line; + + /* Unwritten bytes are initialized to all ones.*/ + uint8_t i; + for (i = 0; i < bank->page_size; i++) { + line.b[i] = 0xFF; + } + + /* Programming address aligned to flash lines.*/ + address = (volatile uint32_t *)(bank->address + + (offset & ~STM32_FLASH_LINE_MASK)); + + /* Copying data inside the prepared line(s).*/ + do { + line.b[offset & STM32_FLASH_LINE_MASK] = *pp; + offset++; + n--; + pp++; + } + while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U)); + + /* Programming line according to parallelism.*/ + switch (STM32_FLASH_LINE_SIZE) { + case 1: + address[0] = line.b[0]; + break; + + case 2: + address[0] = line.h[0]; + break; + + case 4: + address[0] = line.w[0]; + break; + + case 8: + address[0] = line.w[0]; + address[1] = line.w[1]; + break; + + default: + osalDbgAssert(false, "invalid line size"); + break; + } + + stm32_flash_wait_busy(devp); + err = stm32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + break; + } + } + + /* Disabling PGM mode in the controller.*/ + stm32_flash_disable_pgm(devp); + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Starts a whole-device erase operation. + * @note This function only erases the unused bank if in dual bank mode. The + * currently in use bank is not allowed since it is normally where the + * currently running program is executing from. + * Sectors on the in-use bank can be individually erased. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_all(void *instance) { + EFlashDriver *devp = (EFlashDriver *)instance; + + osalDbgCheck(instance != NULL); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No erasing while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + +#if defined(FLASH_CR_MER2) + /* If dual bank is active then mass erase bank2. */ + if (stm32_flash_dual_bank(devp)) { + + /* FLASH_ERASE state while the operation is performed.*/ + devp->state = FLASH_ERASE; + + /* Clearing error status bits.*/ + stm32_flash_clear_status(devp); + + /* Erase the currently unused bank, based on Flash Bank Mode */ + if ((SYSCFG->MEMRMP & SYSCFG_MEMRMP_UFB_MODE) != 0U) { + /* Bank 2 in use, erase Bank 1 */ + devp->flash->CR |= FLASH_CR_MER; + } + else { + /* Bank 1 in use, erase Bank 2 */ + devp->flash->CR |= FLASH_CR_MER2; + } + devp->flash->CR |= FLASH_CR_STRT; + return FLASH_NO_ERROR; + } +#endif + + /* Mass erase not allowed. */ + return FLASH_ERROR_UNIMPLEMENTED; +} + +/** + * @brief Starts an sector erase operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be erased + * this is an index within the total sectors + * in a flash bank + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + const flash_descriptor_t *bank = efl_lld_get_descriptor(instance); + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < bank->sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No erasing while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_ERASE; + + /* Clearing error status bits.*/ + stm32_flash_clear_status(devp); + + /* Enable sector erase.*/ + devp->flash->CR |= FLASH_CR_SER; + + /* Mask off the sector and parallelism selection bits.*/ + devp->flash->CR &= ~FLASH_CR_SNB; + devp->flash->CR &= ~FLASH_CR_PSIZE; + +#if defined(FLASH_CR_MER2) + /* Adjust sector value for dual-bank devices + * For STM32F42x_43x devices (dual-bank), FLASH_CR_SNB values jump to 0b10000 + * for sectors 12 and up. + */ + if (sector >= 12) { + sector -= 12; + sector |= 0x10U; + } +#endif + + /* Set sector and parallelism. */ + devp->flash->CR |= (sector << FLASH_CR_SNB_Pos) | + (STM32_FLASH_PSIZE << FLASH_CR_PSIZE_Pos); + + /* Start the erase.*/ + devp->flash->CR |= FLASH_CR_STRT; + + return FLASH_NO_ERROR; +} + +/** + * @brief Queries the driver for erase operation progress. + * + * @param[in] instance pointer to a @p EFlashDriver instance + * @param[out] msec recommended time, in milliseconds, that + * should be spent before calling this + * function again, can be @p NULL + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_ERASE if the erase operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @api + */ +flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err; + + /* If there is an erase in progress then the device must be checked.*/ + if (devp->state == FLASH_ERASE) { + + /* Checking for operation in progress.*/ + if ((devp->flash->SR & FLASH_SR_BSY) == 0U) { + + /* Disabling the various erase control bits.*/ + devp->flash->CR &= ~(FLASH_CR_MER | +#if defined(FLASH_CR_MER2) + FLASH_CR_MER2 | +#endif + FLASH_CR_SER); + + /* No operation in progress, checking for errors.*/ + err = stm32_flash_check_errors(devp); + + /* Back to ready state.*/ + devp->state = FLASH_READY; + } + else { + /* Recommended time before polling again. This is a simplified + implementation.*/ + if (msec != NULL) { + *msec = (uint32_t)STM32_FLASH_WAIT_TIME_MS; + } + + err = FLASH_BUSY_ERASING; + } + } + else { + err = FLASH_NO_ERROR; + } + + return err; +} + +/** + * @brief Returns the erase state of a sector. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be verified + * @return An error code. + * @retval FLASH_NO_ERROR if the sector is erased. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_VERIFY if the verify operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + uint32_t *address; + const flash_descriptor_t *bank = efl_lld_get_descriptor(instance); + flash_error_t err = FLASH_NO_ERROR; + unsigned i; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < bank->sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No verifying while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* Address of the sector in the bank.*/ + address = (uint32_t *)(bank->address + + flashGetSectorOffset(getBaseFlash(devp), sector)); + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Scanning the sector space.*/ + uint32_t sector_size = flashGetSectorSize(getBaseFlash(devp), sector); + for (i = 0U; i < sector_size / sizeof(uint32_t); i++) { + if (*address != 0xFFFFFFFFU) { + err = FLASH_ERROR_VERIFY; + break; + } + address++; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +#endif /* HAL_USE_EFL == TRUE */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.h b/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.h new file mode 100644 index 0000000000..9281d22bd9 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.h @@ -0,0 +1,179 @@ +/* + ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file hal_efl_lld.h + * @brief STM32F4xx Embedded Flash subsystem low level driver header. + * + * @addtogroup HAL_EFL + * @{ + */ + +#ifndef HAL_EFL_LLD_H +#define HAL_EFL_LLD_H + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name STM32F412/413 EFL driver configuration options + * @{ + */ +/** + * @brief Suggested wait time during erase operations polling. + */ +#if !defined(STM32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__) +#define STM32_FLASH_WAIT_TIME_MS 5 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if defined(STM32F413xx) || defined(STM32F412xx) || \ + defined(STM32F40_41xxx) || defined(__DOXYGEN__) + +/* Flash size register. */ +#define STM32_FLASH_SIZE_REGISTER 0x1FFF7A22 +#define STM32_FLASH_SIZE_SCALE 1024U + +/* + * Device flash size... + * + */ +#define STM32_FLASH_NUMBER_OF_BANKS 1 +#define STM32_FLASH1_SIZE 1536U +#define STM32_FLASH2_SIZE 1024U +#define STM32_FLASH1_SECTORS_TOTAL 16 +#define STM32_FLASH2_SECTORS_TOTAL 12 + +#elif defined(STM32F401xx) || defined(STM32F411xx) || \ + defined(__DOXYGEN__) + +/* Flash size register. */ +#define STM32_FLASH_SIZE_REGISTER 0x1FFF7A22 +#define STM32_FLASH_SIZE_SCALE 1024U + +/* + * Device flash size... + * + */ +#define STM32_FLASH_NUMBER_OF_BANKS 1 +#define STM32_FLASH1_SIZE 128U +#define STM32_FLASH2_SIZE 512U +#define STM32_FLASH3_SIZE 384U +#define STM32_FLASH4_SIZE 512U +#define STM32_FLASH1_SECTORS_TOTAL 5 +#define STM32_FLASH2_SECTORS_TOTAL 6 +#define STM32_FLASH3_SECTORS_TOTAL 7 +#define STM32_FLASH4_SECTORS_TOTAL 8 + +#elif defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(__DOXYGEN__) + +/* Flash size register. */ +#define STM32_FLASH_SIZE_REGISTER 0x1FFF7A22 +#define STM32_FLASH_SIZE_SCALE 1024U + +/* + * Device flash size is: + * 1M for STM32F4x7/4x9 suffix G devices + * 2M for STM32F4x7/4x9 suffix I devices. + * + * For 1M devices SBM is organised as 16K x 4 + 64K + 128K x 7 sectors. + * For 1M devices DBM is organised as 16K x 4 + 64K + 128K x 3 sectors per bank. + * + * For 2M devices are organised as 16K x 4 + 64K + 128K x 7 sectors per bank. + */ +#define STM32_FLASH_NUMBER_OF_BANKS 2 +#define STM32_FLASH_SIZE_1M 1024U +#define STM32_FLASH_SIZE_2M 2048U +#define STM32_FLASH_SECTORS_TOTAL_1M_SBM 12 +#define STM32_FLASH_SECTORS_TOTAL_1M_DBM 20 +#define STM32_FLASH_SECTORS_TOTAL_2M 24 +#else +#error "This EFL driver does not support the selected device" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/* A flash size declaration. */ +typedef struct { + const flash_descriptor_t* desc; +} efl_lld_size_t; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Low level fields of the embedded flash driver structure. + */ +#define efl_lld_driver_fields \ + /* Flash registers.*/ \ + FLASH_TypeDef *flash; \ + const flash_descriptor_t *descriptor; + +/** + * @brief Low level fields of the embedded flash configuration structure. + */ +#define efl_lld_config_fields \ + /* Dummy configuration, it is not needed.*/ \ + uint32_t dummy + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EFlashDriver EFLD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void efl_lld_init(void); + void efl_lld_start(EFlashDriver *eflp); + void efl_lld_stop(EFlashDriver *eflp); + const flash_descriptor_t *efl_lld_get_descriptor(void *instance); + flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); + flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); + flash_error_t efl_lld_start_erase_all(void *instance); + flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector); + flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec); + flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EFL == TRUE */ + +#endif /* HAL_EFL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/hal_lld.c b/os/hal/ports/AT32/AT32F4xx/hal_lld.c new file mode 100644 index 0000000000..0d3953e2ae --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/hal_lld.c @@ -0,0 +1,252 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld.c + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f4xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= RCC_BDCR_LSEON; +#endif + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ + RCC->BDCR |= STM32_RTCSEL; + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + +#if STM32_BKPRAM_ENABLE + rccEnableBKPSRAM(true); + + PWR->CSR |= PWR_CSR_BRE; + while ((PWR->CSR & PWR_CSR_BRR) == 0) + ; /* Waits until the regulator is stable */ +#else + PWR->CSR &= ~PWR_CSR_BRE; +#endif /* STM32_BKPRAM_ENABLE */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. AHB3 is not reseted because it could have + been initialized in the board initialization file (board.c). + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~STM32_GPIO_EN_MASK); +#if !defined(STM32F410xx) + rccResetAHB2(~0); +#endif + rccResetAPB1(~RCC_APB1RSTR_PWRRST); + rccResetAPB2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32F2xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ +#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR_RTCAPBEN) + RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_RTCAPBEN; +#else + RCC->APB1ENR = RCC_APB1ENR_PWREN; +#endif + + /* config ldo voltage */ + PWR->LDOOV = PWR_LDOOV_1V3; + +#if 0 + /* Flash setup.*/ + /* set the flash clock divider */ + flash_clock_divider_set(FLASH_CLOCK_DIV_3); +#endif + + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->PLLCFGR = STM32_PLLSRC | STM32_PLLP | STM32_PLLN | STM32_PLLM; + RCC->CR |= RCC_CR_PLLON; + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; +#endif /* STM32_ACTIVATE_PLL */ + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR = STM32_MCO2PRE | STM32_MCO2SEL | + STM32_MCO1PRE | STM32_MCO1SEL | + STM32_RTCPRE | + STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + + /* enable auto step mode */ + RCC->MISC2 |= RCC_MISC2_AUTO_STEP_EN; + + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; + + /* disable auto step mode */ + RCC->MISC2 &= ~RCC_MISC2_AUTO_STEP_EN; +#endif + +#if STM32_CLOCK48_REQUIRED + RCC->MISC2 = (RCC->MISC2 & (~(STM32_CK48MSEL_MASK | RCC_MISC2_USB_DIV_Msk))) | + (STM32_CK48MSEL | STM32_USBDIV_VALUE); +#endif /* STM32_CLOCK48_REQUIRED */ +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/hal_lld.h b/os/hal/ports/AT32/AT32F4xx/hal_lld.h new file mode 100644 index 0000000000..61b597687d --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/hal_lld.h @@ -0,0 +1,286 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld.h + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "at32_registry.h" + +#include "hal_lld_type1.h" + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "at32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "at32_rcc.h" +#include "stm32_tim.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Requires use of SPIv2 driver model. + */ +#define HAL_LLD_SELECT_SPI_V2 TRUE + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/** + * @brief MCO1 divider clock. + */ +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || defined(__DOXYGEN__) +#define STM32_MCO1DIVCLK STM32_HSICLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE +#define STM32_MCO1DIVCLK STM32_LSECLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE +#define STM32_MCO1DIVCLK STM32_HSECLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL +#define STM32_MCO1DIVCLK STM32_PLLCLKOUT + +#else +#error "invalid STM32_MCO1SEL value specified" +#endif + +/** + * @brief MCO1 output pin clock. + */ +#if (STM32_MCO1PRE == STM32_MCO1PRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCO1CLK STM32_MCO1DIVCLK + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV2 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 2) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV3 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 3) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV4 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 4) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV5 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 5) + +#else +#error "invalid STM32_MCO1PRE value specified" +#endif + +/** + * @brief MCO2 divider clock. + */ +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || defined(__DOXYGEN__) +#define STM32_MCO2DIVCLK STM32_HSECLK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL +#define STM32_MCO2DIVCLK STM32_PLLCLKOUT + +#elif STM32_MCO2SEL == STM32_MCO2SEL_SYSCLK +#define STM32_MCO2DIVCLK STM32_SYSCLK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S +#define STM32_MCO2DIVCLK STM32_PLLI2S + +#else +#error "invalid STM32_MCO2SEL value specified" +#endif + +/** + * @brief MCO2 output pin clock. + */ +#if (STM32_MCO2PRE == STM32_MCO2PRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCO2CLK STM32_MCO2DIVCLK + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV2 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 2) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV3 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 3) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV4 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 4) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV5 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 5) + +#else +#error "invalid STM32_MCO2PRE value specified" +#endif + +/** + * @brief RTC HSE divider setting. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief HSE divider toward RTC clock. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK STM32_HSEDIVCLK + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief 48MHz frequency. + */ +#if STM32_CLOCK48_REQUIRED || defined(__DOXYGEN__) +#if (STM32_CK48MSEL == STM32_CK48MSEL_PLL) || defined(__DOXYGEN__) +#if (STM32_PLLCLKOUT == 48000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_1 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 72000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_1_5 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 96000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_2 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 120000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_2_5 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 144000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_3 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 168000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_3_5 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 192000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_4 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 216000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_4_5 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 240000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_5 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 264000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_5_5 + #define STM32_PLL48CLK 48000000 +#elif (STM32_PLLCLKOUT == 288000000) + #define STM32_USBDIV_VALUE RCC_MISC2_USB_DIV_6 + #define STM32_PLL48CLK 48000000 +#else + #error "no divider to get 48000000 USB clock from PLLCLKOUT" +#endif +#elif STM32_CK48MSEL == STM32_CK48MSEL_HICK +#error "HICK clock as USB 48MHz source is not implemented" +//#define STM32_PLL48CLK STM32_PLL48CLK_ALTSRC +#else +#error "invalid source selected for PLL48CLK clock" +#endif +#else /* !STM32_CLOCK48_REQUIRED */ +#define STM32_PLL48CLK 0 +#endif /* STM32_CLOCK48_REQUIRED */ + +#if !STM32_HAS_RCC_DCKCFGR || (STM32_TIMPRE == STM32_TIMPRE_PCLK) || \ + defined(__DOXYGEN__) +/** + * @brief Clock of timers connected to APB1 + * (Timers 2, 3, 4, 5, 6, 7, 12, 13, 14). + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Clock of timers connected to APB2 (Timers 1, 8, 9, 10, 11). + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +#else /* STM32_HAS_RCC_DCKCFGR && (STM32_TIMPRE == STM32_TIMPRE_HCLK) */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || \ + (STM32_PPRE1 == STM32_PPRE1_DIV2) || \ + ((STM32_PPRE1 == STM32_PPRE1_DIV4) && \ + (STM32_TIMPRE_PRESCALE4 == TRUE)) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 STM32_HCLK +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 4) +#endif + +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || \ + (STM32_PPRE2 == STM32_PPRE2_DIV2) || \ + ((STM32_PPRE2 == STM32_PPRE2_DIV4) && \ + (STM32_TIMPRE_PRESCALE4 == TRUE)) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 STM32_HCLK +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 4) +#endif +#endif /* STM32_HAS_RCC_DCKCFGR && (STM32_TIMPRE == STM32_TIMPRE_HCLK) */ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/hal_lld_type1.h b/os/hal/ports/AT32/AT32F4xx/hal_lld_type1.h new file mode 100644 index 0000000000..ab49237294 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/hal_lld_type1.h @@ -0,0 +1,1449 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld_type1.h + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * - STM32_VDD (as hundredths of Volt). + * . + * One of the following macros must also be defined: + * - STM32F2XX for High-performance STM32F2 devices. + * - STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, + * STM32F446xx for High-performance STM32F4 devices of + * Foundation line. + * - STM32F401xx, STM32F410xx, STM32F411xx, STM32F412xx + * for High-performance STM32F4 devices of Access line. + * - STM32F427xx, STM32F437xx, STM32F429xx, STM32F439xx, STM32F469xx, + * STM32F479xx for High-performance STM32F4 devices of Advanced line. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_TYPE1_H +#define HAL_LLD_TYPE1_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Defines the support for realtime counters in the HAL. + */ +#define HAL_IMPLEMENTS_COUNTERS TRUE + +/** + * @name Platform identification macros + * @{ + */ +#if defined(AT32F435xx) || defined(AT32F437xx) +#define PLATFORM_NAME "AT32F435/437 High Performance with DSP, FPU and MPU" + +#else +#error "AT32FF4xx device not specified" +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +#if defined(AT32F435xx) || defined(AT32F437xx) || defined(__DOXYGEN__) +/** + * @brief Absolute maximum system clock. + */ +#define STM32_SYSCLK_MAX 288000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 25000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 25000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency using an external source. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 2000000 + +/** + * @brief Maximum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MAX 1200000000 + +/** + * @brief Minimum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MIN 500000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 288000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 16000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 144000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 144000000 +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 16000000 /**< High speed internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_VOS_SCALE3 0x00004000 +#define STM32_VOS_SCALE2 0x00008000 +#define STM32_VOS_SCALE1 0x0000C000 +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLP_MASK (7 << 16) /**< PLLP mask. */ +#define STM32_PLLP_DIV4 (2 << 16) /**< PLL clock divided by 2. */ +#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 4. */ +#define STM32_PLLP_DIV16 (4 << 16) /**< PLL clock divided by 6. */ +#define STM32_PLLP_DIV32 (5 << 16) /**< PLL clock divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW mask. */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ +#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ +#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ + +#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ + +#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ +#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ +#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ + +#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ +#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ +#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ +#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ +#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ +#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ + +#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ +#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ +#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ +#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ +#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ +#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ + +#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ +#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ +#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ + +/** + * @name RCC_PLLI2SCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SM_MASK (31 << 0) /**< PLLI2SM mask. */ +#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ +#define STM32_PLLI2SP_MASK (3 << 16) /**< PLLI2SP mask. */ +#define STM32_PLLI2SP_DIV2 (0 << 16) /**< PLLI2S clock divided by 2. */ +#define STM32_PLLI2SP_DIV4 (1 << 16) /**< PLLI2S clock divided by 4. */ +#define STM32_PLLI2SP_DIV6 (2 << 16) /**< PLLI2S clock divided by 6. */ +#define STM32_PLLI2SP_DIV8 (3 << 16) /**< PLLI2S clock divided by 8. */ +#define STM32_PLLI2SSRC_MASK (1 << 22) /**< PLLI2SSRC mask. */ +#define STM32_PLLI2SSRC_PLLSRC (0 << 22) /**< PLLI2SSRC is selected PLL + source. */ +#define STM32_PLLI2SSRC_CKIN (1 << 22) /**< PLLI2SSRC is I2S_CKIN. */ +#define STM32_PLLI2SQ_MASK (15 << 24) /**< PLLI2SQ mask. */ +#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ +/** @} */ + +/** + * @name RCC_PLLSAICFGR register bits definitions + * @{ + */ +#define STM32_PLLSAIM_MASK (31 << 0) /**< PLLSAIM mask. */ +#define STM32_PLLSAIN_MASK (511 << 6) /**< PLLSAIN mask. */ +#define STM32_PLLSAIP_MASK (3 << 16) /**< PLLSAIP mask. */ +#define STM32_PLLSAIP_DIV2 (0 << 16) /**< PLLSAI clock divided by 2. */ +#define STM32_PLLSAIP_DIV4 (1 << 16) /**< PLLSAI clock divided by 4. */ +#define STM32_PLLSAIP_DIV6 (2 << 16) /**< PLLSAI clock divided by 6. */ +#define STM32_PLLSAIP_DIV8 (3 << 16) /**< PLLSAI clock divided by 8. */ +#define STM32_PLLSAIQ_MASK (15 << 24) /**< PLLSAIQ mask. */ +#define STM32_PLLSAIR_MASK (7 << 28) /**< PLLSAIR mask. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ +/** @} */ + +/** + * @name RCC_DCKCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SDIVQ_MASK (31 << 0) /**< PLLI2SDIVQ mask. */ +#define STM32_PLLSAIDIVQ_MASK (31 << 8) /**< PLLSAIDIVQ mask. */ + +#define STM32_PLLSAIDIVR_MASK (3 << 16) /**< PLLSAIDIVR mask. */ +#define STM32_PLLSAIDIVR_DIV2 (0 << 16) /**< LCD_CLK is R divided by 2. */ +#define STM32_PLLSAIDIVR_DIV4 (1 << 16) /**< LCD_CLK is R divided by 4. */ +#define STM32_PLLSAIDIVR_DIV8 (2 << 16) /**< LCD_CLK is R divided by 8. */ +#define STM32_PLLSAIDIVR_DIV16 (3 << 16) /**< LCD_CLK is R divided by 16.*/ +#define STM32_PLLSAIDIVR_OFF 0xFFFFFFFFU /**< LCD CLK is not required. */ + +#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ +#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ +#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ + +#define STM32_I2S1SEL_MASK (3 << 25) /**< I2S1SEL mask. */ +#define STM32_I2S1SEL_PLLR (0 << 25) /**< I2S1 source is PLLR. */ +#define STM32_I2S1SEL_AFIN (1 << 25) /**< I2S1 source is AF Input. */ +#define STM32_I2S1SEL_MCO1 (2 << 25) /**< I2S1 source is MCO1. */ +#define STM32_I2S1SEL_OFF 0xFFFFFFFFU /**< I2S1 clock is not required.*/ + +#define STM32_I2S2SEL_MASK (3 << 27) /**< I2S2SEL mask. */ +#define STM32_I2S2SEL_PLLR (0 << 27) /**< I2S2 source is PLLR. */ +#define STM32_I2S2SEL_AFIN (1 << 27) /**< I2S2 source is AF Input. */ +#define STM32_I2S2SEL_MCO1 (2 << 27) /**< I2S2 source is MCO1. */ +#define STM32_I2S2SEL_OFF 0xFFFFFFFFU /**< I2S2 clock is not required.*/ + +#define STM32_DSISEL_MASK (1 << 28) /**< DSISEL mask. */ +#define STM32_DSISEL_PHY (0 << 28) /**< DSI source is DSI-PSY. */ +#define STM32_DSISEL_PLLR (1 << 28) /**< DSI source is PLLR. */ +/** @} */ + +/** + * @name RCC_DCKCFGR2 register bits definitions + * @{ + */ +#define STM32_CECSEL_MASK (1 << 26) /**< CECSEL mask. */ +#define STM32_CECSEL_LSE (0 << 26) /**< CEC source is LSE. */ +#define STM32_CECSEL_HSIDIV488 (1 << 26) /**< CEC source is HSI/488. */ + +#define STM32_SDMMCSEL_MASK (1 << 28) /**< SDMMCSEL mask. */ +#define STM32_SDMMCSEL_PLL48CLK (0 << 28) /**< SDMMC source is PLL48CLK. */ +#define STM32_SDMMCSEL_SYSCLK (1 << 28) /**< SDMMC source is SYSCLK. */ + +#define STM32_SPDIFSEL_MASK (1 << 29) /**< SPDIFSEL mask. */ +#define STM32_SPDIFSEL_PLLI2S (0 << 29) /**< SPDIF source is PLLI2S. */ +#define STM32_SPDIFSEL_PLL (1 << 29) /**< SPDIF source is PLL. */ + +#define STM32_LPTIM1SEL_MASK (3 << 30) /**< LPTIM1 mask. */ +#define STM32_LPTIM1SEL_APB (0 << 30) /**< LPTIM1 source is APB. */ +#define STM32_LPTIM1SEL_HSI (1 << 30) /**< LPTIM1 source is HSI. */ +#define STM32_LPTIM1SEL_LSI (2 << 30) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_LSE (3 << 30) /**< LPTIM1 source is LSE. */ +/** @} */ + +/** + * @name RCC_MISC1 register bits definitions + * @{ + */ +#define STM32_CK48MSEL_MASK (1 << 13) /**< CK48MSEL mask. */ +#define STM32_CK48MSEL_PLL (0 << 13) /**< PLL48CLK source is PLL. */ +#define STM32_CK48MSEL_HICK (1 << 13) /**< PLL48CLK source is HICK. */ +#define STM32_CK48MSEL_PLLALT (1 << 13) /**< Alias. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables the backup RAM regulator. + */ +#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) +#define STM32_BKPRAM_ENABLE FALSE +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief USB/SDIO clock setting. + */ +#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) +#define STM32_CLOCK48_REQUIRED TRUE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLLs. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 1..15. + * @note The default value is calculated for a 96MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 2 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 31..500. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 192 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 4, 8, 16, 32. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 8 +#endif + +/** + * @brief I2S clock source (post-PLL). + * @note Not all devices have this setting, it is alternative to + * @p STM32_PLLI2SSRC. + */ +#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) +#define STM32_I2SSRC STM32_I2SSRC_CKIN +#endif + +/** + * @brief I2S clock source (pre-PLL). + * @note Not all devices have this setting, it is alternative to + * @p STM32_I2SSRC. + */ +#if !defined(STM32_PLLI2SSRC) || defined(__DOXYGEN__) +#define STM32_PLLI2SSRC STM32_PLLI2SSRC_CKIN +#endif + +/** + * @brief I2S external clock value, zero if not present. + * @note Not all devices have this setting. + */ +#if !defined(STM32_I2SCKIN_VALUE) || defined(__DOXYGEN__) +#define STM32_I2SCKIN_VALUE 0 +#endif + +/** + * @brief PLLI2SN multiplier value. + * @note The allowed values are 192..432, except for + * STM32F446 where values are 50...432. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SN_VALUE 192 +#endif + +/** + * @brief PLLI2SM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SM_VALUE 4 +#endif + +/** + * @brief PLLI2SR divider value. + * @note The allowed values are 2..7. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SR_VALUE 4 +#endif + +/** + * @brief PLLI2SP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SP_VALUE 4 +#endif + +/** + * @brief PLLI2SQ divider value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SQ_VALUE 4 +#endif + +/** + * @brief PLLI2SDIVQ divider value (SAI clock divider). + * @note The allowed values are 1..32. + */ +#if !defined(STM32_PLLI2SDIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SDIVQ_VALUE 1 +#endif + +/** + * @brief PLLSAIM value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIM_VALUE 4 +#endif + +/** + * @brief PLLSAIN value. + * @note The allowed values are 50..432. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIN_VALUE 192 +#endif + +/** + * @brief PLLSAIM value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIM_VALUE 4 +#endif + +/** + * @brief PLLSAIR value. + * @note The allowed values are 2..7. + */ +#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIR_VALUE 4 +#endif + +/** + * @brief PLLSAIP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLSAIP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIP_VALUE 8 +#endif + +/** + * @brief PLLSAIQ value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIQ_VALUE 4 +#endif + +/** + * @brief PLLSAIDIVR divider value (SAI clock divider). + */ +#if !defined(STM32_PLLSAIDIVR) || defined(__DOXYGEN__) +#define STM32_PLLSAIDIVR STM32_PLLSAIDIVR_OFF +#endif + +/** + * @brief TIM prescaler clock source. + */ +#if !defined(STM32_TIMPRE) || defined(__DOXYGEN__) +#define STM32_TIMPRE STM32_TIMPRE_PCLK +#endif + +/** + * @brief PLL48CLK clock source. + */ +#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) +#define STM32_CK48MSEL STM32_CK48MSEL_PLL +#endif + +/** + * @brief AHB prescaler value. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief RTC HSE prescaler value. + */ +#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#define STM32_RTCPRE_VALUE 8 +#endif + +/** + * @brief MCO1 clock source value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#endif + +/** + * @brief MCO1 prescaler value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#endif + +/** + * @brief MCO2 clock source value. + * @note The default value outputs SYSCLK / 5 on MCO2 pin. + */ +#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#endif + +/** + * @brief MCO2 prescaler value. + * @note The default value outputs SYSCLK / 5 on MCO2 pin. + */ +#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if defined(STM32F4XX) || defined(__DOXYGEN__) +/* + * Configuration-related checks. + */ +#if !defined(STM32F4xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F4xx_MCUCONF not defined" +#endif + +#if defined(STM32F401xx) && !defined(STM32F401_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F401_MCUCONF not defined" +#endif + +#if defined(STM32F410xx) && !defined(STM32F410_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F410_MCUCONF not defined" +#endif + +#if defined(STM32F411xx) && !defined(STM32F411_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F411_MCUCONF not defined" +#endif + +#if defined(STM32F412xx) && !defined(STM32F412_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F412_MCUCONF not defined" +#endif + +#if defined(STM32F405xx) && !defined(STM32F405_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F405_MCUCONF not defined" +#endif + +#if defined(STM32F415xx) && !defined(STM32F415_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F415_MCUCONF not defined" +#endif + +#if defined(STM32F407xx) && !defined(STM32F407_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F407_MCUCONF not defined" +#endif + +#if defined(STM32F417xx) && !defined(STM32F417_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F417_MCUCONF not defined" +#endif + +#if defined(STM32F427xx) && !defined(STM32F427_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F427_MCUCONF not defined" +#endif + +#if defined(STM32F429xx) && !defined(STM32F429_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F429_MCUCONF not defined" +#endif + +#if defined(STM32F437xx) && !defined(STM32F437_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F437_MCUCONF not defined" +#endif + +#if defined(STM32F439xx) && !defined(STM32F439_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F439_MCUCONF not defined" +#endif + +#if defined(STM32F446xx) && !defined(STM32F446_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F446_MCUCONF not defined" +#endif + +#if defined(STM32F469xx) && !defined(STM32F469_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F469_MCUCONF not defined" +#endif + +#if defined(STM32F479xx) && !defined(STM32F479_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F479_MCUCONF not defined" +#endif + +#else /* !defined(STM32F4XX) */ +/* + * Configuration-related checks. + */ +#if !defined(STM32F2xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F2xx_MCUCONF not defined" +#endif +#endif /* !defined(STM32F4XX) */ + +/** + * @name Maximum frequency thresholds, wait states and + * parallelism for flash access. + * @{ + */ +#if defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(STM32F40_41xxx) || defined(STM32F446xx) || \ + defined(STM32F469_479xx) || defined(__DOXYGEN__) +#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 120000000 +#define STM32_4WS_THRESHOLD 150000000 +#define STM32_5WS_THRESHOLD 180000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 120000000 +#define STM32_5WS_THRESHOLD 144000000 +#define STM32_6WS_THRESHOLD 168000000 +#define STM32_7WS_THRESHOLD 180000000 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 22000000 +#define STM32_1WS_THRESHOLD 44000000 +#define STM32_2WS_THRESHOLD 66000000 +#define STM32_3WS_THRESHOLD 88000000 +#define STM32_4WS_THRESHOLD 110000000 +#define STM32_5WS_THRESHOLD 132000000 +#define STM32_6WS_THRESHOLD 154000000 +#define STM32_7WS_THRESHOLD 176000000 +#define STM32_8WS_THRESHOLD 180000000 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 120000000 +#define STM32_6WS_THRESHOLD 140000000 +#define STM32_7WS_THRESHOLD 168000000 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 +#else +#error "invalid VDD voltage specified" +#endif + +#elif defined(STM32F412xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 64000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 100000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 100000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 170) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 100000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 +#else +#error "invalid VDD voltage specified" +#endif + +#elif defined(STM32F410xx) || defined(STM32F411xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 64000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 100000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 100000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 171) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 100000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 + +#else +#error "invalid VDD voltage specified" +#endif + +#elif defined(STM32F401xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 84000000 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 + +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 84000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 + +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 84000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 + +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 84000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 + +#else +#error "invalid VDD voltage specified" +#endif + +#else /* STM32F2XX */ +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 120000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 120000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 108000000 +#define STM32_6WS_THRESHOLD 120000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 112000000 +#define STM32_7WS_THRESHOLD 120000000 +#define STM32_FLASH_PSIZE 0 + +#else +#error "invalid VDD voltage specified" +#endif +#endif /* STM32F2XX */ +/** @} */ + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2SSRC" +#endif + +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2SSRC" +#endif +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#else /* STM32_HSECLK != 0 */ +#if defined(STM32_HSE_BYPASS) +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" +#endif +#else /* !defined(STM32_HSE_BYPASS) */ +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif +#endif /* !defined(STM32_HSE_BYPASS) */ +#endif /* STM32_HSECLK != 0 */ +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ + ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_I2SSRC" +#endif + +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_PLLI2SSRC" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief Clock frequency feeding PLLs. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSRCCLK STM32_HSECLK +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLSRCCLK STM32_HSICLK +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM (STM32_PLLM_VALUE << 0) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#define STM32_PLLCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) + +/* + * PLLs input frequency range check. + */ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_CLOCK48_REQUIRED && \ + STM32_HAS_RCC_CK48MSEL && \ + (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ + (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 31) && (STM32_PLLN_VALUE <= 500)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 6) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 4) || defined(__DOXYGEN__) +#define STM32_PLLP STM32_PLLP_DIV4 +#elif STM32_PLLP_VALUE == 8 +#define STM32_PLLP STM32_PLLP_DIV8 +#elif STM32_PLLP_VALUE == 16 +#define STM32_PLLP STM32_PLLP_DIV16 +#elif STM32_PLLP_VALUE == 32 +#define STM32_PLLP STM32_PLLP_DIV32 +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) + +/* + * PLL output frequency range check. + */ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/* Calculating VOS settings, it is different for each sub-platform.*/ +#if defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(STM32F446xx) || defined(STM32F469_479xx) || \ + defined(__DOXYGEN__) +#if STM32_SYSCLK <= 120000000 +#define STM32_VOS STM32_VOS_SCALE3 +#define STM32_OVERDRIVE_REQUIRED FALSE +#elif STM32_SYSCLK <= 144000000 +#define STM32_VOS STM32_VOS_SCALE2 +#define STM32_OVERDRIVE_REQUIRED FALSE +#elif STM32_SYSCLK <= 168000000 +#define STM32_VOS STM32_VOS_SCALE1 +#define STM32_OVERDRIVE_REQUIRED FALSE +#else +#define STM32_VOS STM32_VOS_SCALE1 +#define STM32_OVERDRIVE_REQUIRED TRUE +#endif + +#elif defined(STM32F40_41xxx) +#if STM32_SYSCLK <= 144000000 +#define STM32_VOS STM32_VOS_SCALE2 +#else +#define STM32_VOS STM32_VOS_SCALE1 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE + +#elif defined(STM32F401xx) +#if STM32_SYSCLK <= 60000000 +#define STM32_VOS STM32_VOS_SCALE3 +#else +#define STM32_VOS STM32_VOS_SCALE2 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE + +#elif defined(STM32F410xx) || defined(STM32F411xx) || \ + defined(STM32F412xx) +#if STM32_SYSCLK <= 64000000 +#define STM32_VOS STM32_VOS_SCALE3 +#elif STM32_SYSCLK <= 84000000 +#define STM32_VOS STM32_VOS_SCALE2 +#else +#define STM32_VOS STM32_VOS_SCALE1 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE + +#else /* STM32F2XX */ +#define STM32_OVERDRIVE_REQUIRED FALSE +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_TYPE1_H */ + +/** @} */ diff --git a/os/hal/ports/AT32/AT32F4xx/platform.mk b/os/hal/ports/AT32/AT32F4xx/platform.mk new file mode 100644 index 0000000000..0ee6b39331 --- /dev/null +++ b/os/hal/ports/AT32/AT32F4xx/platform.mk @@ -0,0 +1,49 @@ +# Required platform files. +PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ + $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx/at32_isr.c \ + $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx/hal_lld.c \ + $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx/hal_efl_lld.c + +# Required include directories. +PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \ + $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx + +# Optional platform files. +ifeq ($(USE_SMART_BUILD),yes) + +# Configuration files directory +ifeq ($(HALCONFDIR),) + ifeq ($(CONFDIR),) + HALCONFDIR = . + else + HALCONFDIR := $(CONFDIR) + endif +endif + +HALCONF := $(strip $(shell cat $(HALCONFDIR)/halconf.h | egrep -e "\#define")) + +else +endif + +# Drivers compatible with the platform. +include $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv2/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk + +# Shared variables +ALLCSRC += $(PLATFORMSRC) +ALLINC += $(PLATFORMINC) diff --git a/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c index 248a9c3cc1..40d523dbc3 100644 --- a/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c @@ -1,447 +1,447 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv1/hal_rtc_lld.c - * @brief STM32 RTC subsystem low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#include "hal.h" - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief RTC driver identifier. - */ -RTCDriver RTCD1; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Wait for synchronization of RTC registers with APB1 bus. - * @details This function must be invoked before trying to read RTC registers - * in the backup domain: DIV, CNT, ALR. CR registers can always - * be read. - * - * @notapi - */ -static void rtc_apb1_sync(void) { - - while ((RTC->CRL & RTC_CRL_RSF) == 0) - ; -} - -/** - * @brief Wait for for previous write operation complete. - * @details This function must be invoked before writing to any RTC registers - * - * @notapi - */ -static void rtc_wait_write_completed(void) { - - while ((RTC->CRL & RTC_CRL_RTOFF) == 0) - ; -} - -/** - * @brief Acquires write access to RTC registers. - * @details Before writing to the backup domain RTC registers the previous - * write operation must be completed. Use this function before - * writing to PRL, CNT, ALR registers. - * - * @notapi - */ -static void rtc_acquire_access(void) { - - rtc_wait_write_completed(); - RTC->CRL |= RTC_CRL_CNF; -} - -/** - * @brief Releases write access to RTC registers. - * - * @notapi - */ -static void rtc_release_access(void) { - - RTC->CRL &= ~RTC_CRL_CNF; -} - -/** - * @brief Converts time from timespec to seconds counter. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the TR register encoding. - * - * @notapi - */ -static time_t rtc_encode(const RTCDateTime *timespec) { - struct tm tim; - - rtcConvertDateTimeToStructTm(timespec, &tim, NULL); - return mktime(&tim); -} - -/** - * @brief Converts time from seconds/milliseconds to timespec. - * - * @param[in] tv_sec seconds value - * @param[in] tv_msec milliseconds value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode(uint32_t tv_sec, - uint32_t tv_msec, - RTCDateTime *timespec) { - struct tm tim; - struct tm *t; - const time_t time = (const time_t)tv_sec; /* Could be 64 bits.*/ - - /* If the conversion is successful the function returns a pointer - to the object the result was written into.*/ -#if defined(__GNUC__) || defined(__CC_ARM) - t = localtime_r(&time, &tim); - osalDbgAssert(t != NULL, "conversion failed"); -#else - t = localtime(&time); - memcpy(&tim, t, sizeof(struct tm)); -#endif - - rtcConvertStructTmToDateTime(&tim, tv_msec, timespec); -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/** - * @brief RTC interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC1_HANDLER) { - uint16_t flags; - - OSAL_IRQ_PROLOGUE(); - - /* Code hits this wait only when AHB1 bus was previously powered off by any - reason (standby, reset, etc). In other cases there is no waiting.*/ - rtc_apb1_sync(); - - /* Mask of all enabled and pending sources.*/ - flags = RTCD1.rtc->CRH & RTCD1.rtc->CRL; - RTCD1.rtc->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); - - if (flags & RTC_CRL_SECF) - RTCD1.callback(&RTCD1, RTC_EVENT_SECOND); - - if (flags & RTC_CRL_ALRF) - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM); - - if (flags & RTC_CRL_OWF) - RTCD1.callback(&RTCD1, RTC_EVENT_OVERFLOW); - - OSAL_IRQ_EPILOGUE(); -} - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Load value of RTCCLK to prescaler registers. - * @note The pre-scaler must not be set on every reset as RTC clock - * counts are lost when it is set. - * @note This function designed to be called from - * hal_lld_backup_domain_init(). Because there is only place - * where possible to detect BKP domain reset event reliably. - * - * @notapi - */ -void rtc_lld_set_prescaler(void) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - rtc_acquire_access(); - RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16) & 0x000F; - RTC->PRLL = (uint16_t)(((STM32_RTCCLK - 1)) & 0xFFFF); - rtc_release_access(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Initialize RTC. - * - * @notapi - */ -void rtc_lld_init(void) { - - /* RTC object initialization.*/ - rtcObjectInit(&RTCD1); - - /* RTC pointer initialization.*/ - RTCD1.rtc = RTC; - - /* RSF bit must be cleared by software after an APB1 reset or an APB1 clock - stop. Otherwise its value will not be actual. */ - RTCD1.rtc->CRL &= ~RTC_CRL_RSF; - - /* Required because access to PRL.*/ - rtc_apb1_sync(); - - /* All interrupts initially disabled.*/ - rtc_wait_write_completed(); - RTCD1.rtc->CRH = 0; - - /* Callback initially disabled.*/ - RTCD1.callback = NULL; - - /* IRQ vector permanently assigned to this driver.*/ - nvicEnableVector(STM32_RTC1_NUMBER, STM32_RTC_IRQ_PRIORITY); -} - -/** - * @brief Set current time. - * @note Fractional part will be silently ignored. There is no possibility - * to change it on STM32F1xx platform. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { - time_t tv_sec = rtc_encode(timespec); - - rtcSTM32SetSec(rtcp, tv_sec); -} - -/** - * @brief Get current time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { - uint32_t tv_sec, tv_msec; - - rtcSTM32GetSecMsec(rtcp, &tv_sec, &tv_msec); - rtc_decode(tv_sec, tv_msec, timespec); -} - -/** - * @brief Set alarm time. - * - * @note Default value after BKP domain reset is 0xFFFFFFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier - * @param[in] alarmspec pointer to a @p RTCAlarm structure - * - * @notapi - */ -void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm_number, - const RTCAlarm *alarmspec) { - syssts_t sts; - (void)alarm_number; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - rtc_acquire_access(); - if (alarmspec != NULL) { - rtcp->rtc->ALRH = (uint16_t)(alarmspec->tv_sec >> 16); - rtcp->rtc->ALRL = (uint16_t)(alarmspec->tv_sec & 0xFFFF); - } - else { - rtcp->rtc->ALRH = 0; - rtcp->rtc->ALRL = 0; - } - rtc_release_access(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get current alarm. - * @note If an alarm has not been set then the returned alarm specification - * is not meaningful. - * @note The function can be called from any context. - * @note Default value after BKP domain reset is 0xFFFFFFFF. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier - * @param[out] alarmspec pointer to a @p RTCAlarm structure - * - * @notapi - */ -void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm_number, - RTCAlarm *alarmspec) { - syssts_t sts; - (void)alarm_number; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Required because access to ALR.*/ - rtc_apb1_sync(); - - alarmspec->tv_sec = ((rtcp->rtc->ALRH << 16) + rtcp->rtc->ALRL); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Enables or disables RTC callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] callback callback function pointer or @p NULL - * - * @notapi - */ -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (callback != NULL) { - - /* IRQ sources enabled only after setting up the callback.*/ - rtcp->callback = callback; - - rtc_wait_write_completed(); - rtcp->rtc->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF); - rtcp->rtc->CRH = RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE; - } - else { - rtc_wait_write_completed(); - rtcp->rtc->CRH = 0; - - /* Callback set to NULL only after disabling the IRQ sources.*/ - rtcp->callback = NULL; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get seconds and (optionally) milliseconds from RTC. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] tv_sec pointer to seconds value - * @param[out] tv_msec pointer to milliseconds value, set it - * to @p NULL if not needed - * - * @api - */ -void rtcSTM32GetSecMsec(RTCDriver *rtcp, uint32_t *tv_sec, uint32_t *tv_msec) { - uint32_t time_frac; - syssts_t sts; - - osalDbgCheck((NULL != tv_sec) && (NULL != rtcp)); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Required because access to CNT and DIV.*/ - rtc_apb1_sync(); - - /* wait for previous write accesses to complete.*/ - rtc_wait_write_completed(); - - /* Loops until two consecutive read returning the same value.*/ - do { - *tv_sec = ((uint32_t)(rtcp->rtc->CNTH) << 16) + rtcp->rtc->CNTL; - time_frac = (((uint32_t)rtcp->rtc->DIVH) << 16) + (uint32_t)rtcp->rtc->DIVL; - } while ((*tv_sec) != (((uint32_t)(rtcp->rtc->CNTH) << 16) + rtcp->rtc->CNTL)); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - if (NULL != tv_msec) - *tv_msec = (((uint32_t)STM32_RTCCLK - 1 - time_frac) * 1000) / STM32_RTCCLK; -} - -/** - * @brief Set seconds in RTC. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] tv_sec seconds value - * - * @api - */ -void rtcSTM32SetSec(RTCDriver *rtcp, uint32_t tv_sec) { - syssts_t sts; - - osalDbgCheck(NULL != rtcp); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - rtc_acquire_access(); - rtcp->rtc->CNTH = (uint16_t)(tv_sec >> 16); - rtcp->rtc->CNTL = (uint16_t)(tv_sec & 0xFFFF); - rtc_release_access(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -#endif /* HAL_USE_RTC */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv1/hal_rtc_lld.c + * @brief STM32 RTC subsystem low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief RTC driver identifier. + */ +RTCDriver RTCD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Wait for synchronization of RTC registers with APB1 bus. + * @details This function must be invoked before trying to read RTC registers + * in the backup domain: DIV, CNT, ALR. CR registers can always + * be read. + * + * @notapi + */ +static void rtc_apb1_sync(void) { + + while ((RTC->CRL & RTC_CRL_RSF) == 0) + ; +} + +/** + * @brief Wait for for previous write operation complete. + * @details This function must be invoked before writing to any RTC registers + * + * @notapi + */ +static void rtc_wait_write_completed(void) { + + while ((RTC->CRL & RTC_CRL_RTOFF) == 0) + ; +} + +/** + * @brief Acquires write access to RTC registers. + * @details Before writing to the backup domain RTC registers the previous + * write operation must be completed. Use this function before + * writing to PRL, CNT, ALR registers. + * + * @notapi + */ +static void rtc_acquire_access(void) { + + rtc_wait_write_completed(); + RTC->CRL |= RTC_CRL_CNF; +} + +/** + * @brief Releases write access to RTC registers. + * + * @notapi + */ +static void rtc_release_access(void) { + + RTC->CRL &= ~RTC_CRL_CNF; +} + +/** + * @brief Converts time from timespec to seconds counter. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the TR register encoding. + * + * @notapi + */ +static time_t rtc_encode(const RTCDateTime *timespec) { + struct tm tim; + + rtcConvertDateTimeToStructTm(timespec, &tim, NULL); + return mktime(&tim); +} + +/** + * @brief Converts time from seconds/milliseconds to timespec. + * + * @param[in] tv_sec seconds value + * @param[in] tv_msec milliseconds value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode(uint32_t tv_sec, + uint32_t tv_msec, + RTCDateTime *timespec) { + struct tm tim; + struct tm *t; + const time_t time = (const time_t)tv_sec; /* Could be 64 bits.*/ + + /* If the conversion is successful the function returns a pointer + to the object the result was written into.*/ +#if defined(__GNUC__) || defined(__CC_ARM) + t = localtime_r(&time, &tim); + osalDbgAssert(t != NULL, "conversion failed"); +#else + t = localtime(&time); + memcpy(&tim, t, sizeof(struct tm)); +#endif + + rtcConvertStructTmToDateTime(&tim, tv_msec, timespec); +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief RTC interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC1_HANDLER) { + uint16_t flags; + + OSAL_IRQ_PROLOGUE(); + + /* Code hits this wait only when AHB1 bus was previously powered off by any + reason (standby, reset, etc). In other cases there is no waiting.*/ + rtc_apb1_sync(); + + /* Mask of all enabled and pending sources.*/ + flags = RTCD1.rtc->CRH & RTCD1.rtc->CRL; + RTCD1.rtc->CRL &= ~(RTC_CRL_SECF | RTC_CRL_ALRF | RTC_CRL_OWF); + + if (flags & RTC_CRL_SECF) + RTCD1.callback(&RTCD1, RTC_EVENT_SECOND); + + if (flags & RTC_CRL_ALRF) + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM); + + if (flags & RTC_CRL_OWF) + RTCD1.callback(&RTCD1, RTC_EVENT_OVERFLOW); + + OSAL_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Load value of RTCCLK to prescaler registers. + * @note The pre-scaler must not be set on every reset as RTC clock + * counts are lost when it is set. + * @note This function designed to be called from + * hal_lld_backup_domain_init(). Because there is only place + * where possible to detect BKP domain reset event reliably. + * + * @notapi + */ +void rtc_lld_set_prescaler(void) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + rtc_acquire_access(); + RTC->PRLH = (uint16_t)((STM32_RTCCLK - 1) >> 16) & 0x000F; + RTC->PRLL = (uint16_t)(((STM32_RTCCLK - 1)) & 0xFFFF); + rtc_release_access(); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Initialize RTC. + * + * @notapi + */ +void rtc_lld_init(void) { + + /* RTC object initialization.*/ + rtcObjectInit(&RTCD1); + + /* RTC pointer initialization.*/ + RTCD1.rtc = RTC; + + /* RSF bit must be cleared by software after an APB1 reset or an APB1 clock + stop. Otherwise its value will not be actual. */ + RTCD1.rtc->CRL &= ~RTC_CRL_RSF; + + /* Required because access to PRL.*/ + rtc_apb1_sync(); + + /* All interrupts initially disabled.*/ + rtc_wait_write_completed(); + RTCD1.rtc->CRH = 0; + + /* Callback initially disabled.*/ + RTCD1.callback = NULL; + + /* IRQ vector permanently assigned to this driver.*/ + nvicEnableVector(STM32_RTC1_NUMBER, STM32_RTC_IRQ_PRIORITY); +} + +/** + * @brief Set current time. + * @note Fractional part will be silently ignored. There is no possibility + * to change it on STM32F1xx platform. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { + time_t tv_sec = rtc_encode(timespec); + + rtcSTM32SetSec(rtcp, tv_sec); +} + +/** + * @brief Get current time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { + uint32_t tv_sec, tv_msec; + + rtcSTM32GetSecMsec(rtcp, &tv_sec, &tv_msec); + rtc_decode(tv_sec, tv_msec, timespec); +} + +/** + * @brief Set alarm time. + * + * @note Default value after BKP domain reset is 0xFFFFFFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[in] alarmspec pointer to a @p RTCAlarm structure + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm_number, + const RTCAlarm *alarmspec) { + syssts_t sts; + (void)alarm_number; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + rtc_acquire_access(); + if (alarmspec != NULL) { + rtcp->rtc->ALRH = (uint16_t)(alarmspec->tv_sec >> 16); + rtcp->rtc->ALRL = (uint16_t)(alarmspec->tv_sec & 0xFFFF); + } + else { + rtcp->rtc->ALRH = 0; + rtcp->rtc->ALRL = 0; + } + rtc_release_access(); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get current alarm. + * @note If an alarm has not been set then the returned alarm specification + * is not meaningful. + * @note The function can be called from any context. + * @note Default value after BKP domain reset is 0xFFFFFFFF. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier + * @param[out] alarmspec pointer to a @p RTCAlarm structure + * + * @notapi + */ +void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm_number, + RTCAlarm *alarmspec) { + syssts_t sts; + (void)alarm_number; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Required because access to ALR.*/ + rtc_apb1_sync(); + + alarmspec->tv_sec = ((rtcp->rtc->ALRH << 16) + rtcp->rtc->ALRL); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Enables or disables RTC callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL + * + * @notapi + */ +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (callback != NULL) { + + /* IRQ sources enabled only after setting up the callback.*/ + rtcp->callback = callback; + + rtc_wait_write_completed(); + rtcp->rtc->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF); + rtcp->rtc->CRH = RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE; + } + else { + rtc_wait_write_completed(); + rtcp->rtc->CRH = 0; + + /* Callback set to NULL only after disabling the IRQ sources.*/ + rtcp->callback = NULL; + } + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get seconds and (optionally) milliseconds from RTC. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] tv_sec pointer to seconds value + * @param[out] tv_msec pointer to milliseconds value, set it + * to @p NULL if not needed + * + * @api + */ +void rtcSTM32GetSecMsec(RTCDriver *rtcp, uint32_t *tv_sec, uint32_t *tv_msec) { + uint32_t time_frac; + syssts_t sts; + + osalDbgCheck((NULL != tv_sec) && (NULL != rtcp)); + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Required because access to CNT and DIV.*/ + rtc_apb1_sync(); + + /* wait for previous write accesses to complete.*/ + rtc_wait_write_completed(); + + /* Loops until two consecutive read returning the same value.*/ + do { + *tv_sec = ((uint32_t)(rtcp->rtc->CNTH) << 16) + rtcp->rtc->CNTL; + time_frac = (((uint32_t)rtcp->rtc->DIVH) << 16) + (uint32_t)rtcp->rtc->DIVL; + } while ((*tv_sec) != (((uint32_t)(rtcp->rtc->CNTH) << 16) + rtcp->rtc->CNTL)); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); + + if (NULL != tv_msec) + *tv_msec = (((uint32_t)STM32_RTCCLK - 1 - time_frac) * 1000) / STM32_RTCCLK; +} + +/** + * @brief Set seconds in RTC. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] tv_sec seconds value + * + * @api + */ +void rtcSTM32SetSec(RTCDriver *rtcp, uint32_t tv_sec) { + syssts_t sts; + + osalDbgCheck(NULL != rtcp); + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + rtc_acquire_access(); + rtcp->rtc->CNTH = (uint16_t)(tv_sec >> 16); + rtcp->rtc->CNTL = (uint16_t)(tv_sec & 0xFFFF); + rtc_release_access(); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h b/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h index 09263156d0..7e8b35dd58 100644 --- a/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h +++ b/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.h @@ -1,152 +1,152 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv1/hal_rtc_lld.h - * @brief STM32 RTC subsystem low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#ifndef HAL_RTC_LLD_H -#define HAL_RTC_LLD_H - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Implementation capabilities - */ -/** - * @brief This RTC implementation supports callbacks. - */ -#define RTC_SUPPORTS_CALLBACKS TRUE - -/** - * @brief One alarm comparator available. - */ -#define RTC_ALARMS 1 - -/** - * @brief Presence of a local persistent storage. - */ -#define RTC_HAS_STORAGE FALSE -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/* - * RTC driver system settings. - */ -#define STM32_RTC_IRQ_PRIORITY 15 -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if HAL_USE_RTC && !STM32_HAS_RTC -#error "RTC not present in the selected device" -#endif - -#if STM32_RTCCLK == 0 -#error "RTC clock not enabled" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an RTC event. - */ -typedef enum { - RTC_EVENT_SECOND = 0, /** Triggered every second. */ - RTC_EVENT_ALARM = 1, /** Triggered on alarm. */ - RTC_EVENT_OVERFLOW = 2 /** Triggered on counter overflow. */ -} rtcevent_t; - -/** - * @brief Type of a generic RTC callback. - */ -typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); - -/** - * @brief Type of a structure representing an RTC alarm time stamp. - */ -typedef struct hal_rtc_alarm { - /** - * @brief Seconds since UNIX epoch. - */ - uint32_t tv_sec; -} RTCAlarm; - -/** - * @brief Implementation-specific @p RTCDriver fields. - */ -#define rtc_lld_driver_fields \ - /* Pointer to the RTC registers block.*/ \ - RTC_TypeDef *rtc; \ - /* Callback pointer.*/ \ - rtccb_t callback - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void rtc_lld_set_prescaler(void); - void rtc_lld_init(void); - void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); - void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); - void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm_number, - const RTCAlarm *alarmspec); - void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm_number, - RTCAlarm *alarmspec); - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); - void rtcSTM32GetSecMsec(RTCDriver *rtcp, uint32_t *tv_sec, uint32_t *tv_msec); - void rtcSTM32SetSec(RTCDriver *rtcp, uint32_t tv_sec); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_RTC */ - -#endif /* HAL_RTC_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv1/hal_rtc_lld.h + * @brief STM32 RTC subsystem low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#ifndef HAL_RTC_LLD_H +#define HAL_RTC_LLD_H + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Implementation capabilities + */ +/** + * @brief This RTC implementation supports callbacks. + */ +#define RTC_SUPPORTS_CALLBACKS TRUE + +/** + * @brief One alarm comparator available. + */ +#define RTC_ALARMS 1 + +/** + * @brief Presence of a local persistent storage. + */ +#define RTC_HAS_STORAGE FALSE +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/* + * RTC driver system settings. + */ +#define STM32_RTC_IRQ_PRIORITY 15 +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if HAL_USE_RTC && !STM32_HAS_RTC +#error "RTC not present in the selected device" +#endif + +#if STM32_RTCCLK == 0 +#error "RTC clock not enabled" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an RTC event. + */ +typedef enum { + RTC_EVENT_SECOND = 0, /** Triggered every second. */ + RTC_EVENT_ALARM = 1, /** Triggered on alarm. */ + RTC_EVENT_OVERFLOW = 2 /** Triggered on counter overflow. */ +} rtcevent_t; + +/** + * @brief Type of a generic RTC callback. + */ +typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); + +/** + * @brief Type of a structure representing an RTC alarm time stamp. + */ +typedef struct hal_rtc_alarm { + /** + * @brief Seconds since UNIX epoch. + */ + uint32_t tv_sec; +} RTCAlarm; + +/** + * @brief Implementation-specific @p RTCDriver fields. + */ +#define rtc_lld_driver_fields \ + /* Pointer to the RTC registers block.*/ \ + RTC_TypeDef *rtc; \ + /* Callback pointer.*/ \ + rtccb_t callback + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void rtc_lld_set_prescaler(void); + void rtc_lld_init(void); + void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); + void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); + void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm_number, + const RTCAlarm *alarmspec); + void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm_number, + RTCAlarm *alarmspec); + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); + void rtcSTM32GetSecMsec(RTCDriver *rtcp, uint32_t *tv_sec, uint32_t *tv_msec); + void rtcSTM32SetSec(RTCDriver *rtcp, uint32_t tv_sec); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_RTC */ + +#endif /* HAL_RTC_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c index 79807ecb97..12c5d32f42 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c @@ -1,854 +1,854 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv2/hal_rtc_lld.c - * @brief STM32 RTC low level driver. - * - * @addtogroup RTC - * @{ - */ - -#include "hal.h" - -// If you enable subseconds, there is a chance that this code will hang while locked (!) -// See https://github.com/rusefi/rusefi/issues/4557 -#undef STM32_RTC_HAS_SUBSECONDS -#define STM32_RTC_HAS_SUBSECONDS FALSE - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define RTC_TR_PM_OFFSET 22 -#define RTC_TR_HT_OFFSET 20 -#define RTC_TR_HU_OFFSET 16 -#define RTC_TR_MNT_OFFSET 12 -#define RTC_TR_MNU_OFFSET 8 -#define RTC_TR_ST_OFFSET 4 -#define RTC_TR_SU_OFFSET 0 - -#define RTC_DR_YT_OFFSET 20 -#define RTC_DR_YU_OFFSET 16 -#define RTC_DR_WDU_OFFSET 13 -#define RTC_DR_MT_OFFSET 12 -#define RTC_DR_MU_OFFSET 8 -#define RTC_DR_DT_OFFSET 4 -#define RTC_DR_DU_OFFSET 0 - -#define RTC_CR_BKP_OFFSET 18 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief RTC driver identifier. - */ -RTCDriver RTCD1; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Beginning of configuration procedure. - * - * @notapi - */ -static void rtc_enter_init(void) { - - RTCD1.rtc->ISR |= RTC_ISR_INIT; - while ((RTCD1.rtc->ISR & RTC_ISR_INITF) == 0) - ; -} - -/** - * @brief Finalizing of configuration procedure. - * - * @notapi - */ -static inline void rtc_exit_init(void) { - - RTCD1.rtc->ISR &= ~RTC_ISR_INIT; -} - -/** - * @brief Converts time from TR register encoding to timespec. - * - * @param[in] tr TR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) { - uint32_t n; - - n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000; - n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000; - n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000; - n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000; - n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000; - n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000; - timespec->millisecond = n; -} - -/** - * @brief Converts date from DR register encoding to timespec. - * - * @param[in] dr DR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) { - - timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) + - ((dr >> RTC_DR_YU_OFFSET) & 15); - timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) + - ((dr >> RTC_TR_MNU_OFFSET) & 15); - timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) + - ((dr >> RTC_DR_DU_OFFSET) & 15); - timespec->dayofweek = (dr >> RTC_DR_WDU_OFFSET) & 7; -} - -/** - * @brief Converts time from timespec to TR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the TR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_time(const RTCDateTime *timespec) { - uint32_t n, tr = 0; - - /* Subseconds cannot be set.*/ - n = timespec->millisecond / 1000; - - /* Seconds conversion.*/ - tr = tr | ((n % 10) << RTC_TR_SU_OFFSET); - n /= 10; - tr = tr | ((n % 6) << RTC_TR_ST_OFFSET); - n /= 6; - - /* Minutes conversion.*/ - tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET); - n /= 10; - tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET); - n /= 6; - - /* Hours conversion.*/ - tr = tr | ((n % 10) << RTC_TR_HU_OFFSET); - n /= 10; - tr = tr | (n << RTC_TR_HT_OFFSET); - - return tr; -} - -/** - * @brief Converts a date from timespec to DR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the DR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_date(const RTCDateTime *timespec) { - uint32_t n, dr = 0; - - /* Year conversion. Note, only years last two digits are considered.*/ - n = timespec->year; - dr = dr | ((n % 10) << RTC_DR_YU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_YT_OFFSET); - - /* Months conversion.*/ - n = timespec->month; - dr = dr | ((n % 10) << RTC_DR_MU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_MT_OFFSET); - - /* Days conversion.*/ - n = timespec->day; - dr = dr | ((n % 10) << RTC_DR_DU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_DT_OFFSET); - - /* Days of week conversion.*/ - dr = dr | (timespec->dayofweek << RTC_DR_WDU_OFFSET); - - return dr; -} - -#if RTC_HAS_STORAGE == TRUE -static size_t _getsize(void *instance) { - - (void)instance; - - return (size_t)STM32_RTC_STORAGE_SIZE; -} - -static ps_error_t _read(void *instance, ps_offset_t offset, - size_t n, uint8_t *rp) { - volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; - unsigned i; - - osalDbgCheck((instance != NULL) && (rp != NULL)); - osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); - osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && - (offset + n <= STM32_RTC_STORAGE_SIZE)); - - for (i = 0; i < (unsigned)n; i++) { - unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); - unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); - *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U)); - } - - return PS_NO_ERROR; -} - -static ps_error_t _write(void *instance, ps_offset_t offset, - size_t n, const uint8_t *wp) { - volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; - unsigned i; - - osalDbgCheck((instance != NULL) && (wp != NULL)); - osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); - osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && - (offset + n <= STM32_RTC_STORAGE_SIZE)); - - for (i = 0; i < (unsigned)n; i++) { - unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); - unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); - uint32_t regval = bkpr[index]; - regval &= ~(0xFFU << (shift * 8U)); - regval |= (uint32_t)*wp++ << (shift * 8U); - bkpr[index] = regval; - } - - return PS_NO_ERROR; -} - -/** - * @brief VMT for the RTC storage file interface. - */ -struct RTCDriverVMT _rtc_lld_vmt = { - (size_t)0, - _getsize, _read, _write -}; -#endif /* RTC_HAS_STORAGE == TRUE */ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if defined(STM32_RTC_COMMON_HANDLER) -#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) -/** - * @brief RTC common interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { - uint32_t isr, clear; - - OSAL_IRQ_PROLOGUE(); - - clear = (0U - | RTC_ISR_TSF - | RTC_ISR_TSOVF -#if defined(RTC_ISR_TAMP1F) - | RTC_ISR_TAMP1F -#endif -#if defined(RTC_ISR_TAMP2F) - | RTC_ISR_TAMP2F -#endif -#if defined(RTC_ISR_TAMP3F) - | RTC_ISR_TAMP3F -#endif -#if defined(RTC_ISR_WUTF) - | RTC_ISR_WUTF -#endif -#if defined(RTC_ISR_ALRAF) - | RTC_ISR_ALRAF -#endif -#if defined(RTC_ISR_ALRBF) - | RTC_ISR_ALRBF -#endif - ); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~clear; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | - EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | - EXTI_MASK1(STM32_RTC_WKUP_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr = RTCD1.rtc->CR; - uint32_t tcr; - -#if defined(RTC_ISR_WUTF) - if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); - } -#endif - -#if defined(RTC_ISR_ALRAF) - if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); - } -#endif -#if defined(RTC_ISR_ALRBF) - if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); - } -#endif - - if ((cr & RTC_CR_TSIE) != 0U) { - if ((isr & RTC_ISR_TSF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS); - } - if ((isr & RTC_ISR_TSOVF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); - } - } - - /* This part is different depending on if the RTC has a TAMPCR or TAFCR - register.*/ -#if defined(RTC_TAFCR_TAMP1E) - tcr = RTCD1.rtc->TAFCR; - if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { -#if defined(RTC_ISR_TAMP1F) - if ((isr & RTC_ISR_TAMP1F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if ((isr & RTC_ISR_TAMP2F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif - } - -#else /* !defined(RTC_TAFCR_TAMP1E) */ - tcr = RTCD1.rtc->TAMPCR; -#if defined(RTC_ISR_TAMP1F) - if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && - ((isr & RTC_ISR_TAMP1F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && - ((isr & RTC_ISR_TAMP2F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif -#if defined(RTC_ISR_TAMP3F) - if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && - ((isr & RTC_ISR_TAMP3F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); - } -#endif -#endif /* !defined(RTC_TAFCR_TAMP1E) */ - } - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ - -#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ - defined(STM32_RTC_WKUP_HANDLER) && \ - defined(STM32_RTC_ALARM_HANDLER) -/** - * @brief RTC TAMP/STAMP interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { - uint32_t isr, clear; - - OSAL_IRQ_PROLOGUE(); - - clear = (0U - | RTC_ISR_TSF - | RTC_ISR_TSOVF -#if defined(RTC_ISR_TAMP1F) - | RTC_ISR_TAMP1F -#endif -#if defined(RTC_ISR_TAMP2F) - | RTC_ISR_TAMP2F -#endif -#if defined(RTC_ISR_TAMP3F) - | RTC_ISR_TAMP3F -#endif - ); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~clear; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr, tcr; - - cr = RTCD1.rtc->CR; - if ((cr & RTC_CR_TSIE) != 0U) { - if ((isr & RTC_ISR_TSF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS); - } - if ((isr & RTC_ISR_TSOVF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); - } - } - - /* This part is different depending on if the RTC has a TAMPCR or TAFCR - register.*/ -#if defined(RTC_TAFCR_TAMP1E) - tcr = RTCD1.rtc->TAFCR; - if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { -#if defined(RTC_ISR_TAMP1F) - if ((isr & RTC_ISR_TAMP1F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if ((isr & RTC_ISR_TAMP2F) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif - } - -#else /* !defined(RTC_TAFCR_TAMP1E) */ - tcr = RTCD1.rtc->TAMPCR; -#if defined(RTC_ISR_TAMP1F) - if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && - ((isr & RTC_ISR_TAMP1F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(RTC_ISR_TAMP2F) - if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && - ((isr & RTC_ISR_TAMP2F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif -#if defined(RTC_ISR_TAMP3F) - if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && - ((isr & RTC_ISR_TAMP3F) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); - } -#endif -#endif /* !defined(RTC_TAFCR_TAMP1E) */ - } - - OSAL_IRQ_EPILOGUE(); -} -/** - * @brief RTC wakeup interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { - uint32_t isr; - - OSAL_IRQ_PROLOGUE(); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~RTC_ISR_WUTF; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_WKUP_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr = RTCD1.rtc->CR; - - if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); - } - } - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief RTC alarm interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { - uint32_t isr, clear; - - OSAL_IRQ_PROLOGUE(); - - clear = (0U -#if defined(RTC_ISR_ALRAF) - | RTC_ISR_ALRAF -#endif -#if defined(RTC_ISR_ALRBF) - | RTC_ISR_ALRBF -#endif - ); - - isr = RTCD1.rtc->ISR; - RTCD1.rtc->ISR = isr & ~clear; - - extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI)); - - if (RTCD1.callback != NULL) { - uint32_t cr = RTCD1.rtc->CR; -#if defined(RTC_ISR_ALRAF) - if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); - } -#endif -#if defined(RTC_ISR_ALRBF) - if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); - } -#endif - } - - OSAL_IRQ_EPILOGUE(); -} - -#else -#error "missing required RTC handlers definitions in registry" -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Enable access to registers. - * - * @notapi - */ -void rtc_lld_init(void) { - - /* RTC object initialization.*/ - rtcObjectInit(&RTCD1); - - /* RTC pointer initialization.*/ - RTCD1.rtc = RTC; - - /* Disable write protection. */ - RTCD1.rtc->WPR = 0xCA; - RTCD1.rtc->WPR = 0x53; - - /* If calendar has not been initialized yet then proceed with the - initial setup.*/ - if (!(RTCD1.rtc->ISR & RTC_ISR_INITS)) { - - rtc_enter_init(); - - RTCD1.rtc->CR = STM32_RTC_CR_INIT; -#if defined(RTC_TAFCR_TAMP1E) - RTCD1.rtc->TAFCR = STM32_RTC_TAMPCR_INIT; -#else - RTCD1.rtc->TAMPCR = STM32_RTC_TAMPCR_INIT; -#endif - RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */ - RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; - RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; - - rtc_exit_init(); - } - else { - RTCD1.rtc->ISR &= ~RTC_ISR_RSF; - } - - /* Callback initially disabled.*/ - RTCD1.callback = NULL; - - /* Enabling RTC-related EXTI lines.*/ - extiEnableGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | - EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | - EXTI_MASK1(STM32_RTC_WKUP_EXTI), - EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); - - /* IRQ vectors permanently assigned to this driver.*/ - STM32_RTC_IRQ_ENABLE(); -} - -/** - * @brief Set current time. - * @note Fractional part will be silently ignored. There is no possibility - * to set it on STM32 platform. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { - uint32_t dr, tr; - syssts_t sts; - - tr = rtc_encode_time(timespec); - dr = rtc_encode_date(timespec); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Writing the registers.*/ - rtc_enter_init(); - rtcp->rtc->TR = tr; - rtcp->rtc->DR = dr; - rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) | - (timespec->dstflag << RTC_CR_BKP_OFFSET); - rtc_exit_init(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get current time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { - uint32_t dr, tr, cr; - uint32_t subs; -#if STM32_RTC_HAS_SUBSECONDS - uint32_t oldssr, ssr; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Synchronization with the RTC and reading the registers, note - DR must be read last.*/ - while ((rtcp->rtc->ISR & RTC_ISR_RSF) == 0) - ; -#if STM32_RTC_HAS_SUBSECONDS - oldssr = rtcp->rtc->SSR; - do -#endif /* STM32_RTC_HAS_SUBSECONDS */ - { - tr = rtcp->rtc->TR; - dr = rtcp->rtc->DR; - cr = rtcp->rtc->CR; - } -#if STM32_RTC_HAS_SUBSECONDS - while (oldssr != (ssr = rtcp->rtc->SSR)); -#endif /* STM32_RTC_HAS_SUBSECONDS */ - rtcp->rtc->ISR &= ~RTC_ISR_RSF; - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - /* Decoding day time, this starts the atomic read sequence, see "Reading - the calendar" in the RTC documentation.*/ - rtc_decode_time(tr, timespec); - - /* If the RTC is capable of sub-second counting then the value is - normalized in milliseconds and added to the time.*/ -#if STM32_RTC_HAS_SUBSECONDS - subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE; -#else - subs = 0; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - timespec->millisecond += subs; - - /* Decoding date, this concludes the atomic read sequence.*/ - rtc_decode_date(dr, timespec); - - /* Retrieving the DST bit.*/ - timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1; -} - -#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) -/** - * @brief Set alarm time. - * @note Default value after BKP domain reset for both comparators is 0. - * @note Function does not performs any checks of alarm time validity. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] alarm alarm identifier. Can be 0 or 1. - * @param[in] alarmspec pointer to a @p RTCAlarm structure. - * - * @notapi - */ -void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (alarm == 0) { - if (alarmspec != NULL) { - rtcp->rtc->CR &= ~RTC_CR_ALRAE; - while (!(rtcp->rtc->ISR & RTC_ISR_ALRAWF)) - ; - rtcp->rtc->ALRMAR = alarmspec->alrmr; - rtcp->rtc->CR |= RTC_CR_ALRAE; - rtcp->rtc->CR |= RTC_CR_ALRAIE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_ALRAIE; - rtcp->rtc->CR &= ~RTC_CR_ALRAE; - } - } -#if RTC_ALARMS > 1 - else { - if (alarmspec != NULL) { - rtcp->rtc->CR &= ~RTC_CR_ALRBE; - while (!(rtcp->rtc->ISR & RTC_ISR_ALRBWF)) - ; - rtcp->rtc->ALRMBR = alarmspec->alrmr; - rtcp->rtc->CR |= RTC_CR_ALRBE; - rtcp->rtc->CR |= RTC_CR_ALRBIE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_ALRBIE; - rtcp->rtc->CR &= ~RTC_CR_ALRBE; - } - } -#endif /* RTC_ALARMS > 1 */ - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get alarm time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier. Can be 0 or 1. - * @param[out] alarmspec pointer to a @p RTCAlarm structure - * - * @notapi - */ -void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec) { - - if (alarm == 0) - alarmspec->alrmr = rtcp->rtc->ALRMAR; -#if RTC_ALARMS > 1 - else - alarmspec->alrmr = rtcp->rtc->ALRMBR; -#endif /* RTC_ALARMS > 1 */ -} -#endif /* RTC_ALARMS > 0 */ - -/** - * @brief Enables or disables RTC callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] callback callback function pointer or @p NULL - * - * @notapi - */ -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { - - rtcp->callback = callback; -} - -#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) -/** - * @brief Sets time of periodic wakeup. - * @note Default value after BKP domain reset is 0x0000FFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] wakeupspec pointer to a @p RTCWakeup structure - * - * @api - */ -void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (wakeupspec != NULL) { - osalDbgCheck(wakeupspec->wutr != 0x30000); - - rtcp->rtc->CR &= ~RTC_CR_WUTE; - rtcp->rtc->CR &= ~RTC_CR_WUTIE; - while (!(rtcp->rtc->ISR & RTC_ISR_WUTWF)) - ; - rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF; - rtcp->rtc->CR &= ~RTC_CR_WUCKSEL; - rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL; - rtcp->rtc->CR |= RTC_CR_WUTIE; - rtcp->rtc->CR |= RTC_CR_WUTE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_WUTE; - rtcp->rtc->CR &= ~RTC_CR_WUTIE; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Gets time of periodic wakeup. - * @note Default value after BKP domain reset is 0x0000FFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] wakeupspec pointer to a @p RTCWakeup structure - * - * @api - */ -void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - wakeupspec->wutr = 0; - wakeupspec->wutr |= rtcp->rtc->WUTR; - wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16; - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} -#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ - -#endif /* HAL_USE_RTC */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv2/hal_rtc_lld.c + * @brief STM32 RTC low level driver. + * + * @addtogroup RTC + * @{ + */ + +#include "hal.h" + +// If you enable subseconds, there is a chance that this code will hang while locked (!) +// See https://github.com/rusefi/rusefi/issues/4557 +#undef STM32_RTC_HAS_SUBSECONDS +#define STM32_RTC_HAS_SUBSECONDS FALSE + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define RTC_TR_PM_OFFSET 22 +#define RTC_TR_HT_OFFSET 20 +#define RTC_TR_HU_OFFSET 16 +#define RTC_TR_MNT_OFFSET 12 +#define RTC_TR_MNU_OFFSET 8 +#define RTC_TR_ST_OFFSET 4 +#define RTC_TR_SU_OFFSET 0 + +#define RTC_DR_YT_OFFSET 20 +#define RTC_DR_YU_OFFSET 16 +#define RTC_DR_WDU_OFFSET 13 +#define RTC_DR_MT_OFFSET 12 +#define RTC_DR_MU_OFFSET 8 +#define RTC_DR_DT_OFFSET 4 +#define RTC_DR_DU_OFFSET 0 + +#define RTC_CR_BKP_OFFSET 18 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief RTC driver identifier. + */ +RTCDriver RTCD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Beginning of configuration procedure. + * + * @notapi + */ +static void rtc_enter_init(void) { + + RTCD1.rtc->ISR |= RTC_ISR_INIT; + while ((RTCD1.rtc->ISR & RTC_ISR_INITF) == 0) + ; +} + +/** + * @brief Finalizing of configuration procedure. + * + * @notapi + */ +static inline void rtc_exit_init(void) { + + RTCD1.rtc->ISR &= ~RTC_ISR_INIT; +} + +/** + * @brief Converts time from TR register encoding to timespec. + * + * @param[in] tr TR register value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) { + uint32_t n; + + n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000; + n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000; + n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000; + n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000; + n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000; + n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000; + timespec->millisecond = n; +} + +/** + * @brief Converts date from DR register encoding to timespec. + * + * @param[in] dr DR register value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) { + + timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) + + ((dr >> RTC_DR_YU_OFFSET) & 15); + timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) + + ((dr >> RTC_TR_MNU_OFFSET) & 15); + timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) + + ((dr >> RTC_DR_DU_OFFSET) & 15); + timespec->dayofweek = (dr >> RTC_DR_WDU_OFFSET) & 7; +} + +/** + * @brief Converts time from timespec to TR register encoding. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the TR register encoding. + * + * @notapi + */ +static uint32_t rtc_encode_time(const RTCDateTime *timespec) { + uint32_t n, tr = 0; + + /* Subseconds cannot be set.*/ + n = timespec->millisecond / 1000; + + /* Seconds conversion.*/ + tr = tr | ((n % 10) << RTC_TR_SU_OFFSET); + n /= 10; + tr = tr | ((n % 6) << RTC_TR_ST_OFFSET); + n /= 6; + + /* Minutes conversion.*/ + tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET); + n /= 10; + tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET); + n /= 6; + + /* Hours conversion.*/ + tr = tr | ((n % 10) << RTC_TR_HU_OFFSET); + n /= 10; + tr = tr | (n << RTC_TR_HT_OFFSET); + + return tr; +} + +/** + * @brief Converts a date from timespec to DR register encoding. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the DR register encoding. + * + * @notapi + */ +static uint32_t rtc_encode_date(const RTCDateTime *timespec) { + uint32_t n, dr = 0; + + /* Year conversion. Note, only years last two digits are considered.*/ + n = timespec->year; + dr = dr | ((n % 10) << RTC_DR_YU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_YT_OFFSET); + + /* Months conversion.*/ + n = timespec->month; + dr = dr | ((n % 10) << RTC_DR_MU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_MT_OFFSET); + + /* Days conversion.*/ + n = timespec->day; + dr = dr | ((n % 10) << RTC_DR_DU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_DT_OFFSET); + + /* Days of week conversion.*/ + dr = dr | (timespec->dayofweek << RTC_DR_WDU_OFFSET); + + return dr; +} + +#if RTC_HAS_STORAGE == TRUE +static size_t _getsize(void *instance) { + + (void)instance; + + return (size_t)STM32_RTC_STORAGE_SIZE; +} + +static ps_error_t _read(void *instance, ps_offset_t offset, + size_t n, uint8_t *rp) { + volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; + unsigned i; + + osalDbgCheck((instance != NULL) && (rp != NULL)); + osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); + osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && + (offset + n <= STM32_RTC_STORAGE_SIZE)); + + for (i = 0; i < (unsigned)n; i++) { + unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); + unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); + *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U)); + } + + return PS_NO_ERROR; +} + +static ps_error_t _write(void *instance, ps_offset_t offset, + size_t n, const uint8_t *wp) { + volatile uint32_t *bkpr = &((RTCDriver *)instance)->rtc->BKP0R; + unsigned i; + + osalDbgCheck((instance != NULL) && (wp != NULL)); + osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); + osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && + (offset + n <= STM32_RTC_STORAGE_SIZE)); + + for (i = 0; i < (unsigned)n; i++) { + unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); + unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); + uint32_t regval = bkpr[index]; + regval &= ~(0xFFU << (shift * 8U)); + regval |= (uint32_t)*wp++ << (shift * 8U); + bkpr[index] = regval; + } + + return PS_NO_ERROR; +} + +/** + * @brief VMT for the RTC storage file interface. + */ +struct RTCDriverVMT _rtc_lld_vmt = { + (size_t)0, + _getsize, _read, _write +}; +#endif /* RTC_HAS_STORAGE == TRUE */ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(STM32_RTC_COMMON_HANDLER) +#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) +/** + * @brief RTC common interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = (0U + | RTC_ISR_TSF + | RTC_ISR_TSOVF +#if defined(RTC_ISR_TAMP1F) + | RTC_ISR_TAMP1F +#endif +#if defined(RTC_ISR_TAMP2F) + | RTC_ISR_TAMP2F +#endif +#if defined(RTC_ISR_TAMP3F) + | RTC_ISR_TAMP3F +#endif +#if defined(RTC_ISR_WUTF) + | RTC_ISR_WUTF +#endif +#if defined(RTC_ISR_ALRAF) + | RTC_ISR_ALRAF +#endif +#if defined(RTC_ISR_ALRBF) + | RTC_ISR_ALRBF +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~clear; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | + EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | + EXTI_MASK1(STM32_RTC_WKUP_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr = RTCD1.rtc->CR; + uint32_t tcr; + +#if defined(RTC_ISR_WUTF) + if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } +#endif + +#if defined(RTC_ISR_ALRAF) + if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_ISR_ALRBF) + if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif + + if ((cr & RTC_CR_TSIE) != 0U) { + if ((isr & RTC_ISR_TSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } + if ((isr & RTC_ISR_TSOVF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } + } + + /* This part is different depending on if the RTC has a TAMPCR or TAFCR + register.*/ +#if defined(RTC_TAFCR_TAMP1E) + tcr = RTCD1.rtc->TAFCR; + if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { +#if defined(RTC_ISR_TAMP1F) + if ((isr & RTC_ISR_TAMP1F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if ((isr & RTC_ISR_TAMP2F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif + } + +#else /* !defined(RTC_TAFCR_TAMP1E) */ + tcr = RTCD1.rtc->TAMPCR; +#if defined(RTC_ISR_TAMP1F) + if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && + ((isr & RTC_ISR_TAMP1F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && + ((isr & RTC_ISR_TAMP2F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(RTC_ISR_TAMP3F) + if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && + ((isr & RTC_ISR_TAMP3F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif +#endif /* !defined(RTC_TAFCR_TAMP1E) */ + } + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ + +#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ + defined(STM32_RTC_WKUP_HANDLER) && \ + defined(STM32_RTC_ALARM_HANDLER) +/** + * @brief RTC TAMP/STAMP interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = (0U + | RTC_ISR_TSF + | RTC_ISR_TSOVF +#if defined(RTC_ISR_TAMP1F) + | RTC_ISR_TAMP1F +#endif +#if defined(RTC_ISR_TAMP2F) + | RTC_ISR_TAMP2F +#endif +#if defined(RTC_ISR_TAMP3F) + | RTC_ISR_TAMP3F +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~clear; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr, tcr; + + cr = RTCD1.rtc->CR; + if ((cr & RTC_CR_TSIE) != 0U) { + if ((isr & RTC_ISR_TSF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } + if ((isr & RTC_ISR_TSOVF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } + } + + /* This part is different depending on if the RTC has a TAMPCR or TAFCR + register.*/ +#if defined(RTC_TAFCR_TAMP1E) + tcr = RTCD1.rtc->TAFCR; + if ((tcr & RTC_TAFCR_TAMPIE) != 0U) { +#if defined(RTC_ISR_TAMP1F) + if ((isr & RTC_ISR_TAMP1F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if ((isr & RTC_ISR_TAMP2F) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif + } + +#else /* !defined(RTC_TAFCR_TAMP1E) */ + tcr = RTCD1.rtc->TAMPCR; +#if defined(RTC_ISR_TAMP1F) + if (((tcr & RTC_TAMPCR_TAMP1IE) != 0U) && + ((isr & RTC_ISR_TAMP1F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(RTC_ISR_TAMP2F) + if (((tcr & RTC_TAMPCR_TAMP2IE) != 0U) && + ((isr & RTC_ISR_TAMP2F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(RTC_ISR_TAMP3F) + if (((tcr & RTC_TAMPCR_TAMP3IE) != 0U) && + ((isr & RTC_ISR_TAMP3F) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif +#endif /* !defined(RTC_TAFCR_TAMP1E) */ + } + + OSAL_IRQ_EPILOGUE(); +} +/** + * @brief RTC wakeup interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { + uint32_t isr; + + OSAL_IRQ_PROLOGUE(); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~RTC_ISR_WUTF; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_WKUP_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr = RTCD1.rtc->CR; + + if (((cr & RTC_CR_WUTIE) != 0U) && ((isr & RTC_ISR_WUTF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } + } + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief RTC alarm interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { + uint32_t isr, clear; + + OSAL_IRQ_PROLOGUE(); + + clear = (0U +#if defined(RTC_ISR_ALRAF) + | RTC_ISR_ALRAF +#endif +#if defined(RTC_ISR_ALRBF) + | RTC_ISR_ALRBF +#endif + ); + + isr = RTCD1.rtc->ISR; + RTCD1.rtc->ISR = isr & ~clear; + + extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI)); + + if (RTCD1.callback != NULL) { + uint32_t cr = RTCD1.rtc->CR; +#if defined(RTC_ISR_ALRAF) + if (((cr & RTC_CR_ALRAIE) != 0U) && ((isr & RTC_ISR_ALRAF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_ISR_ALRBF) + if (((cr & RTC_CR_ALRBIE) != 0U) && ((isr & RTC_ISR_ALRBF) != 0U)) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif + } + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "missing required RTC handlers definitions in registry" +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enable access to registers. + * + * @notapi + */ +void rtc_lld_init(void) { + + /* RTC object initialization.*/ + rtcObjectInit(&RTCD1); + + /* RTC pointer initialization.*/ + RTCD1.rtc = RTC; + + /* Disable write protection. */ + RTCD1.rtc->WPR = 0xCA; + RTCD1.rtc->WPR = 0x53; + + /* If calendar has not been initialized yet then proceed with the + initial setup.*/ + if (!(RTCD1.rtc->ISR & RTC_ISR_INITS)) { + + rtc_enter_init(); + + RTCD1.rtc->CR = STM32_RTC_CR_INIT; +#if defined(RTC_TAFCR_TAMP1E) + RTCD1.rtc->TAFCR = STM32_RTC_TAMPCR_INIT; +#else + RTCD1.rtc->TAMPCR = STM32_RTC_TAMPCR_INIT; +#endif + RTCD1.rtc->ISR = RTC_ISR_INIT; /* Clearing all but RTC_ISR_INIT. */ + RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; + RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; + + rtc_exit_init(); + } + else { + RTCD1.rtc->ISR &= ~RTC_ISR_RSF; + } + + /* Callback initially disabled.*/ + RTCD1.callback = NULL; + + /* Enabling RTC-related EXTI lines.*/ + extiEnableGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | + EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | + EXTI_MASK1(STM32_RTC_WKUP_EXTI), + EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); + + /* IRQ vectors permanently assigned to this driver.*/ + STM32_RTC_IRQ_ENABLE(); +} + +/** + * @brief Set current time. + * @note Fractional part will be silently ignored. There is no possibility + * to set it on STM32 platform. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { + uint32_t dr, tr; + syssts_t sts; + + tr = rtc_encode_time(timespec); + dr = rtc_encode_date(timespec); + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Writing the registers.*/ + rtc_enter_init(); + rtcp->rtc->TR = tr; + rtcp->rtc->DR = dr; + rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) | + (timespec->dstflag << RTC_CR_BKP_OFFSET); + rtc_exit_init(); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get current time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { + uint32_t dr, tr, cr; + uint32_t subs; +#if STM32_RTC_HAS_SUBSECONDS + uint32_t oldssr, ssr; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Synchronization with the RTC and reading the registers, note + DR must be read last.*/ + while ((rtcp->rtc->ISR & RTC_ISR_RSF) == 0) + ; +#if STM32_RTC_HAS_SUBSECONDS + oldssr = rtcp->rtc->SSR; + do +#endif /* STM32_RTC_HAS_SUBSECONDS */ + { + tr = rtcp->rtc->TR; + dr = rtcp->rtc->DR; + cr = rtcp->rtc->CR; + } +#if STM32_RTC_HAS_SUBSECONDS + while (oldssr != (ssr = rtcp->rtc->SSR)); +#endif /* STM32_RTC_HAS_SUBSECONDS */ + rtcp->rtc->ISR &= ~RTC_ISR_RSF; + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); + + /* Decoding day time, this starts the atomic read sequence, see "Reading + the calendar" in the RTC documentation.*/ + rtc_decode_time(tr, timespec); + + /* If the RTC is capable of sub-second counting then the value is + normalized in milliseconds and added to the time.*/ +#if STM32_RTC_HAS_SUBSECONDS + subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE; +#else + subs = 0; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + timespec->millisecond += subs; + + /* Decoding date, this concludes the atomic read sequence.*/ + rtc_decode_date(dr, timespec); + + /* Retrieving the DST bit.*/ + timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1; +} + +#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) +/** + * @brief Set alarm time. + * @note Default value after BKP domain reset for both comparators is 0. + * @note Function does not performs any checks of alarm time validity. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure. + * @param[in] alarm alarm identifier. Can be 0 or 1. + * @param[in] alarmspec pointer to a @p RTCAlarm structure. + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (alarm == 0) { + if (alarmspec != NULL) { + rtcp->rtc->CR &= ~RTC_CR_ALRAE; + while (!(rtcp->rtc->ISR & RTC_ISR_ALRAWF)) + ; + rtcp->rtc->ALRMAR = alarmspec->alrmr; + rtcp->rtc->CR |= RTC_CR_ALRAE; + rtcp->rtc->CR |= RTC_CR_ALRAIE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_ALRAIE; + rtcp->rtc->CR &= ~RTC_CR_ALRAE; + } + } +#if RTC_ALARMS > 1 + else { + if (alarmspec != NULL) { + rtcp->rtc->CR &= ~RTC_CR_ALRBE; + while (!(rtcp->rtc->ISR & RTC_ISR_ALRBWF)) + ; + rtcp->rtc->ALRMBR = alarmspec->alrmr; + rtcp->rtc->CR |= RTC_CR_ALRBE; + rtcp->rtc->CR |= RTC_CR_ALRBIE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_ALRBIE; + rtcp->rtc->CR &= ~RTC_CR_ALRBE; + } + } +#endif /* RTC_ALARMS > 1 */ + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get alarm time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier. Can be 0 or 1. + * @param[out] alarmspec pointer to a @p RTCAlarm structure + * + * @notapi + */ +void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec) { + + if (alarm == 0) + alarmspec->alrmr = rtcp->rtc->ALRMAR; +#if RTC_ALARMS > 1 + else + alarmspec->alrmr = rtcp->rtc->ALRMBR; +#endif /* RTC_ALARMS > 1 */ +} +#endif /* RTC_ALARMS > 0 */ + +/** + * @brief Enables or disables RTC callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL + * + * @notapi + */ +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { + + rtcp->callback = callback; +} + +#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) +/** + * @brief Sets time of periodic wakeup. + * @note Default value after BKP domain reset is 0x0000FFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (wakeupspec != NULL) { + osalDbgCheck(wakeupspec->wutr != 0x30000); + + rtcp->rtc->CR &= ~RTC_CR_WUTE; + rtcp->rtc->CR &= ~RTC_CR_WUTIE; + while (!(rtcp->rtc->ISR & RTC_ISR_WUTWF)) + ; + rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF; + rtcp->rtc->CR &= ~RTC_CR_WUCKSEL; + rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL; + rtcp->rtc->CR |= RTC_CR_WUTIE; + rtcp->rtc->CR |= RTC_CR_WUTE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_WUTE; + rtcp->rtc->CR &= ~RTC_CR_WUTIE; + } + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Gets time of periodic wakeup. + * @note Default value after BKP domain reset is 0x0000FFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + wakeupspec->wutr = 0; + wakeupspec->wutr |= rtcp->rtc->WUTR; + wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16; + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} +#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h index f60e798465..b25580834a 100644 --- a/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h +++ b/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.h @@ -1,249 +1,249 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv2/hal_rtc_lld.h - * @brief STM32 RTC low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#ifndef HAL_RTC_LLD_H -#define HAL_RTC_LLD_H - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Implementation capabilities - */ -/** - * @brief Callback support int the driver. - */ -#define RTC_SUPPORTS_CALLBACKS TRUE - -/** - * @brief Number of alarms available. - */ -#define RTC_ALARMS STM32_RTC_NUM_ALARMS - -/** - * @brief Presence of a local persistent storage. - */ -#define RTC_HAS_STORAGE (STM32_RTC_STORAGE_SIZE > 0) -/** @} */ - -/** - * @brief RTC PRER register initializer. - */ -#define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1)) - -/** - * @name Alarm helper macros - * @{ - */ -#define RTC_ALRM_MSK4 (1U << 31) -#define RTC_ALRM_WDSEL (1U << 30) -#define RTC_ALRM_DT(n) ((n) << 28) -#define RTC_ALRM_DU(n) ((n) << 24) -#define RTC_ALRM_MSK3 (1U << 23) -#define RTC_ALRM_HT(n) ((n) << 20) -#define RTC_ALRM_HU(n) ((n) << 16) -#define RTC_ALRM_MSK2 (1U << 15) -#define RTC_ALRM_MNT(n) ((n) << 12) -#define RTC_ALRM_MNU(n) ((n) << 8) -#define RTC_ALRM_MSK1 (1U << 7) -#define RTC_ALRM_ST(n) ((n) << 4) -#define RTC_ALRM_SU(n) ((n) << 0) -/** @} */ - -/* Requires services from the EXTI driver.*/ -#if !defined(STM32_EXTI_REQUIRED) -#define STM32_EXTI_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief RTC PRES register initialization. - * @note The default is calculated for a 32768Hz clock. - */ -#if !defined(STM32_RTC_PRESA_VALUE) || defined(__DOXYGEN__) -#define STM32_RTC_PRESA_VALUE 32 -#endif - -/** - * @brief RTC PRESS divider initialization. - * @note The default is calculated for a 32768Hz clock. - */ -#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__) -#define STM32_RTC_PRESS_VALUE 1024 -#endif - -/** - * @brief RTC CR register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - */ -#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__) -#define STM32_RTC_CR_INIT 0 -#endif - -/** - * @brief RTC TAMPCR register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - * @note On some devices this values goes in the similar TAFCR register. - */ -#if !defined(STM32_RTC_TAMPCR_INIT) || defined(__DOXYGEN__) -#define STM32_RTC_TAMPCR_INIT 0 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if HAL_USE_RTC && !STM32_HAS_RTC -#error "RTC not present in the selected device" -#endif - -#if defined(STM32_RTC_CK) && !defined(STM32_RTCCLK) -#define STM32_RTCCLK STM32_RTC_CK -#endif - -#if !defined(STM32_RTCCLK) -#error "RTC clock not exported by HAL layer" -#endif - -#if STM32_PCLK1 < (STM32_RTCCLK * 7) -#error "STM32_PCLK1 frequency is too low" -#endif - -/** - * @brief Initialization for the RTC_PRER register. - */ -#define STM32_RTC_PRER_BITS RTC_PRER(STM32_RTC_PRESA_VALUE, \ - STM32_RTC_PRESS_VALUE) - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an RTC event. - */ -typedef enum { - RTC_EVENT_ALARM_A = 0, /** Alarm A. */ - RTC_EVENT_ALARM_B = 1, /** Alarm B. */ - RTC_EVENT_TS = 2, /** Time stamp. */ - RTC_EVENT_TS_OVF = 3, /** Time stamp overflow. */ - RTC_EVENT_TAMP1 = 4, /** Tamper 1. */ - RTC_EVENT_TAMP2 = 5, /** Tamper 2- */ - RTC_EVENT_TAMP3 = 6, /** Tamper 3. */ - RTC_EVENT_WAKEUP = 7 /** Wakeup. */ - } rtcevent_t; - -/** - * @brief Type of a generic RTC callback. - */ -typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); - -/** - * @brief Type of a structure representing an RTC alarm time stamp. - */ -typedef struct hal_rtc_alarm { - /** - * @brief Type of an alarm as encoded in RTC ALRMxR registers. - */ - uint32_t alrmr; -} RTCAlarm; - -#if STM32_RTC_HAS_PERIODIC_WAKEUPS -/** - * @brief Type of a wakeup as encoded in RTC WUTR register. - */ -typedef struct hal_rtc_wakeup { - /** - * @brief Wakeup as encoded in RTC WUTR register. - * @note ((WUTR == 0) || (WUCKSEL == 3)) are a forbidden combination. - * @note Bits 16..18 are copied in the CR bits 0..2 (WUCKSEL). - */ - uint32_t wutr; -} RTCWakeup; -#endif - -/** - * @brief Implementation-specific @p RTCDriver fields. - */ -#define rtc_lld_driver_fields \ - /* Pointer to the RTC registers block.*/ \ - RTC_TypeDef *rtc; \ - /* Callback pointer.*/ \ - rtccb_t callback - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void rtc_lld_init(void); - void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); - void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); -#if RTC_SUPPORTS_CALLBACKS == TRUE - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); -#endif -#if RTC_ALARMS > 0 - void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec); - void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec); -#endif -#if STM32_RTC_HAS_PERIODIC_WAKEUPS - void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec); - void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); -#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_RTC */ - -#endif /* HAL_RTC_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv2/hal_rtc_lld.h + * @brief STM32 RTC low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#ifndef HAL_RTC_LLD_H +#define HAL_RTC_LLD_H + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Implementation capabilities + */ +/** + * @brief Callback support int the driver. + */ +#define RTC_SUPPORTS_CALLBACKS TRUE + +/** + * @brief Number of alarms available. + */ +#define RTC_ALARMS STM32_RTC_NUM_ALARMS + +/** + * @brief Presence of a local persistent storage. + */ +#define RTC_HAS_STORAGE (STM32_RTC_STORAGE_SIZE > 0) +/** @} */ + +/** + * @brief RTC PRER register initializer. + */ +#define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1)) + +/** + * @name Alarm helper macros + * @{ + */ +#define RTC_ALRM_MSK4 (1U << 31) +#define RTC_ALRM_WDSEL (1U << 30) +#define RTC_ALRM_DT(n) ((n) << 28) +#define RTC_ALRM_DU(n) ((n) << 24) +#define RTC_ALRM_MSK3 (1U << 23) +#define RTC_ALRM_HT(n) ((n) << 20) +#define RTC_ALRM_HU(n) ((n) << 16) +#define RTC_ALRM_MSK2 (1U << 15) +#define RTC_ALRM_MNT(n) ((n) << 12) +#define RTC_ALRM_MNU(n) ((n) << 8) +#define RTC_ALRM_MSK1 (1U << 7) +#define RTC_ALRM_ST(n) ((n) << 4) +#define RTC_ALRM_SU(n) ((n) << 0) +/** @} */ + +/* Requires services from the EXTI driver.*/ +#if !defined(STM32_EXTI_REQUIRED) +#define STM32_EXTI_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief RTC PRES register initialization. + * @note The default is calculated for a 32768Hz clock. + */ +#if !defined(STM32_RTC_PRESA_VALUE) || defined(__DOXYGEN__) +#define STM32_RTC_PRESA_VALUE 32 +#endif + +/** + * @brief RTC PRESS divider initialization. + * @note The default is calculated for a 32768Hz clock. + */ +#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__) +#define STM32_RTC_PRESS_VALUE 1024 +#endif + +/** + * @brief RTC CR register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + */ +#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__) +#define STM32_RTC_CR_INIT 0 +#endif + +/** + * @brief RTC TAMPCR register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + * @note On some devices this values goes in the similar TAFCR register. + */ +#if !defined(STM32_RTC_TAMPCR_INIT) || defined(__DOXYGEN__) +#define STM32_RTC_TAMPCR_INIT 0 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if HAL_USE_RTC && !STM32_HAS_RTC +#error "RTC not present in the selected device" +#endif + +#if defined(STM32_RTC_CK) && !defined(STM32_RTCCLK) +#define STM32_RTCCLK STM32_RTC_CK +#endif + +#if !defined(STM32_RTCCLK) +#error "RTC clock not exported by HAL layer" +#endif + +#if STM32_PCLK1 < (STM32_RTCCLK * 7) +#error "STM32_PCLK1 frequency is too low" +#endif + +/** + * @brief Initialization for the RTC_PRER register. + */ +#define STM32_RTC_PRER_BITS RTC_PRER(STM32_RTC_PRESA_VALUE, \ + STM32_RTC_PRESS_VALUE) + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an RTC event. + */ +typedef enum { + RTC_EVENT_ALARM_A = 0, /** Alarm A. */ + RTC_EVENT_ALARM_B = 1, /** Alarm B. */ + RTC_EVENT_TS = 2, /** Time stamp. */ + RTC_EVENT_TS_OVF = 3, /** Time stamp overflow. */ + RTC_EVENT_TAMP1 = 4, /** Tamper 1. */ + RTC_EVENT_TAMP2 = 5, /** Tamper 2- */ + RTC_EVENT_TAMP3 = 6, /** Tamper 3. */ + RTC_EVENT_WAKEUP = 7 /** Wakeup. */ + } rtcevent_t; + +/** + * @brief Type of a generic RTC callback. + */ +typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); + +/** + * @brief Type of a structure representing an RTC alarm time stamp. + */ +typedef struct hal_rtc_alarm { + /** + * @brief Type of an alarm as encoded in RTC ALRMxR registers. + */ + uint32_t alrmr; +} RTCAlarm; + +#if STM32_RTC_HAS_PERIODIC_WAKEUPS +/** + * @brief Type of a wakeup as encoded in RTC WUTR register. + */ +typedef struct hal_rtc_wakeup { + /** + * @brief Wakeup as encoded in RTC WUTR register. + * @note ((WUTR == 0) || (WUCKSEL == 3)) are a forbidden combination. + * @note Bits 16..18 are copied in the CR bits 0..2 (WUCKSEL). + */ + uint32_t wutr; +} RTCWakeup; +#endif + +/** + * @brief Implementation-specific @p RTCDriver fields. + */ +#define rtc_lld_driver_fields \ + /* Pointer to the RTC registers block.*/ \ + RTC_TypeDef *rtc; \ + /* Callback pointer.*/ \ + rtccb_t callback + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void rtc_lld_init(void); + void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); + void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); +#if RTC_SUPPORTS_CALLBACKS == TRUE + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); +#endif +#if RTC_ALARMS > 0 + void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec); + void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec); +#endif +#if STM32_RTC_HAS_PERIODIC_WAKEUPS + void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec); + void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); +#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_RTC */ + +#endif /* HAL_RTC_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c index e586c70fe3..4e96d94103 100644 --- a/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c +++ b/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c @@ -1,717 +1,717 @@ -/* - ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio - - Licensed 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv3/hal_rtc_lld.c - * @brief STM32 RTC low level driver. - * - * @addtogroup RTC - * @{ - */ - -#include "hal.h" - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define RTC_TR_PM_OFFSET RTC_TR_PM_Pos -#define RTC_TR_HT_OFFSET RTC_TR_HT_Pos -#define RTC_TR_HU_OFFSET RTC_TR_HU_Pos -#define RTC_TR_MNT_OFFSET RTC_TR_MNT_Pos -#define RTC_TR_MNU_OFFSET RTC_TR_MNU_Pos -#define RTC_TR_ST_OFFSET RTC_TR_ST_Pos -#define RTC_TR_SU_OFFSET RTC_TR_SU_Pos - -#define RTC_DR_YT_OFFSET RTC_DR_YT_Pos -#define RTC_DR_YU_OFFSET RTC_DR_YU_Pos -#define RTC_DR_WDU_OFFSET RTC_DR_WDU_Pos -#define RTC_DR_MT_OFFSET RTC_DR_MT_Pos -#define RTC_DR_MU_OFFSET RTC_DR_MU_Pos -#define RTC_DR_DT_OFFSET RTC_DR_DT_Pos -#define RTC_DR_DU_OFFSET RTC_DR_DU_Pos - -#define RTC_CR_BKP_OFFSET RTC_CR_BKP_Pos - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief RTC driver identifier. - */ -RTCDriver RTCD1; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Beginning of configuration procedure. - * - * @notapi - */ -static void rtc_enter_init(void) { - - RTCD1.rtc->ICSR |= RTC_ICSR_INIT; - while ((RTCD1.rtc->ICSR & RTC_ICSR_INITF) == 0) - ; -} - -/** - * @brief Finalizing of configuration procedure. - * - * @notapi - */ -static inline void rtc_exit_init(void) { - - RTCD1.rtc->ICSR &= ~RTC_ICSR_INIT; -} - -/** - * @brief Converts time from TR register encoding to timespec. - * - * @param[in] tr TR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) { - uint32_t n; - - n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000; - n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000; - n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000; - n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000; - n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000; - n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000; - timespec->millisecond = n; -} - -/** - * @brief Converts date from DR register encoding to timespec. - * - * @param[in] dr DR register value - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) { - - timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) + - ((dr >> RTC_DR_YU_OFFSET) & 15); - timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) + - ((dr >> RTC_TR_MNU_OFFSET) & 15); - timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) + - ((dr >> RTC_DR_DU_OFFSET) & 15); - timespec->dayofweek = ((dr >> RTC_DR_WDU_OFFSET) & 7) + 1; -} - -/** - * @brief Converts time from timespec to TR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the TR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_time(const RTCDateTime *timespec) { - uint32_t n, tr = 0; - - /* Subseconds cannot be set.*/ - n = timespec->millisecond / 1000; - - /* Seconds conversion.*/ - tr = tr | ((n % 10) << RTC_TR_SU_OFFSET); - n /= 10; - tr = tr | ((n % 6) << RTC_TR_ST_OFFSET); - n /= 6; - - /* Minutes conversion.*/ - tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET); - n /= 10; - tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET); - n /= 6; - - /* Hours conversion.*/ - tr = tr | ((n % 10) << RTC_TR_HU_OFFSET); - n /= 10; - tr = tr | (n << RTC_TR_HT_OFFSET); - - return tr; -} - -/** - * @brief Converts a date from timespec to DR register encoding. - * - * @param[in] timespec pointer to a @p RTCDateTime structure - * @return the DR register encoding. - * - * @notapi - */ -static uint32_t rtc_encode_date(const RTCDateTime *timespec) { - uint32_t n, dr = 0; - - /* Year conversion. Note, only years last two digits are considered.*/ - n = timespec->year; - dr = dr | ((n % 10) << RTC_DR_YU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_YT_OFFSET); - - /* Months conversion.*/ - n = timespec->month; - dr = dr | ((n % 10) << RTC_DR_MU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_MT_OFFSET); - - /* Days conversion.*/ - n = timespec->day; - dr = dr | ((n % 10) << RTC_DR_DU_OFFSET); - n /= 10; - dr = dr | ((n % 10) << RTC_DR_DT_OFFSET); - - /* Days of week conversion.*/ - dr = dr | ((timespec->dayofweek) << RTC_DR_WDU_OFFSET); - - return dr; -} - -#if RTC_HAS_STORAGE == TRUE -static size_t _getsize(void *instance) { - - (void)instance; - - return (size_t)STM32_RTC_STORAGE_SIZE; -} - -static ps_error_t _read(void *instance, ps_offset_t offset, - size_t n, uint8_t *rp) { - volatile uint32_t *bkpr = &((RTCDriver *)instance)->tamp->BKP0R; - unsigned i; - - osalDbgCheck((instance != NULL) && (rp != NULL)); - osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); - osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && - (offset + n <= STM32_RTC_STORAGE_SIZE)); - - for (i = 0; i < (unsigned)n; i++) { - unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); - unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); - *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U)); - } - - return PS_NO_ERROR; -} - -static ps_error_t _write(void *instance, ps_offset_t offset, - size_t n, const uint8_t *wp) { - volatile uint32_t *bkpr = &((RTCDriver *)instance)->tamp->BKP0R; - unsigned i; - - osalDbgCheck((instance != NULL) && (wp != NULL)); - osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); - osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && - (offset + n <= STM32_RTC_STORAGE_SIZE)); - - for (i = 0; i < (unsigned)n; i++) { - unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); - unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); - uint32_t regval = bkpr[index]; - regval &= ~(0xFFU << (shift * 8U)); - regval |= (uint32_t)*wp++ << (shift * 8U); - bkpr[index] = regval; - } - - return PS_NO_ERROR; -} - -/** - * @brief VMT for the RTC storage file interface. - */ -struct RTCDriverVMT _rtc_lld_vmt = { - (size_t)0, - _getsize, _read, _write -}; -#endif /* RTC_HAS_STORAGE == TRUE */ - -/** - * @brief RTC ISR service routine. - * - */ -static void rtc_lld_serve_interrupt(void) { - - uint32_t isr; - - /* Get and clear the RTC interrupts. */ - isr = RTCD1.rtc->MISR; - RTCD1.rtc->SCR = isr; - - /* Clear EXTI events. */ - STM32_RTC_CLEAR_ALL_EXTI(); - - /* Process call backs if enabled. */ - if (RTCD1.callback != NULL) { - -#if defined(RTC_MISR_WUTMF) - if ((isr & RTC_MISR_WUTMF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); - } -#endif - -#if defined(RTC_MISR_ALRAMF) - if ((isr & RTC_MISR_ALRAMF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); - } -#endif -#if defined(RTC_MISR_ALRBMF) - if ((isr & RTC_MISR_ALRBMF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); - } -#endif -#if defined(RTC_MISR_ITSMF) - if ((isr & RTC_MISR_ITSMF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS); - } -#endif -#if defined(RTC_MISR_TSOVMF) - if ((isr & RTC_MISR_TSOVMF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); - } -#endif - - /* Get and clear the TAMP interrupts. */ - isr = RTCD1.tamp->MISR; - RTCD1.tamp->SCR = isr; -#if defined(TAMP_MISR_TAMP1MF) - if ((isr & TAMP_MISR_TAMP1MF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); - } -#endif -#if defined(TAMP_MISR_TAMP2MF) - if ((isr & TAMP_MISR_TAMP2MF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); - } -#endif -#if defined(TAMP_MISR_ITAMP3MF) - if ((isr & TAMP_MISR_ITAMP3MF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); - } -#endif -#if defined(TAMP_MISR_ITAMP4MF) - if ((isr & TAMP_MISR_ITAMP4MF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP4); - } -#endif -#if defined(TAMP_MISR_ITAMP5MF) - if ((isr & TAMP_MISR_ITAMP5MF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP5); - } -#endif -#if defined(TAMP_MISR_ITAMP6MF) - if ((isr & TAMP_MISR_ITAMP6MF) != 0U) { - RTCD1.callback(&RTCD1, RTC_EVENT_TAMP6); - } -#endif - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if defined(STM32_RTC_COMMON_HANDLER) -#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) -/** - * @brief RTC common interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - rtc_lld_serve_interrupt(); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ - -#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ - defined(STM32_RTC_WKUP_HANDLER) && \ - defined(STM32_RTC_ALARM_HANDLER) -/** - * @brief RTC TAMP/STAMP interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - rtc_lld_serve_interrupt(); - - OSAL_IRQ_EPILOGUE(); -} -/** - * @brief RTC wakeup interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - rtc_lld_serve_interrupt(); - - OSAL_IRQ_EPILOGUE(); -} - -/** - * @brief RTC alarm interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - rtc_lld_serve_interrupt(); - - OSAL_IRQ_EPILOGUE(); -} - -#else -#error "missing required RTC handler definitions in registry" -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Enable access to registers. - * - * @notapi - */ -void rtc_lld_init(void) { - - /* RTC object initialization.*/ - rtcObjectInit(&RTCD1); - - /* RTC pointer initialization.*/ - RTCD1.rtc = RTC; - - /* Disable write protection. */ - RTCD1.rtc->WPR = 0xCA; - RTCD1.rtc->WPR = 0x53; - - /* If calendar has not been initialized yet then proceed with the - initial setup.*/ - if (!(RTCD1.rtc->ICSR & RTC_ICSR_INITS)) { - - rtc_enter_init(); - - RTCD1.rtc->CR |= (STM32_RTC_CR_INIT & STM32_RTC_CR_MASK); - /* Setting PRER has to be done as two writes. Write Sync part first - then Sync + Async. */ - RTCD1.rtc->PRER = STM32_RTC_PRER_BITS & 0x7FFF; - RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; - - rtc_exit_init(); - } - else { - RTCD1.rtc->ICSR &= ~RTC_ICSR_RSF; - } - - /* TAMP pointer initialization. */ - RTCD1.tamp = TAMP; - - /* Initialise TAMP registers. */ - RTCD1.tamp->CR1 |= (STM32_TAMP_CR1_INIT & STM32_TAMP_CR1_MASK); - RTCD1.tamp->CR2 |= (STM32_TAMP_CR2_INIT & STM32_TAMP_CR2_MASK); - RTCD1.tamp->FLTCR |= (STM32_TAMP_FLTCR_INIT & STM32_TAMP_FLTCR_MASK); - RTCD1.tamp->IER |= (STM32_TAMP_IER_INIT & STM32_TAMP_IER_MASK); - - /* Callback initially disabled.*/ - RTCD1.callback = NULL; - - /* Enabling RTC-related EXTI lines.*/ - STM32_RTC_ENABLE_ALL_EXTI(); - - /* IRQ vectors permanently assigned to this driver.*/ - STM32_RTC_IRQ_ENABLE(); -} - -/** - * @brief Set current time. - * @note Fractional part will be silently ignored. There is no possibility - * to set it on STM32 platform. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { - uint32_t dr, tr; - syssts_t sts; - - tr = rtc_encode_time(timespec); - dr = rtc_encode_date(timespec); - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Writing the registers.*/ - rtc_enter_init(); - rtcp->rtc->TR = tr; - rtcp->rtc->DR = dr; - rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) | - (timespec->dstflag << RTC_CR_BKP_OFFSET); - rtc_exit_init(); - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get current time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] timespec pointer to a @p RTCDateTime structure - * - * @notapi - */ -void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { - uint32_t dr, tr, cr; - uint32_t subs; -#if STM32_RTC_HAS_SUBSECONDS - uint32_t ssr; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - /* Synchronization with the RTC and reading the registers, note - DR must be read last.*/ - while ((rtcp->rtc->ICSR & RTC_ICSR_RSF) == 0) - ; -#if STM32_RTC_HAS_SUBSECONDS - ssr = rtcp->rtc->SSR; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - tr = rtcp->rtc->TR; - dr = rtcp->rtc->DR; - cr = rtcp->rtc->CR; - rtcp->rtc->ICSR &= ~RTC_ICSR_RSF; - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); - - /* Decoding day time, this starts the atomic read sequence, see "Reading - the calendar" in the RTC documentation.*/ - rtc_decode_time(tr, timespec); - - /* If the RTC is capable of sub-second counting then the value is - normalized in milliseconds and added to the time.*/ -#if STM32_RTC_HAS_SUBSECONDS - subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE; -#else - subs = 0; -#endif /* STM32_RTC_HAS_SUBSECONDS */ - timespec->millisecond += subs; - - /* Decoding date, this concludes the atomic read sequence.*/ - rtc_decode_date(dr, timespec); - - /* Retrieving the DST bit.*/ - timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1; -} - -#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) -/** - * @brief Set alarm time. - * @note Default value after BKP domain reset for both comparators is 0. - * @note Function does not performs any checks of alarm time validity. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure. - * @param[in] alarm alarm identifier. Can be 0 or 1. - * @param[in] alarmspec pointer to a @p RTCAlarm structure. - * - * @notapi - */ -void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (alarm == 0) { - if (alarmspec != NULL) { - rtcp->rtc->CR &= ~RTC_CR_ALRAE; - while (!(rtcp->rtc->ICSR & RTC_ICSR_ALRAWF)) - ; - rtcp->rtc->ALRMAR = alarmspec->alrmr; - rtcp->rtc->CR |= RTC_CR_ALRAE; - rtcp->rtc->CR |= RTC_CR_ALRAIE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_ALRAIE; - rtcp->rtc->CR &= ~RTC_CR_ALRAE; - } - } -#if RTC_ALARMS > 1 - else { - if (alarmspec != NULL) { - rtcp->rtc->CR &= ~RTC_CR_ALRBE; - while (!(rtcp->rtc->ICSR & RTC_ICSR_ALRBWF)) - ; - rtcp->rtc->ALRMBR = alarmspec->alrmr; - rtcp->rtc->CR |= RTC_CR_ALRBE; - rtcp->rtc->CR |= RTC_CR_ALRBIE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_ALRBIE; - rtcp->rtc->CR &= ~RTC_CR_ALRBE; - } - } -#endif /* RTC_ALARMS > 1 */ - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Get alarm time. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] alarm alarm identifier. Can be 0 or 1. - * @param[out] alarmspec pointer to a @p RTCAlarm structure - * - * @notapi - */ -void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec) { - - if (alarm == 0) - alarmspec->alrmr = rtcp->rtc->ALRMAR; -#if RTC_ALARMS > 1 - else - alarmspec->alrmr = rtcp->rtc->ALRMBR; -#endif /* RTC_ALARMS > 1 */ -} -#endif /* RTC_ALARMS > 0 */ - -/** - * @brief Enables or disables RTC callbacks. - * @details This function enables or disables callbacks, use a @p NULL pointer - * in order to disable a callback. - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] callback callback function pointer or @p NULL - * - * @notapi - */ -void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { - - rtcp->callback = callback; -} - -#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) -/** - * @brief Sets time of periodic wakeup. - * @note Default value after BKP domain reset is 0x0000FFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[in] wakeupspec pointer to a @p RTCWakeup structure - * - * @api - */ -void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - if (wakeupspec != NULL) { - osalDbgCheck(wakeupspec->wutr != 0x30000); - - rtcp->rtc->CR &= ~RTC_CR_WUTE; - rtcp->rtc->CR &= ~RTC_CR_WUTIE; - while (!(rtcp->rtc->ICSR & RTC_ICSR_WUTWF)) - ; - rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF; - rtcp->rtc->CR &= ~RTC_CR_WUCKSEL; - rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL; - rtcp->rtc->CR |= RTC_CR_WUTIE; - rtcp->rtc->CR |= RTC_CR_WUTE; - } - else { - rtcp->rtc->CR &= ~RTC_CR_WUTE; - rtcp->rtc->CR &= ~RTC_CR_WUTIE; - } - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} - -/** - * @brief Gets time of periodic wakeup. - * @note Default value after BKP domain reset is 0x0000FFFF - * @note The function can be called from any context. - * - * @param[in] rtcp pointer to RTC driver structure - * @param[out] wakeupspec pointer to a @p RTCWakeup structure - * - * @api - */ -void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { - syssts_t sts; - - /* Entering a reentrant critical zone.*/ - sts = osalSysGetStatusAndLockX(); - - wakeupspec->wutr = 0; - wakeupspec->wutr |= rtcp->rtc->WUTR; - wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16; - - /* Leaving a reentrant critical zone.*/ - osalSysRestoreStatusX(sts); -} -#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ - -#endif /* HAL_USE_RTC */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv3/hal_rtc_lld.c + * @brief STM32 RTC low level driver. + * + * @addtogroup RTC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define RTC_TR_PM_OFFSET RTC_TR_PM_Pos +#define RTC_TR_HT_OFFSET RTC_TR_HT_Pos +#define RTC_TR_HU_OFFSET RTC_TR_HU_Pos +#define RTC_TR_MNT_OFFSET RTC_TR_MNT_Pos +#define RTC_TR_MNU_OFFSET RTC_TR_MNU_Pos +#define RTC_TR_ST_OFFSET RTC_TR_ST_Pos +#define RTC_TR_SU_OFFSET RTC_TR_SU_Pos + +#define RTC_DR_YT_OFFSET RTC_DR_YT_Pos +#define RTC_DR_YU_OFFSET RTC_DR_YU_Pos +#define RTC_DR_WDU_OFFSET RTC_DR_WDU_Pos +#define RTC_DR_MT_OFFSET RTC_DR_MT_Pos +#define RTC_DR_MU_OFFSET RTC_DR_MU_Pos +#define RTC_DR_DT_OFFSET RTC_DR_DT_Pos +#define RTC_DR_DU_OFFSET RTC_DR_DU_Pos + +#define RTC_CR_BKP_OFFSET RTC_CR_BKP_Pos + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief RTC driver identifier. + */ +RTCDriver RTCD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Beginning of configuration procedure. + * + * @notapi + */ +static void rtc_enter_init(void) { + + RTCD1.rtc->ICSR |= RTC_ICSR_INIT; + while ((RTCD1.rtc->ICSR & RTC_ICSR_INITF) == 0) + ; +} + +/** + * @brief Finalizing of configuration procedure. + * + * @notapi + */ +static inline void rtc_exit_init(void) { + + RTCD1.rtc->ICSR &= ~RTC_ICSR_INIT; +} + +/** + * @brief Converts time from TR register encoding to timespec. + * + * @param[in] tr TR register value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) { + uint32_t n; + + n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000; + n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000; + n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000; + n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000; + n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000; + n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000; + timespec->millisecond = n; +} + +/** + * @brief Converts date from DR register encoding to timespec. + * + * @param[in] dr DR register value + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) { + + timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) + + ((dr >> RTC_DR_YU_OFFSET) & 15); + timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) + + ((dr >> RTC_TR_MNU_OFFSET) & 15); + timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) + + ((dr >> RTC_DR_DU_OFFSET) & 15); + timespec->dayofweek = ((dr >> RTC_DR_WDU_OFFSET) & 7) + 1; +} + +/** + * @brief Converts time from timespec to TR register encoding. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the TR register encoding. + * + * @notapi + */ +static uint32_t rtc_encode_time(const RTCDateTime *timespec) { + uint32_t n, tr = 0; + + /* Subseconds cannot be set.*/ + n = timespec->millisecond / 1000; + + /* Seconds conversion.*/ + tr = tr | ((n % 10) << RTC_TR_SU_OFFSET); + n /= 10; + tr = tr | ((n % 6) << RTC_TR_ST_OFFSET); + n /= 6; + + /* Minutes conversion.*/ + tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET); + n /= 10; + tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET); + n /= 6; + + /* Hours conversion.*/ + tr = tr | ((n % 10) << RTC_TR_HU_OFFSET); + n /= 10; + tr = tr | (n << RTC_TR_HT_OFFSET); + + return tr; +} + +/** + * @brief Converts a date from timespec to DR register encoding. + * + * @param[in] timespec pointer to a @p RTCDateTime structure + * @return the DR register encoding. + * + * @notapi + */ +static uint32_t rtc_encode_date(const RTCDateTime *timespec) { + uint32_t n, dr = 0; + + /* Year conversion. Note, only years last two digits are considered.*/ + n = timespec->year; + dr = dr | ((n % 10) << RTC_DR_YU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_YT_OFFSET); + + /* Months conversion.*/ + n = timespec->month; + dr = dr | ((n % 10) << RTC_DR_MU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_MT_OFFSET); + + /* Days conversion.*/ + n = timespec->day; + dr = dr | ((n % 10) << RTC_DR_DU_OFFSET); + n /= 10; + dr = dr | ((n % 10) << RTC_DR_DT_OFFSET); + + /* Days of week conversion.*/ + dr = dr | ((timespec->dayofweek) << RTC_DR_WDU_OFFSET); + + return dr; +} + +#if RTC_HAS_STORAGE == TRUE +static size_t _getsize(void *instance) { + + (void)instance; + + return (size_t)STM32_RTC_STORAGE_SIZE; +} + +static ps_error_t _read(void *instance, ps_offset_t offset, + size_t n, uint8_t *rp) { + volatile uint32_t *bkpr = &((RTCDriver *)instance)->tamp->BKP0R; + unsigned i; + + osalDbgCheck((instance != NULL) && (rp != NULL)); + osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); + osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && + (offset + n <= STM32_RTC_STORAGE_SIZE)); + + for (i = 0; i < (unsigned)n; i++) { + unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); + unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); + *rp++ = (uint8_t)(bkpr[index] >> (shift * 8U)); + } + + return PS_NO_ERROR; +} + +static ps_error_t _write(void *instance, ps_offset_t offset, + size_t n, const uint8_t *wp) { + volatile uint32_t *bkpr = &((RTCDriver *)instance)->tamp->BKP0R; + unsigned i; + + osalDbgCheck((instance != NULL) && (wp != NULL)); + osalDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE)); + osalDbgCheck((offset < STM32_RTC_STORAGE_SIZE) && + (offset + n <= STM32_RTC_STORAGE_SIZE)); + + for (i = 0; i < (unsigned)n; i++) { + unsigned index = ((unsigned)offset + i) / sizeof (uint32_t); + unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t); + uint32_t regval = bkpr[index]; + regval &= ~(0xFFU << (shift * 8U)); + regval |= (uint32_t)*wp++ << (shift * 8U); + bkpr[index] = regval; + } + + return PS_NO_ERROR; +} + +/** + * @brief VMT for the RTC storage file interface. + */ +struct RTCDriverVMT _rtc_lld_vmt = { + (size_t)0, + _getsize, _read, _write +}; +#endif /* RTC_HAS_STORAGE == TRUE */ + +/** + * @brief RTC ISR service routine. + * + */ +static void rtc_lld_serve_interrupt(void) { + + uint32_t isr; + + /* Get and clear the RTC interrupts. */ + isr = RTCD1.rtc->MISR; + RTCD1.rtc->SCR = isr; + + /* Clear EXTI events. */ + STM32_RTC_CLEAR_ALL_EXTI(); + + /* Process call backs if enabled. */ + if (RTCD1.callback != NULL) { + +#if defined(RTC_MISR_WUTMF) + if ((isr & RTC_MISR_WUTMF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP); + } +#endif + +#if defined(RTC_MISR_ALRAMF) + if ((isr & RTC_MISR_ALRAMF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A); + } +#endif +#if defined(RTC_MISR_ALRBMF) + if ((isr & RTC_MISR_ALRBMF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B); + } +#endif +#if defined(RTC_MISR_ITSMF) + if ((isr & RTC_MISR_ITSMF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS); + } +#endif +#if defined(RTC_MISR_TSOVMF) + if ((isr & RTC_MISR_TSOVMF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF); + } +#endif + + /* Get and clear the TAMP interrupts. */ + isr = RTCD1.tamp->MISR; + RTCD1.tamp->SCR = isr; +#if defined(TAMP_MISR_TAMP1MF) + if ((isr & TAMP_MISR_TAMP1MF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1); + } +#endif +#if defined(TAMP_MISR_TAMP2MF) + if ((isr & TAMP_MISR_TAMP2MF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2); + } +#endif +#if defined(TAMP_MISR_ITAMP3MF) + if ((isr & TAMP_MISR_ITAMP3MF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3); + } +#endif +#if defined(TAMP_MISR_ITAMP4MF) + if ((isr & TAMP_MISR_ITAMP4MF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP4); + } +#endif +#if defined(TAMP_MISR_ITAMP5MF) + if ((isr & TAMP_MISR_ITAMP5MF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP5); + } +#endif +#if defined(TAMP_MISR_ITAMP6MF) + if ((isr & TAMP_MISR_ITAMP6MF) != 0U) { + RTCD1.callback(&RTCD1, RTC_EVENT_TAMP6); + } +#endif + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(STM32_RTC_COMMON_HANDLER) +#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR) +/** + * @brief RTC common interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + rtc_lld_serve_interrupt(); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */ + +#elif defined(STM32_RTC_TAMP_STAMP_HANDLER) && \ + defined(STM32_RTC_WKUP_HANDLER) && \ + defined(STM32_RTC_ALARM_HANDLER) +/** + * @brief RTC TAMP/STAMP interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_TAMP_STAMP_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + rtc_lld_serve_interrupt(); + + OSAL_IRQ_EPILOGUE(); +} +/** + * @brief RTC wakeup interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_WKUP_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + rtc_lld_serve_interrupt(); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief RTC alarm interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_RTC_ALARM_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + rtc_lld_serve_interrupt(); + + OSAL_IRQ_EPILOGUE(); +} + +#else +#error "missing required RTC handler definitions in registry" +#endif + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Enable access to registers. + * + * @notapi + */ +void rtc_lld_init(void) { + + /* RTC object initialization.*/ + rtcObjectInit(&RTCD1); + + /* RTC pointer initialization.*/ + RTCD1.rtc = RTC; + + /* Disable write protection. */ + RTCD1.rtc->WPR = 0xCA; + RTCD1.rtc->WPR = 0x53; + + /* If calendar has not been initialized yet then proceed with the + initial setup.*/ + if (!(RTCD1.rtc->ICSR & RTC_ICSR_INITS)) { + + rtc_enter_init(); + + RTCD1.rtc->CR |= (STM32_RTC_CR_INIT & STM32_RTC_CR_MASK); + /* Setting PRER has to be done as two writes. Write Sync part first + then Sync + Async. */ + RTCD1.rtc->PRER = STM32_RTC_PRER_BITS & 0x7FFF; + RTCD1.rtc->PRER = STM32_RTC_PRER_BITS; + + rtc_exit_init(); + } + else { + RTCD1.rtc->ICSR &= ~RTC_ICSR_RSF; + } + + /* TAMP pointer initialization. */ + RTCD1.tamp = TAMP; + + /* Initialise TAMP registers. */ + RTCD1.tamp->CR1 |= (STM32_TAMP_CR1_INIT & STM32_TAMP_CR1_MASK); + RTCD1.tamp->CR2 |= (STM32_TAMP_CR2_INIT & STM32_TAMP_CR2_MASK); + RTCD1.tamp->FLTCR |= (STM32_TAMP_FLTCR_INIT & STM32_TAMP_FLTCR_MASK); + RTCD1.tamp->IER |= (STM32_TAMP_IER_INIT & STM32_TAMP_IER_MASK); + + /* Callback initially disabled.*/ + RTCD1.callback = NULL; + + /* Enabling RTC-related EXTI lines.*/ + STM32_RTC_ENABLE_ALL_EXTI(); + + /* IRQ vectors permanently assigned to this driver.*/ + STM32_RTC_IRQ_ENABLE(); +} + +/** + * @brief Set current time. + * @note Fractional part will be silently ignored. There is no possibility + * to set it on STM32 platform. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) { + uint32_t dr, tr; + syssts_t sts; + + tr = rtc_encode_time(timespec); + dr = rtc_encode_date(timespec); + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Writing the registers.*/ + rtc_enter_init(); + rtcp->rtc->TR = tr; + rtcp->rtc->DR = dr; + rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) | + (timespec->dstflag << RTC_CR_BKP_OFFSET); + rtc_exit_init(); + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get current time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timespec pointer to a @p RTCDateTime structure + * + * @notapi + */ +void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) { + uint32_t dr, tr, cr; + uint32_t subs; +#if STM32_RTC_HAS_SUBSECONDS + uint32_t ssr; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + /* Synchronization with the RTC and reading the registers, note + DR must be read last.*/ + while ((rtcp->rtc->ICSR & RTC_ICSR_RSF) == 0) + ; +#if STM32_RTC_HAS_SUBSECONDS + ssr = rtcp->rtc->SSR; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + tr = rtcp->rtc->TR; + dr = rtcp->rtc->DR; + cr = rtcp->rtc->CR; + rtcp->rtc->ICSR &= ~RTC_ICSR_RSF; + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); + + /* Decoding day time, this starts the atomic read sequence, see "Reading + the calendar" in the RTC documentation.*/ + rtc_decode_time(tr, timespec); + + /* If the RTC is capable of sub-second counting then the value is + normalized in milliseconds and added to the time.*/ +#if STM32_RTC_HAS_SUBSECONDS + subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE; +#else + subs = 0; +#endif /* STM32_RTC_HAS_SUBSECONDS */ + timespec->millisecond += subs; + + /* Decoding date, this concludes the atomic read sequence.*/ + rtc_decode_date(dr, timespec); + + /* Retrieving the DST bit.*/ + timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1; +} + +#if (RTC_ALARMS > 0) || defined(__DOXYGEN__) +/** + * @brief Set alarm time. + * @note Default value after BKP domain reset for both comparators is 0. + * @note Function does not performs any checks of alarm time validity. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure. + * @param[in] alarm alarm identifier. Can be 0 or 1. + * @param[in] alarmspec pointer to a @p RTCAlarm structure. + * + * @notapi + */ +void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (alarm == 0) { + if (alarmspec != NULL) { + rtcp->rtc->CR &= ~RTC_CR_ALRAE; + while (!(rtcp->rtc->ICSR & RTC_ICSR_ALRAWF)) + ; + rtcp->rtc->ALRMAR = alarmspec->alrmr; + rtcp->rtc->CR |= RTC_CR_ALRAE; + rtcp->rtc->CR |= RTC_CR_ALRAIE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_ALRAIE; + rtcp->rtc->CR &= ~RTC_CR_ALRAE; + } + } +#if RTC_ALARMS > 1 + else { + if (alarmspec != NULL) { + rtcp->rtc->CR &= ~RTC_CR_ALRBE; + while (!(rtcp->rtc->ICSR & RTC_ICSR_ALRBWF)) + ; + rtcp->rtc->ALRMBR = alarmspec->alrmr; + rtcp->rtc->CR |= RTC_CR_ALRBE; + rtcp->rtc->CR |= RTC_CR_ALRBIE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_ALRBIE; + rtcp->rtc->CR &= ~RTC_CR_ALRBE; + } + } +#endif /* RTC_ALARMS > 1 */ + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Get alarm time. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] alarm alarm identifier. Can be 0 or 1. + * @param[out] alarmspec pointer to a @p RTCAlarm structure + * + * @notapi + */ +void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec) { + + if (alarm == 0) + alarmspec->alrmr = rtcp->rtc->ALRMAR; +#if RTC_ALARMS > 1 + else + alarmspec->alrmr = rtcp->rtc->ALRMBR; +#endif /* RTC_ALARMS > 1 */ +} +#endif /* RTC_ALARMS > 0 */ + +/** + * @brief Enables or disables RTC callbacks. + * @details This function enables or disables callbacks, use a @p NULL pointer + * in order to disable a callback. + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] callback callback function pointer or @p NULL + * + * @notapi + */ +void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { + + rtcp->callback = callback; +} + +#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__) +/** + * @brief Sets time of periodic wakeup. + * @note Default value after BKP domain reset is 0x0000FFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + if (wakeupspec != NULL) { + osalDbgCheck(wakeupspec->wutr != 0x30000); + + rtcp->rtc->CR &= ~RTC_CR_WUTE; + rtcp->rtc->CR &= ~RTC_CR_WUTIE; + while (!(rtcp->rtc->ICSR & RTC_ICSR_WUTWF)) + ; + rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF; + rtcp->rtc->CR &= ~RTC_CR_WUCKSEL; + rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL; + rtcp->rtc->CR |= RTC_CR_WUTIE; + rtcp->rtc->CR |= RTC_CR_WUTE; + } + else { + rtcp->rtc->CR &= ~RTC_CR_WUTE; + rtcp->rtc->CR &= ~RTC_CR_WUTIE; + } + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} + +/** + * @brief Gets time of periodic wakeup. + * @note Default value after BKP domain reset is 0x0000FFFF + * @note The function can be called from any context. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + syssts_t sts; + + /* Entering a reentrant critical zone.*/ + sts = osalSysGetStatusAndLockX(); + + wakeupspec->wutr = 0; + wakeupspec->wutr |= rtcp->rtc->WUTR; + wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16; + + /* Leaving a reentrant critical zone.*/ + osalSysRestoreStatusX(sts); +} +#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ + +#endif /* HAL_USE_RTC */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.h b/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.h index 4097a62505..ab32b9ad17 100644 --- a/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.h +++ b/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.h @@ -1,289 +1,289 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ -/* - Concepts and parts of this file have been contributed by Uladzimir Pylinsky - aka barthess. - */ - -/** - * @file RTCv3/hal_rtc_lld.h - * @brief STM32 RTC low level driver header. - * - * @addtogroup RTC - * @{ - */ - -#ifndef HAL_RTC_LLD_H -#define HAL_RTC_LLD_H - -#if HAL_USE_RTC || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Implementation capabilities - */ -/** - * @brief Callback support int the driver. - */ -#define RTC_SUPPORTS_CALLBACKS TRUE - -/** - * @brief Number of alarms available. - */ -#define RTC_ALARMS STM32_RTC_NUM_ALARMS - -/** - * @brief Presence of a local persistent storage. - */ -#define RTC_HAS_STORAGE (STM32_RTC_STORAGE_SIZE > 0) -/** @} */ - -/** - * @brief RTC PRER register initializer. - */ -#define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1)) - -/** - * @name Alarm helper macros - * @{ - */ -#define RTC_ALRM_MSK4 (1U << 31) -#define RTC_ALRM_WDSEL (1U << 30) -#define RTC_ALRM_DT(n) ((n) << 28) -#define RTC_ALRM_DU(n) ((n) << 24) -#define RTC_ALRM_MSK3 (1U << 23) -#define RTC_ALRM_HT(n) ((n) << 20) -#define RTC_ALRM_HU(n) ((n) << 16) -#define RTC_ALRM_MSK2 (1U << 15) -#define RTC_ALRM_MNT(n) ((n) << 12) -#define RTC_ALRM_MNU(n) ((n) << 8) -#define RTC_ALRM_MSK1 (1U << 7) -#define RTC_ALRM_ST(n) ((n) << 4) -#define RTC_ALRM_SU(n) ((n) << 0) -/** @} */ - -/* Requires services from the EXTI driver.*/ -#if !defined(STM32_EXTI_REQUIRED) -#define STM32_EXTI_REQUIRED -#endif - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief RTC PRESA register initialization. - * @note The default is calculated for a 32768Hz clock. - */ -#if !defined(STM32_RTC_PRESA_VALUE) || defined(__DOXYGEN__) -#define STM32_RTC_PRESA_VALUE 32 -#endif - -/** - * @brief RTC PRESS divider initialization. - * @note The default is calculated for a 32768Hz clock. - */ -#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__) -#define STM32_RTC_PRESS_VALUE 1024 -#endif - -/** - * @brief RTC CR register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - */ -#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__) -#define STM32_RTC_CR_INIT 0 -#endif - -/** - * @brief TAMP register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - * @note On some devices this values goes in the similar TAFCR register. - */ -#if !defined(STM32_TAMP_CR1_INIT) || defined(__DOXYGEN__) -#define STM32_TAMP_CR1_INIT 0 -#endif - -/** - * @brief TAMP register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - * @note On some devices this values goes in the similar TAFCR register. - */ -#if !defined(STM32_TAMP_CR2_INIT) || defined(__DOXYGEN__) -#define STM32_TAMP_CR2_INIT 0 -#endif - -/** - * @brief TAMP register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - * @note On some devices this values goes in the similar TAFCR register. - */ -#if !defined(STM32_TAMP_FLTCR_INIT) || defined(__DOXYGEN__) -#define STM32_TAMP_FLTCR_INIT 0 -#endif - -/** - * @brief TAMP register initialization value. - * @note Use this value to initialize features not directly handled by - * the RTC driver. - * @note On some devices this values goes in the similar TAFCR register. - */ -#if !defined(STM32_TAMP_IER_INIT) || defined(__DOXYGEN__) -#define STM32_TAMP_IER_INIT 0 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if HAL_USE_RTC && !STM32_HAS_RTC -#error "RTC not present in the selected device" -#endif - -#if defined(STM32_RTC_CK) && !defined(STM32_RTCCLK) -#define STM32_RTCCLK STM32_RTC_CK -#endif - -#if !defined(STM32_RTCCLK) -#error "RTC clock not exported by HAL layer" -#endif - -#if STM32_RTCCLK == 0 -#error "RTC has no clock source selected" -#endif - -#if STM32_PCLK1 < (STM32_RTCCLK * 7) -#error "STM32_PCLK1 frequency is too low for RTC" -#endif - -/** - * @brief Initialization for the RTC_PRER register. - */ -#define STM32_RTC_PRER_BITS RTC_PRER(STM32_RTC_PRESA_VALUE, \ - STM32_RTC_PRESS_VALUE) - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of an RTC event. - */ -typedef enum { - RTC_EVENT_ALARM_A = 0, /** Alarm A. */ - RTC_EVENT_ALARM_B = 1, /** Alarm B. */ - RTC_EVENT_TS = 2, /** Time stamp. */ - RTC_EVENT_TS_OVF = 3, /** Time stamp overflow. */ - RTC_EVENT_TAMP1 = 4, /** Tamper 1. */ - RTC_EVENT_TAMP2 = 5, /** Tamper 2- */ - RTC_EVENT_TAMP3 = 6, /** Tamper 3. */ - RTC_EVENT_TAMP4 = 7, /** Tamper 4. */ - RTC_EVENT_TAMP5 = 8, /** Tamper 5. */ - RTC_EVENT_TAMP6 = 9, /** Tamper 6. */ - RTC_EVENT_WAKEUP = 10, /** Wakeup. */ - } rtcevent_t; - -/** - * @brief Type of a generic RTC callback. - */ -typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); - -/** - * @brief Type of a structure representing an RTC alarm time stamp. - */ -typedef struct hal_rtc_alarm { - /** - * @brief Type of an alarm as encoded in RTC ALRMxR registers. - */ - uint32_t alrmr; -} RTCAlarm; - -#if STM32_RTC_HAS_PERIODIC_WAKEUPS -/** - * @brief Type of a wakeup as encoded in RTC WUTR register. - */ -typedef struct hal_rtc_wakeup { - /** - * @brief Wakeup as encoded in RTC WUTR register. - * @note ((WUTR == 0) || (WUCKSEL == 3)) are a forbidden combination. - * @note Bits 16..18 are copied in the CR bits 0..2 (WUCKSEL). - */ - uint32_t wutr; -} RTCWakeup; -#endif - -/** - * @brief Implementation-specific @p RTCDriver fields. - */ -#define rtc_lld_driver_fields \ - /* Pointer to the RTC registers block.*/ \ - RTC_TypeDef *rtc; \ - /* RTC event callback pointer.*/ \ - rtccb_t callback; \ - /* Pointer to TAMPER registers block. */ \ - TAMP_TypeDef *tamp - - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void rtc_lld_init(void); - void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); - void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); -#if RTC_SUPPORTS_CALLBACKS == TRUE - void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); -#endif -#if RTC_ALARMS > 0 - void rtc_lld_set_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - const RTCAlarm *alarmspec); - void rtc_lld_get_alarm(RTCDriver *rtcp, - rtcalarm_t alarm, - RTCAlarm *alarmspec); -#endif -#if STM32_RTC_HAS_PERIODIC_WAKEUPS - void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec); - void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); -#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_RTC */ - -#endif /* HAL_RTC_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +/** + * @file RTCv3/hal_rtc_lld.h + * @brief STM32 RTC low level driver header. + * + * @addtogroup RTC + * @{ + */ + +#ifndef HAL_RTC_LLD_H +#define HAL_RTC_LLD_H + +#if HAL_USE_RTC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Implementation capabilities + */ +/** + * @brief Callback support int the driver. + */ +#define RTC_SUPPORTS_CALLBACKS TRUE + +/** + * @brief Number of alarms available. + */ +#define RTC_ALARMS STM32_RTC_NUM_ALARMS + +/** + * @brief Presence of a local persistent storage. + */ +#define RTC_HAS_STORAGE (STM32_RTC_STORAGE_SIZE > 0) +/** @} */ + +/** + * @brief RTC PRER register initializer. + */ +#define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1)) + +/** + * @name Alarm helper macros + * @{ + */ +#define RTC_ALRM_MSK4 (1U << 31) +#define RTC_ALRM_WDSEL (1U << 30) +#define RTC_ALRM_DT(n) ((n) << 28) +#define RTC_ALRM_DU(n) ((n) << 24) +#define RTC_ALRM_MSK3 (1U << 23) +#define RTC_ALRM_HT(n) ((n) << 20) +#define RTC_ALRM_HU(n) ((n) << 16) +#define RTC_ALRM_MSK2 (1U << 15) +#define RTC_ALRM_MNT(n) ((n) << 12) +#define RTC_ALRM_MNU(n) ((n) << 8) +#define RTC_ALRM_MSK1 (1U << 7) +#define RTC_ALRM_ST(n) ((n) << 4) +#define RTC_ALRM_SU(n) ((n) << 0) +/** @} */ + +/* Requires services from the EXTI driver.*/ +#if !defined(STM32_EXTI_REQUIRED) +#define STM32_EXTI_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief RTC PRESA register initialization. + * @note The default is calculated for a 32768Hz clock. + */ +#if !defined(STM32_RTC_PRESA_VALUE) || defined(__DOXYGEN__) +#define STM32_RTC_PRESA_VALUE 32 +#endif + +/** + * @brief RTC PRESS divider initialization. + * @note The default is calculated for a 32768Hz clock. + */ +#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__) +#define STM32_RTC_PRESS_VALUE 1024 +#endif + +/** + * @brief RTC CR register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + */ +#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__) +#define STM32_RTC_CR_INIT 0 +#endif + +/** + * @brief TAMP register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + * @note On some devices this values goes in the similar TAFCR register. + */ +#if !defined(STM32_TAMP_CR1_INIT) || defined(__DOXYGEN__) +#define STM32_TAMP_CR1_INIT 0 +#endif + +/** + * @brief TAMP register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + * @note On some devices this values goes in the similar TAFCR register. + */ +#if !defined(STM32_TAMP_CR2_INIT) || defined(__DOXYGEN__) +#define STM32_TAMP_CR2_INIT 0 +#endif + +/** + * @brief TAMP register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + * @note On some devices this values goes in the similar TAFCR register. + */ +#if !defined(STM32_TAMP_FLTCR_INIT) || defined(__DOXYGEN__) +#define STM32_TAMP_FLTCR_INIT 0 +#endif + +/** + * @brief TAMP register initialization value. + * @note Use this value to initialize features not directly handled by + * the RTC driver. + * @note On some devices this values goes in the similar TAFCR register. + */ +#if !defined(STM32_TAMP_IER_INIT) || defined(__DOXYGEN__) +#define STM32_TAMP_IER_INIT 0 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if HAL_USE_RTC && !STM32_HAS_RTC +#error "RTC not present in the selected device" +#endif + +#if defined(STM32_RTC_CK) && !defined(STM32_RTCCLK) +#define STM32_RTCCLK STM32_RTC_CK +#endif + +#if !defined(STM32_RTCCLK) +#error "RTC clock not exported by HAL layer" +#endif + +#if STM32_RTCCLK == 0 +#error "RTC has no clock source selected" +#endif + +#if STM32_PCLK1 < (STM32_RTCCLK * 7) +#error "STM32_PCLK1 frequency is too low for RTC" +#endif + +/** + * @brief Initialization for the RTC_PRER register. + */ +#define STM32_RTC_PRER_BITS RTC_PRER(STM32_RTC_PRESA_VALUE, \ + STM32_RTC_PRESS_VALUE) + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of an RTC event. + */ +typedef enum { + RTC_EVENT_ALARM_A = 0, /** Alarm A. */ + RTC_EVENT_ALARM_B = 1, /** Alarm B. */ + RTC_EVENT_TS = 2, /** Time stamp. */ + RTC_EVENT_TS_OVF = 3, /** Time stamp overflow. */ + RTC_EVENT_TAMP1 = 4, /** Tamper 1. */ + RTC_EVENT_TAMP2 = 5, /** Tamper 2- */ + RTC_EVENT_TAMP3 = 6, /** Tamper 3. */ + RTC_EVENT_TAMP4 = 7, /** Tamper 4. */ + RTC_EVENT_TAMP5 = 8, /** Tamper 5. */ + RTC_EVENT_TAMP6 = 9, /** Tamper 6. */ + RTC_EVENT_WAKEUP = 10, /** Wakeup. */ + } rtcevent_t; + +/** + * @brief Type of a generic RTC callback. + */ +typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event); + +/** + * @brief Type of a structure representing an RTC alarm time stamp. + */ +typedef struct hal_rtc_alarm { + /** + * @brief Type of an alarm as encoded in RTC ALRMxR registers. + */ + uint32_t alrmr; +} RTCAlarm; + +#if STM32_RTC_HAS_PERIODIC_WAKEUPS +/** + * @brief Type of a wakeup as encoded in RTC WUTR register. + */ +typedef struct hal_rtc_wakeup { + /** + * @brief Wakeup as encoded in RTC WUTR register. + * @note ((WUTR == 0) || (WUCKSEL == 3)) are a forbidden combination. + * @note Bits 16..18 are copied in the CR bits 0..2 (WUCKSEL). + */ + uint32_t wutr; +} RTCWakeup; +#endif + +/** + * @brief Implementation-specific @p RTCDriver fields. + */ +#define rtc_lld_driver_fields \ + /* Pointer to the RTC registers block.*/ \ + RTC_TypeDef *rtc; \ + /* RTC event callback pointer.*/ \ + rtccb_t callback; \ + /* Pointer to TAMPER registers block. */ \ + TAMP_TypeDef *tamp + + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void rtc_lld_init(void); + void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec); + void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec); +#if RTC_SUPPORTS_CALLBACKS == TRUE + void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); +#endif +#if RTC_ALARMS > 0 + void rtc_lld_set_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + const RTCAlarm *alarmspec); + void rtc_lld_get_alarm(RTCDriver *rtcp, + rtcalarm_t alarm, + RTCAlarm *alarmspec); +#endif +#if STM32_RTC_HAS_PERIODIC_WAKEUPS + void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec); + void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); +#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */ +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_RTC */ + +#endif /* HAL_RTC_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F0xx/hal_lld.c b/os/hal/ports/STM32/STM32F0xx/hal_lld.c index 2815d5f611..09ae204eac 100644 --- a/os/hal/ports/STM32/STM32F0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F0xx/hal_lld.c @@ -1,363 +1,363 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F0xx/hal_lld.c - * @brief STM32F0xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define STM32_PLLXTPRE_OFFSET 17 /**< PLLXTPRE offset */ -#define STM32_PLLXTPRE_MASK 0x01 /**< PLLXTPRE mask */ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f0xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - - /* If enabled then the LSE is started.*/ -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) -#if defined(STM32_DMA1_CH23_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 streams 2 and 3 shared ISR. - * @note It is declared here because this device has a non-standard - * DMA shared IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - /* Check on channel 2.*/ - dmaServeInterrupt(STM32_DMA1_STREAM2); - - /* Check on channel 3.*/ - dmaServeInterrupt(STM32_DMA1_STREAM3); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* defined(STM32_DMA1_CH23_HANDLER) */ - -#if defined(STM32_DMA1_CH4567_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 streams 4, 5, 6 and 7 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - /* Check on channel 4.*/ - dmaServeInterrupt(STM32_DMA1_STREAM4); - - /* Check on channel 5.*/ - dmaServeInterrupt(STM32_DMA1_STREAM5); - -#if STM32_DMA1_NUM_CHANNELS > 5 - /* Check on channel 6.*/ - dmaServeInterrupt(STM32_DMA1_STREAM6); -#endif - -#if STM32_DMA1_NUM_CHANNELS > 6 - /* Check on channel 7.*/ - dmaServeInterrupt(STM32_DMA1_STREAM7); -#endif - - OSAL_IRQ_EPILOGUE(); -} -#endif /* defined(STM32_DMA1_CH4567_HANDLER) */ - -#if defined(STM32_DMA12_CH23_CH12_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 streams 2 and 3, DMA2 streams 1 and 1 shared ISR. - * @note It is declared here because this device has a non-standard - * DMA shared IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA12_CH23_CH12_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - /* Check on channel 2 of DMA1.*/ - dmaServeInterrupt(STM32_DMA1_STREAM2); - - /* Check on channel 3 of DMA1.*/ - dmaServeInterrupt(STM32_DMA1_STREAM3); - - /* Check on channel 1 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM1); - - /* Check on channel 2 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM2); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* defined(STM32_DMA12_CH23_CH12_HANDLER) */ - -#if defined(STM32_DMA12_CH4567_CH345_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 streams 4, 5, 6 and 7, DMA2 streams 3, 4 and 5 shared ISR. - * @note It is declared here because this device has a non-standard - * DMA shared IRQ handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA12_CH4567_CH345_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - /* Check on channel 4 of DMA1.*/ - dmaServeInterrupt(STM32_DMA1_STREAM4); - - /* Check on channel 5 of DMA1.*/ - dmaServeInterrupt(STM32_DMA1_STREAM5); - - /* Check on channel 6 of DMA1.*/ - dmaServeInterrupt(STM32_DMA1_STREAM6); - - /* Check on channel 7 of DMA1.*/ - dmaServeInterrupt(STM32_DMA1_STREAM7); - - /* Check on channel 3 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM3); - - /* Check on channel 4 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM4); - - /* Check on channel 5 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM5); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* defined(STM32_DMA12_CH4567_CH345_HANDLER) */ -#endif /* defined(STM32_DMA_REQUIRED) */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB(~STM32_GPIO_EN_MASK); - rccResetAPB1(0xFFFFFFFF); - rccResetAPB2(~RCC_APB2RSTR_DBGMCURST); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ -} - -/** - * @brief STM32 clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. Clearing the register has to be postponed after HSI is the - new source.*/ - RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers finally cleared to reset values.*/ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - -#if STM32_HSE_ENABLED - /* HSE activation.*/ -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - /* No HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON; -#endif - while (!(RCC->CR & RCC_CR_HSERDY)) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_HSI14_ENABLED - /* HSI14 activation.*/ - RCC->CR2 |= RCC_CR2_HSI14ON; - while (!(RCC->CR2 & RCC_CR2_HSI14RDY)) - ; /* Waits until HSI14 is stable. */ -#endif - -#if STM32_HSI48_ENABLED - /* HSI48 activation.*/ - RCC->CR2 |= RCC_CR2_HSI48ON; - while (!(RCC->CR2 & RCC_CR2_HSI48RDY)) - ; /* Waits until HSI48 is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - - /* Clock settings.*/ - /* CFGR2 must be configured first since CFGR value could change CFGR2 */ - RCC->CFGR2 = STM32_PREDIV; - RCC->CFGR = STM32_PLLNODIV | STM32_MCOPRE | STM32_MCOSEL | STM32_PLLMUL | - STM32_PLLSRC | STM32_PPRE | STM32_HPRE | - ((STM32_PREDIV & STM32_PLLXTPRE_MASK) << STM32_PLLXTPRE_OFFSET); -#if STM32_CECSW == STM32_CECSW_OFF - RCC->CFGR3 = STM32_USBSW | STM32_I2C1SW | STM32_USART1SW; -#else - RCC->CFGR3 = STM32_USBSW | STM32_CECSW | STM32_I2C1SW | STM32_USART1SW; -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL is stable. */ -#endif - - /* Flash setup and final clock selection. */ - FLASH->ACR = STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - /* Switches clock source.*/ - RCC->CFGR |= STM32_SW; - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; /* Waits selection complete. */ -#endif - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -#endif /* !STM32_NO_INIT */ -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F0xx/hal_lld.c + * @brief STM32F0xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define STM32_PLLXTPRE_OFFSET 17 /**< PLLXTPRE offset */ +#define STM32_PLLXTPRE_MASK 0x01 /**< PLLXTPRE mask */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f0xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) +#if defined(STM32_DMA1_CH23_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 streams 2 and 3 shared ISR. + * @note It is declared here because this device has a non-standard + * DMA shared IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 2.*/ + dmaServeInterrupt(STM32_DMA1_STREAM2); + + /* Check on channel 3.*/ + dmaServeInterrupt(STM32_DMA1_STREAM3); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* defined(STM32_DMA1_CH23_HANDLER) */ + +#if defined(STM32_DMA1_CH4567_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 streams 4, 5, 6 and 7 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + dmaServeInterrupt(STM32_DMA1_STREAM4); + + /* Check on channel 5.*/ + dmaServeInterrupt(STM32_DMA1_STREAM5); + +#if STM32_DMA1_NUM_CHANNELS > 5 + /* Check on channel 6.*/ + dmaServeInterrupt(STM32_DMA1_STREAM6); +#endif + +#if STM32_DMA1_NUM_CHANNELS > 6 + /* Check on channel 7.*/ + dmaServeInterrupt(STM32_DMA1_STREAM7); +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif /* defined(STM32_DMA1_CH4567_HANDLER) */ + +#if defined(STM32_DMA12_CH23_CH12_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 streams 2 and 3, DMA2 streams 1 and 1 shared ISR. + * @note It is declared here because this device has a non-standard + * DMA shared IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA12_CH23_CH12_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 2 of DMA1.*/ + dmaServeInterrupt(STM32_DMA1_STREAM2); + + /* Check on channel 3 of DMA1.*/ + dmaServeInterrupt(STM32_DMA1_STREAM3); + + /* Check on channel 1 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM1); + + /* Check on channel 2 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM2); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* defined(STM32_DMA12_CH23_CH12_HANDLER) */ + +#if defined(STM32_DMA12_CH4567_CH345_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA1 streams 4, 5, 6 and 7, DMA2 streams 3, 4 and 5 shared ISR. + * @note It is declared here because this device has a non-standard + * DMA shared IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA12_CH4567_CH345_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 4 of DMA1.*/ + dmaServeInterrupt(STM32_DMA1_STREAM4); + + /* Check on channel 5 of DMA1.*/ + dmaServeInterrupt(STM32_DMA1_STREAM5); + + /* Check on channel 6 of DMA1.*/ + dmaServeInterrupt(STM32_DMA1_STREAM6); + + /* Check on channel 7 of DMA1.*/ + dmaServeInterrupt(STM32_DMA1_STREAM7); + + /* Check on channel 3 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM3); + + /* Check on channel 4 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM4); + + /* Check on channel 5 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM5); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* defined(STM32_DMA12_CH4567_CH345_HANDLER) */ +#endif /* defined(STM32_DMA_REQUIRED) */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB(~STM32_GPIO_EN_MASK); + rccResetAPB1(0xFFFFFFFF); + rccResetAPB2(~RCC_APB2RSTR_DBGMCURST); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32 clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while (!(RCC->CR & RCC_CR_HSERDY)) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_HSI14_ENABLED + /* HSI14 activation.*/ + RCC->CR2 |= RCC_CR2_HSI14ON; + while (!(RCC->CR2 & RCC_CR2_HSI14RDY)) + ; /* Waits until HSI14 is stable. */ +#endif + +#if STM32_HSI48_ENABLED + /* HSI48 activation.*/ + RCC->CR2 |= RCC_CR2_HSI48ON; + while (!(RCC->CR2 & RCC_CR2_HSI48RDY)) + ; /* Waits until HSI48 is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + + /* Clock settings.*/ + /* CFGR2 must be configured first since CFGR value could change CFGR2 */ + RCC->CFGR2 = STM32_PREDIV; + RCC->CFGR = STM32_PLLNODIV | STM32_MCOPRE | STM32_MCOSEL | STM32_PLLMUL | + STM32_PLLSRC | STM32_PPRE | STM32_HPRE | + ((STM32_PREDIV & STM32_PLLXTPRE_MASK) << STM32_PLLXTPRE_OFFSET); +#if STM32_CECSW == STM32_CECSW_OFF + RCC->CFGR3 = STM32_USBSW | STM32_I2C1SW | STM32_USART1SW; +#else + RCC->CFGR3 = STM32_USBSW | STM32_CECSW | STM32_I2C1SW | STM32_USART1SW; +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + + /* Flash setup and final clock selection. */ + FLASH->ACR = STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + /* Switches clock source.*/ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; /* Waits selection complete. */ +#endif + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +#endif /* !STM32_NO_INIT */ +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F0xx/hal_lld.h b/os/hal/ports/STM32/STM32F0xx/hal_lld.h index 82e3e1db8f..e16f3af2fb 100644 --- a/os/hal/ports/STM32/STM32F0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F0xx/hal_lld.h @@ -1,1025 +1,1029 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F0xx/hal_lld.h - * @brief STM32F0xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32F030x4, STM32F030x6, STM32F030x8, STM32F030xC, - * STM32F070x6, STM32F070xB for Value Line devices. - * - STM32F031x6, STM32F051x8, STM32F071xB, STM32F091xC - * for Access Line devices. - * - STM32F042x6, STM32F072xB for USB Line devices. - * - STM32F038xx, STM32F048xx, STM32F058xx, STM32F078xx, - * STM32F098xx for Low Voltage Line devices. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -/* - * Registry definitions. - */ -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32F030x4) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F030x4 Entry Level Value Line devices" - -#elif defined(STM32F030x6) -#define PLATFORM_NAME "STM32F030x6 Entry Level Value Line devices" - -#elif defined(STM32F030x8) -#define PLATFORM_NAME "STM32F030x8 Entry Level Value Line devices" - -#elif defined(STM32F030xC) -#define PLATFORM_NAME "STM32F030xC Entry Level Value Line devices" - -#elif defined(STM32F070x6) -#define PLATFORM_NAME "STM32F070x6 Entry Level Value Line devices" - -#elif defined(STM32F070xB) -#define PLATFORM_NAME "STM32F070xB Entry Level Value Line devices" - -#elif defined(STM32F031x6) -#define PLATFORM_NAME "STM32F031x6 Entry Level Access Line devices" - -#elif defined(STM32F051x8) -#define PLATFORM_NAME "STM32F051x8 Entry Level Access Line devices" - -#elif defined(STM32F071xB) -#define PLATFORM_NAME "STM32F071xB Entry Level Access Line devices" - -#elif defined(STM32F091xC) -#define PLATFORM_NAME "STM32F091xC Entry Level Access Line devices" - -#elif defined(STM32F042x6) -#define PLATFORM_NAME "STM32F042x6 Entry Level USB Line devices" - -#elif defined(STM32F072xB) -#define PLATFORM_NAME "STM32F072xB Entry Level USB Line devices" - -#elif defined(STM32F038xx) -#define PLATFORM_NAME "STM32F038xx Entry Level Low Voltage Line devices" - -#elif defined(STM32F048xx) -#define PLATFORM_NAME "STM32F048xx Entry Level Low Voltage Line devices" - -#elif defined(STM32F058xx) -#define PLATFORM_NAME "STM32F058xx Entry Level Low Voltage Line devices" - -#elif defined(STM32F078xx) -#define PLATFORM_NAME "STM32F078xx Entry Level Low Voltage Line devices" - -#elif defined(STM32F098xx) -#define PLATFORM_NAME "STM32F098xx Entry Level Low Voltage Line devices" - -#else -#error "STM32F0xx device unsupported or not specified" -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum system clock frequency. - */ -#define STM32_SYSCLK_MAX 48000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 32000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 25000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 1000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 48000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 16000000 - -/** - * @brief Maximum APB clock frequency. - */ -#define STM32_PCLK_MAX 48000000 -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 8000000 /**< High speed internal clock. */ -#define STM32_HSI14CLK 14000000 /**< 14MHz speed internal clock.*/ -#define STM32_HSI48CLK 48000000 /**< 48MHz speed internal clock.*/ -#define STM32_LSICLK 40000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ -#define STM32_SW_HSI48 (3 << 0) /**< SYSCLK source is HSI48. */ - -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PLLSRC_HSI_DIV2 (0 << 15) /**< PLL clock source is HSI/2. */ -#define STM32_PLLSRC_HSI (1 << 15) /**< PLL clock source is HSI */ -#define STM32_PLLSRC_HSE (2 << 15) /**< PLL clock source is HSE. */ -#define STM32_PLLSRC_HSI48 (3 << 15) /**< PLL clock source is HSI48. */ - -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_HSI14 (1 << 24) /**< HSI14 clock on MCO pin. */ -#define STM32_MCOSEL_LSI (2 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (3 << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ - -#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ -#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ -#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ -#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ -#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ -#define STM32_MCOPRE_DIV32 (5 << 28) /**< MCO divided by 32. */ -#define STM32_MCOPRE_DIV64 (6 << 28) /**< MCO divided by 64. */ -#define STM32_MCOPRE_DIV128 (7 << 28) /**< MCO divided by 128. */ - -#define STM32_PLLNODIV_MASK (1 << 31) /**< MCO PLL divider mask. */ -#define STM32_PLLNODIV_DIV2 (0 << 31) /**< MCO PLL is divided by two. */ -#define STM32_PLLNODIV_DIV1 (1 << 31) /**< MCO PLL is divided by one. */ -/** @} */ - -/** - * @name RCC_CFGR2 register bits definitions - * @{ - */ -#define STM32_PRE_DIV1 (0 << 0) /**< PLLSRC divided by 1. */ -#define STM32_PRE_DIV2 (1 << 0) /**< SYSCLK divided by 2. */ -#define STM32_PRE_DIV3 (2 << 0) /**< SYSCLK divided by 3. */ -#define STM32_PRE_DIV4 (3 << 0) /**< PLLSRC divided by 4. */ -#define STM32_PRE_DIV5 (4 << 0) /**< SYSCLK divided by 5. */ -#define STM32_PRE_DIV6 (5 << 0) /**< SYSCLK divided by 6. */ -#define STM32_PRE_DIV7 (6 << 0) /**< PLLSRC divided by 7. */ -#define STM32_PRE_DIV8 (7 << 0) /**< SYSCLK divided by 8. */ -#define STM32_PRE_DIV9 (8 << 0) /**< SYSCLK divided by 9. */ -#define STM32_PRE_DIV10 (9 << 0) /**< PLLSRC divided by 10. */ -#define STM32_PRE_DIV11 (10 << 0) /**< SYSCLK divided by 11. */ -#define STM32_PRE_DIV12 (11 << 0) /**< SYSCLK divided by 12. */ -#define STM32_PRE_DIV13 (12 << 0) /**< PLLSRC divided by 13. */ -#define STM32_PRE_DIV14 (13 << 0) /**< SYSCLK divided by 14. */ -#define STM32_PRE_DIV15 (14 << 0) /**< SYSCLK divided by 15. */ -#define STM32_PRE_DIV16 (15 << 0) /**< PLLSRC divided by 16. */ -/** @} */ - -/** - * @name RCC_CFGR3 register bits definitions - * @{ - */ -#define STM32_USART1SW_MASK (3 << 0) /**< USART1 clock source mask. */ -#define STM32_USART1SW_PCLK (0 << 0) /**< USART1 clock is PCLK. */ -#define STM32_USART1SW_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */ -#define STM32_USART1SW_LSE (2 << 0) /**< USART1 clock is LSE. */ -#define STM32_USART1SW_HSI (3 << 0) /**< USART1 clock is HSI. */ -#define STM32_I2C1SW_MASK (1 << 4) /**< I2C clock source mask. */ -#define STM32_I2C1SW_HSI (0 << 4) /**< I2C clock is HSI. */ -#define STM32_I2C1SW_SYSCLK (1 << 4) /**< I2C clock is SYSCLK. */ -#define STM32_CECSW_MASK (1 << 6) /**< CEC clock source mask. */ -#define STM32_CECSW_HSI (0 << 6) /**< CEC clock is HSI/244. */ -#define STM32_CECSW_LSE (1 << 6) /**< CEC clock is LSE. */ -#define STM32_CECSW_OFF 0xFFFFFFFF /**< CEC clock is not required. */ -#define STM32_USBSW_MASK (1 << 7) /**< USB clock source mask. */ -#define STM32_USBSW_HSI48 (0 << 7) /**< USB clock is HSI48. */ -#define STM32_USBSW_PCLK (1 << 7) /**< USB clock is PCLK. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 32 used as - RTC clock. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSI14 clock source. - */ -#if !defined(STM32_HSI14_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI14_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSI48 clock source. - */ -#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI48_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 48MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 48MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief Crystal PLL pre-divider. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PREDIV_VALUE 1 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed range is 2...16. - * @note The default value is calculated for a 48MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 6 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 48MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE) || defined(__DOXYGEN__) -#define STM32_PPRE STM32_PPRE_DIV1 -#endif - -/** - * @brief MCO pin setting. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief MCO PLL divider setting. - */ -#if !defined(STM32_PLLNODIV) || defined(__DOXYGEN__) -#define STM32_PLLNODIV STM32_PLLNODIV_DIV2 -#endif - -/** - * @brief USB Clock source. - */ -#if !defined(STM32_USBSW) || defined(__DOXYGEN__) -#define STM32_USBSW STM32_USBSW_HSI48 -#endif - -/** - * @brief CEC clock source. - */ -#if !defined(STM32_CECSW) || defined(__DOXYGEN__) -#define STM32_CECSW STM32_CECSW_HSI -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__) -#define STM32_I2C1SW STM32_I2C1SW_HSI -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SW) || defined(__DOXYGEN__) -#define STM32_USART1SW STM32_USART1SW_PCLK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F0xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F0xx_MCUCONF not defined" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#if (STM32_SW == STM32_SW_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) && !STM32_HAS_HSI_PREDIV -#error "STM32_PLLSRC_HSI not available on this platform. Select STM32_PLLSRC_HSI_DIV2 instead." -#endif -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if STM32_CECSW == STM32_CECSW_HSI -#error "HSI not enabled, required by STM32_CECSW" -#endif - -#if STM32_I2C1SW == STM32_I2C1SW_HSI -#error "HSI not enabled, required by STM32_I2C1SW" -#endif - -#if STM32_USART1SW == STM32_USART1SW_HSI -#error "HSI not enabled, required by STM32_USART1SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2) || \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - ((STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2) || \ - (STM32_PLLSRC == STM32_PLLSRC_HSI))) -#error "HSI not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSI14 related checks. - */ -#if STM32_HSI14_ENABLED -#else /* !STM32_HSI14_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_HSI14 -#error "HSI14 not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI14_ENABLED */ - -/* - * HSI48 related checks. - */ -#if STM32_HSI48_ENABLED -#if !STM32_HAS_HSI48 -#error "HSI48 not available on this platform" -#endif -#else /* !STM32_HSI48_ENABLED */ - -#if STM32_SW == STM32_SW_HSI48 -#error "HSI48 not enabled, required by STM32_SW" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI48) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - ((STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2) || \ - (STM32_PLLSRC == STM32_PLLSRC_HSI48))) -#error "HSI48 not enabled, required by STM32_MCOSEL" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI48) -#error "HSI48 not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#endif /* !STM32_HSI48_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif - -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined" -#endif - -#if (STM32_LSEDRV >> 3) > 3 -#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_CECSW == STM32_CECSW_LSE -#error "LSE not enabled, required by STM32_CECSW" -#endif - -#if STM32_USART1SW == STM32_USART1SW_LSE -#error "LSE not enabled, required by STM32_USART1SW" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL activation conditions.*/ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_USBSW == STM32_USBSW_PCLK) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/* HSE, HSI prescaler setting check.*/ -#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16)) -#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0) -#else -#error "invalid STM32_PREDIV value specified" -#endif - -/** - * @brief PLLMUL field. - */ -#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2 -#define STM32_PLLCLKIN (STM32_HSICLK / 2) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PREDIV_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI48 -#define STM32_PLLCLKIN (STM32_HSI48CLK / STM32_PREDIV_VALUE) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_PLLCLKOUT -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSI48) -#define STM32_SYSCLK STM32_HSI48CLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB frequency. - */ -#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK (STM32_HCLK / 1) -#elif STM32_PPRE == STM32_PPRE_DIV2 -#define STM32_PCLK (STM32_HCLK / 2) -#elif STM32_PPRE == STM32_PPRE_DIV4 -#define STM32_PCLK (STM32_HCLK / 4) -#elif STM32_PPRE == STM32_PPRE_DIV8 -#define STM32_PCLK (STM32_HCLK / 8) -#elif STM32_PPRE == STM32_PPRE_DIV16 -#define STM32_PCLK (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE value specified" -#endif - -/* APB frequency check.*/ -#if STM32_PCLK > STM32_PCLK_MAX -#error "STM32_PCLK exceeding maximum frequency (STM32_PCLK_MAX)" -#endif - -/* STM32_PLLNODIV check.*/ -#if (STM32_PLLNODIV != STM32_PLLNODIV_DIV2) && \ - (STM32_PLLNODIV != STM32_PLLNODIV_DIV1) -#error "invalid STM32_PLLNODIV value specified" -#endif - -/** - * @brief MCO clock before divider. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 -#elif STM32_MCOSEL == STM32_MCOSEL_HSI14 -#define STM32_MCODIVCLK STM32_HSI14CLK -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK -#define STM32_MCODIVCLK STM32_SYSCLK -#elif STM32_MCOSEL == STM32_MCOSEL_HSI -#define STM32_MCODIVCLK STM32_HSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK -#elif STM32_MCOSEL == STM32_MCOSEL_PLLDIV2 -#if STM32_PLLNODIV == STM32_PLLNODIV_DIV2 -#define STM32_MCODIVCLK (STM32_PLLCLKOUT / 2) -#else -#define STM32_MCODIVCLK (STM32_PLLCLKOUT / 1) -#endif -#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 -#define STM32_MCODIVCLK STM32_HSI48CLK -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK -#elif (STM32_MCOPRE == STM32_MCOPRE_DIV2) && STM32_HAS_MCO_PREDIV -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) -#elif (STM32_MCOPRE == STM32_MCOPRE_DIV4) && STM32_HAS_MCO_PREDIV -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) -#elif (STM32_MCOPRE == STM32_MCOPRE_DIV8) && STM32_HAS_MCO_PREDIV -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) -#elif (STM32_MCOPRE == STM32_MCOPRE_DIV16) && STM32_HAS_MCO_PREDIV -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) -#elif !STM32_HAS_MCO_PREDIV -#error "MCO_PREDIV not available on this platform. Select STM32_MCODIVCLK." -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) -#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK -#define STM32_RTCCLK 0 -#else -#error "invalid source selected for RTC clock" -#endif - -/** - * @brief USB frequency. - */ -#if (STM32_USBSW == STM32_USBSW_HSI48) || defined(__DOXYGEN__) -#define STM32_USBCLK STM32_HSI48CLK -#elif STM32_USBSW == STM32_USBSW_PCLK -#define STM32_USBCLK STM32_PLLCLKOUT -#else -#error "invalid source selected for USB clock" -#endif - -/** - * @brief CEC frequency. - */ -#if (STM32_CECSW == STM32_CECSW_HSI) || defined(__DOXYGEN__) -#define STM32_CECCLK STM32_HSICLK -#elif STM32_CECSW == STM32_CECSW_LSE -#define STM32_CECCLK STM32_LSECLK -#elif STM32_CECSW == STM32_CECSW_OFF -#define STM32_CECCLK 0 -#else -#error "invalid source selected for CEC clock" -#endif - -/** - * @brief I2C1 frequency. - */ -#if (STM32_I2C1SW == STM32_I2C1SW_HSI) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_HSICLK -#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief USART1 frequency. - */ -#if (STM32_USART1SW == STM32_USART1SW_PCLK) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK -#elif STM32_USART1SW == STM32_USART1SW_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SW == STM32_USART1SW_LSE -#define STM32_USART1CLK STM32_LSECLK -#elif STM32_USART1SW == STM32_USART1SW_HSI -#define STM32_USART1CLK STM32_HSICLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 frequency. - */ -#define STM32_USART2CLK STM32_PCLK - -/** - * @brief USART3 frequency. - */ -#define STM32_USART3CLK STM32_PCLK - -/** - * @brief USART4 frequency. - */ -#define STM32_UART4CLK STM32_PCLK - -/** - * @brief USART5 frequency. - */ -#define STM32_UART5CLK STM32_PCLK - -/** - * @brief USART6 frequency. - */ -#define STM32_USART6CLK STM32_PCLK - -/** - * @brief USART7 frequency. - */ -#define STM32_UART7CLK STM32_PCLK - -/** - * @brief USART8 frequency. - */ -#define STM32_UART8CLK STM32_PCLK - -/** - * @brief Timers clock. - */ -#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK * 1) -#define STM32_TIMCLK2 (STM32_PCLK * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK * 2) -#define STM32_TIMCLK2 (STM32_PCLK * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000010 -#else -#define STM32_FLASHBITS 0x00000011 -#endif - -/* - * For compatibility with driver assuming a specific PPRE clock. - */ -#define STM32_PCLK1 STM32_PCLK -#define STM32_PCLK2 STM32_PCLK - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F0xx/hal_lld.h + * @brief STM32F0xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32F030x4, STM32F030x6, STM32F030x8, STM32F030xC, + * STM32F070x6, STM32F070xB for Value Line devices. + * - STM32F031x6, STM32F051x8, STM32F071xB, STM32F091xC + * for Access Line devices. + * - STM32F042x6, STM32F072xB for USB Line devices. + * - STM32F038xx, STM32F048xx, STM32F058xx, STM32F078xx, + * STM32F098xx for Low Voltage Line devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +/* + * Registry definitions. + */ +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32F030x4) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32F030x4 Entry Level Value Line devices" + +#elif defined(STM32F030x6) +#define PLATFORM_NAME "STM32F030x6 Entry Level Value Line devices" + +#elif defined(STM32F030x8) +#define PLATFORM_NAME "STM32F030x8 Entry Level Value Line devices" + +#elif defined(STM32F030xC) +#define PLATFORM_NAME "STM32F030xC Entry Level Value Line devices" + +#elif defined(STM32F070x6) +#define PLATFORM_NAME "STM32F070x6 Entry Level Value Line devices" + +#elif defined(STM32F070xB) +#define PLATFORM_NAME "STM32F070xB Entry Level Value Line devices" + +#elif defined(STM32F031x6) +#define PLATFORM_NAME "STM32F031x6 Entry Level Access Line devices" + +#elif defined(STM32F051x8) +#define PLATFORM_NAME "STM32F051x8 Entry Level Access Line devices" + +#elif defined(STM32F071xB) +#define PLATFORM_NAME "STM32F071xB Entry Level Access Line devices" + +#elif defined(STM32F091xC) +#define PLATFORM_NAME "STM32F091xC Entry Level Access Line devices" + +#elif defined(STM32F042x6) +#define PLATFORM_NAME "STM32F042x6 Entry Level USB Line devices" + +#elif defined(STM32F072xB) +#define PLATFORM_NAME "STM32F072xB Entry Level USB Line devices" + +#elif defined(STM32F038xx) +#define PLATFORM_NAME "STM32F038xx Entry Level Low Voltage Line devices" + +#elif defined(STM32F048xx) +#define PLATFORM_NAME "STM32F048xx Entry Level Low Voltage Line devices" + +#elif defined(STM32F058xx) +#define PLATFORM_NAME "STM32F058xx Entry Level Low Voltage Line devices" + +#elif defined(STM32F078xx) +#define PLATFORM_NAME "STM32F078xx Entry Level Low Voltage Line devices" + +#elif defined(STM32F098xx) +#define PLATFORM_NAME "STM32F098xx Entry Level Low Voltage Line devices" + +#else +#error "STM32F0xx device unsupported or not specified" +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define STM32_SYSCLK_MAX 48000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 32000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 25000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 1000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 48000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 16000000 + +/** + * @brief Maximum APB clock frequency. + */ +#define STM32_PCLK_MAX 48000000 +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 8000000 /**< High speed internal clock. */ +#define STM32_HSI14CLK 14000000 /**< 14MHz speed internal clock.*/ +#define STM32_HSI48CLK 48000000 /**< 48MHz speed internal clock.*/ +#define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ +#define STM32_SW_HSI48 (3 << 0) /**< SYSCLK source is HSI48. */ + +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PLLSRC_HSI_DIV2 (0 << 15) /**< PLL clock source is HSI/2. */ +#define STM32_PLLSRC_HSI (1 << 15) /**< PLL clock source is HSI */ +#define STM32_PLLSRC_HSE (2 << 15) /**< PLL clock source is HSE. */ +#define STM32_PLLSRC_HSI48 (3 << 15) /**< PLL clock source is HSI48. */ + +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_HSI14 (1 << 24) /**< HSI14 clock on MCO pin. */ +#define STM32_MCOSEL_LSI (2 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (3 << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ + +#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ +#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ +#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ +#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ +#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ +#define STM32_MCOPRE_DIV32 (5 << 28) /**< MCO divided by 32. */ +#define STM32_MCOPRE_DIV64 (6 << 28) /**< MCO divided by 64. */ +#define STM32_MCOPRE_DIV128 (7 << 28) /**< MCO divided by 128. */ + +#define STM32_PLLNODIV_MASK (1 << 31) /**< MCO PLL divider mask. */ +#define STM32_PLLNODIV_DIV2 (0 << 31) /**< MCO PLL is divided by two. */ +#define STM32_PLLNODIV_DIV1 (1 << 31) /**< MCO PLL is divided by one. */ +/** @} */ + +/** + * @name RCC_CFGR2 register bits definitions + * @{ + */ +#define STM32_PRE_DIV1 (0 << 0) /**< PLLSRC divided by 1. */ +#define STM32_PRE_DIV2 (1 << 0) /**< SYSCLK divided by 2. */ +#define STM32_PRE_DIV3 (2 << 0) /**< SYSCLK divided by 3. */ +#define STM32_PRE_DIV4 (3 << 0) /**< PLLSRC divided by 4. */ +#define STM32_PRE_DIV5 (4 << 0) /**< SYSCLK divided by 5. */ +#define STM32_PRE_DIV6 (5 << 0) /**< SYSCLK divided by 6. */ +#define STM32_PRE_DIV7 (6 << 0) /**< PLLSRC divided by 7. */ +#define STM32_PRE_DIV8 (7 << 0) /**< SYSCLK divided by 8. */ +#define STM32_PRE_DIV9 (8 << 0) /**< SYSCLK divided by 9. */ +#define STM32_PRE_DIV10 (9 << 0) /**< PLLSRC divided by 10. */ +#define STM32_PRE_DIV11 (10 << 0) /**< SYSCLK divided by 11. */ +#define STM32_PRE_DIV12 (11 << 0) /**< SYSCLK divided by 12. */ +#define STM32_PRE_DIV13 (12 << 0) /**< PLLSRC divided by 13. */ +#define STM32_PRE_DIV14 (13 << 0) /**< SYSCLK divided by 14. */ +#define STM32_PRE_DIV15 (14 << 0) /**< SYSCLK divided by 15. */ +#define STM32_PRE_DIV16 (15 << 0) /**< PLLSRC divided by 16. */ +/** @} */ + +/** + * @name RCC_CFGR3 register bits definitions + * @{ + */ +#define STM32_USART1SW_MASK (3 << 0) /**< USART1 clock source mask. */ +#define STM32_USART1SW_PCLK (0 << 0) /**< USART1 clock is PCLK. */ +#define STM32_USART1SW_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */ +#define STM32_USART1SW_LSE (2 << 0) /**< USART1 clock is LSE. */ +#define STM32_USART1SW_HSI (3 << 0) /**< USART1 clock is HSI. */ +#define STM32_I2C1SW_MASK (1 << 4) /**< I2C clock source mask. */ +#define STM32_I2C1SW_HSI (0 << 4) /**< I2C clock is HSI. */ +#define STM32_I2C1SW_SYSCLK (1 << 4) /**< I2C clock is SYSCLK. */ +#define STM32_CECSW_MASK (1 << 6) /**< CEC clock source mask. */ +#define STM32_CECSW_HSI (0 << 6) /**< CEC clock is HSI/244. */ +#define STM32_CECSW_LSE (1 << 6) /**< CEC clock is LSE. */ +#define STM32_CECSW_OFF 0xFFFFFFFF /**< CEC clock is not required. */ +#define STM32_USBSW_MASK (1 << 7) /**< USB clock source mask. */ +#define STM32_USBSW_HSI48 (0 << 7) /**< USB clock is HSI48. */ +#define STM32_USBSW_PCLK (1 << 7) /**< USB clock is PCLK. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 32 used as + RTC clock. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSI14 clock source. + */ +#if !defined(STM32_HSI14_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI14_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSI48 clock source. + */ +#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI48_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 48MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 48MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief Crystal PLL pre-divider. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PREDIV_VALUE 1 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed range is 2...16. + * @note The default value is calculated for a 48MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 6 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 48MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE) || defined(__DOXYGEN__) +#define STM32_PPRE STM32_PPRE_DIV1 +#endif + +/** + * @brief MCO pin setting. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief MCO PLL divider setting. + */ +#if !defined(STM32_PLLNODIV) || defined(__DOXYGEN__) +#define STM32_PLLNODIV STM32_PLLNODIV_DIV2 +#endif + +/** + * @brief USB Clock source. + */ +#if !defined(STM32_USBSW) || defined(__DOXYGEN__) +#define STM32_USBSW STM32_USBSW_HSI48 +#endif + +/** + * @brief CEC clock source. + */ +#if !defined(STM32_CECSW) || defined(__DOXYGEN__) +#define STM32_CECSW STM32_CECSW_HSI +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__) +#define STM32_I2C1SW STM32_I2C1SW_HSI +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SW) || defined(__DOXYGEN__) +#define STM32_USART1SW STM32_USART1SW_PCLK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F0xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F0xx_MCUCONF not defined" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#if (STM32_SW == STM32_SW_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) && !STM32_HAS_HSI_PREDIV +#error "STM32_PLLSRC_HSI not available on this platform. Select STM32_PLLSRC_HSI_DIV2 instead." +#endif +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if STM32_CECSW == STM32_CECSW_HSI +#error "HSI not enabled, required by STM32_CECSW" +#endif + +#if STM32_I2C1SW == STM32_I2C1SW_HSI +#error "HSI not enabled, required by STM32_I2C1SW" +#endif + +#if STM32_USART1SW == STM32_USART1SW_HSI +#error "HSI not enabled, required by STM32_USART1SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2) || \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + ((STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2) || \ + (STM32_PLLSRC == STM32_PLLSRC_HSI))) +#error "HSI not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSI14 related checks. + */ +#if STM32_HSI14_ENABLED +#else /* !STM32_HSI14_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_HSI14 +#error "HSI14 not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI14_ENABLED */ + +/* + * HSI48 related checks. + */ +#if STM32_HSI48_ENABLED +#if !STM32_HAS_HSI48 +#error "HSI48 not available on this platform" +#endif +#else /* !STM32_HSI48_ENABLED */ + +#if STM32_SW == STM32_SW_HSI48 +#error "HSI48 not enabled, required by STM32_SW" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI48) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + ((STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2) || \ + (STM32_PLLSRC == STM32_PLLSRC_HSI48))) +#error "HSI48 not enabled, required by STM32_MCOSEL" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI48) +#error "HSI48 not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#endif /* !STM32_HSI48_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif + +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined" +#endif + +#if (STM32_LSEDRV >> 3) > 3 +#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if STM32_CECSW == STM32_CECSW_LSE +#error "LSE not enabled, required by STM32_CECSW" +#endif + +#if STM32_USART1SW == STM32_USART1SW_LSE +#error "LSE not enabled, required by STM32_USART1SW" +#endif + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL activation conditions.*/ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_USBSW == STM32_USBSW_PCLK) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/* HSE, HSI prescaler setting check.*/ +#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16)) +#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0) +#else +#error "invalid STM32_PREDIV value specified" +#endif + +/** + * @brief PLLMUL field. + */ +#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI_DIV2 +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PREDIV_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI48 +#define STM32_PLLCLKIN (STM32_HSI48CLK / STM32_PREDIV_VALUE) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_PLLCLKOUT +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSI48) +#define STM32_SYSCLK STM32_HSI48CLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB frequency. + */ +#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK (STM32_HCLK / 1) +#elif STM32_PPRE == STM32_PPRE_DIV2 +#define STM32_PCLK (STM32_HCLK / 2) +#elif STM32_PPRE == STM32_PPRE_DIV4 +#define STM32_PCLK (STM32_HCLK / 4) +#elif STM32_PPRE == STM32_PPRE_DIV8 +#define STM32_PCLK (STM32_HCLK / 8) +#elif STM32_PPRE == STM32_PPRE_DIV16 +#define STM32_PCLK (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE value specified" +#endif + +/* APB frequency check.*/ +#if STM32_PCLK > STM32_PCLK_MAX +#error "STM32_PCLK exceeding maximum frequency (STM32_PCLK_MAX)" +#endif + +/* STM32_PLLNODIV check.*/ +#if (STM32_PLLNODIV != STM32_PLLNODIV_DIV2) && \ + (STM32_PLLNODIV != STM32_PLLNODIV_DIV1) +#error "invalid STM32_PLLNODIV value specified" +#endif + +/** + * @brief MCO clock before divider. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 +#elif STM32_MCOSEL == STM32_MCOSEL_HSI14 +#define STM32_MCODIVCLK STM32_HSI14CLK +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK +#define STM32_MCODIVCLK STM32_SYSCLK +#elif STM32_MCOSEL == STM32_MCOSEL_HSI +#define STM32_MCODIVCLK STM32_HSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK +#elif STM32_MCOSEL == STM32_MCOSEL_PLLDIV2 +#if STM32_PLLNODIV == STM32_PLLNODIV_DIV2 +#define STM32_MCODIVCLK (STM32_PLLCLKOUT / 2) +#else +#define STM32_MCODIVCLK (STM32_PLLCLKOUT / 1) +#endif +#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 +#define STM32_MCODIVCLK STM32_HSI48CLK +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK +#elif (STM32_MCOPRE == STM32_MCOPRE_DIV2) && STM32_HAS_MCO_PREDIV +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) +#elif (STM32_MCOPRE == STM32_MCOPRE_DIV4) && STM32_HAS_MCO_PREDIV +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) +#elif (STM32_MCOPRE == STM32_MCOPRE_DIV8) && STM32_HAS_MCO_PREDIV +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) +#elif (STM32_MCOPRE == STM32_MCOPRE_DIV16) && STM32_HAS_MCO_PREDIV +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) +#elif !STM32_HAS_MCO_PREDIV +#error "MCO_PREDIV not available on this platform. Select STM32_MCODIVCLK." +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + +/** + * @brief USB frequency. + */ +#if (STM32_USBSW == STM32_USBSW_HSI48) || defined(__DOXYGEN__) +#define STM32_USBCLK STM32_HSI48CLK +#elif STM32_USBSW == STM32_USBSW_PCLK +#define STM32_USBCLK STM32_PLLCLKOUT +#else +#error "invalid source selected for USB clock" +#endif + +/** + * @brief CEC frequency. + */ +#if (STM32_CECSW == STM32_CECSW_HSI) || defined(__DOXYGEN__) +#define STM32_CECCLK STM32_HSICLK +#elif STM32_CECSW == STM32_CECSW_LSE +#define STM32_CECCLK STM32_LSECLK +#elif STM32_CECSW == STM32_CECSW_OFF +#define STM32_CECCLK 0 +#else +#error "invalid source selected for CEC clock" +#endif + +/** + * @brief I2C1 frequency. + */ +#if (STM32_I2C1SW == STM32_I2C1SW_HSI) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_HSICLK +#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief USART1 frequency. + */ +#if (STM32_USART1SW == STM32_USART1SW_PCLK) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK +#elif STM32_USART1SW == STM32_USART1SW_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SW == STM32_USART1SW_LSE +#define STM32_USART1CLK STM32_LSECLK +#elif STM32_USART1SW == STM32_USART1SW_HSI +#define STM32_USART1CLK STM32_HSICLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 frequency. + */ +#define STM32_USART2CLK STM32_PCLK + +/** + * @brief USART3 frequency. + */ +#define STM32_USART3CLK STM32_PCLK + +/** + * @brief USART4 frequency. + */ +#define STM32_UART4CLK STM32_PCLK + +/** + * @brief USART5 frequency. + */ +#define STM32_UART5CLK STM32_PCLK + +/** + * @brief USART6 frequency. + */ +#define STM32_USART6CLK STM32_PCLK + +/** + * @brief USART7 frequency. + */ +#define STM32_UART7CLK STM32_PCLK + +/** + * @brief USART8 frequency. + */ +#define STM32_UART8CLK STM32_PCLK + +/** + * @brief Timers clock. + */ +#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK * 1) +#define STM32_TIMCLK2 (STM32_PCLK * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK * 2) +#define STM32_TIMCLK2 (STM32_PCLK * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000010 +#else +#define STM32_FLASHBITS 0x00000011 +#endif + +/* + * For compatibility with driver assuming a specific PPRE clock. + */ +#define STM32_PCLK1 STM32_PCLK +#define STM32_PCLK2 STM32_PCLK + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld.c b/os/hal/ports/STM32/STM32F1xx/hal_lld.c index 271abd2fb1..764df160c5 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld.c @@ -1,346 +1,346 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F1xx/hal_lld.c - * @brief STM32F1xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f10x.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - -#if HAL_USE_RTC - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - - /* If enabled then the LSE is started.*/ -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif /* STM32_LSE_ENABLED */ - -#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* Prescaler value loaded in registers.*/ - rtc_lld_set_prescaler(); - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ -#endif /* HAL_USE_RTC */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) -#if defined(STM32_DMA2_CH45_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 streams 4 and 5 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH45_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - /* Check on channel 4 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM4); - - /* Check on channel 5 of DMA2.*/ - dmaServeInterrupt(STM32_DMA2_STREAM5); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* defined(STM32_DMA2_CH45_HANDLER) */ -#endif /* defined(STM32_DMA_REQUIRED) */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals.*/ - rccResetAPB1(0xFFFFFFFF); - rccResetAPB2(0xFFFFFFFF); - - /* PWR and BD clocks enabled.*/ - rccEnablePWRInterface(true); - rccEnableBKPInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ -} - -/** - * @brief STM32 clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -#if defined(STM32F10X_LD) || defined(STM32F10X_LD_VL) || \ - defined(STM32F10X_MD) || defined(STM32F10X_MD_VL) || \ - defined(STM32F10X_HD) || defined(STM32F10X_XL) || \ - defined(__DOXYGEN__) -/* - * Clocks initialization for all sub-families except CL. - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Waits until HSI is selected. */ - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while (!(RCC->CR & RCC_CR_HSERDY)) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL is stable. */ -#endif - - /* Clock settings.*/ -#if STM32_HAS_USB - RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE | - STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | - STM32_HPRE; -#else - RCC->CFGR = STM32_MCOSEL | STM32_PLLMUL | STM32_PLLXTPRE | - STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | - STM32_HPRE; -#endif - - /* Flash setup and final clock selection. */ - FLASH->ACR = STM32_FLASHBITS; - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - /* Switches clock source.*/ - RCC->CFGR |= STM32_SW; - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; /* Waits selection complete. */ -#endif - -#if !STM32_HSI_ENABLED - RCC->CR &= ~RCC_CR_HSION; -#endif -#endif /* !STM32_NO_INIT */ -} - -#elif defined(STM32F10X_CL) -/* - * Clocks initialization for the CL sub-family. - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. Clearing the register has to be postponed after HSI is the - new source.*/ - RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers finally cleared to reset values.*/ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while (!(RCC->CR & RCC_CR_HSERDY)) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - - /* Settings of various dividers and multipliers in CFGR2.*/ - RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 | - STM32_PREDIV1 | STM32_PREDIV1SRC; - - /* PLL2 setup, if activated.*/ -#if STM32_ACTIVATE_PLL2 - RCC->CR |= RCC_CR_PLL2ON; - while (!(RCC->CR & RCC_CR_PLL2RDY)) - ; /* Waits until PLL2 is stable. */ -#endif - - /* PLL3 setup, if activated.*/ -#if STM32_ACTIVATE_PLL3 - RCC->CR |= RCC_CR_PLL3ON; - while (!(RCC->CR & RCC_CR_PLL3RDY)) - ; /* Waits until PLL3 is stable. */ -#endif - - /* PLL1 setup, if activated.*/ -#if STM32_ACTIVATE_PLL1 - RCC->CFGR |= STM32_PLLMUL | STM32_PLLSRC; - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL1 is stable. */ -#endif - - /* Clock settings.*/ -#if STM32_HAS_OTG1 - RCC->CFGR = STM32_MCOSEL | STM32_OTGFSPRE | STM32_PLLMUL | STM32_PLLSRC | - STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; -#else - RCC->CFGR = STM32_MCO | STM32_PLLMUL | STM32_PLLSRC | - STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; -#endif - - /* Flash setup and final clock selection. */ - FLASH->ACR = STM32_FLASHBITS; /* Flash wait states depending on clock. */ - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif - -#if !STM32_HSI_ENABLED - RCC->CR &= ~RCC_CR_HSION; -#endif -#endif /* !STM32_NO_INIT */ -} -#else -void stm32_clock_init(void) {} -#endif - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F1xx/hal_lld.c + * @brief STM32F1xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f10x.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + +#if HAL_USE_RTC + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif /* STM32_LSE_ENABLED */ + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* Prescaler value loaded in registers.*/ + rtc_lld_set_prescaler(); + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +#endif /* HAL_USE_RTC */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) +#if defined(STM32_DMA2_CH45_HANDLER) || defined(__DOXYGEN__) +/** + * @brief DMA2 streams 4 and 5 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA2_CH45_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 4 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM4); + + /* Check on channel 5 of DMA2.*/ + dmaServeInterrupt(STM32_DMA2_STREAM5); + + OSAL_IRQ_EPILOGUE(); +} +#endif /* defined(STM32_DMA2_CH45_HANDLER) */ +#endif /* defined(STM32_DMA_REQUIRED) */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals.*/ + rccResetAPB1(0xFFFFFFFF); + rccResetAPB2(0xFFFFFFFF); + + /* PWR and BD clocks enabled.*/ + rccEnablePWRInterface(true); + rccEnableBKPInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32 clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +#if defined(STM32F10X_LD) || defined(STM32F10X_LD_VL) || \ + defined(STM32F10X_MD) || defined(STM32F10X_MD_VL) || \ + defined(STM32F10X_HD) || defined(STM32F10X_XL) || \ + defined(__DOXYGEN__) +/* + * Clocks initialization for all sub-families except CL. + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Waits until HSI is selected. */ + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while (!(RCC->CR & RCC_CR_HSERDY)) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CFGR |= STM32_PLLMUL | STM32_PLLXTPRE | STM32_PLLSRC; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + + /* Clock settings.*/ +#if STM32_HAS_USB + RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | STM32_PLLXTPRE | + STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; +#else + RCC->CFGR = STM32_MCOSEL | STM32_PLLMUL | STM32_PLLXTPRE | + STM32_PLLSRC | STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; +#endif + + /* Flash setup and final clock selection. */ + FLASH->ACR = STM32_FLASHBITS; + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + /* Switches clock source.*/ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; /* Waits selection complete. */ +#endif + +#if !STM32_HSI_ENABLED + RCC->CR &= ~RCC_CR_HSION; +#endif +#endif /* !STM32_NO_INIT */ +} + +#elif defined(STM32F10X_CL) +/* + * Clocks initialization for the CL sub-family. + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while (!(RCC->CR & RCC_CR_HSERDY)) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + + /* Settings of various dividers and multipliers in CFGR2.*/ + RCC->CFGR2 = STM32_PLL3MUL | STM32_PLL2MUL | STM32_PREDIV2 | + STM32_PREDIV1 | STM32_PREDIV1SRC; + + /* PLL2 setup, if activated.*/ +#if STM32_ACTIVATE_PLL2 + RCC->CR |= RCC_CR_PLL2ON; + while (!(RCC->CR & RCC_CR_PLL2RDY)) + ; /* Waits until PLL2 is stable. */ +#endif + + /* PLL3 setup, if activated.*/ +#if STM32_ACTIVATE_PLL3 + RCC->CR |= RCC_CR_PLL3ON; + while (!(RCC->CR & RCC_CR_PLL3RDY)) + ; /* Waits until PLL3 is stable. */ +#endif + + /* PLL1 setup, if activated.*/ +#if STM32_ACTIVATE_PLL1 + RCC->CFGR |= STM32_PLLMUL | STM32_PLLSRC; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL1 is stable. */ +#endif + + /* Clock settings.*/ +#if STM32_HAS_OTG1 + RCC->CFGR = STM32_MCOSEL | STM32_OTGFSPRE | STM32_PLLMUL | STM32_PLLSRC | + STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; +#else + RCC->CFGR = STM32_MCO | STM32_PLLMUL | STM32_PLLSRC | + STM32_ADCPRE | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; +#endif + + /* Flash setup and final clock selection. */ + FLASH->ACR = STM32_FLASHBITS; /* Flash wait states depending on clock. */ + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif + +#if !STM32_HSI_ENABLED + RCC->CR &= ~RCC_CR_HSION; +#endif +#endif /* !STM32_NO_INIT */ +} +#else +void stm32_clock_init(void) {} +#endif + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld.h b/os/hal/ports/STM32/STM32F1xx/hal_lld.h index 908276dc65..0666df4b66 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld.h @@ -1,245 +1,245 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F1xx/hal_lld.h - * @brief STM32F1xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32F100xB for Value Line Medium Density devices. - * - STM32F100xE for Value Line High Density devices. - * - STM32F101x6, STM32F102x6, STM32F103x6 for Performance - * Low Density devices. - * - STM32F101xB, STM32F102xB, STM32F103xB for Performance - * Medium Density devices. - * - STM32F101xE, STM32F103xE for Performance High Density devices. - * - STM32F101xG, STM32F103xG for Performance eXtra Density devices. - * - STM32F105xC, STM32F107xC for Connectivity Line devices. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F1xx" - -#elif defined(STM32F10X_MD_VL) -#define PLATFORM_NAME "STM32F100 Value Line Medium Density" - -#elif defined(STM32F10X_HD_VL) -#define PLATFORM_NAME "STM32F100 Value Line High Density" - -#elif defined(STM32F10X_LD) -#define PLATFORM_NAME "STM32F10x Performance Line Low Density" - -#elif defined(STM32F10X_MD) -#define PLATFORM_NAME "STM32F10x Performance Line Medium Density" - -#elif defined(STM32F10X_HD) -#define PLATFORM_NAME "STM32F10x Performance Line High Density" - -#elif defined(STM32F10X_XL) -#define PLATFORM_NAME "STM32F10x Performance Line eXtra Density" - -#elif defined(STM32F10X_CL) -#define PLATFORM_NAME "STM32F10x Connectivity Line" - -#else -#error "unsupported or unrecognized STM32F1xx member" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32F1XX) || defined(__DOXYGEN__) -#define STM32F1XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 8000000 /**< High speed internal clock. */ -#define STM32_LSICLK 40000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/*===========================================================================*/ -/* Platform capabilities. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if defined(STM32F10X_MD_VL) || defined(STM32F10X_HD_VL) || \ - defined(__DOXYGEN__) -#include "hal_lld_f100.h" - -#elif defined(STM32F10X_LD) || defined(STM32F10X_MD) || \ - defined(STM32F10X_HD) || defined(STM32F10X_XL) || \ - defined(__DOXYGEN__) -#include "hal_lld_f103.h" - -#elif defined(STM32F10X_CL) || defined(__DOXYGEN__) -#include "hal_lld_f105_f107.h" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F1xx/hal_lld.h + * @brief STM32F1xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32F100xB for Value Line Medium Density devices. + * - STM32F100xE for Value Line High Density devices. + * - STM32F101x6, STM32F102x6, STM32F103x6 for Performance + * Low Density devices. + * - STM32F101xB, STM32F102xB, STM32F103xB for Performance + * Medium Density devices. + * - STM32F101xE, STM32F103xE for Performance High Density devices. + * - STM32F101xG, STM32F103xG for Performance eXtra Density devices. + * - STM32F105xC, STM32F107xC for Connectivity Line devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32F1xx" + +#elif defined(STM32F10X_MD_VL) +#define PLATFORM_NAME "STM32F100 Value Line Medium Density" + +#elif defined(STM32F10X_HD_VL) +#define PLATFORM_NAME "STM32F100 Value Line High Density" + +#elif defined(STM32F10X_LD) +#define PLATFORM_NAME "STM32F10x Performance Line Low Density" + +#elif defined(STM32F10X_MD) +#define PLATFORM_NAME "STM32F10x Performance Line Medium Density" + +#elif defined(STM32F10X_HD) +#define PLATFORM_NAME "STM32F10x Performance Line High Density" + +#elif defined(STM32F10X_XL) +#define PLATFORM_NAME "STM32F10x Performance Line eXtra Density" + +#elif defined(STM32F10X_CL) +#define PLATFORM_NAME "STM32F10x Connectivity Line" + +#else +#error "unsupported or unrecognized STM32F1xx member" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32F1XX) || defined(__DOXYGEN__) +#define STM32F1XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 8000000 /**< High speed internal clock. */ +#define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if defined(STM32F10X_MD_VL) || defined(STM32F10X_HD_VL) || \ + defined(__DOXYGEN__) +#include "hal_lld_f100.h" + +#elif defined(STM32F10X_LD) || defined(STM32F10X_MD) || \ + defined(STM32F10X_HD) || defined(STM32F10X_XL) || \ + defined(__DOXYGEN__) +#include "hal_lld_f103.h" + +#elif defined(STM32F10X_CL) || defined(__DOXYGEN__) +#include "hal_lld_f105_f107.h" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld_f100.h b/os/hal/ports/STM32/STM32F1xx/hal_lld_f100.h index 65d8571278..8ac3624aa7 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld_f100.h +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld_f100.h @@ -1,575 +1,579 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @defgroup STM32F100_HAL STM32F100 HAL Support - * @details HAL support for STM32 Value Line LD, MD and HD sub-families. - * - * @ingroup HAL - */ - -/** - * @file STM32F1xx/hal_lld_f100.h - * @brief STM32F100 Value Line HAL subsystem low level driver header. - * - * @addtogroup STM32F100_HAL - * @{ - */ - -#ifndef _HAL_LLD_F100_H_ -#define _HAL_LLD_F100_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum system clock frequency. - */ -#define STM32_SYSCLK_MAX 24000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 24000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 24000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 1000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 24000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 16000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 24000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 24000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 12000000 -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_ADCPRE_DIV2 (0 << 14) /**< PPRE2 divided by 2. */ -#define STM32_ADCPRE_DIV4 (1 << 14) /**< PPRE2 divided by 4. */ -#define STM32_ADCPRE_DIV6 (2 << 14) /**< PPRE2 divided by 6. */ -#define STM32_ADCPRE_DIV8 (3 << 14) /**< PPRE2 divided by 8. */ - -#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ - -#define STM32_PLLXTPRE_DIV1 (0 << 17) /**< HSE divided by 1. */ -#define STM32_PLLXTPRE_DIV2 (1 << 17) /**< HSE divided by 2. */ - -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 128 used as - RTC clock. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief Crystal PLL pre-divider. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLXTPRE) || defined(__DOXYGEN__) -#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed range is 2...16. - * @note The default value is calculated for a 24MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 3 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 24MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief ADC prescaler value. - */ -#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) -#define STM32_ADCPRE STM32_ADCPRE_DIV2 -#endif - -/** - * @brief MCO pin setting. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F100_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F100_MCUCONF not defined" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif - -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSELSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL activation conditions.*/ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/* HSE prescaler setting check.*/ -#if (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV1) && \ - (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV2) -#error "invalid STM32_PLLXTPRE value specified" -#endif - -/** - * @brief PLLMUL field. - */ -#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#if STM32_PLLXTPRE == STM32_PLLXTPRE_DIV1 -#define STM32_PLLCLKIN (STM32_HSECLK / 1) -#else -#define STM32_PLLCLKIN (STM32_HSECLK / 2) -#endif -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / 2) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_PLLCLKOUT -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 128) -#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK -#define STM32_RTCCLK 0 -#else -#error "invalid source selected for RTC clock" -#endif - -/** - * @brief ADC frequency. - */ -#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_ADCCLK (STM32_PCLK2 / 2) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 -#define STM32_ADCCLK (STM32_PCLK2 / 4) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 -#define STM32_ADCCLK (STM32_PCLK2 / 6) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 -#define STM32_ADCCLK (STM32_PCLK2 / 8) -#else -#error "invalid STM32_ADCPRE value specified" -#endif - -/* ADC frequency check.*/ -#if STM32_ADCCLK > STM32_ADCCLK_MAX -#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" -#endif - -/** - * @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14 clock. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers 1, 8, 9, 10, 11 clock. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000010 -#elif STM32_HCLK <= 48000000 -#define STM32_FLASHBITS 0x00000011 -#else -#define STM32_FLASHBITS 0x00000012 -#endif - -#endif /* _HAL_LLD_F100_H_ */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @defgroup STM32F100_HAL STM32F100 HAL Support + * @details HAL support for STM32 Value Line LD, MD and HD sub-families. + * + * @ingroup HAL + */ + +/** + * @file STM32F1xx/hal_lld_f100.h + * @brief STM32F100 Value Line HAL subsystem low level driver header. + * + * @addtogroup STM32F100_HAL + * @{ + */ + +#ifndef _HAL_LLD_F100_H_ +#define _HAL_LLD_F100_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define STM32_SYSCLK_MAX 24000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 24000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 24000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 1000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 24000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 16000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 24000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 24000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 12000000 +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_ADCPRE_DIV2 (0 << 14) /**< PPRE2 divided by 2. */ +#define STM32_ADCPRE_DIV4 (1 << 14) /**< PPRE2 divided by 4. */ +#define STM32_ADCPRE_DIV6 (2 << 14) /**< PPRE2 divided by 6. */ +#define STM32_ADCPRE_DIV8 (3 << 14) /**< PPRE2 divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ + +#define STM32_PLLXTPRE_DIV1 (0 << 17) /**< HSE divided by 1. */ +#define STM32_PLLXTPRE_DIV2 (1 << 17) /**< HSE divided by 2. */ + +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 128 used as + RTC clock. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief Crystal PLL pre-divider. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLXTPRE) || defined(__DOXYGEN__) +#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed range is 2...16. + * @note The default value is calculated for a 24MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 3 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 24MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief ADC prescaler value. + */ +#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) +#define STM32_ADCPRE STM32_ADCPRE_DIV2 +#endif + +/** + * @brief MCO pin setting. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F100_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F100_MCUCONF not defined" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif + +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSELSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL activation conditions.*/ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/* HSE prescaler setting check.*/ +#if (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV1) && \ + (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV2) +#error "invalid STM32_PLLXTPRE value specified" +#endif + +/** + * @brief PLLMUL field. + */ +#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#if STM32_PLLXTPRE == STM32_PLLXTPRE_DIV1 +#define STM32_PLLCLKIN (STM32_HSECLK / 1) +#else +#define STM32_PLLCLKIN (STM32_HSECLK / 2) +#endif +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_PLLCLKOUT +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 128) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + +/** + * @brief ADC frequency. + */ +#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_ADCCLK (STM32_PCLK2 / 2) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 +#define STM32_ADCCLK (STM32_PCLK2 / 4) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 +#define STM32_ADCCLK (STM32_PCLK2 / 6) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 +#define STM32_ADCCLK (STM32_PCLK2 / 8) +#else +#error "invalid STM32_ADCPRE value specified" +#endif + +/* ADC frequency check.*/ +#if STM32_ADCCLK > STM32_ADCCLK_MAX +#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" +#endif + +/** + * @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14 clock. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 1, 8, 9, 10, 11 clock. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000010 +#elif STM32_HCLK <= 48000000 +#define STM32_FLASHBITS 0x00000011 +#else +#define STM32_FLASHBITS 0x00000012 +#endif + +#endif /* _HAL_LLD_F100_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld_f103.h b/os/hal/ports/STM32/STM32F1xx/hal_lld_f103.h index 64c27deaa4..2103830704 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld_f103.h +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld_f103.h @@ -1,604 +1,608 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @defgroup STM32F103_HAL STM32F103 HAL Support - * @details HAL support for STM32 Performance Line LD, MD and HD sub-families. - * - * @ingroup HAL - */ - -/** - * @file STM32F1xx/hal_lld_f103.h - * @brief STM32F103 Performance Line HAL subsystem low level driver header. - * - * @addtogroup STM32F103_HAL - * @{ - */ - -#ifndef _HAL_LLD_F103_H_ -#define _HAL_LLD_F103_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum system clock frequency. - */ -#define STM32_SYSCLK_MAX 72000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 25000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 25000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 1000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 72000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 16000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 36000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 72000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 14000000 -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_ADCPRE_DIV2 (0 << 14) /**< PPRE2 divided by 2. */ -#define STM32_ADCPRE_DIV4 (1 << 14) /**< PPRE2 divided by 4. */ -#define STM32_ADCPRE_DIV6 (2 << 14) /**< PPRE2 divided by 6. */ -#define STM32_ADCPRE_DIV8 (3 << 14) /**< PPRE2 divided by 8. */ - -#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ - -#define STM32_PLLXTPRE_DIV1 (0 << 17) /**< HSE divided by 1. */ -#define STM32_PLLXTPRE_DIV2 (1 << 17) /**< HSE divided by 2. */ - -#define STM32_USBPRE_DIV1P5 (0 << 22) /**< PLLOUT divided by 1.5. */ -#define STM32_USBPRE_DIV1 (1 << 22) /**< PLLOUT divided by 1. */ - -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 128 used as - RTC clock. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief Crystal PLL pre-divider. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLXTPRE) || defined(__DOXYGEN__) -#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed range is 2...16. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 9 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV2 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief ADC prescaler value. - */ -#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) -#define STM32_ADCPRE STM32_ADCPRE_DIV4 -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_REQUIRED TRUE -#endif - -/** - * @brief USB prescaler initialization. - */ -#if !defined(STM32_USBPRE) || defined(__DOXYGEN__) -#define STM32_USBPRE STM32_USBPRE_DIV1P5 -#endif - -/** - * @brief MCO pin setting. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F103_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F103_MCUCONF not defined" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif - -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL activation conditions.*/ -#if STM32_USB_CLOCK_REQUIRED || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/* HSE prescaler setting check.*/ -#if (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV1) && \ - (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV2) -#error "invalid STM32_PLLXTPRE value specified" -#endif - -/** - * @brief PLLMUL field. - */ -#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#if STM32_PLLXTPRE == STM32_PLLXTPRE_DIV1 -#define STM32_PLLCLKIN (STM32_HSECLK / 1) -#else -#define STM32_PLLCLKIN (STM32_HSECLK / 2) -#endif -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / 2) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_PLLCLKOUT -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 128) -#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK -#define STM32_RTCCLK 0 -#else -#error "invalid source selected for RTC clock" -#endif - -/** - * @brief ADC frequency. - */ -#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_ADCCLK (STM32_PCLK2 / 2) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 -#define STM32_ADCCLK (STM32_PCLK2 / 4) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 -#define STM32_ADCCLK (STM32_PCLK2 / 6) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 -#define STM32_ADCCLK (STM32_PCLK2 / 8) -#else -#error "invalid STM32_ADCPRE value specified" -#endif - -/* ADC frequency check.*/ -#if STM32_ADCCLK > STM32_ADCCLK_MAX -#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" -#endif - -/** - * @brief USB frequency. - */ -#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__) -#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3) -#elif (STM32_USBPRE == STM32_USBPRE_DIV1) -#define STM32_USBCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_USBPRE value specified" -#endif - -/** - * @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14 clock. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers 1, 8, 9, 10, 11 clock. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000010 -#elif STM32_HCLK <= 48000000 -#define STM32_FLASHBITS 0x00000011 -#else -#define STM32_FLASHBITS 0x00000012 -#endif - -#endif /* _HAL_LLD_F103_H_ */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @defgroup STM32F103_HAL STM32F103 HAL Support + * @details HAL support for STM32 Performance Line LD, MD and HD sub-families. + * + * @ingroup HAL + */ + +/** + * @file STM32F1xx/hal_lld_f103.h + * @brief STM32F103 Performance Line HAL subsystem low level driver header. + * + * @addtogroup STM32F103_HAL + * @{ + */ + +#ifndef _HAL_LLD_F103_H_ +#define _HAL_LLD_F103_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define STM32_SYSCLK_MAX 72000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 25000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 25000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 1000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 72000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 16000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 36000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 72000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 14000000 +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_ADCPRE_DIV2 (0 << 14) /**< PPRE2 divided by 2. */ +#define STM32_ADCPRE_DIV4 (1 << 14) /**< PPRE2 divided by 4. */ +#define STM32_ADCPRE_DIV6 (2 << 14) /**< PPRE2 divided by 6. */ +#define STM32_ADCPRE_DIV8 (3 << 14) /**< PPRE2 divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ + +#define STM32_PLLXTPRE_DIV1 (0 << 17) /**< HSE divided by 1. */ +#define STM32_PLLXTPRE_DIV2 (1 << 17) /**< HSE divided by 2. */ + +#define STM32_USBPRE_DIV1P5 (0 << 22) /**< PLLOUT divided by 1.5. */ +#define STM32_USBPRE_DIV1 (1 << 22) /**< PLLOUT divided by 1. */ + +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 128 used as + RTC clock. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief Crystal PLL pre-divider. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLXTPRE) || defined(__DOXYGEN__) +#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed range is 2...16. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 9 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief ADC prescaler value. + */ +#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) +#define STM32_ADCPRE STM32_ADCPRE_DIV4 +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_REQUIRED TRUE +#endif + +/** + * @brief USB prescaler initialization. + */ +#if !defined(STM32_USBPRE) || defined(__DOXYGEN__) +#define STM32_USBPRE STM32_USBPRE_DIV1P5 +#endif + +/** + * @brief MCO pin setting. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F103_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F103_MCUCONF not defined" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif + +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL activation conditions.*/ +#if STM32_USB_CLOCK_REQUIRED || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/* HSE prescaler setting check.*/ +#if (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV1) && \ + (STM32_PLLXTPRE != STM32_PLLXTPRE_DIV2) +#error "invalid STM32_PLLXTPRE value specified" +#endif + +/** + * @brief PLLMUL field. + */ +#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#if STM32_PLLXTPRE == STM32_PLLXTPRE_DIV1 +#define STM32_PLLCLKIN (STM32_HSECLK / 1) +#else +#define STM32_PLLCLKIN (STM32_HSECLK / 2) +#endif +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_PLLCLKOUT +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 128) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + +/** + * @brief ADC frequency. + */ +#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_ADCCLK (STM32_PCLK2 / 2) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 +#define STM32_ADCCLK (STM32_PCLK2 / 4) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 +#define STM32_ADCCLK (STM32_PCLK2 / 6) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 +#define STM32_ADCCLK (STM32_PCLK2 / 8) +#else +#error "invalid STM32_ADCPRE value specified" +#endif + +/* ADC frequency check.*/ +#if STM32_ADCCLK > STM32_ADCCLK_MAX +#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" +#endif + +/** + * @brief USB frequency. + */ +#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__) +#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3) +#elif (STM32_USBPRE == STM32_USBPRE_DIV1) +#define STM32_USBCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_USBPRE value specified" +#endif + +/** + * @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14 clock. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 1, 8, 9, 10, 11 clock. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000010 +#elif STM32_HCLK <= 48000000 +#define STM32_FLASHBITS 0x00000011 +#else +#define STM32_FLASHBITS 0x00000012 +#endif + +#endif /* _HAL_LLD_F103_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld_f105_f107.h b/os/hal/ports/STM32/STM32F1xx/hal_lld_f105_f107.h index efbe94deb6..3ebb2199ff 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld_f105_f107.h @@ -1,814 +1,818 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @defgroup STM32F10X_CL_HAL STM32F105/F107 HAL Support - * @details HAL support for STM32 Connectivity Line sub-family. - * - * @ingroup HAL - */ - -/** - * @file STM32F1xx/hal_lld_f105_f107.h - * @brief STM32F10x Connectivity Line HAL subsystem low level driver header. - * - * @addtogroup STM32F10X_CL_HAL - * @{ - */ - -#ifndef _HAL_LLD_F105_F107_H_ -#define _HAL_LLD_F105_F107_H_ - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum system clock frequency. - */ -#define STM32_SYSCLK_MAX 72000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 50000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLL1IN_MAX 12000000 - -/** - * @brief Minimum PLL1 input clock frequency. - */ -#define STM32_PLL1IN_MIN 3000000 - -/** - * @brief Maximum PLL1 input clock frequency. - */ -#define STM32_PLL23IN_MAX 5000000 - -/** - * @brief Minimum PLL2 and PLL3 input clock frequency. - */ -#define STM32_PLL23IN_MIN 3000000 - -/** - * @brief Maximum PLL1 VCO clock frequency. - */ -#define STM32_PLL1VCO_MAX 144000000 - -/** - * @brief Minimum PLL1 VCO clock frequency. - */ -#define STM32_PLL1VCO_MIN 36000000 - -/** - * @brief Maximum PLL2 and PLL3 VCO clock frequency. - */ -#define STM32_PLL23VCO_MAX 148000000 - -/** - * @brief Minimum PLL2 and PLL3 VCO clock frequency. - */ -#define STM32_PLL23VCO_MIN 80000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 36000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 72000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 14000000 - -/** - * @brief Maximum SPI/I2S clock frequency. - */ -#define STM32_SPII2S_MAX 18000000 -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_ADCPRE_DIV2 (0 << 14) /**< PPRE2 divided by 2. */ -#define STM32_ADCPRE_DIV4 (1 << 14) /**< PPRE2 divided by 4. */ -#define STM32_ADCPRE_DIV6 (2 << 14) /**< PPRE2 divided by 6. */ -#define STM32_ADCPRE_DIV8 (3 << 14) /**< PPRE2 divided by 8. */ - -#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_PREDIV1 (1 << 16) /**< PLL clock source is - PREDIV1. */ - -#define STM32_OTGFSPRE_DIV2 (1 << 22) /**< HCLK*2 divided by 2. */ -#define STM32_OTGFSPRE_DIV3 (0 << 22) /**< HCLK*2 divided by 3. */ - -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -#define STM32_MCOSEL_PLL2 (8 << 24) /**< PLL2 clock on MCO pin. */ -#define STM32_MCOSEL_PLL3DIV2 (9 << 24) /**< PLL3/2 clock on MCO pin. */ -#define STM32_MCOSEL_XT1 (10 << 24) /**< XT1 clock on MCO pin. */ -#define STM32_MCOSEL_PLL3 (11 << 24) /**< PLL3 clock on MCO pin. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 128 used as - RTC clock. */ -/** @} */ - -/** - * @name RCC_CFGR2 register bits definitions - * @{ - */ -#define STM32_PREDIV1SRC_HSE (0 << 16) /**< PREDIV1 source is HSE. */ -#define STM32_PREDIV1SRC_PLL2 (1 << 16) /**< PREDIV1 source is PLL2. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Main clock source selection. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_PREDIV1 -#endif - -/** - * @brief PREDIV1 clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_PREDIV1SRC) || defined(__DOXYGEN__) -#define STM32_PREDIV1SRC STM32_PREDIV1SRC_HSE -#endif - -/** - * @brief PREDIV1 division factor. - * @note The allowed range is 1...16. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_PREDIV1_VALUE) || defined(__DOXYGEN__) -#define STM32_PREDIV1_VALUE 5 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed range is 4...9. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 9 -#endif - -/** - * @brief PREDIV2 division factor. - * @note The allowed range is 1...16. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_PREDIV2_VALUE) || defined(__DOXYGEN__) -#define STM32_PREDIV2_VALUE 5 -#endif - -/** - * @brief PLL2 multiplier value. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_PLL2MUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2MUL_VALUE 8 -#endif - -/** - * @brief PLL3 multiplier value. - * @note The default value is calculated for a 50MHz clock from - * a 25MHz crystal. - */ -#if !defined(STM32_PLL3MUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3MUL_VALUE 10 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 72MHz system clock from - * a 25MHz crystal using both PLL and PLL2. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV2 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief ADC prescaler value. - */ -#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) -#define STM32_ADCPRE STM32_ADCPRE_DIV4 -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_OTG_CLOCK_REQUIRED) || defined(__DOXYGEN__) -#define STM32_OTG_CLOCK_REQUIRED TRUE -#endif - -/** - * @brief OTG prescaler initialization. - */ -#if !defined(STM32_OTGFSPRE) || defined(__DOXYGEN__) -#define STM32_OTGFSPRE STM32_OTGFSPRE_DIV3 -#endif - -/** - * @brief Dedicated I2S clock setting. - */ -#if !defined(STM32_I2S_CLOCK_REQUIRED) || defined(__DOXYGEN__) -#define STM32_I2S_CLOCK_REQUIRED FALSE -#endif - -/** - * @brief MCO pin setting. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_HSEDIV -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F107_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F107_MCUCONF not defined" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif - -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_PREDIV1) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - (((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL2) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL3) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL3DIV2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ - (STM32_MCOSEL == STM32_MCOSEL_XT1) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL1 activation conditions.*/ -#if STM32_OTG_CLOCK_REQUIRED || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - defined(__DOXYGEN__) -/** - * @brief PLL1 activation flag. - */ -#define STM32_ACTIVATE_PLL1 TRUE -#else -#define STM32_ACTIVATE_PLL1 FALSE -#endif - -/* PLL2 activation conditions.*/ -#if ((STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2) && STM32_ACTIVATE_PLL1) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL2) || defined(__DOXYGEN__) -/** - * @brief PLL2 activation flag. - */ -#define STM32_ACTIVATE_PLL2 TRUE -#else -#define STM32_ACTIVATE_PLL2 FALSE -#endif - -/* PLL3 activation conditions.*/ -#if STM32_I2S_CLOCK_REQUIRED || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL3DIV2) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL3) || \ - defined(__DOXYGEN__) -/** - * @brief PLL3 activation flag. - */ -#define STM32_ACTIVATE_PLL3 TRUE -#else -#define STM32_ACTIVATE_PLL3 FALSE -#endif - -/** - * @brief PREDIV1 field. - */ -#if (STM32_PREDIV1_VALUE >= 1) && (STM32_PREDIV1_VALUE <= 16) || \ - defined(__DOXYGEN__) -#define STM32_PREDIV1 ((STM32_PREDIV1_VALUE - 1) << 0) -#else -#error "invalid STM32_PREDIV1_VALUE value specified" -#endif - -/** - * @brief PREDIV2 field. - */ -#if (STM32_PREDIV2_VALUE >= 1) && (STM32_PREDIV2_VALUE <= 16) || \ - defined(__DOXYGEN__) -#define STM32_PREDIV2 ((STM32_PREDIV2_VALUE - 1) << 4) -#else -#error "invalid STM32_PREDIV2_VALUE value specified" -#endif - -/** - * @brief PLLMUL field. - */ -#if ((STM32_PLLMUL_VALUE >= 4) && (STM32_PLLMUL_VALUE <= 9)) || \ - defined(__DOXYGEN__) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLL2MUL field. - */ -#if ((STM32_PLL2MUL_VALUE >= 8) && (STM32_PLL2MUL_VALUE <= 14)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2MUL ((STM32_PLL2MUL_VALUE - 2) << 8) -#elif (STM32_PLL2MUL_VALUE == 16) -#define STM32_PLL2MUL (14 << 8) -#elif (STM32_PLL2MUL_VALUE == 20) -#define STM32_PLL2MUL (15 << 8) -#else -#error "invalid STM32_PLL2MUL_VALUE value specified" -#endif - -/** - * @brief PLL3MUL field. - */ -#if ((STM32_PLL3MUL_VALUE >= 8) && (STM32_PLL3MUL_VALUE <= 14)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3MUL ((STM32_PLL3MUL_VALUE - 2) << 12) -#elif (STM32_PLL3MUL_VALUE == 16) -#define STM32_PLL3MUL (14 << 12) -#elif (STM32_PLL3MUL_VALUE == 20) -#define STM32_PLL3MUL (15 << 12) -#else -#error "invalid STM32_PLL3MUL_VALUE value specified" -#endif - -/** - * @brief PLL2 input frequency. - */ -#define STM32_PLL2CLKIN (STM32_HSECLK / STM32_PREDIV2_VALUE) - -/* PLL2 input frequency range check.*/ -#if (STM32_PLL2CLKIN < STM32_PLL23IN_MIN) || \ - (STM32_PLL2CLKIN > STM32_PLL23IN_MAX) -#error "STM32_PLL2CLKIN outside acceptable range (STM32_PLL23IN_MIN...STM32_PLL23IN_MAX)" -#endif - -/** - * @brief PLL2 output clock frequency. - */ -#define STM32_PLL2CLKOUT (STM32_PLL2CLKIN * STM32_PLL2MUL_VALUE) - -/** - * @brief PLL2 VCO clock frequency. - */ -#define STM32_PLL2VCO (STM32_PLL2CLKOUT * 2) - -/* PLL2 output frequency range check.*/ -#if (STM32_PLL2VCO < STM32_PLL23VCO_MIN) || \ - (STM32_PLL2VCO > STM32_PLL23VCO_MAX) -#error "STM32_PLL2VCO outside acceptable range (STM32_PLL23VCO_MIN...STM32_PLL23VCO_MAX)" -#endif - -/** - * @brief PLL3 input frequency. - */ -#define STM32_PLL3CLKIN (STM32_HSECLK / STM32_PREDIV2_VALUE) - -/* PLL3 input frequency range check.*/ -#if (STM32_PLL3CLKIN < STM32_PLL23IN_MIN) || \ - (STM32_PLL3CLKIN > STM32_PLL23IN_MAX) -#error "STM32_PLL3CLKIN outside acceptable range (STM32_PLL23IN_MIN...STM32_PLL23IN_MAX)" -#endif - -/** - * @brief PLL3 output clock frequency. - */ -#define STM32_PLL3CLKOUT (STM32_PLL3CLKIN * STM32_PLL3MUL_VALUE) - -/** - * @brief PLL3 VCO clock frequency. - */ -#define STM32_PLL3VCO (STM32_PLL3CLKOUT * 2) - -/* PLL3 output frequency range check.*/ -#if (STM32_PLL3VCO < STM32_PLL23VCO_MIN) || \ - (STM32_PLL3VCO > STM32_PLL23VCO_MAX) -#error "STM32_PLL3CLKOUT outside acceptable range (STM32_PLL23VCO_MIN...STM32_PLL23VCO_MAX)" -#endif - -/** - * @brief PREDIV1 input frequency. - */ -#if (STM32_PREDIV1SRC == STM32_PREDIV1SRC_HSE) || defined(__DOXYGEN__) -#define STM32_PREDIV1CLK STM32_HSECLK -#elif STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2 -#define STM32_PREDIV1CLK STM32_PLL2CLKOUT -#else -#error "invalid STM32_PREDIV1SRC value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_PREDIV1) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_PREDIV1CLK / STM32_PREDIV1_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / 2) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLL1IN_MIN) || (STM32_PLLCLKIN > STM32_PLL1IN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLL1IN_MIN...STM32_PLL1IN_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/** - * @brief PLL VCO clock frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKOUT * 2) - -/* PLL output frequency range check.*/ -#if (STM32_PLLVCO < STM32_PLL1VCO_MIN) || (STM32_PLLVCO > STM32_PLL1VCO_MAX) -#error "STM32_PLLVCO outside acceptable range (STM32_PLL1VCO_MIN...STM32_PLL1VCO_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_PLLCLKOUT -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 128) -#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK -#define STM32_RTCCLK 0 -#else -#error "invalid source selected for RTC clock" -#endif - -/** - * @brief ADC frequency. - */ -#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_ADCCLK (STM32_PCLK2 / 2) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 -#define STM32_ADCCLK (STM32_PCLK2 / 4) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 -#define STM32_ADCCLK (STM32_PCLK2 / 6) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 -#define STM32_ADCCLK (STM32_PCLK2 / 8) -#else -#error "invalid STM32_ADCPRE value specified" -#endif - -/* ADC frequency check.*/ -#if STM32_ADCCLK > STM32_ADCCLK_MAX -#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" -#endif - -/** - * @brief OTG frequency. - */ -#if (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV3) || defined(__DOXYGEN__) -#define STM32_OTGFSCLK (STM32_PLLVCO / 3) -#elif (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV2) -#define STM32_OTGFSCLK (STM32_PLLVCO / 2) -#else -#error "invalid STM32_OTGFSPRE value specified" -#endif - -/** - * @brief Timers 2, 3, 4, 5, 6, 7 clock. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers 1, 8 clock. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000010 -#elif STM32_HCLK <= 48000000 -#define STM32_FLASHBITS 0x00000011 -#else -#define STM32_FLASHBITS 0x00000012 -#endif - -#endif /* _HAL_LLD_F105_F107_H_ */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @defgroup STM32F10X_CL_HAL STM32F105/F107 HAL Support + * @details HAL support for STM32 Connectivity Line sub-family. + * + * @ingroup HAL + */ + +/** + * @file STM32F1xx/hal_lld_f105_f107.h + * @brief STM32F10x Connectivity Line HAL subsystem low level driver header. + * + * @addtogroup STM32F10X_CL_HAL + * @{ + */ + +#ifndef _HAL_LLD_F105_F107_H_ +#define _HAL_LLD_F105_F107_H_ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define STM32_SYSCLK_MAX 72000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 50000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLL1IN_MAX 12000000 + +/** + * @brief Minimum PLL1 input clock frequency. + */ +#define STM32_PLL1IN_MIN 3000000 + +/** + * @brief Maximum PLL1 input clock frequency. + */ +#define STM32_PLL23IN_MAX 5000000 + +/** + * @brief Minimum PLL2 and PLL3 input clock frequency. + */ +#define STM32_PLL23IN_MIN 3000000 + +/** + * @brief Maximum PLL1 VCO clock frequency. + */ +#define STM32_PLL1VCO_MAX 144000000 + +/** + * @brief Minimum PLL1 VCO clock frequency. + */ +#define STM32_PLL1VCO_MIN 36000000 + +/** + * @brief Maximum PLL2 and PLL3 VCO clock frequency. + */ +#define STM32_PLL23VCO_MAX 148000000 + +/** + * @brief Minimum PLL2 and PLL3 VCO clock frequency. + */ +#define STM32_PLL23VCO_MIN 80000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 36000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 72000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 14000000 + +/** + * @brief Maximum SPI/I2S clock frequency. + */ +#define STM32_SPII2S_MAX 18000000 +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_ADCPRE_DIV2 (0 << 14) /**< PPRE2 divided by 2. */ +#define STM32_ADCPRE_DIV4 (1 << 14) /**< PPRE2 divided by 4. */ +#define STM32_ADCPRE_DIV6 (2 << 14) /**< PPRE2 divided by 6. */ +#define STM32_ADCPRE_DIV8 (3 << 14) /**< PPRE2 divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_PREDIV1 (1 << 16) /**< PLL clock source is + PREDIV1. */ + +#define STM32_OTGFSPRE_DIV2 (1 << 22) /**< HCLK*2 divided by 2. */ +#define STM32_OTGFSPRE_DIV3 (0 << 22) /**< HCLK*2 divided by 3. */ + +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +#define STM32_MCOSEL_PLL2 (8 << 24) /**< PLL2 clock on MCO pin. */ +#define STM32_MCOSEL_PLL3DIV2 (9 << 24) /**< PLL3/2 clock on MCO pin. */ +#define STM32_MCOSEL_XT1 (10 << 24) /**< XT1 clock on MCO pin. */ +#define STM32_MCOSEL_PLL3 (11 << 24) /**< PLL3 clock on MCO pin. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 128 used as + RTC clock. */ +/** @} */ + +/** + * @name RCC_CFGR2 register bits definitions + * @{ + */ +#define STM32_PREDIV1SRC_HSE (0 << 16) /**< PREDIV1 source is HSE. */ +#define STM32_PREDIV1SRC_PLL2 (1 << 16) /**< PREDIV1 source is PLL2. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Main clock source selection. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_PREDIV1 +#endif + +/** + * @brief PREDIV1 clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_PREDIV1SRC) || defined(__DOXYGEN__) +#define STM32_PREDIV1SRC STM32_PREDIV1SRC_HSE +#endif + +/** + * @brief PREDIV1 division factor. + * @note The allowed range is 1...16. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_PREDIV1_VALUE) || defined(__DOXYGEN__) +#define STM32_PREDIV1_VALUE 5 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed range is 4...9. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 9 +#endif + +/** + * @brief PREDIV2 division factor. + * @note The allowed range is 1...16. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_PREDIV2_VALUE) || defined(__DOXYGEN__) +#define STM32_PREDIV2_VALUE 5 +#endif + +/** + * @brief PLL2 multiplier value. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_PLL2MUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2MUL_VALUE 8 +#endif + +/** + * @brief PLL3 multiplier value. + * @note The default value is calculated for a 50MHz clock from + * a 25MHz crystal. + */ +#if !defined(STM32_PLL3MUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3MUL_VALUE 10 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 72MHz system clock from + * a 25MHz crystal using both PLL and PLL2. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief ADC prescaler value. + */ +#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) +#define STM32_ADCPRE STM32_ADCPRE_DIV4 +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_OTG_CLOCK_REQUIRED) || defined(__DOXYGEN__) +#define STM32_OTG_CLOCK_REQUIRED TRUE +#endif + +/** + * @brief OTG prescaler initialization. + */ +#if !defined(STM32_OTGFSPRE) || defined(__DOXYGEN__) +#define STM32_OTGFSPRE STM32_OTGFSPRE_DIV3 +#endif + +/** + * @brief Dedicated I2S clock setting. + */ +#if !defined(STM32_I2S_CLOCK_REQUIRED) || defined(__DOXYGEN__) +#define STM32_I2S_CLOCK_REQUIRED FALSE +#endif + +/** + * @brief MCO pin setting. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_HSEDIV +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F107_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F107_MCUCONF not defined" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif + +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_PREDIV1) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + (((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL2) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL3) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL3DIV2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ + (STM32_MCOSEL == STM32_MCOSEL_XT1) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL1 activation conditions.*/ +#if STM32_OTG_CLOCK_REQUIRED || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + defined(__DOXYGEN__) +/** + * @brief PLL1 activation flag. + */ +#define STM32_ACTIVATE_PLL1 TRUE +#else +#define STM32_ACTIVATE_PLL1 FALSE +#endif + +/* PLL2 activation conditions.*/ +#if ((STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2) && STM32_ACTIVATE_PLL1) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL2) || defined(__DOXYGEN__) +/** + * @brief PLL2 activation flag. + */ +#define STM32_ACTIVATE_PLL2 TRUE +#else +#define STM32_ACTIVATE_PLL2 FALSE +#endif + +/* PLL3 activation conditions.*/ +#if STM32_I2S_CLOCK_REQUIRED || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL3DIV2) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL3) || \ + defined(__DOXYGEN__) +/** + * @brief PLL3 activation flag. + */ +#define STM32_ACTIVATE_PLL3 TRUE +#else +#define STM32_ACTIVATE_PLL3 FALSE +#endif + +/** + * @brief PREDIV1 field. + */ +#if (STM32_PREDIV1_VALUE >= 1) && (STM32_PREDIV1_VALUE <= 16) || \ + defined(__DOXYGEN__) +#define STM32_PREDIV1 ((STM32_PREDIV1_VALUE - 1) << 0) +#else +#error "invalid STM32_PREDIV1_VALUE value specified" +#endif + +/** + * @brief PREDIV2 field. + */ +#if (STM32_PREDIV2_VALUE >= 1) && (STM32_PREDIV2_VALUE <= 16) || \ + defined(__DOXYGEN__) +#define STM32_PREDIV2 ((STM32_PREDIV2_VALUE - 1) << 4) +#else +#error "invalid STM32_PREDIV2_VALUE value specified" +#endif + +/** + * @brief PLLMUL field. + */ +#if ((STM32_PLLMUL_VALUE >= 4) && (STM32_PLLMUL_VALUE <= 9)) || \ + defined(__DOXYGEN__) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLL2MUL field. + */ +#if ((STM32_PLL2MUL_VALUE >= 8) && (STM32_PLL2MUL_VALUE <= 14)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2MUL ((STM32_PLL2MUL_VALUE - 2) << 8) +#elif (STM32_PLL2MUL_VALUE == 16) +#define STM32_PLL2MUL (14 << 8) +#elif (STM32_PLL2MUL_VALUE == 20) +#define STM32_PLL2MUL (15 << 8) +#else +#error "invalid STM32_PLL2MUL_VALUE value specified" +#endif + +/** + * @brief PLL3MUL field. + */ +#if ((STM32_PLL3MUL_VALUE >= 8) && (STM32_PLL3MUL_VALUE <= 14)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3MUL ((STM32_PLL3MUL_VALUE - 2) << 12) +#elif (STM32_PLL3MUL_VALUE == 16) +#define STM32_PLL3MUL (14 << 12) +#elif (STM32_PLL3MUL_VALUE == 20) +#define STM32_PLL3MUL (15 << 12) +#else +#error "invalid STM32_PLL3MUL_VALUE value specified" +#endif + +/** + * @brief PLL2 input frequency. + */ +#define STM32_PLL2CLKIN (STM32_HSECLK / STM32_PREDIV2_VALUE) + +/* PLL2 input frequency range check.*/ +#if (STM32_PLL2CLKIN < STM32_PLL23IN_MIN) || \ + (STM32_PLL2CLKIN > STM32_PLL23IN_MAX) +#error "STM32_PLL2CLKIN outside acceptable range (STM32_PLL23IN_MIN...STM32_PLL23IN_MAX)" +#endif + +/** + * @brief PLL2 output clock frequency. + */ +#define STM32_PLL2CLKOUT (STM32_PLL2CLKIN * STM32_PLL2MUL_VALUE) + +/** + * @brief PLL2 VCO clock frequency. + */ +#define STM32_PLL2VCO (STM32_PLL2CLKOUT * 2) + +/* PLL2 output frequency range check.*/ +#if (STM32_PLL2VCO < STM32_PLL23VCO_MIN) || \ + (STM32_PLL2VCO > STM32_PLL23VCO_MAX) +#error "STM32_PLL2VCO outside acceptable range (STM32_PLL23VCO_MIN...STM32_PLL23VCO_MAX)" +#endif + +/** + * @brief PLL3 input frequency. + */ +#define STM32_PLL3CLKIN (STM32_HSECLK / STM32_PREDIV2_VALUE) + +/* PLL3 input frequency range check.*/ +#if (STM32_PLL3CLKIN < STM32_PLL23IN_MIN) || \ + (STM32_PLL3CLKIN > STM32_PLL23IN_MAX) +#error "STM32_PLL3CLKIN outside acceptable range (STM32_PLL23IN_MIN...STM32_PLL23IN_MAX)" +#endif + +/** + * @brief PLL3 output clock frequency. + */ +#define STM32_PLL3CLKOUT (STM32_PLL3CLKIN * STM32_PLL3MUL_VALUE) + +/** + * @brief PLL3 VCO clock frequency. + */ +#define STM32_PLL3VCO (STM32_PLL3CLKOUT * 2) + +/* PLL3 output frequency range check.*/ +#if (STM32_PLL3VCO < STM32_PLL23VCO_MIN) || \ + (STM32_PLL3VCO > STM32_PLL23VCO_MAX) +#error "STM32_PLL3CLKOUT outside acceptable range (STM32_PLL23VCO_MIN...STM32_PLL23VCO_MAX)" +#endif + +/** + * @brief PREDIV1 input frequency. + */ +#if (STM32_PREDIV1SRC == STM32_PREDIV1SRC_HSE) || defined(__DOXYGEN__) +#define STM32_PREDIV1CLK STM32_HSECLK +#elif STM32_PREDIV1SRC == STM32_PREDIV1SRC_PLL2 +#define STM32_PREDIV1CLK STM32_PLL2CLKOUT +#else +#error "invalid STM32_PREDIV1SRC value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_PREDIV1) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_PREDIV1CLK / STM32_PREDIV1_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLL1IN_MIN) || (STM32_PLLCLKIN > STM32_PLL1IN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLL1IN_MIN...STM32_PLL1IN_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/** + * @brief PLL VCO clock frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKOUT * 2) + +/* PLL output frequency range check.*/ +#if (STM32_PLLVCO < STM32_PLL1VCO_MIN) || (STM32_PLLVCO > STM32_PLL1VCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLL1VCO_MIN...STM32_PLL1VCO_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_PLLCLKOUT +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 128) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + +/** + * @brief ADC frequency. + */ +#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_ADCCLK (STM32_PCLK2 / 2) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 +#define STM32_ADCCLK (STM32_PCLK2 / 4) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 +#define STM32_ADCCLK (STM32_PCLK2 / 6) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 +#define STM32_ADCCLK (STM32_PCLK2 / 8) +#else +#error "invalid STM32_ADCPRE value specified" +#endif + +/* ADC frequency check.*/ +#if STM32_ADCCLK > STM32_ADCCLK_MAX +#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" +#endif + +/** + * @brief OTG frequency. + */ +#if (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV3) || defined(__DOXYGEN__) +#define STM32_OTGFSCLK (STM32_PLLVCO / 3) +#elif (STM32_OTGFSPRE == STM32_OTGFSPRE_DIV2) +#define STM32_OTGFSCLK (STM32_PLLVCO / 2) +#else +#error "invalid STM32_OTGFSPRE value specified" +#endif + +/** + * @brief Timers 2, 3, 4, 5, 6, 7 clock. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 1, 8 clock. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000010 +#elif STM32_HCLK <= 48000000 +#define STM32_FLASHBITS 0x00000011 +#else +#define STM32_FLASHBITS 0x00000012 +#endif + +#endif /* _HAL_LLD_F105_F107_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F37x/hal_lld.c b/os/hal/ports/STM32/STM32F37x/hal_lld.c index 902f688ac4..b41bdc6334 100644 --- a/os/hal/ports/STM32/STM32F37x/hal_lld.c +++ b/os/hal/ports/STM32/STM32F37x/hal_lld.c @@ -1,223 +1,223 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F37x/hal_lld.c - * @brief STM32F37x HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f3xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - - /* If enabled then the LSE is started.*/ -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB(~STM32_GPIO_EN_MASK); - rccResetAPB1(0xFFFFFFFF); - rccResetAPB2(0xFFFFFFFF); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** - * @brief STM32 clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. Clearing the register has to be postponed after HSI is the - new source.*/ - RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers finally cleared to reset values.*/ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - -#if STM32_HSE_ENABLED - /* HSE activation.*/ -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - /* No HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON; -#endif - while (!(RCC->CR & RCC_CR_HSERDY)) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - - /* Clock settings.*/ - RCC->CFGR = STM32_SDPRE | STM32_MCOSEL | STM32_USBPRE | - STM32_PLLMUL | STM32_PLLSRC | STM32_ADCPRE | - STM32_PPRE1 | STM32_PPRE2 | STM32_HPRE; - RCC->CFGR2 = STM32_PREDIV; - RCC->CFGR3 = STM32_USART3SW | STM32_USART2SW | STM32_I2C2SW | - STM32_I2C1SW | STM32_USART1SW; - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL is stable. */ -#endif - - /* Flash setup and final clock selection. */ - FLASH->ACR = STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - /* Switches clock source.*/ - RCC->CFGR |= STM32_SW; - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; /* Waits selection complete. */ -#endif -#endif /* !STM32_NO_INIT */ -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F37x/hal_lld.c + * @brief STM32F37x HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f3xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB(~STM32_GPIO_EN_MASK); + rccResetAPB1(0xFFFFFFFF); + rccResetAPB2(0xFFFFFFFF); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** + * @brief STM32 clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while (!(RCC->CR & RCC_CR_HSERDY)) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + + /* Clock settings.*/ + RCC->CFGR = STM32_SDPRE | STM32_MCOSEL | STM32_USBPRE | + STM32_PLLMUL | STM32_PLLSRC | STM32_ADCPRE | + STM32_PPRE1 | STM32_PPRE2 | STM32_HPRE; + RCC->CFGR2 = STM32_PREDIV; + RCC->CFGR3 = STM32_USART3SW | STM32_USART2SW | STM32_I2C2SW | + STM32_I2C1SW | STM32_USART1SW; + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + + /* Flash setup and final clock selection. */ + FLASH->ACR = STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + /* Switches clock source.*/ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; /* Waits selection complete. */ +#endif +#endif /* !STM32_NO_INIT */ +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F37x/hal_lld.h b/os/hal/ports/STM32/STM32F37x/hal_lld.h index 4214a56b5c..b0318bffe4 100644 --- a/os/hal/ports/STM32/STM32F37x/hal_lld.h +++ b/os/hal/ports/STM32/STM32F37x/hal_lld.h @@ -1,1030 +1,1034 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F37x/hal_lld.h - * @brief STM32F37x HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32F373xC for Analog & DSP devices. - * - STM32F378xx for Analog & DSP devices. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32F373xC) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F373xC Analog & DSP" - -#elif defined(STM32F378xx) -#define PLATFORM_NAME "STM32F378xx Analog & DSP" - -#else -#error "STM32F7x device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32F37X) || defined(__DOXYGEN__) -#define STM32F37X -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum system clock frequency. - */ -#define STM32_SYSCLK_MAX 72000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 32000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 24000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 1000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 72000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 16000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 36000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 72000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 14000000 - -/** - * @brief Minimum ADC clock frequency. - */ -#define STM32_ADCCLK_MIN 600000 - -/** - * @brief Maximum SDADC clock frequency in fast mode. - */ -#define STM32_SDADCCLK_FAST_MAX 6000000 - -/** - * @brief Maximum SDADC clock frequency in slow mode. - */ -#define STM32_SDADCCLK_SLOW_MAX 1500000 - -/** - * @brief Minimum SDADC clock frequency. - */ -#define STM32_SDADCCLK_MIN 500000 -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 8000000 /**< High speed internal clock. */ -#define STM32_LSICLK 40000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7U << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0U << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1U << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2U << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3U << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4U << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5U << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6U << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7U << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_HSI (0U << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1U << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2U << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_DIV1 (0U << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8u << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9U << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10U << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11U << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12U << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13U << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14U << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15U << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_DIV1 (0U << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4U << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5U << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6U << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7U << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_DIV1 (0U << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4U << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5U << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6U << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7U << 11) /**< HCLK divided by 16. */ - -#define STM32_ADCPRE_DIV2 (0U << 14) /**< PPRE2 divided by 2. */ -#define STM32_ADCPRE_DIV4 (1U << 14) /**< PPRE2 divided by 4. */ -#define STM32_ADCPRE_DIV6 (2U << 14) /**< PPRE2 divided by 6. */ -#define STM32_ADCPRE_DIV8 (3U << 14) /**< PPRE2 divided by 8. */ - -#define STM32_PLLSRC_HSI (0U << 16) /**< PLL clock source is HSI/2. */ -#define STM32_PLLSRC_HSE (1U << 16) /**< PLL clock source is - HSE/PREDIV. */ - -#define STM32_USBPRE_DIV1P5 (0U << 22) /**< USB clock is PLLCLK/1.5. */ -#define STM32_USBPRE_DIV1 (1U << 22) /**< USB clock is PLLCLK/1. */ - -#define STM32_MCOSEL_NOCLOCK (0U << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_LSI (2U << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (3U << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (4U << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (5U << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (6U << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLDIV2 (7U << 24) /**< PLL/2 clock on MCO pin. */ - -#define STM32_SDPRE_DIV2 (16U << 27) /**< SYSCLK divided by 2. */ -#define STM32_SDPRE_DIV4 (17U << 27) /**< SYSCLK divided by 4. */ -#define STM32_SDPRE_DIV6 (18U << 27) /**< SYSCLK divided by 6. */ -#define STM32_SDPRE_DIV8 (19U << 27) /**< SYSCLK divided by 8. */ -#define STM32_SDPRE_DIV10 (20U << 27) /**< SYSCLK divided by 10. */ -#define STM32_SDPRE_DIV12 (21U << 27) /**< SYSCLK divided by 12. */ -#define STM32_SDPRE_DIV14 (22U << 27) /**< SYSCLK divided by 14. */ -#define STM32_SDPRE_DIV16 (23U << 27) /**< SYSCLK divided by 16. */ -#define STM32_SDPRE_DIV20 (24U << 27) /**< SYSCLK divided by 20. */ -#define STM32_SDPRE_DIV24 (25U << 27) /**< SYSCLK divided by 24. */ -#define STM32_SDPRE_DIV28 (26U << 27) /**< SYSCLK divided by 28. */ -#define STM32_SDPRE_DIV32 (27U << 27) /**< SYSCLK divided by 32. */ -#define STM32_SDPRE_DIV36 (28U << 27) /**< SYSCLK divided by 36. */ -#define STM32_SDPRE_DIV40 (29U << 27) /**< SYSCLK divided by 40. */ -#define STM32_SDPRE_DIV44 (30U << 27) /**< SYSCLK divided by 44. */ -#define STM32_SDPRE_DIV48 (31U << 27) /**< SYSCLK divided by 48. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3U << 8) /**< RTC clock source mask. */ -#define STM32_RTCSEL_NOCLOCK (0U << 8) /**< No clock. */ -#define STM32_RTCSEL_LSE (1U << 8) /**< LSE used as RTC clock. */ -#define STM32_RTCSEL_LSI (2U << 8) /**< LSI used as RTC clock. */ -#define STM32_RTCSEL_HSEDIV (3U << 8) /**< HSE divided by 32 used as - RTC clock. */ -/** @} */ - -/** - * @name RCC_CFGR2 register bits definitions - * @{ - */ -#define STM32_PREDIV_MASK (15U << 0) /**< PREDIV divisor mask. */ -/** @} */ - -/** - * @name RCC_CFGR3 register bits definitions - * @{ - */ -#define STM32_USART1SW_MASK (3U << 0) /**< USART1 clock source mask. */ -#define STM32_USART1SW_PCLK (0U << 0) /**< USART1 clock is PCLK. */ -#define STM32_USART1SW_SYSCLK (1U << 0) /**< USART1 clock is SYSCLK. */ -#define STM32_USART1SW_LSE (2U << 0) /**< USART1 clock is LSE. */ -#define STM32_USART1SW_HSI (3U << 0) /**< USART1 clock is HSI. */ -#define STM32_I2C1SW_MASK (1U << 4) /**< I2C1 clock source mask. */ -#define STM32_I2C1SW_HSI (0U << 4) /**< I2C1 clock is HSI. */ -#define STM32_I2C1SW_SYSCLK (1U << 4) /**< I2C1 clock is SYSCLK. */ -#define STM32_I2C2SW_MASK (1U << 5) /**< I2C2 clock source mask. */ -#define STM32_I2C2SW_HSI (0U << 5) /**< I2C2 clock is HSI. */ -#define STM32_I2C2SW_SYSCLK (1U << 5) /**< I2C2 clock is SYSCLK. */ -#define STM32_USART2SW_MASK (3U << 16) /**< USART2 clock source mask. */ -#define STM32_USART2SW_PCLK (0U << 16) /**< USART2 clock is PCLK. */ -#define STM32_USART2SW_SYSCLK (1U << 16) /**< USART2 clock is SYSCLK. */ -#define STM32_USART2SW_LSE (2U << 16) /**< USART2 clock is LSE. */ -#define STM32_USART2SW_HSI (3U << 16) /**< USART2 clock is HSI. */ -#define STM32_USART3SW_MASK (3U << 18) /**< USART3 clock source mask. */ -#define STM32_USART3SW_PCLK (0U << 18) /**< USART3 clock is PCLK. */ -#define STM32_USART3SW_SYSCLK (1U << 18) /**< USART3 clock is SYSCLK. */ -#define STM32_USART3SW_LSE (2U << 18) /**< USART3 clock is LSE. */ -#define STM32_USART3SW_HSI (3U << 18) /**< USART3 clock is HSI. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief Crystal PLL pre-divider. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PREDIV_VALUE 1 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed range is 2...16. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 9 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV2 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief MCO pin setting. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief ADC prescaler value. - */ -#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) -#define STM32_ADCPRE STM32_ADCPRE_DIV4 -#endif - -/** - * @brief SDADC prescaler value. - */ -#if !defined(STM32_SDPRE) || defined(__DOXYGEN__) -#define STM32_SDPRE STM32_SDPRE_DIV12 -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SW) || defined(__DOXYGEN__) -#define STM32_USART1SW STM32_USART1SW_PCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SW) || defined(__DOXYGEN__) -#define STM32_USART2SW STM32_USART2SW_PCLK -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SW) || defined(__DOXYGEN__) -#define STM32_USART3SW STM32_USART3SW_PCLK -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__) -#define STM32_I2C1SW STM32_I2C1SW_SYSCLK -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SW) || defined(__DOXYGEN__) -#define STM32_I2C2SW STM32_I2C2SW_SYSCLK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_REQUIRED TRUE -#endif - -/** - * @brief USB prescaler initialization. - */ -#if !defined(STM32_USBPRE) || defined(__DOXYGEN__) -#define STM32_USBPRE STM32_USBPRE_DIV1P5 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F37x_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F37x_MCUCONF not defined" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if STM32_USART1SW == STM32_USART1SW_HSI -#error "HSI not enabled, required by STM32_USART1SW" -#endif - -#if STM32_USART2SW == STM32_USART2SW_HSI -#error "HSI not enabled, required by STM32_USART2SW" -#endif - -#if STM32_USART3SW == STM32_USART3SW_HSI -#error "HSI not enabled, required by STM32_USART3SW" -#endif - -#if STM32_I2C1SW == STM32_I2C1SW_HSI -#error "HSI not enabled, required by STM32_I2C1SW" -#endif - -#if STM32_I2C2SW == STM32_I2C2SW_HSI -#error "HSI not enabled, required by STM32_I2C2SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif - -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if !defined(STM32_LSECLK) || (STM32_LSECLK == 0) -#error "STM32_LSECLK not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined" -#endif - -#if (STM32_LSEDRV >> 3) > 3 -#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" -#endif - -#if STM32_USART1SW == STM32_USART1SW_LSE -#error "LSE not enabled, required by STM32_USART1SW" -#endif - -#if STM32_USART2SW == STM32_USART2SW_LSE -#error "LSE not enabled, required by STM32_USART2SW" -#endif - -#if STM32_USART3SW == STM32_USART3SW_LSE -#error "LSE not enabled, required by STM32_USART3SW" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL activation conditions.*/ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - STM32_USB_CLOCK_REQUIRED || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/* HSE prescaler setting check.*/ -#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16)) -#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0) -#else -#error "invalid STM32_PREDIV value specified" -#endif - -/** - * @brief PLLMUL field. - */ -#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / 2) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_PLLCLKOUT -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) -#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK -#define STM32_RTCCLK 0 -#else -#error "invalid source selected for RTC clock" -#endif - -/** - * @brief ADC frequency. - */ -#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_ADCCLK (STM32_PCLK2 / 2) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 -#define STM32_ADCCLK (STM32_PCLK2 / 4) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 -#define STM32_ADCCLK (STM32_PCLK2 / 6) -#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 -#define STM32_ADCCLK (STM32_PCLK2 / 8) -#else -#error "invalid STM32_ADCPRE value specified" -#endif - -/* ADC maximum frequency check.*/ -#if STM32_ADC_USE_ADC1 && (STM32_ADCCLK > STM32_ADCCLK_MAX) -#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" -#endif - -/* ADC minimum frequency check.*/ -#if STM32_ADC_USE_ADC1 && (STM32_ADCCLK < STM32_ADCCLK_MIN) -#error "STM32_ADCCLK exceeding minimum frequency (STM32_ADCCLK_MIN)" -#endif - -/** - * @brief SDADC frequency. - */ -#if (STM32_SDPRE == STM32_SDPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 2) -#elif (STM32_SDPRE == STM32_SDPRE_DIV4) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 4) -#elif (STM32_SDPRE == STM32_SDPRE_DIV6) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 6) -#elif (STM32_SDPRE == STM32_SDPRE_DIV8) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 8) -#elif (STM32_SDPRE == STM32_SDPRE_DIV10) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 10) -#elif (STM32_SDPRE == STM32_SDPRE_DIV12) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 12) -#elif (STM32_SDPRE == STM32_SDPRE_DIV14) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 14) -#elif (STM32_SDPRE == STM32_SDPRE_DIV16) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 16) -#elif (STM32_SDPRE == STM32_SDPRE_DIV20) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 20) -#elif (STM32_SDPRE == STM32_SDPRE_DIV24) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 24) -#elif (STM32_SDPRE == STM32_SDPRE_DIV28) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 28) -#elif (STM32_SDPRE == STM32_SDPRE_DIV32) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 32) -#elif (STM32_SDPRE == STM32_SDPRE_DIV36) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 36) -#elif (STM32_SDPRE == STM32_SDPRE_DIV40) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 40) -#elif (STM32_SDPRE == STM32_SDPRE_DIV44) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 44) -#elif (STM32_SDPRE == STM32_SDPRE_DIV48) || defined(__DOXYGEN__) -#define STM32_SDADCCLK (STM32_SYSCLK / 48) -#else -#error "invalid STM32_SDPRE value specified" -#endif - -/* SDADC maximum frequency check.*/ -#if (STM32_ADC_USE_SDADC1 || \ - STM32_ADC_USE_SDADC2 || \ - STM32_ADC_USE_SDADC3) && (STM32_SDADCCLK > STM32_SDADCCLK_FAST_MAX) -#error "STM32_SDADCCLK exceeding maximum frequency (STM32_SDADCCLK_FAST_MAX)" -#endif - -/* SDADC minimum frequency check.*/ -#if (STM32_ADC_USE_SDADC1 || \ - STM32_ADC_USE_SDADC2 || \ - STM32_ADC_USE_SDADC3) && \ - (STM32_SDADCCLK < STM32_SDADCCLK_MIN) -#error "STM32_SDADCCLK exceeding maximum frequency (STM32_SDADCCLK_MIN)" -#endif - -/** - * @brief I2C1 frequency. - */ -#if STM32_I2C1SW == STM32_I2C1SW_HSI -#define STM32_I2C1CLK STM32_HSICLK -#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 frequency. - */ -#if STM32_I2C2SW == STM32_I2C2SW_HSI -#define STM32_I2C2CLK STM32_HSICLK -#elif STM32_I2C2SW == STM32_I2C2SW_SYSCLK -#define STM32_I2C2CLK STM32_SYSCLK -#else -#error "invalid source selected for I2C2 clock" -#endif - -/** - * @brief USART1 frequency. - */ -#if STM32_USART1SW == STM32_USART1SW_PCLK -#define STM32_USART1CLK STM32_PCLK2 -#elif STM32_USART1SW == STM32_USART1SW_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SW == STM32_USART1SW_LSE -#define STM32_USART1CLK STM32_LSECLK -#elif STM32_USART1SW == STM32_USART1SW_HSI -#define STM32_USART1CLK STM32_HSICLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 frequency. - */ -#if STM32_USART2SW == STM32_USART2SW_PCLK -#define STM32_USART2CLK STM32_PCLK1 -#elif STM32_USART2SW == STM32_USART2SW_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK -#elif STM32_USART2SW == STM32_USART2SW_LSE -#define STM32_USART2CLK STM32_LSECLK -#elif STM32_USART2SW == STM32_USART2SW_HSI -#define STM32_USART2CLK STM32_HSICLK -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 frequency. - */ -#if STM32_USART3SW == STM32_USART3SW_PCLK -#define STM32_USART3CLK STM32_PCLK1 -#elif STM32_USART3SW == STM32_USART3SW_SYSCLK -#define STM32_USART3CLK STM32_SYSCLK -#elif STM32_USART3SW == STM32_USART3SW_LSE -#define STM32_USART3CLK STM32_LSECLK -#elif STM32_USART3SW == STM32_USART3SW_HSI -#define STM32_USART3CLK STM32_HSICLK -#else -#error "invalid source selected for USART3 clock" -#endif - -/** - * @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14, 18 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers 15, 16, 17, 19 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief USB frequency. - */ -#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__) -#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3) -#elif (STM32_USBPRE == STM32_USBPRE_DIV1) -#define STM32_USBCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_USBPRE value specified" -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000010 -#elif STM32_HCLK <= 48000000 -#define STM32_FLASHBITS 0x00000011 -#else -#define STM32_FLASHBITS 0x00000012 -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_registry.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F37x/hal_lld.h + * @brief STM32F37x HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32F373xC for Analog & DSP devices. + * - STM32F378xx for Analog & DSP devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32F373xC) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32F373xC Analog & DSP" + +#elif defined(STM32F378xx) +#define PLATFORM_NAME "STM32F378xx Analog & DSP" + +#else +#error "STM32F7x device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32F37X) || defined(__DOXYGEN__) +#define STM32F37X +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define STM32_SYSCLK_MAX 72000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 32000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 24000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 1000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 72000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 16000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 36000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 72000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 14000000 + +/** + * @brief Minimum ADC clock frequency. + */ +#define STM32_ADCCLK_MIN 600000 + +/** + * @brief Maximum SDADC clock frequency in fast mode. + */ +#define STM32_SDADCCLK_FAST_MAX 6000000 + +/** + * @brief Maximum SDADC clock frequency in slow mode. + */ +#define STM32_SDADCCLK_SLOW_MAX 1500000 + +/** + * @brief Minimum SDADC clock frequency. + */ +#define STM32_SDADCCLK_MIN 500000 +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 8000000 /**< High speed internal clock. */ +#define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7U << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0U << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1U << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2U << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3U << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4U << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5U << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6U << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7U << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_HSI (0U << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1U << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2U << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_DIV1 (0U << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8u << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9U << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10U << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11U << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12U << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13U << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14U << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15U << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_DIV1 (0U << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4U << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5U << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6U << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7U << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_DIV1 (0U << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4U << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5U << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6U << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7U << 11) /**< HCLK divided by 16. */ + +#define STM32_ADCPRE_DIV2 (0U << 14) /**< PPRE2 divided by 2. */ +#define STM32_ADCPRE_DIV4 (1U << 14) /**< PPRE2 divided by 4. */ +#define STM32_ADCPRE_DIV6 (2U << 14) /**< PPRE2 divided by 6. */ +#define STM32_ADCPRE_DIV8 (3U << 14) /**< PPRE2 divided by 8. */ + +#define STM32_PLLSRC_HSI (0U << 16) /**< PLL clock source is HSI/2. */ +#define STM32_PLLSRC_HSE (1U << 16) /**< PLL clock source is + HSE/PREDIV. */ + +#define STM32_USBPRE_DIV1P5 (0U << 22) /**< USB clock is PLLCLK/1.5. */ +#define STM32_USBPRE_DIV1 (1U << 22) /**< USB clock is PLLCLK/1. */ + +#define STM32_MCOSEL_NOCLOCK (0U << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_LSI (2U << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (3U << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (4U << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (5U << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (6U << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLDIV2 (7U << 24) /**< PLL/2 clock on MCO pin. */ + +#define STM32_SDPRE_DIV2 (16U << 27) /**< SYSCLK divided by 2. */ +#define STM32_SDPRE_DIV4 (17U << 27) /**< SYSCLK divided by 4. */ +#define STM32_SDPRE_DIV6 (18U << 27) /**< SYSCLK divided by 6. */ +#define STM32_SDPRE_DIV8 (19U << 27) /**< SYSCLK divided by 8. */ +#define STM32_SDPRE_DIV10 (20U << 27) /**< SYSCLK divided by 10. */ +#define STM32_SDPRE_DIV12 (21U << 27) /**< SYSCLK divided by 12. */ +#define STM32_SDPRE_DIV14 (22U << 27) /**< SYSCLK divided by 14. */ +#define STM32_SDPRE_DIV16 (23U << 27) /**< SYSCLK divided by 16. */ +#define STM32_SDPRE_DIV20 (24U << 27) /**< SYSCLK divided by 20. */ +#define STM32_SDPRE_DIV24 (25U << 27) /**< SYSCLK divided by 24. */ +#define STM32_SDPRE_DIV28 (26U << 27) /**< SYSCLK divided by 28. */ +#define STM32_SDPRE_DIV32 (27U << 27) /**< SYSCLK divided by 32. */ +#define STM32_SDPRE_DIV36 (28U << 27) /**< SYSCLK divided by 36. */ +#define STM32_SDPRE_DIV40 (29U << 27) /**< SYSCLK divided by 40. */ +#define STM32_SDPRE_DIV44 (30U << 27) /**< SYSCLK divided by 44. */ +#define STM32_SDPRE_DIV48 (31U << 27) /**< SYSCLK divided by 48. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3U << 8) /**< RTC clock source mask. */ +#define STM32_RTCSEL_NOCLOCK (0U << 8) /**< No clock. */ +#define STM32_RTCSEL_LSE (1U << 8) /**< LSE used as RTC clock. */ +#define STM32_RTCSEL_LSI (2U << 8) /**< LSI used as RTC clock. */ +#define STM32_RTCSEL_HSEDIV (3U << 8) /**< HSE divided by 32 used as + RTC clock. */ +/** @} */ + +/** + * @name RCC_CFGR2 register bits definitions + * @{ + */ +#define STM32_PREDIV_MASK (15U << 0) /**< PREDIV divisor mask. */ +/** @} */ + +/** + * @name RCC_CFGR3 register bits definitions + * @{ + */ +#define STM32_USART1SW_MASK (3U << 0) /**< USART1 clock source mask. */ +#define STM32_USART1SW_PCLK (0U << 0) /**< USART1 clock is PCLK. */ +#define STM32_USART1SW_SYSCLK (1U << 0) /**< USART1 clock is SYSCLK. */ +#define STM32_USART1SW_LSE (2U << 0) /**< USART1 clock is LSE. */ +#define STM32_USART1SW_HSI (3U << 0) /**< USART1 clock is HSI. */ +#define STM32_I2C1SW_MASK (1U << 4) /**< I2C1 clock source mask. */ +#define STM32_I2C1SW_HSI (0U << 4) /**< I2C1 clock is HSI. */ +#define STM32_I2C1SW_SYSCLK (1U << 4) /**< I2C1 clock is SYSCLK. */ +#define STM32_I2C2SW_MASK (1U << 5) /**< I2C2 clock source mask. */ +#define STM32_I2C2SW_HSI (0U << 5) /**< I2C2 clock is HSI. */ +#define STM32_I2C2SW_SYSCLK (1U << 5) /**< I2C2 clock is SYSCLK. */ +#define STM32_USART2SW_MASK (3U << 16) /**< USART2 clock source mask. */ +#define STM32_USART2SW_PCLK (0U << 16) /**< USART2 clock is PCLK. */ +#define STM32_USART2SW_SYSCLK (1U << 16) /**< USART2 clock is SYSCLK. */ +#define STM32_USART2SW_LSE (2U << 16) /**< USART2 clock is LSE. */ +#define STM32_USART2SW_HSI (3U << 16) /**< USART2 clock is HSI. */ +#define STM32_USART3SW_MASK (3U << 18) /**< USART3 clock source mask. */ +#define STM32_USART3SW_PCLK (0U << 18) /**< USART3 clock is PCLK. */ +#define STM32_USART3SW_SYSCLK (1U << 18) /**< USART3 clock is SYSCLK. */ +#define STM32_USART3SW_LSE (2U << 18) /**< USART3 clock is LSE. */ +#define STM32_USART3SW_HSI (3U << 18) /**< USART3 clock is HSI. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief Crystal PLL pre-divider. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PREDIV_VALUE 1 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed range is 2...16. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 9 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief MCO pin setting. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief ADC prescaler value. + */ +#if !defined(STM32_ADCPRE) || defined(__DOXYGEN__) +#define STM32_ADCPRE STM32_ADCPRE_DIV4 +#endif + +/** + * @brief SDADC prescaler value. + */ +#if !defined(STM32_SDPRE) || defined(__DOXYGEN__) +#define STM32_SDPRE STM32_SDPRE_DIV12 +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SW) || defined(__DOXYGEN__) +#define STM32_USART1SW STM32_USART1SW_PCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SW) || defined(__DOXYGEN__) +#define STM32_USART2SW STM32_USART2SW_PCLK +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SW) || defined(__DOXYGEN__) +#define STM32_USART3SW STM32_USART3SW_PCLK +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__) +#define STM32_I2C1SW STM32_I2C1SW_SYSCLK +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SW) || defined(__DOXYGEN__) +#define STM32_I2C2SW STM32_I2C2SW_SYSCLK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_REQUIRED TRUE +#endif + +/** + * @brief USB prescaler initialization. + */ +#if !defined(STM32_USBPRE) || defined(__DOXYGEN__) +#define STM32_USBPRE STM32_USBPRE_DIV1P5 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F37x_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F37x_MCUCONF not defined" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if STM32_USART1SW == STM32_USART1SW_HSI +#error "HSI not enabled, required by STM32_USART1SW" +#endif + +#if STM32_USART2SW == STM32_USART2SW_HSI +#error "HSI not enabled, required by STM32_USART2SW" +#endif + +#if STM32_USART3SW == STM32_USART3SW_HSI +#error "HSI not enabled, required by STM32_USART3SW" +#endif + +#if STM32_I2C1SW == STM32_I2C1SW_HSI +#error "HSI not enabled, required by STM32_I2C1SW" +#endif + +#if STM32_I2C2SW == STM32_I2C2SW_HSI +#error "HSI not enabled, required by STM32_I2C2SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif + +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if !defined(STM32_LSECLK) || (STM32_LSECLK == 0) +#error "STM32_LSECLK not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined" +#endif + +#if (STM32_LSEDRV >> 3) > 3 +#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" +#endif + +#if STM32_USART1SW == STM32_USART1SW_LSE +#error "LSE not enabled, required by STM32_USART1SW" +#endif + +#if STM32_USART2SW == STM32_USART2SW_LSE +#error "LSE not enabled, required by STM32_USART2SW" +#endif + +#if STM32_USART3SW == STM32_USART3SW_LSE +#error "LSE not enabled, required by STM32_USART3SW" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL activation conditions.*/ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + STM32_USB_CLOCK_REQUIRED || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/* HSE prescaler setting check.*/ +#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16)) +#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0) +#else +#error "invalid STM32_PREDIV value specified" +#endif + +/** + * @brief PLLMUL field. + */ +#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_PLLCLKOUT +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + +/** + * @brief ADC frequency. + */ +#if (STM32_ADCPRE == STM32_ADCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_ADCCLK (STM32_PCLK2 / 2) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV4 +#define STM32_ADCCLK (STM32_PCLK2 / 4) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV6 +#define STM32_ADCCLK (STM32_PCLK2 / 6) +#elif STM32_ADCPRE == STM32_ADCPRE_DIV8 +#define STM32_ADCCLK (STM32_PCLK2 / 8) +#else +#error "invalid STM32_ADCPRE value specified" +#endif + +/* ADC maximum frequency check.*/ +#if STM32_ADC_USE_ADC1 && (STM32_ADCCLK > STM32_ADCCLK_MAX) +#error "STM32_ADCCLK exceeding maximum frequency (STM32_ADCCLK_MAX)" +#endif + +/* ADC minimum frequency check.*/ +#if STM32_ADC_USE_ADC1 && (STM32_ADCCLK < STM32_ADCCLK_MIN) +#error "STM32_ADCCLK exceeding minimum frequency (STM32_ADCCLK_MIN)" +#endif + +/** + * @brief SDADC frequency. + */ +#if (STM32_SDPRE == STM32_SDPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 2) +#elif (STM32_SDPRE == STM32_SDPRE_DIV4) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 4) +#elif (STM32_SDPRE == STM32_SDPRE_DIV6) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 6) +#elif (STM32_SDPRE == STM32_SDPRE_DIV8) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 8) +#elif (STM32_SDPRE == STM32_SDPRE_DIV10) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 10) +#elif (STM32_SDPRE == STM32_SDPRE_DIV12) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 12) +#elif (STM32_SDPRE == STM32_SDPRE_DIV14) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 14) +#elif (STM32_SDPRE == STM32_SDPRE_DIV16) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 16) +#elif (STM32_SDPRE == STM32_SDPRE_DIV20) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 20) +#elif (STM32_SDPRE == STM32_SDPRE_DIV24) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 24) +#elif (STM32_SDPRE == STM32_SDPRE_DIV28) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 28) +#elif (STM32_SDPRE == STM32_SDPRE_DIV32) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 32) +#elif (STM32_SDPRE == STM32_SDPRE_DIV36) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 36) +#elif (STM32_SDPRE == STM32_SDPRE_DIV40) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 40) +#elif (STM32_SDPRE == STM32_SDPRE_DIV44) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 44) +#elif (STM32_SDPRE == STM32_SDPRE_DIV48) || defined(__DOXYGEN__) +#define STM32_SDADCCLK (STM32_SYSCLK / 48) +#else +#error "invalid STM32_SDPRE value specified" +#endif + +/* SDADC maximum frequency check.*/ +#if (STM32_ADC_USE_SDADC1 || \ + STM32_ADC_USE_SDADC2 || \ + STM32_ADC_USE_SDADC3) && (STM32_SDADCCLK > STM32_SDADCCLK_FAST_MAX) +#error "STM32_SDADCCLK exceeding maximum frequency (STM32_SDADCCLK_FAST_MAX)" +#endif + +/* SDADC minimum frequency check.*/ +#if (STM32_ADC_USE_SDADC1 || \ + STM32_ADC_USE_SDADC2 || \ + STM32_ADC_USE_SDADC3) && \ + (STM32_SDADCCLK < STM32_SDADCCLK_MIN) +#error "STM32_SDADCCLK exceeding maximum frequency (STM32_SDADCCLK_MIN)" +#endif + +/** + * @brief I2C1 frequency. + */ +#if STM32_I2C1SW == STM32_I2C1SW_HSI +#define STM32_I2C1CLK STM32_HSICLK +#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 frequency. + */ +#if STM32_I2C2SW == STM32_I2C2SW_HSI +#define STM32_I2C2CLK STM32_HSICLK +#elif STM32_I2C2SW == STM32_I2C2SW_SYSCLK +#define STM32_I2C2CLK STM32_SYSCLK +#else +#error "invalid source selected for I2C2 clock" +#endif + +/** + * @brief USART1 frequency. + */ +#if STM32_USART1SW == STM32_USART1SW_PCLK +#define STM32_USART1CLK STM32_PCLK2 +#elif STM32_USART1SW == STM32_USART1SW_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SW == STM32_USART1SW_LSE +#define STM32_USART1CLK STM32_LSECLK +#elif STM32_USART1SW == STM32_USART1SW_HSI +#define STM32_USART1CLK STM32_HSICLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 frequency. + */ +#if STM32_USART2SW == STM32_USART2SW_PCLK +#define STM32_USART2CLK STM32_PCLK1 +#elif STM32_USART2SW == STM32_USART2SW_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK +#elif STM32_USART2SW == STM32_USART2SW_LSE +#define STM32_USART2CLK STM32_LSECLK +#elif STM32_USART2SW == STM32_USART2SW_HSI +#define STM32_USART2CLK STM32_HSICLK +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 frequency. + */ +#if STM32_USART3SW == STM32_USART3SW_PCLK +#define STM32_USART3CLK STM32_PCLK1 +#elif STM32_USART3SW == STM32_USART3SW_SYSCLK +#define STM32_USART3CLK STM32_SYSCLK +#elif STM32_USART3SW == STM32_USART3SW_LSE +#define STM32_USART3CLK STM32_LSECLK +#elif STM32_USART3SW == STM32_USART3SW_HSI +#define STM32_USART3CLK STM32_HSICLK +#else +#error "invalid source selected for USART3 clock" +#endif + +/** + * @brief Timers 2, 3, 4, 5, 6, 7, 12, 13, 14, 18 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 15, 16, 17, 19 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief USB frequency. + */ +#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__) +#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3) +#elif (STM32_USBPRE == STM32_USBPRE_DIV1) +#define STM32_USBCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_USBPRE value specified" +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000010 +#elif STM32_HCLK <= 48000000 +#define STM32_FLASHBITS 0x00000011 +#else +#define STM32_FLASHBITS 0x00000012 +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_registry.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F3xx/hal_lld.c b/os/hal/ports/STM32/STM32F3xx/hal_lld.c index 42fa3a5d4c..34e4ffbffb 100644 --- a/os/hal/ports/STM32/STM32F3xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F3xx/hal_lld.c @@ -1,233 +1,233 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F3xx/hal_lld.c - * @brief STM32F3xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f3xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - - /* If enabled then the LSE is started.*/ -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB(~STM32_GPIO_EN_MASK); - rccResetAPB1(0xFFFFFFFF); - rccResetAPB2(0xFFFFFFFF); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); - -#if STM32_HAS_USB - /* USB IRQ relocated to not conflict with CAN.*/ - SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; -#endif -} - -/** - * @brief STM32 clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. Clearing the register has to be postponed after HSI is the - new source.*/ - RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers finally cleared to reset values.*/ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - -#if STM32_HSE_ENABLED - /* HSE activation.*/ -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - /* No HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON; -#endif - while (!(RCC->CR & RCC_CR_HSERDY)) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - - /* Clock settings.*/ - RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | - STM32_PLLSRC | STM32_PPRE1 | STM32_PPRE2 | - STM32_HPRE; - RCC->CFGR2 = STM32_ADC34PRES | STM32_ADC12PRES | STM32_PREDIV; - RCC->CFGR3 = STM32_UART5SW | STM32_UART4SW | STM32_USART3SW | - STM32_USART2SW | STM32_I2C2SW | STM32_I2C1SW | - STM32_USART1SW; - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL is stable. */ -#endif - - /* Flash setup and final clock selection. */ - FLASH->ACR = STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - /* Switches clock source.*/ - RCC->CFGR |= STM32_SW; - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; /* Waits selection complete. */ -#endif - - /* After PLL activation because the special requirements for TIM1 and - TIM8 bits.*/ - RCC->CFGR3 |= STM32_HRTIM1SW | STM32_TIM8SW | STM32_TIM1SW; -#endif /* !STM32_NO_INIT */ -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F3xx/hal_lld.c + * @brief STM32F3xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f3xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB(~STM32_GPIO_EN_MASK); + rccResetAPB1(0xFFFFFFFF); + rccResetAPB2(0xFFFFFFFF); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); + +#if STM32_HAS_USB + /* USB IRQ relocated to not conflict with CAN.*/ + SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; +#endif +} + +/** + * @brief STM32 clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while (!(RCC->CR & RCC_CR_HSERDY)) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + + /* Clock settings.*/ + RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | + STM32_PLLSRC | STM32_PPRE1 | STM32_PPRE2 | + STM32_HPRE; + RCC->CFGR2 = STM32_ADC34PRES | STM32_ADC12PRES | STM32_PREDIV; + RCC->CFGR3 = STM32_UART5SW | STM32_UART4SW | STM32_USART3SW | + STM32_USART2SW | STM32_I2C2SW | STM32_I2C1SW | + STM32_USART1SW; + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + + /* Flash setup and final clock selection. */ + FLASH->ACR = STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + /* Switches clock source.*/ + RCC->CFGR |= STM32_SW; + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; /* Waits selection complete. */ +#endif + + /* After PLL activation because the special requirements for TIM1 and + TIM8 bits.*/ + RCC->CFGR3 |= STM32_HRTIM1SW | STM32_TIM8SW | STM32_TIM1SW; +#endif /* !STM32_NO_INIT */ +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F3xx/hal_lld.h b/os/hal/ports/STM32/STM32F3xx/hal_lld.h index b379414c8a..5f10adec26 100644 --- a/os/hal/ports/STM32/STM32F3xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F3xx/hal_lld.h @@ -1,1224 +1,1228 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F3xx/hal_lld.h - * @brief STM32F3xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32F301x8 for Analog & DSP devices. - * - STM32F302x8 for Analog & DSP devices. - * - STM32F302xC for Analog & DSP devices. - * - STM32F302xE for Analog & DSP devices. - * - STM32F303x8 for Analog & DSP devices. - * - STM32F303xC for Analog & DSP devices. - * - STM32F303xE for Analog & DSP devices. - * - STM32F318xx for Analog & DSP devices. - * - STM32F328xx for Analog & DSP devices. - * - STM32F334x8 for Analog & DSP devices. - * - STM32F358xx for Analog & DSP devices. - * - STM32F398xx for Analog & DSP devices. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32F301x8) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F301x8 Analog & DSP" - -#elif defined(STM32F302x8) -#define PLATFORM_NAME "STM32F302x8 Analog & DSP" - -#elif defined(STM32F302xC) -#define PLATFORM_NAME "STM32F302xC Analog & DSP" - -#elif defined(STM32F302xE) -#define PLATFORM_NAME "STM32F302xE Analog & DSP" - -#elif defined(STM32F303x8) -#define PLATFORM_NAME "STM32F303x8 Analog & DSP" - -#elif defined(STM32F303xC) -#define PLATFORM_NAME "STM32F303xC Analog & DSP" - -#elif defined(STM32F303xE) -#define PLATFORM_NAME "STM32F303xE Analog & DSP" - -#elif defined(STM32F318xx) -#define PLATFORM_NAME "STM32F318xx Analog & DSP" - -#elif defined(STM32F328xx) -#define PLATFORM_NAME "STM32F328xx Analog & DSP" - -#elif defined(STM32F334x8) -#define PLATFORM_NAME "STM32F334x8 Analog & DSP" - -#elif defined(STM32F358xx) -#define PLATFORM_NAME "STM32F358xx Analog & DSP" - -#elif defined(STM32F398xx) -#define PLATFORM_NAME "STM32F398xx Analog & DSP" - -#else -#error "STM32F3xx device not specified" -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum system clock frequency. - */ -#define STM32_SYSCLK_MAX 72000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 32000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 24000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 1000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 72000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 16000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 36000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 72000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 72000000 -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 8000000 /**< High speed internal clock. */ -#define STM32_LSICLK 40000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI/2. */ -#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is - HSE/PREDIV. */ - -#define STM32_USBPRE_DIV1P5 (0 << 22) /**< USB clock is PLLCLK/1.5. */ -#define STM32_USBPRE_DIV1 (1 << 22) /**< USB clock is PLLCLK/1. */ - -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_LSI (2 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (3 << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 32 used as - RTC clock. */ -/** @} */ - -/** - * @name RCC_CFGR2 register bits definitions - * @{ - */ -#define STM32_PREDIV_MASK (15 << 0) /**< PREDIV divisor mask. */ -#define STM32_ADC12PRES_MASK (31 << 4) /**< ADC12 clock source mask. */ -#define STM32_ADC12PRES_NOCLOCK (0 << 4) /**< ADC12 clock is disabled. */ -#define STM32_ADC12PRES_DIV1 (16 << 4) /**< ADC12 clock is PLL/1. */ -#define STM32_ADC12PRES_DIV2 (17 << 4) /**< ADC12 clock is PLL/2. */ -#define STM32_ADC12PRES_DIV4 (18 << 4) /**< ADC12 clock is PLL/4. */ -#define STM32_ADC12PRES_DIV6 (19 << 4) /**< ADC12 clock is PLL/6. */ -#define STM32_ADC12PRES_DIV8 (20 << 4) /**< ADC12 clock is PLL/8. */ -#define STM32_ADC12PRES_DIV10 (21 << 4) /**< ADC12 clock is PLL/10. */ -#define STM32_ADC12PRES_DIV12 (22 << 4) /**< ADC12 clock is PLL/12. */ -#define STM32_ADC12PRES_DIV16 (23 << 4) /**< ADC12 clock is PLL/16. */ -#define STM32_ADC12PRES_DIV32 (24 << 4) /**< ADC12 clock is PLL/32. */ -#define STM32_ADC12PRES_DIV64 (25 << 4) /**< ADC12 clock is PLL/64. */ -#define STM32_ADC12PRES_DIV128 (26 << 4) /**< ADC12 clock is PLL/128. */ -#define STM32_ADC12PRES_DIV256 (27 << 4) /**< ADC12 clock is PLL/256. */ -#define STM32_ADC34PRES_MASK (31 << 9) /**< ADC34 clock source mask. */ -#define STM32_ADC34PRES_NOCLOCK (0 << 9) /**< ADC34 clock is disabled. */ -#define STM32_ADC34PRES_DIV1 (16 << 9) /**< ADC34 clock is PLL/1. */ -#define STM32_ADC34PRES_DIV2 (17 << 9) /**< ADC34 clock is PLL/2. */ -#define STM32_ADC34PRES_DIV4 (18 << 9) /**< ADC34 clock is PLL/4. */ -#define STM32_ADC34PRES_DIV6 (19 << 9) /**< ADC34 clock is PLL/6. */ -#define STM32_ADC34PRES_DIV8 (20 << 9) /**< ADC34 clock is PLL/8. */ -#define STM32_ADC34PRES_DIV10 (21 << 9) /**< ADC34 clock is PLL/10. */ -#define STM32_ADC34PRES_DIV12 (22 << 9) /**< ADC34 clock is PLL/12. */ -#define STM32_ADC34PRES_DIV16 (23 << 9) /**< ADC34 clock is PLL/16. */ -#define STM32_ADC34PRES_DIV32 (24 << 9) /**< ADC34 clock is PLL/32. */ -#define STM32_ADC34PRES_DIV64 (25 << 9) /**< ADC34 clock is PLL/64. */ -#define STM32_ADC34PRES_DIV128 (26 << 9) /**< ADC34 clock is PLL/128. */ -#define STM32_ADC34PRES_DIV256 (27 << 9) /**< ADC34 clock is PLL/256. */ -/** @} */ - -/** - * @name RCC_CFGR3 register bits definitions - * @{ - */ -#define STM32_USART1SW_MASK (3 << 0) /**< USART1 clock source mask. */ -#define STM32_USART1SW_PCLK (0 << 0) /**< USART1 clock is PCLK. */ -#define STM32_USART1SW_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */ -#define STM32_USART1SW_LSE (2 << 0) /**< USART1 clock is LSE. */ -#define STM32_USART1SW_HSI (3 << 0) /**< USART1 clock is HSI. */ -#define STM32_I2C1SW_MASK (1 << 4) /**< I2C1 clock source mask. */ -#define STM32_I2C1SW_HSI (0 << 4) /**< I2C1 clock is HSI. */ -#define STM32_I2C1SW_SYSCLK (1 << 4) /**< I2C1 clock is SYSCLK. */ -#define STM32_I2C2SW_MASK (1 << 5) /**< I2C2 clock source mask. */ -#define STM32_I2C2SW_HSI (0 << 5) /**< I2C2 clock is HSI. */ -#define STM32_I2C2SW_SYSCLK (1 << 5) /**< I2C2 clock is SYSCLK. */ -#define STM32_TIM1SW_MASK (1 << 8) /**< TIM1 clock source mask. */ -#define STM32_TIM1SW_PCLK2 (0 << 8) /**< TIM1 clock is PCLK2. */ -#define STM32_TIM1SW_PLLX2 (1 << 8) /**< TIM1 clock is PLL*2. */ -#define STM32_TIM8SW_MASK (1 << 9) /**< TIM8 clock source mask. */ -#define STM32_TIM8SW_PCLK2 (0 << 9) /**< TIM8 clock is PCLK2. */ -#define STM32_TIM8SW_PLLX2 (1 << 9) /**< TIM8 clock is PLL*2. */ -#define STM32_HRTIM1SW_MASK (1 << 12) /**< HRTIM1 clock source mask. */ -#define STM32_HRTIM1SW_PCLK2 (0 << 12) /**< HRTIM1 clock is PCLK2. */ -#define STM32_HRTIM1SW_PLLX2 (1 << 12) /**< HRTIM1 clock is PLL*2. */ -#define STM32_USART2SW_MASK (3 << 16) /**< USART2 clock source mask. */ -#define STM32_USART2SW_PCLK (0 << 16) /**< USART2 clock is PCLK. */ -#define STM32_USART2SW_SYSCLK (1 << 16) /**< USART2 clock is SYSCLK. */ -#define STM32_USART2SW_LSE (2 << 16) /**< USART2 clock is LSE. */ -#define STM32_USART2SW_HSI (3 << 16) /**< USART2 clock is HSI. */ -#define STM32_USART3SW_MASK (3 << 18) /**< USART3 clock source mask. */ -#define STM32_USART3SW_PCLK (0 << 18) /**< USART3 clock is PCLK. */ -#define STM32_USART3SW_SYSCLK (1 << 18) /**< USART3 clock is SYSCLK. */ -#define STM32_USART3SW_LSE (2 << 18) /**< USART3 clock is LSE. */ -#define STM32_USART3SW_HSI (3 << 18) /**< USART3 clock is HSI. */ -#define STM32_UART4SW_MASK (3 << 20) /**< USART4 clock source mask. */ -#define STM32_UART4SW_PCLK (0 << 20) /**< USART4 clock is PCLK. */ -#define STM32_UART4SW_SYSCLK (1 << 20) /**< USART4 clock is SYSCLK. */ -#define STM32_UART4SW_LSE (2 << 20) /**< USART4 clock is LSE. */ -#define STM32_UART4SW_HSI (3 << 20) /**< USART4 clock is HSI. */ -#define STM32_UART5SW_MASK (3 << 22) /**< USART5 clock source mask. */ -#define STM32_UART5SW_PCLK (0 << 22) /**< USART5 clock is PCLK. */ -#define STM32_UART5SW_SYSCLK (1 << 22) /**< USART5 clock is SYSCLK. */ -#define STM32_UART5SW_LSE (2 << 22) /**< USART5 clock is LSE. */ -#define STM32_UART5SW_HSI (3 << 22) /**< USART5 clock is HSI. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief Crystal PLL pre-divider. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PREDIV_VALUE 1 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed range is 2...16. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 9 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 72MHz system clock from - * a 8MHz crystal using the PLL. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV2 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief MCO pin setting. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief ADC12 prescaler value. - */ -#if !defined(STM32_ADC12PRES) || defined(__DOXYGEN__) -#define STM32_ADC12PRES STM32_ADC12PRES_DIV1 -#endif - -/** - * @brief ADC34 prescaler value. - */ -#if !defined(STM32_ADC34PRES) || defined(__DOXYGEN__) -#define STM32_ADC34PRES STM32_ADC34PRES_DIV1 -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SW) || defined(__DOXYGEN__) -#define STM32_USART1SW STM32_USART1SW_PCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SW) || defined(__DOXYGEN__) -#define STM32_USART2SW STM32_USART2SW_PCLK -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SW) || defined(__DOXYGEN__) -#define STM32_USART3SW STM32_USART3SW_PCLK -#endif - -/** - * @brief UART4 clock source. - */ -#if !defined(STM32_UART4SW) || defined(__DOXYGEN__) -#define STM32_UART4SW STM32_UART4SW_PCLK -#endif - -/** - * @brief UART5 clock source. - */ -#if !defined(STM32_UART5SW) || defined(__DOXYGEN__) -#define STM32_UART5SW STM32_UART5SW_PCLK -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__) -#define STM32_I2C1SW STM32_I2C1SW_SYSCLK -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SW) || defined(__DOXYGEN__) -#define STM32_I2C2SW STM32_I2C2SW_SYSCLK -#endif - -/** - * @brief TIM1 clock source. - */ -#if !defined(STM32_TIM1SW) || defined(__DOXYGEN__) -#define STM32_TIM1SW STM32_TIM1SW_PCLK2 -#endif - -/** - * @brief TIM8 clock source. - */ -#if !defined(STM32_TIM8SW) || defined(__DOXYGEN__) -#define STM32_TIM8SW STM32_TIM8SW_PCLK2 -#endif - -/** - * @brief HRTIM1 clock source. - */ -#if !defined(STM32_HRTIM1SW) || defined(__DOXYGEN__) -#define STM32_HRTIM1SW STM32_HRTIM1SW_PCLK2 -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_REQUIRED TRUE -#endif - -/** - * @brief USB prescaler initialization. - */ -#if !defined(STM32_USBPRE) || defined(__DOXYGEN__) -#define STM32_USBPRE STM32_USBPRE_DIV1P5 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F3xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F3xx_MCUCONF not defined" -#endif - -/* Only some devices have strongly checked mcuconf.h files. Others will be - added gradually.*/ -#if (defined(STM32F303xC) || defined(STM32F303xE)) && \ - !defined(STM32F303_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F303_MCUCONF not defined" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if STM32_USART1SW == STM32_USART1SW_HSI -#error "HSI not enabled, required by STM32_USART1SW" -#endif - -#if STM32_USART2SW == STM32_USART2SW_HSI -#error "HSI not enabled, required by STM32_USART2SW" -#endif - -#if STM32_USART3SW == STM32_USART3SW_HSI -#error "HSI not enabled, required by STM32_USART3SW" -#endif - -#if STM32_UART4SW == STM32_UART4SW_HSI -#error "HSI not enabled, required by STM32_UART4SW" -#endif - -#if STM32_UART5SW == STM32_UART5SW_HSI -#error "HSI not enabled, required by STM32_UART5SW" -#endif - -#if STM32_I2C1SW == STM32_I2C1SW_HSI -#error "HSI not enabled, required by STM32_I2C1SW" -#endif - -#if STM32_I2C2SW == STM32_I2C2SW_HSI -#error "HSI not enabled, required by STM32_I2C2SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCOSEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif - -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if !defined(STM32_LSECLK) || (STM32_LSECLK == 0) -#error "STM32_LSECLK not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined" -#endif - -#if (STM32_LSEDRV >> 3) > 3 -#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" -#endif - -#if STM32_USART1SW == STM32_USART1SW_LSE -#error "LSE not enabled, required by STM32_USART1SW" -#endif - -#if STM32_USART2SW == STM32_USART2SW_LSE -#error "LSE not enabled, required by STM32_USART2SW" -#endif - -#if STM32_USART3SW == STM32_USART3SW_LSE -#error "LSE not enabled, required by STM32_USART3SW" -#endif - -#if STM32_UART4SW == STM32_UART4SW_LSE -#error "LSE not enabled, required by STM32_UART4SW" -#endif - -#if STM32_UART5SW == STM32_UART5SW_LSE -#error "LSE not enabled, required by STM32_UART5SW" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL activation conditions.*/ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ - (STM32_TIM1SW == STM32_TIM1SW_PLLX2) || \ - (STM32_TIM8SW == STM32_TIM8SW_PLLX2) || \ - (STM32_ADC12PRES != STM32_ADC12PRES_NOCLOCK) || \ - (STM32_ADC34PRES != STM32_ADC34PRES_NOCLOCK) || \ - STM32_USB_CLOCK_REQUIRED || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/* HSE prescaler setting check.*/ -#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16)) -#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0) -#else -#error "invalid STM32_PREDIV value specified" -#endif - -/** - * @brief PLLMUL field. - */ -#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / 2) -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_PLLCLKOUT -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) -#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK -#define STM32_RTCCLK 0 -#else -#error "invalid source selected for RTC clock" -#endif - -/** - * @brief ADC12 frequency. - */ -#if (STM32_ADC12PRES == STM32_ADC12PRES_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_ADC12CLK 0 -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV1 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 1) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV2 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 2) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV4 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 4) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV6 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 6) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV8 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 8) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV10 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 10) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV12 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 12) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV16 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 16) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV32 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 32) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV64 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 64) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV128 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 128) -#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV256 -#define STM32_ADC12CLK (STM32_PLLCLKOUT / 256) -#else -#error "invalid STM32_ADC12PRES value specified" -#endif - -/** - * @brief ADC34 frequency. - */ -#if (STM32_ADC34PRES == STM32_ADC34PRES_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_ADC34CLK 0 -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV1 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 1) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV2 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 2) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV4 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 4) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV6 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 6) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV8 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 8) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV10 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 10) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV12 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 12) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV16 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 16) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV32 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 32) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV64 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 64) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV128 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 128) -#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV256 -#define STM32_ADC34CLK (STM32_PLLCLKOUT / 256) -#else -#error "invalid STM32_ADC34PRES value specified" -#endif - -/* ADC12 frequency check.*/ -#if STM32_ADC12CLK > STM32_ADCCLK_MAX -#error "STM32_ADC12CLK exceeding maximum frequency (STM32_ADCCLK_MAX)" -#endif - -/* ADC34 frequency check.*/ -#if STM32_ADC34CLK > STM32_ADCCLK_MAX -#error "STM32_ADC34CLK exceeding maximum frequency (STM32_ADCCLK_MAX)" -#endif - -/** - * @brief I2C1 frequency. - */ -#if STM32_I2C1SW == STM32_I2C1SW_HSI -#define STM32_I2C1CLK STM32_HSICLK -#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 frequency. - */ -#if STM32_I2C2SW == STM32_I2C2SW_HSI -#define STM32_I2C2CLK STM32_HSICLK -#elif STM32_I2C2SW == STM32_I2C2SW_SYSCLK -#define STM32_I2C2CLK STM32_SYSCLK -#else -#error "invalid source selected for I2C2 clock" -#endif - -/** - * @brief USART1 frequency. - */ -#if STM32_USART1SW == STM32_USART1SW_PCLK -#define STM32_USART1CLK STM32_PCLK2 -#elif STM32_USART1SW == STM32_USART1SW_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SW == STM32_USART1SW_LSE -#define STM32_USART1CLK STM32_LSECLK -#elif STM32_USART1SW == STM32_USART1SW_HSI -#define STM32_USART1CLK STM32_HSICLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 frequency. - */ -#if STM32_USART2SW == STM32_USART2SW_PCLK -#define STM32_USART2CLK STM32_PCLK1 -#elif STM32_USART2SW == STM32_USART2SW_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK -#elif STM32_USART2SW == STM32_USART2SW_LSE -#define STM32_USART2CLK STM32_LSECLK -#elif STM32_USART2SW == STM32_USART2SW_HSI -#define STM32_USART2CLK STM32_HSICLK -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 frequency. - */ -#if STM32_USART3SW == STM32_USART3SW_PCLK -#define STM32_USART3CLK STM32_PCLK1 -#elif STM32_USART3SW == STM32_USART3SW_SYSCLK -#define STM32_USART3CLK STM32_SYSCLK -#elif STM32_USART3SW == STM32_USART3SW_LSE -#define STM32_USART3CLK STM32_LSECLK -#elif STM32_USART3SW == STM32_USART3SW_HSI -#define STM32_USART3CLK STM32_HSICLK -#else -#error "invalid source selected for USART3 clock" -#endif - -/** - * @brief UART4 frequency. - */ -#if STM32_UART4SW == STM32_UART4SW_PCLK -#define STM32_UART4CLK STM32_PCLK1 -#elif STM32_UART4SW == STM32_UART4SW_SYSCLK -#define STM32_UART4CLK STM32_SYSCLK -#elif STM32_UART4SW == STM32_UART4SW_LSE -#define STM32_UART4CLK STM32_LSECLK -#elif STM32_UART4SW == STM32_UART4SW_HSI -#define STM32_UART4CLK STM32_HSICLK -#else -#error "invalid source selected for UART4 clock" -#endif - -/** - * @brief UART5 frequency. - */ -#if STM32_UART5SW == STM32_UART5SW_PCLK -#define STM32_UART5CLK STM32_PCLK1 -#elif STM32_UART5SW == STM32_UART5SW_SYSCLK -#define STM32_UART5CLK STM32_SYSCLK -#elif STM32_UART5SW == STM32_UART5SW_LSE -#define STM32_UART5CLK STM32_LSECLK -#elif STM32_UART5SW == STM32_UART5SW_HSI -#define STM32_UART5CLK STM32_HSICLK -#else -#error "invalid source selected for UART5 clock" -#endif - -/** - * @brief TIM1 frequency. - */ -#if STM32_TIM1SW == STM32_TIM1SW_PCLK2 -#if STM32_PPRE2 == STM32_PPRE2_DIV1 -#define STM32_TIM1CLK STM32_PCLK2 -#else -#define STM32_TIM1CLK (STM32_PCLK2 * 2) -#endif - -#elif STM32_TIM1SW == STM32_TIM1SW_PLLX2 -#if (STM32_SW != STM32_SW_PLL) || \ - (STM32_HPRE != STM32_HPRE_DIV1) || \ - (STM32_PPRE2 != STM32_PPRE2_DIV1) -#error "double clock mode cannot be activated for TIM1 under the current settings" -#endif -#define STM32_TIM1CLK (STM32_PLLCLKOUT * 2) - -#else -#error "invalid source selected for TIM1 clock" -#endif - -/** - * @brief TIM8 frequency. - */ -#if STM32_TIM8SW == STM32_TIM8SW_PCLK2 -#if STM32_PPRE2 == STM32_PPRE2_DIV1 -#define STM32_TIM8CLK STM32_PCLK2 -#else -#define STM32_TIM8CLK (STM32_PCLK2 * 2) -#endif - -#elif STM32_TIM8SW == STM32_TIM8SW_PLLX2 -#if (STM32_SW != STM32_SW_PLL) || \ - (STM32_HPRE != STM32_HPRE_DIV1) || \ - (STM32_PPRE2 != STM32_PPRE2_DIV1) -#error "double clock mode cannot be activated for TIM8 under the current settings" -#endif -#define STM32_TIM8CLK (STM32_PLLCLKOUT * 2) - -#else -#error "invalid source selected for TIM8 clock" -#endif - -/** - * @brief HRTIM1 frequency. - */ -#if STM32_HRTIM1SW == STM32_HRTIM1SW_PCLK2 -#if STM32_PPRE2 == STM32_PPRE2_DIV1 -#define STM32_HRTIM1CLK STM32_PCLK2 -#else -#define STM32_HRTIM1CLK (STM32_PCLK2 * 2) -#endif - -#elif STM32_HRTIM1SW == STM32_HRTIM1SW_PLLX2 -#if (STM32_SW != STM32_SW_PLL) || \ - (STM32_HPRE != STM32_HPRE_DIV1) || \ - (STM32_PPRE2 != STM32_PPRE2_DIV1) -#error "double clock mode cannot be activated for HRTIM1 under the current settings" -#endif -#define STM32_HRTIM1CLK (STM32_PLLCLKOUT * 2) - -#else -#error "invalid source selected for HRTIM1 clock" -#endif - -/** - * @brief Timers 2, 3, 4, 6, 7 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers 1, 8, 15, 16, 17 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief USB frequency. - */ -#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__) -#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3) -#elif (STM32_USBPRE == STM32_USBPRE_DIV1) -#define STM32_USBCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_USBPRE value specified" -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000010 -#elif STM32_HCLK <= 48000000 -#define STM32_FLASHBITS 0x00000011 -#else -#define STM32_FLASHBITS 0x00000012 -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F3xx/hal_lld.h + * @brief STM32F3xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32F301x8 for Analog & DSP devices. + * - STM32F302x8 for Analog & DSP devices. + * - STM32F302xC for Analog & DSP devices. + * - STM32F302xE for Analog & DSP devices. + * - STM32F303x8 for Analog & DSP devices. + * - STM32F303xC for Analog & DSP devices. + * - STM32F303xE for Analog & DSP devices. + * - STM32F318xx for Analog & DSP devices. + * - STM32F328xx for Analog & DSP devices. + * - STM32F334x8 for Analog & DSP devices. + * - STM32F358xx for Analog & DSP devices. + * - STM32F398xx for Analog & DSP devices. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32F301x8) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32F301x8 Analog & DSP" + +#elif defined(STM32F302x8) +#define PLATFORM_NAME "STM32F302x8 Analog & DSP" + +#elif defined(STM32F302xC) +#define PLATFORM_NAME "STM32F302xC Analog & DSP" + +#elif defined(STM32F302xE) +#define PLATFORM_NAME "STM32F302xE Analog & DSP" + +#elif defined(STM32F303x8) +#define PLATFORM_NAME "STM32F303x8 Analog & DSP" + +#elif defined(STM32F303xC) +#define PLATFORM_NAME "STM32F303xC Analog & DSP" + +#elif defined(STM32F303xE) +#define PLATFORM_NAME "STM32F303xE Analog & DSP" + +#elif defined(STM32F318xx) +#define PLATFORM_NAME "STM32F318xx Analog & DSP" + +#elif defined(STM32F328xx) +#define PLATFORM_NAME "STM32F328xx Analog & DSP" + +#elif defined(STM32F334x8) +#define PLATFORM_NAME "STM32F334x8 Analog & DSP" + +#elif defined(STM32F358xx) +#define PLATFORM_NAME "STM32F358xx Analog & DSP" + +#elif defined(STM32F398xx) +#define PLATFORM_NAME "STM32F398xx Analog & DSP" + +#else +#error "STM32F3xx device not specified" +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum system clock frequency. + */ +#define STM32_SYSCLK_MAX 72000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 32000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 24000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 1000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 72000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 16000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 36000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 72000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 72000000 +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 8000000 /**< High speed internal clock. */ +#define STM32_LSICLK 40000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI/2. */ +#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is + HSE/PREDIV. */ + +#define STM32_USBPRE_DIV1P5 (0 << 22) /**< USB clock is PLLCLK/1.5. */ +#define STM32_USBPRE_DIV1 (1 << 22) /**< USB clock is PLLCLK/1. */ + +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_LSI (2 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (3 << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (4 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (5 << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (6 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLDIV2 (7 << 24) /**< PLL/2 clock on MCO pin. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC clock source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No clock. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< LSE used as RTC clock. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< LSI used as RTC clock. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< HSE divided by 32 used as + RTC clock. */ +/** @} */ + +/** + * @name RCC_CFGR2 register bits definitions + * @{ + */ +#define STM32_PREDIV_MASK (15 << 0) /**< PREDIV divisor mask. */ +#define STM32_ADC12PRES_MASK (31 << 4) /**< ADC12 clock source mask. */ +#define STM32_ADC12PRES_NOCLOCK (0 << 4) /**< ADC12 clock is disabled. */ +#define STM32_ADC12PRES_DIV1 (16 << 4) /**< ADC12 clock is PLL/1. */ +#define STM32_ADC12PRES_DIV2 (17 << 4) /**< ADC12 clock is PLL/2. */ +#define STM32_ADC12PRES_DIV4 (18 << 4) /**< ADC12 clock is PLL/4. */ +#define STM32_ADC12PRES_DIV6 (19 << 4) /**< ADC12 clock is PLL/6. */ +#define STM32_ADC12PRES_DIV8 (20 << 4) /**< ADC12 clock is PLL/8. */ +#define STM32_ADC12PRES_DIV10 (21 << 4) /**< ADC12 clock is PLL/10. */ +#define STM32_ADC12PRES_DIV12 (22 << 4) /**< ADC12 clock is PLL/12. */ +#define STM32_ADC12PRES_DIV16 (23 << 4) /**< ADC12 clock is PLL/16. */ +#define STM32_ADC12PRES_DIV32 (24 << 4) /**< ADC12 clock is PLL/32. */ +#define STM32_ADC12PRES_DIV64 (25 << 4) /**< ADC12 clock is PLL/64. */ +#define STM32_ADC12PRES_DIV128 (26 << 4) /**< ADC12 clock is PLL/128. */ +#define STM32_ADC12PRES_DIV256 (27 << 4) /**< ADC12 clock is PLL/256. */ +#define STM32_ADC34PRES_MASK (31 << 9) /**< ADC34 clock source mask. */ +#define STM32_ADC34PRES_NOCLOCK (0 << 9) /**< ADC34 clock is disabled. */ +#define STM32_ADC34PRES_DIV1 (16 << 9) /**< ADC34 clock is PLL/1. */ +#define STM32_ADC34PRES_DIV2 (17 << 9) /**< ADC34 clock is PLL/2. */ +#define STM32_ADC34PRES_DIV4 (18 << 9) /**< ADC34 clock is PLL/4. */ +#define STM32_ADC34PRES_DIV6 (19 << 9) /**< ADC34 clock is PLL/6. */ +#define STM32_ADC34PRES_DIV8 (20 << 9) /**< ADC34 clock is PLL/8. */ +#define STM32_ADC34PRES_DIV10 (21 << 9) /**< ADC34 clock is PLL/10. */ +#define STM32_ADC34PRES_DIV12 (22 << 9) /**< ADC34 clock is PLL/12. */ +#define STM32_ADC34PRES_DIV16 (23 << 9) /**< ADC34 clock is PLL/16. */ +#define STM32_ADC34PRES_DIV32 (24 << 9) /**< ADC34 clock is PLL/32. */ +#define STM32_ADC34PRES_DIV64 (25 << 9) /**< ADC34 clock is PLL/64. */ +#define STM32_ADC34PRES_DIV128 (26 << 9) /**< ADC34 clock is PLL/128. */ +#define STM32_ADC34PRES_DIV256 (27 << 9) /**< ADC34 clock is PLL/256. */ +/** @} */ + +/** + * @name RCC_CFGR3 register bits definitions + * @{ + */ +#define STM32_USART1SW_MASK (3 << 0) /**< USART1 clock source mask. */ +#define STM32_USART1SW_PCLK (0 << 0) /**< USART1 clock is PCLK. */ +#define STM32_USART1SW_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */ +#define STM32_USART1SW_LSE (2 << 0) /**< USART1 clock is LSE. */ +#define STM32_USART1SW_HSI (3 << 0) /**< USART1 clock is HSI. */ +#define STM32_I2C1SW_MASK (1 << 4) /**< I2C1 clock source mask. */ +#define STM32_I2C1SW_HSI (0 << 4) /**< I2C1 clock is HSI. */ +#define STM32_I2C1SW_SYSCLK (1 << 4) /**< I2C1 clock is SYSCLK. */ +#define STM32_I2C2SW_MASK (1 << 5) /**< I2C2 clock source mask. */ +#define STM32_I2C2SW_HSI (0 << 5) /**< I2C2 clock is HSI. */ +#define STM32_I2C2SW_SYSCLK (1 << 5) /**< I2C2 clock is SYSCLK. */ +#define STM32_TIM1SW_MASK (1 << 8) /**< TIM1 clock source mask. */ +#define STM32_TIM1SW_PCLK2 (0 << 8) /**< TIM1 clock is PCLK2. */ +#define STM32_TIM1SW_PLLX2 (1 << 8) /**< TIM1 clock is PLL*2. */ +#define STM32_TIM8SW_MASK (1 << 9) /**< TIM8 clock source mask. */ +#define STM32_TIM8SW_PCLK2 (0 << 9) /**< TIM8 clock is PCLK2. */ +#define STM32_TIM8SW_PLLX2 (1 << 9) /**< TIM8 clock is PLL*2. */ +#define STM32_HRTIM1SW_MASK (1 << 12) /**< HRTIM1 clock source mask. */ +#define STM32_HRTIM1SW_PCLK2 (0 << 12) /**< HRTIM1 clock is PCLK2. */ +#define STM32_HRTIM1SW_PLLX2 (1 << 12) /**< HRTIM1 clock is PLL*2. */ +#define STM32_USART2SW_MASK (3 << 16) /**< USART2 clock source mask. */ +#define STM32_USART2SW_PCLK (0 << 16) /**< USART2 clock is PCLK. */ +#define STM32_USART2SW_SYSCLK (1 << 16) /**< USART2 clock is SYSCLK. */ +#define STM32_USART2SW_LSE (2 << 16) /**< USART2 clock is LSE. */ +#define STM32_USART2SW_HSI (3 << 16) /**< USART2 clock is HSI. */ +#define STM32_USART3SW_MASK (3 << 18) /**< USART3 clock source mask. */ +#define STM32_USART3SW_PCLK (0 << 18) /**< USART3 clock is PCLK. */ +#define STM32_USART3SW_SYSCLK (1 << 18) /**< USART3 clock is SYSCLK. */ +#define STM32_USART3SW_LSE (2 << 18) /**< USART3 clock is LSE. */ +#define STM32_USART3SW_HSI (3 << 18) /**< USART3 clock is HSI. */ +#define STM32_UART4SW_MASK (3 << 20) /**< USART4 clock source mask. */ +#define STM32_UART4SW_PCLK (0 << 20) /**< USART4 clock is PCLK. */ +#define STM32_UART4SW_SYSCLK (1 << 20) /**< USART4 clock is SYSCLK. */ +#define STM32_UART4SW_LSE (2 << 20) /**< USART4 clock is LSE. */ +#define STM32_UART4SW_HSI (3 << 20) /**< USART4 clock is HSI. */ +#define STM32_UART5SW_MASK (3 << 22) /**< USART5 clock source mask. */ +#define STM32_UART5SW_PCLK (0 << 22) /**< USART5 clock is PCLK. */ +#define STM32_UART5SW_SYSCLK (1 << 22) /**< USART5 clock is SYSCLK. */ +#define STM32_UART5SW_LSE (2 << 22) /**< USART5 clock is LSE. */ +#define STM32_UART5SW_HSI (3 << 22) /**< USART5 clock is HSI. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief Crystal PLL pre-divider. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PREDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PREDIV_VALUE 1 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed range is 2...16. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 9 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 72MHz system clock from + * a 8MHz crystal using the PLL. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief MCO pin setting. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief ADC12 prescaler value. + */ +#if !defined(STM32_ADC12PRES) || defined(__DOXYGEN__) +#define STM32_ADC12PRES STM32_ADC12PRES_DIV1 +#endif + +/** + * @brief ADC34 prescaler value. + */ +#if !defined(STM32_ADC34PRES) || defined(__DOXYGEN__) +#define STM32_ADC34PRES STM32_ADC34PRES_DIV1 +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SW) || defined(__DOXYGEN__) +#define STM32_USART1SW STM32_USART1SW_PCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SW) || defined(__DOXYGEN__) +#define STM32_USART2SW STM32_USART2SW_PCLK +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SW) || defined(__DOXYGEN__) +#define STM32_USART3SW STM32_USART3SW_PCLK +#endif + +/** + * @brief UART4 clock source. + */ +#if !defined(STM32_UART4SW) || defined(__DOXYGEN__) +#define STM32_UART4SW STM32_UART4SW_PCLK +#endif + +/** + * @brief UART5 clock source. + */ +#if !defined(STM32_UART5SW) || defined(__DOXYGEN__) +#define STM32_UART5SW STM32_UART5SW_PCLK +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SW) || defined(__DOXYGEN__) +#define STM32_I2C1SW STM32_I2C1SW_SYSCLK +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SW) || defined(__DOXYGEN__) +#define STM32_I2C2SW STM32_I2C2SW_SYSCLK +#endif + +/** + * @brief TIM1 clock source. + */ +#if !defined(STM32_TIM1SW) || defined(__DOXYGEN__) +#define STM32_TIM1SW STM32_TIM1SW_PCLK2 +#endif + +/** + * @brief TIM8 clock source. + */ +#if !defined(STM32_TIM8SW) || defined(__DOXYGEN__) +#define STM32_TIM8SW STM32_TIM8SW_PCLK2 +#endif + +/** + * @brief HRTIM1 clock source. + */ +#if !defined(STM32_HRTIM1SW) || defined(__DOXYGEN__) +#define STM32_HRTIM1SW STM32_HRTIM1SW_PCLK2 +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_REQUIRED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_REQUIRED TRUE +#endif + +/** + * @brief USB prescaler initialization. + */ +#if !defined(STM32_USBPRE) || defined(__DOXYGEN__) +#define STM32_USBPRE STM32_USBPRE_DIV1P5 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F3xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F3xx_MCUCONF not defined" +#endif + +/* Only some devices have strongly checked mcuconf.h files. Others will be + added gradually.*/ +#if (defined(STM32F303xC) || defined(STM32F303xE)) && \ + !defined(STM32F303_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F303_MCUCONF not defined" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if STM32_USART1SW == STM32_USART1SW_HSI +#error "HSI not enabled, required by STM32_USART1SW" +#endif + +#if STM32_USART2SW == STM32_USART2SW_HSI +#error "HSI not enabled, required by STM32_USART2SW" +#endif + +#if STM32_USART3SW == STM32_USART3SW_HSI +#error "HSI not enabled, required by STM32_USART3SW" +#endif + +#if STM32_UART4SW == STM32_UART4SW_HSI +#error "HSI not enabled, required by STM32_UART4SW" +#endif + +#if STM32_UART5SW == STM32_UART5SW_HSI +#error "HSI not enabled, required by STM32_UART5SW" +#endif + +#if STM32_I2C1SW == STM32_I2C1SW_HSI +#error "HSI not enabled, required by STM32_I2C1SW" +#endif + +#if STM32_I2C2SW == STM32_I2C2SW_HSI +#error "HSI not enabled, required by STM32_I2C2SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCOSEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#elif (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif + +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if !defined(STM32_LSECLK) || (STM32_LSECLK == 0) +#error "STM32_LSECLK not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined" +#endif + +#if (STM32_LSEDRV >> 3) > 3 +#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" +#endif + +#if STM32_USART1SW == STM32_USART1SW_LSE +#error "LSE not enabled, required by STM32_USART1SW" +#endif + +#if STM32_USART2SW == STM32_USART2SW_LSE +#error "LSE not enabled, required by STM32_USART2SW" +#endif + +#if STM32_USART3SW == STM32_USART3SW_LSE +#error "LSE not enabled, required by STM32_USART3SW" +#endif + +#if STM32_UART4SW == STM32_UART4SW_LSE +#error "LSE not enabled, required by STM32_UART4SW" +#endif + +#if STM32_UART5SW == STM32_UART5SW_LSE +#error "LSE not enabled, required by STM32_UART5SW" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL activation conditions.*/ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLDIV2) || \ + (STM32_TIM1SW == STM32_TIM1SW_PLLX2) || \ + (STM32_TIM8SW == STM32_TIM8SW_PLLX2) || \ + (STM32_ADC12PRES != STM32_ADC12PRES_NOCLOCK) || \ + (STM32_ADC34PRES != STM32_ADC34PRES_NOCLOCK) || \ + STM32_USB_CLOCK_REQUIRED || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/* HSE prescaler setting check.*/ +#if ((STM32_PREDIV_VALUE >= 1) || (STM32_PREDIV_VALUE <= 16)) +#define STM32_PREDIV ((STM32_PREDIV_VALUE - 1) << 0) +#else +#error "invalid STM32_PREDIV value specified" +#endif + +/** + * @brief PLLMUL field. + */ +#if ((STM32_PLLMUL_VALUE >= 2) && (STM32_PLLMUL_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLMUL ((STM32_PLLMUL_VALUE - 2) << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PREDIV_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / 2) +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_PLL) || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_PLLCLKOUT +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_LSE) || defined(__DOXYGEN__) +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) +#elif STM32_RTCSEL == STM32_RTCSEL_NOCLOCK +#define STM32_RTCCLK 0 +#else +#error "invalid source selected for RTC clock" +#endif + +/** + * @brief ADC12 frequency. + */ +#if (STM32_ADC12PRES == STM32_ADC12PRES_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_ADC12CLK 0 +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV1 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 1) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV2 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 2) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV4 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 4) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV6 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 6) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV8 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 8) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV10 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 10) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV12 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 12) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV16 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 16) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV32 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 32) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV64 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 64) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV128 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 128) +#elif STM32_ADC12PRES == STM32_ADC12PRES_DIV256 +#define STM32_ADC12CLK (STM32_PLLCLKOUT / 256) +#else +#error "invalid STM32_ADC12PRES value specified" +#endif + +/** + * @brief ADC34 frequency. + */ +#if (STM32_ADC34PRES == STM32_ADC34PRES_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_ADC34CLK 0 +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV1 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 1) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV2 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 2) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV4 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 4) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV6 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 6) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV8 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 8) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV10 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 10) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV12 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 12) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV16 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 16) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV32 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 32) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV64 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 64) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV128 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 128) +#elif STM32_ADC34PRES == STM32_ADC34PRES_DIV256 +#define STM32_ADC34CLK (STM32_PLLCLKOUT / 256) +#else +#error "invalid STM32_ADC34PRES value specified" +#endif + +/* ADC12 frequency check.*/ +#if STM32_ADC12CLK > STM32_ADCCLK_MAX +#error "STM32_ADC12CLK exceeding maximum frequency (STM32_ADCCLK_MAX)" +#endif + +/* ADC34 frequency check.*/ +#if STM32_ADC34CLK > STM32_ADCCLK_MAX +#error "STM32_ADC34CLK exceeding maximum frequency (STM32_ADCCLK_MAX)" +#endif + +/** + * @brief I2C1 frequency. + */ +#if STM32_I2C1SW == STM32_I2C1SW_HSI +#define STM32_I2C1CLK STM32_HSICLK +#elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 frequency. + */ +#if STM32_I2C2SW == STM32_I2C2SW_HSI +#define STM32_I2C2CLK STM32_HSICLK +#elif STM32_I2C2SW == STM32_I2C2SW_SYSCLK +#define STM32_I2C2CLK STM32_SYSCLK +#else +#error "invalid source selected for I2C2 clock" +#endif + +/** + * @brief USART1 frequency. + */ +#if STM32_USART1SW == STM32_USART1SW_PCLK +#define STM32_USART1CLK STM32_PCLK2 +#elif STM32_USART1SW == STM32_USART1SW_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SW == STM32_USART1SW_LSE +#define STM32_USART1CLK STM32_LSECLK +#elif STM32_USART1SW == STM32_USART1SW_HSI +#define STM32_USART1CLK STM32_HSICLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 frequency. + */ +#if STM32_USART2SW == STM32_USART2SW_PCLK +#define STM32_USART2CLK STM32_PCLK1 +#elif STM32_USART2SW == STM32_USART2SW_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK +#elif STM32_USART2SW == STM32_USART2SW_LSE +#define STM32_USART2CLK STM32_LSECLK +#elif STM32_USART2SW == STM32_USART2SW_HSI +#define STM32_USART2CLK STM32_HSICLK +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 frequency. + */ +#if STM32_USART3SW == STM32_USART3SW_PCLK +#define STM32_USART3CLK STM32_PCLK1 +#elif STM32_USART3SW == STM32_USART3SW_SYSCLK +#define STM32_USART3CLK STM32_SYSCLK +#elif STM32_USART3SW == STM32_USART3SW_LSE +#define STM32_USART3CLK STM32_LSECLK +#elif STM32_USART3SW == STM32_USART3SW_HSI +#define STM32_USART3CLK STM32_HSICLK +#else +#error "invalid source selected for USART3 clock" +#endif + +/** + * @brief UART4 frequency. + */ +#if STM32_UART4SW == STM32_UART4SW_PCLK +#define STM32_UART4CLK STM32_PCLK1 +#elif STM32_UART4SW == STM32_UART4SW_SYSCLK +#define STM32_UART4CLK STM32_SYSCLK +#elif STM32_UART4SW == STM32_UART4SW_LSE +#define STM32_UART4CLK STM32_LSECLK +#elif STM32_UART4SW == STM32_UART4SW_HSI +#define STM32_UART4CLK STM32_HSICLK +#else +#error "invalid source selected for UART4 clock" +#endif + +/** + * @brief UART5 frequency. + */ +#if STM32_UART5SW == STM32_UART5SW_PCLK +#define STM32_UART5CLK STM32_PCLK1 +#elif STM32_UART5SW == STM32_UART5SW_SYSCLK +#define STM32_UART5CLK STM32_SYSCLK +#elif STM32_UART5SW == STM32_UART5SW_LSE +#define STM32_UART5CLK STM32_LSECLK +#elif STM32_UART5SW == STM32_UART5SW_HSI +#define STM32_UART5CLK STM32_HSICLK +#else +#error "invalid source selected for UART5 clock" +#endif + +/** + * @brief TIM1 frequency. + */ +#if STM32_TIM1SW == STM32_TIM1SW_PCLK2 +#if STM32_PPRE2 == STM32_PPRE2_DIV1 +#define STM32_TIM1CLK STM32_PCLK2 +#else +#define STM32_TIM1CLK (STM32_PCLK2 * 2) +#endif + +#elif STM32_TIM1SW == STM32_TIM1SW_PLLX2 +#if (STM32_SW != STM32_SW_PLL) || \ + (STM32_HPRE != STM32_HPRE_DIV1) || \ + (STM32_PPRE2 != STM32_PPRE2_DIV1) +#error "double clock mode cannot be activated for TIM1 under the current settings" +#endif +#define STM32_TIM1CLK (STM32_PLLCLKOUT * 2) + +#else +#error "invalid source selected for TIM1 clock" +#endif + +/** + * @brief TIM8 frequency. + */ +#if STM32_TIM8SW == STM32_TIM8SW_PCLK2 +#if STM32_PPRE2 == STM32_PPRE2_DIV1 +#define STM32_TIM8CLK STM32_PCLK2 +#else +#define STM32_TIM8CLK (STM32_PCLK2 * 2) +#endif + +#elif STM32_TIM8SW == STM32_TIM8SW_PLLX2 +#if (STM32_SW != STM32_SW_PLL) || \ + (STM32_HPRE != STM32_HPRE_DIV1) || \ + (STM32_PPRE2 != STM32_PPRE2_DIV1) +#error "double clock mode cannot be activated for TIM8 under the current settings" +#endif +#define STM32_TIM8CLK (STM32_PLLCLKOUT * 2) + +#else +#error "invalid source selected for TIM8 clock" +#endif + +/** + * @brief HRTIM1 frequency. + */ +#if STM32_HRTIM1SW == STM32_HRTIM1SW_PCLK2 +#if STM32_PPRE2 == STM32_PPRE2_DIV1 +#define STM32_HRTIM1CLK STM32_PCLK2 +#else +#define STM32_HRTIM1CLK (STM32_PCLK2 * 2) +#endif + +#elif STM32_HRTIM1SW == STM32_HRTIM1SW_PLLX2 +#if (STM32_SW != STM32_SW_PLL) || \ + (STM32_HPRE != STM32_HPRE_DIV1) || \ + (STM32_PPRE2 != STM32_PPRE2_DIV1) +#error "double clock mode cannot be activated for HRTIM1 under the current settings" +#endif +#define STM32_HRTIM1CLK (STM32_PLLCLKOUT * 2) + +#else +#error "invalid source selected for HRTIM1 clock" +#endif + +/** + * @brief Timers 2, 3, 4, 6, 7 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 1, 8, 15, 16, 17 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief USB frequency. + */ +#if (STM32_USBPRE == STM32_USBPRE_DIV1P5) || defined(__DOXYGEN__) +#define STM32_USBCLK ((STM32_PLLCLKOUT * 2) / 3) +#elif (STM32_USBPRE == STM32_USBPRE_DIV1) +#define STM32_USBCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_USBPRE value specified" +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= 24000000) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000010 +#elif STM32_HCLK <= 48000000 +#define STM32_FLASHBITS 0x00000011 +#else +#define STM32_FLASHBITS 0x00000012 +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.c b/os/hal/ports/STM32/STM32F4xx/hal_lld.c index b2b8a11978..5f746d19a0 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.c @@ -1,341 +1,341 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F4xx/hal_lld.c - * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f4xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ - -#if STM32_BKPRAM_ENABLE - rccEnableBKPSRAM(true); - - PWR->CSR |= PWR_CSR_BRE; - while ((PWR->CSR & PWR_CSR_BRR) == 0) - ; /* Waits until the regulator is stable */ -#else - PWR->CSR &= ~PWR_CSR_BRE; -#endif /* STM32_BKPRAM_ENABLE */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. AHB3 is not reseted because it could have - been initialized in the board initialization file (board.c). - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~STM32_GPIO_EN_MASK); -#if !defined(STM32F410xx) - rccResetAHB2(~0); -#endif - rccResetAPB1(~RCC_APB1RSTR_PWRRST); - rccResetAPB2(~0); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ -} - -/** - * @brief STM32F2xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enable.*/ -#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR_RTCAPBEN) - RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_RTCAPBEN; -#else - RCC->APB1ENR = RCC_APB1ENR_PWREN; -#endif - - /* PWR initialization.*/ -#if defined(STM32F4XX) || defined(__DOXYGEN__) - PWR->CR = STM32_VOS; -#else - PWR->CR = 0; -#endif - - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. Clearing the register has to be postponed after HSI is the - new source.*/ - RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers finally cleared to reset values.*/ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - -#if STM32_HSE_ENABLED - /* HSE activation.*/ -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - /* No HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON; -#endif - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | - STM32_PLLM; - RCC->CR |= RCC_CR_PLLON; - - /* Synchronization with voltage regulator stabilization.*/ -#if defined(STM32F4XX) - while ((PWR->CSR & PWR_CSR_VOSRDY) == 0) - ; /* Waits until power regulator is stable. */ - -#if STM32_OVERDRIVE_REQUIRED - /* Overdrive activation performed after activating the PLL in order to save - time as recommended in RM in "Entering Over-drive mode" paragraph.*/ - PWR->CR |= PWR_CR_ODEN; - while (!(PWR->CSR & PWR_CSR_ODRDY)) - ; - PWR->CR |= PWR_CR_ODSWEN; - while (!(PWR->CSR & PWR_CSR_ODSWRDY)) - ; -#endif /* STM32_OVERDRIVE_REQUIRED */ -#endif /* defined(STM32F4XX) */ - - /* Waiting for PLL lock.*/ - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; -#endif /* STM32_ACTIVATE_PLL */ - -#if STM32_ACTIVATE_PLLI2S - /* PLLI2S activation.*/ - RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SN | STM32_PLLI2SP | - STM32_PLLI2SSRC | STM32_PLLI2SQ | STM32_PLLI2SM; - RCC->CR |= RCC_CR_PLLI2SON; - - /* Waiting for PLL lock.*/ - while (!(RCC->CR & RCC_CR_PLLI2SRDY)) - ; -#endif /* STM32_ACTIVATE_PLLI2S */ - -#if STM32_ACTIVATE_PLLSAI - /* PLLSAI activation.*/ - RCC->PLLSAICFGR = STM32_PLLSAIR | STM32_PLLSAIN | STM32_PLLSAIP | - STM32_PLLSAIQ | STM32_PLLSAIM; - RCC->CR |= RCC_CR_PLLSAION; - - /* Waiting for PLL lock.*/ - while (!(RCC->CR & RCC_CR_PLLSAIRDY)) - ; -#endif /* STM32_ACTIVATE_PLLSAI */ - - /* Other clock-related settings (dividers, MCO etc).*/ -#if !defined(STM32F413xx) - RCC->CFGR = STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL | - STM32_I2SSRC | STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | - STM32_HPRE; -#else - RCC->CFGR = STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL | - STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | - STM32_HPRE; -#endif - -#if STM32_HAS_RCC_DCKCFGR - /* DCKCFGR register initialization, note, must take care of the _OFF - pseudo settings.*/ - { - uint32_t dckcfgr = 0; -#if STM32_SAI2SEL != STM32_SAI2SEL_OFF - dckcfgr |= STM32_SAI2SEL; -#endif -#if STM32_SAI1SEL != STM32_SAI1SEL_OFF - dckcfgr |= STM32_SAI1SEL; -#endif -#if (STM32_ACTIVATE_PLLSAI == TRUE) && \ - (STM32_PLLSAIDIVR != STM32_PLLSAIDIVR_OFF) - dckcfgr |= STM32_PLLSAIDIVR; -#endif -#if defined(STM32F469xx) || defined(STM32F479xx) - /* Special case, in those devices STM32_CK48MSEL is located in the - DCKCFGR register.*/ - dckcfgr |= STM32_CK48MSEL; -#endif -#if !defined(STM32F413xx) - RCC->DCKCFGR = dckcfgr | - STM32_TIMPRE | STM32_PLLSAIDIVQ | STM32_PLLI2SDIVQ; -#else - RCC->DCKCFGR = dckcfgr | - STM32_TIMPRE | STM32_PLLDIVR | STM32_PLLI2SDIVR; -#endif - } -#endif - -#if STM32_HAS_RCC_DCKCFGR2 - /* DCKCFGR2 register initialization.*/ - RCC->DCKCFGR2 = STM32_CK48MSEL; -#endif - - /* Flash setup.*/ -#if !defined(STM32_REMOVE_REVISION_A_FIX) - /* Some old revisions of F4x MCUs randomly crashes with compiler - optimizations enabled AND flash caches enabled. */ - if ((DBGMCU->IDCODE == 0x20006411) && (SCB->CPUID == 0x410FC241)) - FLASH->ACR = FLASH_ACR_PRFTEN | STM32_FLASHBITS; - else - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | - FLASH_ACR_DCEN | STM32_FLASHBITS; -#else - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | - FLASH_ACR_DCEN | STM32_FLASHBITS; -#endif - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld.c + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f4xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + +#if STM32_BKPRAM_ENABLE + rccEnableBKPSRAM(true); + + PWR->CSR |= PWR_CSR_BRE; + while ((PWR->CSR & PWR_CSR_BRR) == 0) + ; /* Waits until the regulator is stable */ +#else + PWR->CSR &= ~PWR_CSR_BRE; +#endif /* STM32_BKPRAM_ENABLE */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. AHB3 is not reseted because it could have + been initialized in the board initialization file (board.c). + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~STM32_GPIO_EN_MASK); +#if !defined(STM32F410xx) + rccResetAHB2(~0); +#endif + rccResetAPB1(~RCC_APB1RSTR_PWRRST); + rccResetAPB2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32F2xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ +#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR_RTCAPBEN) + RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_RTCAPBEN; +#else + RCC->APB1ENR = RCC_APB1ENR_PWREN; +#endif + + /* PWR initialization.*/ +#if defined(STM32F4XX) || defined(__DOXYGEN__) + PWR->CR = STM32_VOS; +#else + PWR->CR = 0; +#endif + + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | + STM32_PLLM; + RCC->CR |= RCC_CR_PLLON; + + /* Synchronization with voltage regulator stabilization.*/ +#if defined(STM32F4XX) + while ((PWR->CSR & PWR_CSR_VOSRDY) == 0) + ; /* Waits until power regulator is stable. */ + +#if STM32_OVERDRIVE_REQUIRED + /* Overdrive activation performed after activating the PLL in order to save + time as recommended in RM in "Entering Over-drive mode" paragraph.*/ + PWR->CR |= PWR_CR_ODEN; + while (!(PWR->CSR & PWR_CSR_ODRDY)) + ; + PWR->CR |= PWR_CR_ODSWEN; + while (!(PWR->CSR & PWR_CSR_ODSWRDY)) + ; +#endif /* STM32_OVERDRIVE_REQUIRED */ +#endif /* defined(STM32F4XX) */ + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; +#endif /* STM32_ACTIVATE_PLL */ + +#if STM32_ACTIVATE_PLLI2S + /* PLLI2S activation.*/ + RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SN | STM32_PLLI2SP | + STM32_PLLI2SSRC | STM32_PLLI2SQ | STM32_PLLI2SM; + RCC->CR |= RCC_CR_PLLI2SON; + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLI2SRDY)) + ; +#endif /* STM32_ACTIVATE_PLLI2S */ + +#if STM32_ACTIVATE_PLLSAI + /* PLLSAI activation.*/ + RCC->PLLSAICFGR = STM32_PLLSAIR | STM32_PLLSAIN | STM32_PLLSAIP | + STM32_PLLSAIQ | STM32_PLLSAIM; + RCC->CR |= RCC_CR_PLLSAION; + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLSAIRDY)) + ; +#endif /* STM32_ACTIVATE_PLLSAI */ + + /* Other clock-related settings (dividers, MCO etc).*/ +#if !defined(STM32F413xx) + RCC->CFGR = STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL | + STM32_I2SSRC | STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; +#else + RCC->CFGR = STM32_MCO2PRE | STM32_MCO2SEL | STM32_MCO1PRE | STM32_MCO1SEL | + STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; +#endif + +#if STM32_HAS_RCC_DCKCFGR + /* DCKCFGR register initialization, note, must take care of the _OFF + pseudo settings.*/ + { + uint32_t dckcfgr = 0; +#if STM32_SAI2SEL != STM32_SAI2SEL_OFF + dckcfgr |= STM32_SAI2SEL; +#endif +#if STM32_SAI1SEL != STM32_SAI1SEL_OFF + dckcfgr |= STM32_SAI1SEL; +#endif +#if (STM32_ACTIVATE_PLLSAI == TRUE) && \ + (STM32_PLLSAIDIVR != STM32_PLLSAIDIVR_OFF) + dckcfgr |= STM32_PLLSAIDIVR; +#endif +#if defined(STM32F469xx) || defined(STM32F479xx) + /* Special case, in those devices STM32_CK48MSEL is located in the + DCKCFGR register.*/ + dckcfgr |= STM32_CK48MSEL; +#endif +#if !defined(STM32F413xx) + RCC->DCKCFGR = dckcfgr | + STM32_TIMPRE | STM32_PLLSAIDIVQ | STM32_PLLI2SDIVQ; +#else + RCC->DCKCFGR = dckcfgr | + STM32_TIMPRE | STM32_PLLDIVR | STM32_PLLI2SDIVR; +#endif + } +#endif + +#if STM32_HAS_RCC_DCKCFGR2 + /* DCKCFGR2 register initialization.*/ + RCC->DCKCFGR2 = STM32_CK48MSEL; +#endif + + /* Flash setup.*/ +#if !defined(STM32_REMOVE_REVISION_A_FIX) + /* Some old revisions of F4x MCUs randomly crashes with compiler + optimizations enabled AND flash caches enabled. */ + if ((DBGMCU->IDCODE == 0x20006411) && (SCB->CPUID == 0x410FC241)) + FLASH->ACR = FLASH_ACR_PRFTEN | STM32_FLASHBITS; + else + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | + FLASH_ACR_DCEN | STM32_FLASHBITS; +#else + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | + FLASH_ACR_DCEN | STM32_FLASHBITS; +#endif + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.h b/os/hal/ports/STM32/STM32F4xx/hal_lld.h index 1063dc09fb..68501510ca 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.h @@ -1,278 +1,278 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F4xx/hal_lld.h - * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -#if defined(STM32F413xx) -#include "hal_lld_type2.h" -#else -#include "hal_lld_type1.h" -#endif - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/** - * @brief MCO1 divider clock. - */ -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || defined(__DOXYGEN__) -#define STM32_MCO1DIVCLK STM32_HSICLK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE -#define STM32_MCO1DIVCLK STM32_LSECLK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE -#define STM32_MCO1DIVCLK STM32_HSECLK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL -#define STM32_MCO1DIVCLK STM32_PLLCLKOUT - -#else -#error "invalid STM32_MCO1SEL value specified" -#endif - -/** - * @brief MCO1 output pin clock. - */ -#if (STM32_MCO1PRE == STM32_MCO1PRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCO1CLK STM32_MCO1DIVCLK - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV2 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 2) - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV3 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 3) - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV4 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 4) - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV5 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 5) - -#else -#error "invalid STM32_MCO1PRE value specified" -#endif - -/** - * @brief MCO2 divider clock. - */ -#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || defined(__DOXYGEN__) -#define STM32_MCO2DIVCLK STM32_HSECLK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL -#define STM32_MCO2DIVCLK STM32_PLLCLKOUT - -#elif STM32_MCO2SEL == STM32_MCO2SEL_SYSCLK -#define STM32_MCO2DIVCLK STM32_SYSCLK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S -#define STM32_MCO2DIVCLK STM32_PLLI2S - -#else -#error "invalid STM32_MCO2SEL value specified" -#endif - -/** - * @brief MCO2 output pin clock. - */ -#if (STM32_MCO2PRE == STM32_MCO2PRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCO2CLK STM32_MCO2DIVCLK - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV2 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 2) - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV3 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 3) - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV4 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 4) - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV5 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 5) - -#else -#error "invalid STM32_MCO2PRE value specified" -#endif - -/** - * @brief RTC HSE divider setting. - */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) -#else -#error "invalid STM32_RTCPRE value specified" -#endif - -/** - * @brief HSE divider toward RTC clock. - */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) -#else -#error "invalid STM32_RTCPRE value specified" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK STM32_HSEDIVCLK - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief 48MHz frequency. - */ -#if STM32_CLOCK48_REQUIRED || defined(__DOXYGEN__) -#if STM32_HAS_RCC_CK48MSEL || defined(__DOXYGEN__) -#if (STM32_CK48MSEL == STM32_CK48MSEL_PLL) || defined(__DOXYGEN__) -#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) -#elif STM32_CK48MSEL == STM32_CK48MSEL_PLLALT -#define STM32_PLL48CLK STM32_PLL48CLK_ALTSRC -#else -#error "invalid source selected for PLL48CLK clock" -#endif -#else /* !STM32_HAS_RCC_CK48MSEL */ -#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) -#endif /* !STM32_HAS_RCC_CK48MSEL */ -#else /* !STM32_CLOCK48_REQUIRED */ -#define STM32_PLL48CLK 0 -#endif /* STM32_CLOCK48_REQUIRED */ - -#if !STM32_HAS_RCC_DCKCFGR || (STM32_TIMPRE == STM32_TIMPRE_PCLK) || \ - defined(__DOXYGEN__) -/** - * @brief Clock of timers connected to APB1 - * (Timers 2, 3, 4, 5, 6, 7, 12, 13, 14). - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Clock of timers connected to APB2 (Timers 1, 8, 9, 10, 11). - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -#else /* STM32_HAS_RCC_DCKCFGR && (STM32_TIMPRE == STM32_TIMPRE_HCLK) */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || \ - (STM32_PPRE1 == STM32_PPRE1_DIV2) || \ - ((STM32_PPRE1 == STM32_PPRE1_DIV4) && \ - (STM32_TIMPRE_PRESCALE4 == TRUE)) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 STM32_HCLK -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 4) -#endif - -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || \ - (STM32_PPRE2 == STM32_PPRE2_DIV2) || \ - ((STM32_PPRE2 == STM32_PPRE2_DIV4) && \ - (STM32_TIMPRE_PRESCALE4 == TRUE)) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 STM32_HCLK -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 4) -#endif -#endif /* STM32_HAS_RCC_DCKCFGR && (STM32_TIMPRE == STM32_TIMPRE_HCLK) */ - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000000 -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS 0x00000001 -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS 0x00000002 -#elif STM32_HCLK <= STM32_3WS_THRESHOLD -#define STM32_FLASHBITS 0x00000003 -#elif STM32_HCLK <= STM32_4WS_THRESHOLD -#define STM32_FLASHBITS 0x00000004 -#elif STM32_HCLK <= STM32_5WS_THRESHOLD -#define STM32_FLASHBITS 0x00000005 -#elif STM32_HCLK <= STM32_6WS_THRESHOLD -#define STM32_FLASHBITS 0x00000006 -#elif STM32_HCLK <= STM32_7WS_THRESHOLD -#define STM32_FLASHBITS 0x00000007 -#elif STM32_HCLK <= STM32_8WS_THRESHOLD -#define STM32_FLASHBITS 0x00000008 -#else -#error "invalid frequency at specified VDD level" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld.h + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +#if defined(STM32F413xx) +#include "hal_lld_type2.h" +#else +#include "hal_lld_type1.h" +#endif + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/** + * @brief MCO1 divider clock. + */ +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || defined(__DOXYGEN__) +#define STM32_MCO1DIVCLK STM32_HSICLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE +#define STM32_MCO1DIVCLK STM32_LSECLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE +#define STM32_MCO1DIVCLK STM32_HSECLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL +#define STM32_MCO1DIVCLK STM32_PLLCLKOUT + +#else +#error "invalid STM32_MCO1SEL value specified" +#endif + +/** + * @brief MCO1 output pin clock. + */ +#if (STM32_MCO1PRE == STM32_MCO1PRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCO1CLK STM32_MCO1DIVCLK + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV2 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 2) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV3 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 3) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV4 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 4) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV5 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 5) + +#else +#error "invalid STM32_MCO1PRE value specified" +#endif + +/** + * @brief MCO2 divider clock. + */ +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || defined(__DOXYGEN__) +#define STM32_MCO2DIVCLK STM32_HSECLK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL +#define STM32_MCO2DIVCLK STM32_PLLCLKOUT + +#elif STM32_MCO2SEL == STM32_MCO2SEL_SYSCLK +#define STM32_MCO2DIVCLK STM32_SYSCLK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S +#define STM32_MCO2DIVCLK STM32_PLLI2S + +#else +#error "invalid STM32_MCO2SEL value specified" +#endif + +/** + * @brief MCO2 output pin clock. + */ +#if (STM32_MCO2PRE == STM32_MCO2PRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCO2CLK STM32_MCO2DIVCLK + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV2 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 2) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV3 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 3) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV4 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 4) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV5 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 5) + +#else +#error "invalid STM32_MCO2PRE value specified" +#endif + +/** + * @brief RTC HSE divider setting. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief HSE divider toward RTC clock. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK STM32_HSEDIVCLK + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief 48MHz frequency. + */ +#if STM32_CLOCK48_REQUIRED || defined(__DOXYGEN__) +#if STM32_HAS_RCC_CK48MSEL || defined(__DOXYGEN__) +#if (STM32_CK48MSEL == STM32_CK48MSEL_PLL) || defined(__DOXYGEN__) +#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#elif STM32_CK48MSEL == STM32_CK48MSEL_PLLALT +#define STM32_PLL48CLK STM32_PLL48CLK_ALTSRC +#else +#error "invalid source selected for PLL48CLK clock" +#endif +#else /* !STM32_HAS_RCC_CK48MSEL */ +#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#endif /* !STM32_HAS_RCC_CK48MSEL */ +#else /* !STM32_CLOCK48_REQUIRED */ +#define STM32_PLL48CLK 0 +#endif /* STM32_CLOCK48_REQUIRED */ + +#if !STM32_HAS_RCC_DCKCFGR || (STM32_TIMPRE == STM32_TIMPRE_PCLK) || \ + defined(__DOXYGEN__) +/** + * @brief Clock of timers connected to APB1 + * (Timers 2, 3, 4, 5, 6, 7, 12, 13, 14). + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Clock of timers connected to APB2 (Timers 1, 8, 9, 10, 11). + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +#else /* STM32_HAS_RCC_DCKCFGR && (STM32_TIMPRE == STM32_TIMPRE_HCLK) */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || \ + (STM32_PPRE1 == STM32_PPRE1_DIV2) || \ + ((STM32_PPRE1 == STM32_PPRE1_DIV4) && \ + (STM32_TIMPRE_PRESCALE4 == TRUE)) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 STM32_HCLK +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 4) +#endif + +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || \ + (STM32_PPRE2 == STM32_PPRE2_DIV2) || \ + ((STM32_PPRE2 == STM32_PPRE2_DIV4) && \ + (STM32_TIMPRE_PRESCALE4 == TRUE)) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 STM32_HCLK +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 4) +#endif +#endif /* STM32_HAS_RCC_DCKCFGR && (STM32_TIMPRE == STM32_TIMPRE_HCLK) */ + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000000 +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS 0x00000001 +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS 0x00000002 +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS 0x00000003 +#elif STM32_HCLK <= STM32_4WS_THRESHOLD +#define STM32_FLASHBITS 0x00000004 +#elif STM32_HCLK <= STM32_5WS_THRESHOLD +#define STM32_FLASHBITS 0x00000005 +#elif STM32_HCLK <= STM32_6WS_THRESHOLD +#define STM32_FLASHBITS 0x00000006 +#elif STM32_HCLK <= STM32_7WS_THRESHOLD +#define STM32_FLASHBITS 0x00000007 +#elif STM32_HCLK <= STM32_8WS_THRESHOLD +#define STM32_FLASHBITS 0x00000008 +#else +#error "invalid frequency at specified VDD level" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h b/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h index 4578f49350..5fe589bab8 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h @@ -1,2015 +1,2019 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F4xx/hal_lld_type1.h - * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * - STM32_VDD (as hundredths of Volt). - * . - * One of the following macros must also be defined: - * - STM32F2XX for High-performance STM32F2 devices. - * - STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, - * STM32F446xx for High-performance STM32F4 devices of - * Foundation line. - * - STM32F401xx, STM32F410xx, STM32F411xx, STM32F412xx - * for High-performance STM32F4 devices of Access line. - * - STM32F427xx, STM32F437xx, STM32F429xx, STM32F439xx, STM32F469xx, - * STM32F479xx for High-performance STM32F4 devices of Advanced line. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_TYPE1_H -#define HAL_LLD_TYPE1_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Defines the support for realtime counters in the HAL. - */ -#define HAL_IMPLEMENTS_COUNTERS TRUE - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32F205xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F205 High Performance" - -#elif defined(STM32F207xx) -#define PLATFORM_NAME "STM32F207 High Performance" - -#elif defined(STM32F215xx) -#define PLATFORM_NAME "STM32F215 High Performance" - -#elif defined(STM32F217xx) -#define PLATFORM_NAME "STM32F217 High Performance" - -#elif defined(STM32F401xx) -#define PLATFORM_NAME "STM32F401 High Performance with DSP and FPU" - -#elif defined(STM32F405xx) -#define PLATFORM_NAME "STM32F405 High Performance with DSP and FPU" - -#elif defined(STM32F407xx) -#define PLATFORM_NAME "STM32F407 High Performance with DSP and FPU" - -#elif defined(STM32F410xx) -#define PLATFORM_NAME "STM32F410 High Performance with DSP and FPU" - -#elif defined(STM32F411xx) -#define PLATFORM_NAME "STM32F411 High Performance with DSP and FPU" - -#elif defined(STM32F412xx) -#define PLATFORM_NAME "STM32F412 High Performance with DSP and FPU" - -#elif defined(STM32F415xx) -#define PLATFORM_NAME "STM32F415 High Performance with DSP and FPU" - -#elif defined(STM32F417xx) -#define PLATFORM_NAME "STM32F417 High Performance with DSP and FPU" - -#elif defined(STM32F427xx) -#define PLATFORM_NAME "STM32F427 High Performance with DSP and FPU" - -#elif defined(STM32F429xx) -#define PLATFORM_NAME "STM32F429 High Performance with DSP and FPU" - -#elif defined(STM32F437xx) -#define PLATFORM_NAME "STM32F437 High Performance with DSP and FPU" - -#elif defined(STM32F439xx) -#define PLATFORM_NAME "STM32F439 High Performance with DSP and FPU" - -#elif defined(STM32F446xx) -#define PLATFORM_NAME "STM32F446 High Performance with DSP and FPU" - -#elif defined(STM32F469xx) -#define PLATFORM_NAME "STM32F469 High Performance with DSP and FPU" - -#elif defined(STM32F479xx) -#define PLATFORM_NAME "STM32F479 High Performance with DSP and FPU" - -#else -#error "STM32F2xx/F4xx device not specified" -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -#if defined(STM32F427xx) || defined(STM32F437xx) || \ - defined(STM32F429xx) || defined(STM32F439xx) || \ - defined(STM32F469xx) || defined(STM32F479xx) || defined(__DOXYGEN__) -/** - * @brief Absolute maximum system clock. - */ -#define STM32_SYSCLK_MAX 180000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 26000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 50000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency using an external source. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 2100000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 950000 - -/** - * @brief Maximum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MAX 432000000 - -/** - * @brief Minimum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MIN 192000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 180000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 24000000 - -/** - * @brief Maximum PLLI2S output clock frequency. - */ -#define STM32_PLLI2SOUT_MAX 216000000 - -/** - * @brief Maximum PLLSAI output clock frequency. - */ -#define STM32_PLLSAIOUT_MAX 216000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) - -/** - * @brief Maximum SPI/I2S clock frequency. - */ -#define STM32_SPII2S_MAX 45000000 -#endif - -#if defined(STM32F40_41xxx) -#define STM32_SYSCLK_MAX 168000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 50000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 1000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_PLLIN_MAX 2100000 -#define STM32_PLLIN_MIN 950000 -#define STM32_PLLVCO_MAX 432000000 -#define STM32_PLLVCO_MIN 192000000 -#define STM32_PLLOUT_MAX 168000000 -#define STM32_PLLOUT_MIN 24000000 -#define STM32_PCLK1_MAX 42000000 -#define STM32_PCLK2_MAX 84000000 -#define STM32_SPII2S_MAX 42000000 -#endif - -#if defined(STM32F401xx) -#define STM32_SYSCLK_MAX 84000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 50000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 1000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_PLLIN_MAX 2100000 -#define STM32_PLLIN_MIN 950000 -#define STM32_PLLVCO_MAX 432000000 -#define STM32_PLLVCO_MIN 192000000 -#define STM32_PLLOUT_MAX 84000000 -#define STM32_PLLOUT_MIN 24000000 -#define STM32_PCLK1_MAX 42000000 -#define STM32_PCLK2_MAX 84000000 -#define STM32_SPII2S_MAX 42000000 -#endif - -#if defined(STM32F410xx) || defined(STM32F411xx) || \ - defined(STM32F412xx) -#define STM32_SYSCLK_MAX 100000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 50000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 1000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_PLLIN_MAX 2100000 -#define STM32_PLLIN_MIN 950000 -#define STM32_PLLVCO_MAX 432000000 -#define STM32_PLLVCO_MIN 100000000 -#define STM32_PLLOUT_MAX 100000000 -#define STM32_PLLOUT_MIN 24000000 -#define STM32_PCLK1_MAX 50000000 -#define STM32_PCLK2_MAX 100000000 -#define STM32_SPII2S_MAX 50000000 -#endif - -#if defined(STM32F446xx) -#define STM32_SYSCLK_MAX 180000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 50000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 1000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_PLLIN_MAX 2100000 -#define STM32_PLLIN_MIN 950000 -#define STM32_PLLVCO_MAX 432000000 -#define STM32_PLLVCO_MIN 100000000 -#define STM32_PLLOUT_MAX 180000000 -#define STM32_PLLOUT_MIN 12500000 -#define STM32_PLLI2SOUT_MAX 216000000 -#define STM32_PLLSAIOUT_MAX 216000000 -#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) -#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) -#define STM32_SPII2S_MAX 45000000 -#endif - -#if defined(STM32F2XX) -#define STM32_SYSCLK_MAX 120000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 26000000 -#define STM32_HSECLK_MIN 1000000 -#define STM32_HSECLK_BYP_MIN 1000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_PLLIN_MAX 2000000 -#define STM32_PLLIN_MIN 950000 -#define STM32_PLLVCO_MAX 432000000 -#define STM32_PLLVCO_MIN 192000000 -#define STM32_PLLOUT_MAX 120000000 -#define STM32_PLLOUT_MIN 24000000 -#define STM32_PCLK1_MAX 30000000 -#define STM32_PCLK2_MAX 60000000 -#define STM32_SPII2S_MAX 30000000 -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 16000000 /**< High speed internal clock. */ -#define STM32_LSICLK 32000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_VOS_SCALE3 0x00004000 -#define STM32_VOS_SCALE2 0x00008000 -#define STM32_VOS_SCALE1 0x0000C000 -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ -#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ -#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ -#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ -#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ - -#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW mask. */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ -#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ -#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ - -#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ - -#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ -#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ -#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ -#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ -#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ - -#define STM32_I2SSRC_MASK (1 << 23) /**< I2CSRC mask. */ -#define STM32_I2SSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */ -#define STM32_I2SSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */ - -#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ -#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ -#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ -#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ -#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ -#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ - -#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ -#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ -#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ -#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ -#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ -#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ - -#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ -#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ -#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ - -/** - * @name RCC_PLLI2SCFGR register bits definitions - * @{ - */ -#define STM32_PLLI2SM_MASK (31 << 0) /**< PLLI2SM mask. */ -#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ -#define STM32_PLLI2SP_MASK (3 << 16) /**< PLLI2SP mask. */ -#define STM32_PLLI2SP_DIV2 (0 << 16) /**< PLLI2S clock divided by 2. */ -#define STM32_PLLI2SP_DIV4 (1 << 16) /**< PLLI2S clock divided by 4. */ -#define STM32_PLLI2SP_DIV6 (2 << 16) /**< PLLI2S clock divided by 6. */ -#define STM32_PLLI2SP_DIV8 (3 << 16) /**< PLLI2S clock divided by 8. */ -#define STM32_PLLI2SSRC_MASK (1 << 22) /**< PLLI2SSRC mask. */ -#define STM32_PLLI2SSRC_PLLSRC (0 << 22) /**< PLLI2SSRC is selected PLL - source. */ -#define STM32_PLLI2SSRC_CKIN (1 << 22) /**< PLLI2SSRC is I2S_CKIN. */ -#define STM32_PLLI2SQ_MASK (15 << 24) /**< PLLI2SQ mask. */ -#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ -/** @} */ - -/** - * @name RCC_PLLSAICFGR register bits definitions - * @{ - */ -#define STM32_PLLSAIM_MASK (31 << 0) /**< PLLSAIM mask. */ -#define STM32_PLLSAIN_MASK (511 << 6) /**< PLLSAIN mask. */ -#define STM32_PLLSAIP_MASK (3 << 16) /**< PLLSAIP mask. */ -#define STM32_PLLSAIP_DIV2 (0 << 16) /**< PLLSAI clock divided by 2. */ -#define STM32_PLLSAIP_DIV4 (1 << 16) /**< PLLSAI clock divided by 4. */ -#define STM32_PLLSAIP_DIV6 (2 << 16) /**< PLLSAI clock divided by 6. */ -#define STM32_PLLSAIP_DIV8 (3 << 16) /**< PLLSAI clock divided by 8. */ -#define STM32_PLLSAIQ_MASK (15 << 24) /**< PLLSAIQ mask. */ -#define STM32_PLLSAIR_MASK (7 << 28) /**< PLLSAIR mask. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ -/** @} */ - -/** - * @name RCC_DCKCFGR register bits definitions - * @{ - */ -#define STM32_PLLI2SDIVQ_MASK (31 << 0) /**< PLLI2SDIVQ mask. */ -#define STM32_PLLSAIDIVQ_MASK (31 << 8) /**< PLLSAIDIVQ mask. */ - -#define STM32_PLLSAIDIVR_MASK (3 << 16) /**< PLLSAIDIVR mask. */ -#define STM32_PLLSAIDIVR_DIV2 (0 << 16) /**< LCD_CLK is R divided by 2. */ -#define STM32_PLLSAIDIVR_DIV4 (1 << 16) /**< LCD_CLK is R divided by 4. */ -#define STM32_PLLSAIDIVR_DIV8 (2 << 16) /**< LCD_CLK is R divided by 8. */ -#define STM32_PLLSAIDIVR_DIV16 (3 << 16) /**< LCD_CLK is R divided by 16.*/ -#define STM32_PLLSAIDIVR_OFF 0xFFFFFFFFU /**< LCD CLK is not required. */ - -#define STM32_SAI1SEL_MASK (3 << 20) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_PLLSAI (0 << 20) /**< SAI1 source is PLLSAI. */ -#define STM32_SAI1SEL_PLLI2S (1 << 20) /**< SAI1 source is PLLI2S. */ -#define STM32_SAI1SEL_PLLR (2 << 20) /**< SAI1 source is PLLR. */ -#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ - -#define STM32_SAI2SEL_MASK (3 << 22) /**< SAI2SEL mask. */ -#define STM32_SAI2SEL_PLLSAI (0 << 22) /**< SAI2 source is PLLSAI. */ -#define STM32_SAI2SEL_PLLI2S (1 << 22) /**< SAI2 source is PLLI2S. */ -#define STM32_SAI2SEL_PLLR (2 << 22) /**< SAI2 source is PLLR. */ -#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ - -#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ -#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ -#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ - -#define STM32_I2S1SEL_MASK (3 << 25) /**< I2S1SEL mask. */ -#define STM32_I2S1SEL_PLLR (0 << 25) /**< I2S1 source is PLLR. */ -#define STM32_I2S1SEL_AFIN (1 << 25) /**< I2S1 source is AF Input. */ -#define STM32_I2S1SEL_MCO1 (2 << 25) /**< I2S1 source is MCO1. */ -#define STM32_I2S1SEL_OFF 0xFFFFFFFFU /**< I2S1 clock is not required.*/ - -#define STM32_I2S2SEL_MASK (3 << 27) /**< I2S2SEL mask. */ -#define STM32_I2S2SEL_PLLR (0 << 27) /**< I2S2 source is PLLR. */ -#define STM32_I2S2SEL_AFIN (1 << 27) /**< I2S2 source is AF Input. */ -#define STM32_I2S2SEL_MCO1 (2 << 27) /**< I2S2 source is MCO1. */ -#define STM32_I2S2SEL_OFF 0xFFFFFFFFU /**< I2S2 clock is not required.*/ - -#define STM32_DSISEL_MASK (1 << 28) /**< DSISEL mask. */ -#define STM32_DSISEL_PHY (0 << 28) /**< DSI source is DSI-PSY. */ -#define STM32_DSISEL_PLLR (1 << 28) /**< DSI source is PLLR. */ -/** @} */ - -/** - * @name RCC_DCKCFGR2 register bits definitions - * @{ - */ -#define STM32_I2C1SEL_MASK (3 << 22) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK1 (0 << 22) /**< I2C1 source is APB/PCLK1. */ -#define STM32_I2C1SEL_SYSCLK (1 << 22) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI (2 << 22) /**< I2C1 source is HSI. */ - -#define STM32_CECSEL_MASK (1 << 26) /**< CECSEL mask. */ -#define STM32_CECSEL_LSE (0 << 26) /**< CEC source is LSE. */ -#define STM32_CECSEL_HSIDIV488 (1 << 26) /**< CEC source is HSI/488. */ - -#define STM32_CK48MSEL_MASK (1 << 27) /**< CK48MSEL mask. */ -#define STM32_CK48MSEL_PLL (0 << 27) /**< PLL48CLK source is PLL. */ -#define STM32_CK48MSEL_PLLSAI (1 << 27) /**< PLL48CLK source is PLLSAI. */ -#define STM32_CK48MSEL_PLLALT (1 << 27) /**< Alias. */ - -#define STM32_SDMMCSEL_MASK (1 << 28) /**< SDMMCSEL mask. */ -#define STM32_SDMMCSEL_PLL48CLK (0 << 28) /**< SDMMC source is PLL48CLK. */ -#define STM32_SDMMCSEL_SYSCLK (1 << 28) /**< SDMMC source is SYSCLK. */ - -#define STM32_SPDIFSEL_MASK (1 << 29) /**< SPDIFSEL mask. */ -#define STM32_SPDIFSEL_PLLI2S (0 << 29) /**< SPDIF source is PLLI2S. */ -#define STM32_SPDIFSEL_PLL (1 << 29) /**< SPDIF source is PLL. */ - -#define STM32_LPTIM1SEL_MASK (3 << 30) /**< LPTIM1 mask. */ -#define STM32_LPTIM1SEL_APB (0 << 30) /**< LPTIM1 source is APB. */ -#define STM32_LPTIM1SEL_HSI (1 << 30) /**< LPTIM1 source is HSI. */ -#define STM32_LPTIM1SEL_LSI (2 << 30) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_LSE (3 << 30) /**< LPTIM1 source is LSE. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables the backup RAM regulator. - */ -#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) -#define STM32_BKPRAM_ENABLE FALSE -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief USB/SDIO clock setting. - */ -#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) -#define STM32_CLOCK48_REQUIRED TRUE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -#if defined(STM32F4XX) || defined(__DOXYGEN__) -/** - * @brief Clock source for the PLLs. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 8 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 192..432. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 336 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 2 -#endif - -/** - * @brief PLLQ multiplier value. - * @note The allowed values are 2..15. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 7 -#endif - -/** - * @brief PLLR divider value. - * @note The allowed values are 2..7. - * @note The default value is calculated for a 96MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLR_VALUE 4 -#endif - -#else /* !defined(STM32F4XX) */ -/** - * @brief Clock source for the PLLs. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 120MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 120MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 8 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 192..432. - * @note The default value is calculated for a 120MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 240 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 120MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 2 -#endif - -/** - * @brief PLLQ multiplier value. - * @note The allowed values are 2..15. - * @note The default value is calculated for a 120MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 5 -#endif -#endif /* !defined(STM32F4XX) */ - -/** - * @brief I2S clock source (post-PLL). - * @note Not all devices have this setting, it is alternative to - * @p STM32_PLLI2SSRC. - */ -#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) -#define STM32_I2SSRC STM32_I2SSRC_CKIN -#endif - -/** - * @brief I2S clock source (pre-PLL). - * @note Not all devices have this setting, it is alternative to - * @p STM32_I2SSRC. - */ -#if !defined(STM32_PLLI2SSRC) || defined(__DOXYGEN__) -#define STM32_PLLI2SSRC STM32_PLLI2SSRC_CKIN -#endif - -/** - * @brief I2S external clock value, zero if not present. - * @note Not all devices have this setting. - */ -#if !defined(STM32_I2SCKIN_VALUE) || defined(__DOXYGEN__) -#define STM32_I2SCKIN_VALUE 0 -#endif - -/** - * @brief PLLI2SN multiplier value. - * @note The allowed values are 192..432, except for - * STM32F446 where values are 50...432. - * @note The default value is calculated for a 96MHz I2S clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SN_VALUE 192 -#endif - -/** - * @brief PLLI2SM divider value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 96MHz I2S clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLI2SM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SM_VALUE 4 -#endif - -/** - * @brief PLLI2SR divider value. - * @note The allowed values are 2..7. - * @note The default value is calculated for a 96MHz I2S clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SR_VALUE 4 -#endif - -/** - * @brief PLLI2SP divider value. - * @note The allowed values are 2, 4, 6 and 8. - */ -#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SP_VALUE 4 -#endif - -/** - * @brief PLLI2SQ divider value. - * @note The allowed values are 2..15. - */ -#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SQ_VALUE 4 -#endif - -/** - * @brief PLLI2SDIVQ divider value (SAI clock divider). - * @note The allowed values are 1..32. - */ -#if !defined(STM32_PLLI2SDIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SDIVQ_VALUE 1 -#endif - -/** - * @brief PLLSAIM value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 96MHz SAI clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIM_VALUE 4 -#endif - -/** - * @brief PLLSAIN value. - * @note The allowed values are 50..432. - * @note The default value is calculated for a 96MHz SAI clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIN_VALUE 192 -#endif - -/** - * @brief PLLSAIM value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 96MHz SAI clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIM_VALUE 4 -#endif - -/** - * @brief PLLSAIR value. - * @note The allowed values are 2..7. - */ -#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIR_VALUE 4 -#endif - -/** - * @brief PLLSAIP divider value. - * @note The allowed values are 2, 4, 6 and 8. - */ -#if !defined(STM32_PLLSAIP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIP_VALUE 8 -#endif - -/** - * @brief PLLSAIQ value. - * @note The allowed values are 2..15. - */ -#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIQ_VALUE 4 -#endif - -/** - * @brief PLLSAIDIVR divider value (SAI clock divider). - */ -#if !defined(STM32_PLLSAIDIVR) || defined(__DOXYGEN__) -#define STM32_PLLSAIDIVR STM32_PLLSAIDIVR_OFF -#endif - -/** - * @brief PLLSAIDIVQ divider value (LCD clock divider). - * @note The allowed values are 1..32. - */ -#if !defined(STM32_PLLSAIDIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIDIVQ_VALUE 1 -#endif - -/** - * @brief SAI1SEL value (SAI1 clock source). - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#endif - -/** - * @brief SAI2SEL value (SAI2 clock source). - */ -#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) -#define STM32_SAI2SEL STM32_SAI2SEL_OFF -#endif - -/** - * @brief TIM prescaler clock source. - */ -#if !defined(STM32_TIMPRE) || defined(__DOXYGEN__) -#define STM32_TIMPRE STM32_TIMPRE_PCLK -#endif - -/** - * @brief PLL48CLK clock source. - */ -#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) -#define STM32_CK48MSEL STM32_CK48MSEL_PLL -#endif - -/** - * @brief AHB prescaler value. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV4 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief RTC HSE prescaler value. - */ -#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) -#define STM32_RTCPRE_VALUE 8 -#endif - -/** - * @brief MCO1 clock source value. - * @note The default value outputs HSI clock on MCO1 pin. - */ -#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) -#define STM32_MCO1SEL STM32_MCO1SEL_HSI -#endif - -/** - * @brief MCO1 prescaler value. - * @note The default value outputs HSI clock on MCO1 pin. - */ -#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) -#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 -#endif - -/** - * @brief MCO2 clock source value. - * @note The default value outputs SYSCLK / 5 on MCO2 pin. - */ -#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) -#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK -#endif - -/** - * @brief MCO2 prescaler value. - * @note The default value outputs SYSCLK / 5 on MCO2 pin. - */ -#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) -#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if defined(STM32F4XX) || defined(__DOXYGEN__) -/* - * Configuration-related checks. - */ -#if !defined(STM32F4xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F4xx_MCUCONF not defined" -#endif - -#if defined(STM32F405xx) && !defined(STM32F405_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F405_MCUCONF not defined" -#endif - -#if defined(STM32F415xx) && !defined(STM32F415_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F415_MCUCONF not defined" -#endif - -#if defined(STM32F407xx) && !defined(STM32F407_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F407_MCUCONF not defined" -#endif - -#if defined(STM32F417xx) && !defined(STM32F417_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F417_MCUCONF not defined" -#endif - -#else /* !defined(STM32F4XX) */ -/* - * Configuration-related checks. - */ -#if !defined(STM32F2xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F2xx_MCUCONF not defined" -#endif -#endif /* !defined(STM32F4XX) */ - -/** - * @name Maximum frequency thresholds, wait states and - * parallelism for flash access. - * @{ - */ -#if defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ - defined(STM32F40_41xxx) || defined(STM32F446xx) || \ - defined(STM32F469_479xx) || defined(__DOXYGEN__) -#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__) -#define STM32_0WS_THRESHOLD 30000000 -#define STM32_1WS_THRESHOLD 60000000 -#define STM32_2WS_THRESHOLD 90000000 -#define STM32_3WS_THRESHOLD 120000000 -#define STM32_4WS_THRESHOLD 150000000 -#define STM32_5WS_THRESHOLD 180000000 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 2 -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 72000000 -#define STM32_3WS_THRESHOLD 96000000 -#define STM32_4WS_THRESHOLD 120000000 -#define STM32_5WS_THRESHOLD 144000000 -#define STM32_6WS_THRESHOLD 168000000 -#define STM32_7WS_THRESHOLD 180000000 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 22000000 -#define STM32_1WS_THRESHOLD 44000000 -#define STM32_2WS_THRESHOLD 66000000 -#define STM32_3WS_THRESHOLD 88000000 -#define STM32_4WS_THRESHOLD 110000000 -#define STM32_5WS_THRESHOLD 132000000 -#define STM32_6WS_THRESHOLD 154000000 -#define STM32_7WS_THRESHOLD 176000000 -#define STM32_8WS_THRESHOLD 180000000 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 180) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 20000000 -#define STM32_1WS_THRESHOLD 40000000 -#define STM32_2WS_THRESHOLD 60000000 -#define STM32_3WS_THRESHOLD 80000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 120000000 -#define STM32_6WS_THRESHOLD 140000000 -#define STM32_7WS_THRESHOLD 168000000 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 0 -#else -#error "invalid VDD voltage specified" -#endif - -#elif defined(STM32F412xx) -#if (STM32_VDD >= 270) && (STM32_VDD <= 360) -#define STM32_0WS_THRESHOLD 30000000 -#define STM32_1WS_THRESHOLD 64000000 -#define STM32_2WS_THRESHOLD 90000000 -#define STM32_3WS_THRESHOLD 100000000 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 2 -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 72000000 -#define STM32_3WS_THRESHOLD 96000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 18000000 -#define STM32_1WS_THRESHOLD 36000000 -#define STM32_2WS_THRESHOLD 54000000 -#define STM32_3WS_THRESHOLD 72000000 -#define STM32_4WS_THRESHOLD 90000000 -#define STM32_5WS_THRESHOLD 100000000 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 170) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 16000000 -#define STM32_1WS_THRESHOLD 32000000 -#define STM32_2WS_THRESHOLD 48000000 -#define STM32_3WS_THRESHOLD 64000000 -#define STM32_4WS_THRESHOLD 80000000 -#define STM32_5WS_THRESHOLD 96000000 -#define STM32_6WS_THRESHOLD 100000000 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 0 -#else -#error "invalid VDD voltage specified" -#endif - -#elif defined(STM32F410xx) || defined(STM32F411xx) -#if (STM32_VDD >= 270) && (STM32_VDD <= 360) -#define STM32_0WS_THRESHOLD 30000000 -#define STM32_1WS_THRESHOLD 64000000 -#define STM32_2WS_THRESHOLD 90000000 -#define STM32_3WS_THRESHOLD 100000000 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 2 -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 72000000 -#define STM32_3WS_THRESHOLD 96000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 18000000 -#define STM32_1WS_THRESHOLD 36000000 -#define STM32_2WS_THRESHOLD 54000000 -#define STM32_3WS_THRESHOLD 72000000 -#define STM32_4WS_THRESHOLD 90000000 -#define STM32_5WS_THRESHOLD 100000000 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 171) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 16000000 -#define STM32_1WS_THRESHOLD 32000000 -#define STM32_2WS_THRESHOLD 48000000 -#define STM32_3WS_THRESHOLD 64000000 -#define STM32_4WS_THRESHOLD 80000000 -#define STM32_5WS_THRESHOLD 96000000 -#define STM32_6WS_THRESHOLD 100000000 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 0 - -#else -#error "invalid VDD voltage specified" -#endif - -#elif defined(STM32F401xx) -#if (STM32_VDD >= 270) && (STM32_VDD <= 360) -#define STM32_0WS_THRESHOLD 30000000 -#define STM32_1WS_THRESHOLD 60000000 -#define STM32_2WS_THRESHOLD 84000000 -#define STM32_3WS_THRESHOLD 0 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 2 - -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 72000000 -#define STM32_3WS_THRESHOLD 84000000 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 - -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 18000000 -#define STM32_1WS_THRESHOLD 36000000 -#define STM32_2WS_THRESHOLD 54000000 -#define STM32_3WS_THRESHOLD 72000000 -#define STM32_4WS_THRESHOLD 84000000 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 - -#elif (STM32_VDD >= 180) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 16000000 -#define STM32_1WS_THRESHOLD 32000000 -#define STM32_2WS_THRESHOLD 48000000 -#define STM32_3WS_THRESHOLD 64000000 -#define STM32_4WS_THRESHOLD 80000000 -#define STM32_5WS_THRESHOLD 84000000 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 0 - -#else -#error "invalid VDD voltage specified" -#endif - -#else /* STM32F2XX */ -#if (STM32_VDD >= 270) && (STM32_VDD <= 360) -#define STM32_0WS_THRESHOLD 30000000 -#define STM32_1WS_THRESHOLD 60000000 -#define STM32_2WS_THRESHOLD 90000000 -#define STM32_3WS_THRESHOLD 120000000 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 2 -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 72000000 -#define STM32_3WS_THRESHOLD 96000000 -#define STM32_4WS_THRESHOLD 120000000 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 18000000 -#define STM32_1WS_THRESHOLD 36000000 -#define STM32_2WS_THRESHOLD 54000000 -#define STM32_3WS_THRESHOLD 72000000 -#define STM32_4WS_THRESHOLD 90000000 -#define STM32_5WS_THRESHOLD 108000000 -#define STM32_6WS_THRESHOLD 120000000 -#define STM32_7WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 180) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 16000000 -#define STM32_1WS_THRESHOLD 32000000 -#define STM32_2WS_THRESHOLD 48000000 -#define STM32_3WS_THRESHOLD 64000000 -#define STM32_4WS_THRESHOLD 80000000 -#define STM32_5WS_THRESHOLD 96000000 -#define STM32_6WS_THRESHOLD 112000000 -#define STM32_7WS_THRESHOLD 120000000 -#define STM32_FLASH_PSIZE 0 - -#else -#error "invalid VDD voltage specified" -#endif -#endif /* STM32F2XX */ -/** @} */ - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ - ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCO1SEL" -#endif - -#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_MCO2SEL" -#endif - -#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_I2SSRC" -#endif - -#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_I2SSRC" -#endif - -#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SAI1SEL" -#endif - -#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SAI2SEL" -#endif -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#else /* STM32_HSECLK != 0 */ -#if defined(STM32_HSE_BYPASS) -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" -#endif -#else /* !defined(STM32_HSE_BYPASS) */ -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif -#endif /* !defined(STM32_HSE_BYPASS) */ -#endif /* STM32_HSECLK != 0 */ -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ - ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCO1SEL" -#endif - -#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ - ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCO2SEL" -#endif - -#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_I2SSRC" -#endif - -#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_PLLI2SSRC" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/** - * @brief Clock frequency feeding PLLs. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSRCCLK STM32_HSECLK -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLSRCCLK STM32_HSICLK -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM (STM32_PLLM_VALUE << 0) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#define STM32_PLLCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) - -/* - * PLLs input frequency range check. - */ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_CLOCK48_REQUIRED && \ - STM32_HAS_RCC_CK48MSEL && \ - (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ - (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 64) && (STM32_PLLN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 6) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLP STM32_PLLP_DIV2 -#elif STM32_PLLP_VALUE == 4 -#define STM32_PLLP STM32_PLLP_DIV4 -#elif STM32_PLLP_VALUE == 6 -#define STM32_PLLP STM32_PLLP_DIV6 -#elif STM32_PLLP_VALUE == 8 -#define STM32_PLLP STM32_PLLP_DIV8 -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -#if defined(STM32F4XX) || defined(__DOXYGEN__) -/** - * @brief STM32_PLLR field. - */ -#if ((STM32_PLLR_VALUE >= 2) && (STM32_PLLR_VALUE <= 7)) || \ - defined(__DOXYGEN__) -#define STM32_PLLR (STM32_PLLR_VALUE << 28) -#else -#error "invalid STM32_PLLR_VALUE value specified" -#endif -#else /* !defined(STM32F4XX) */ -#define STM32_PLLR 0 -#endif /* !defined(STM32F4XX) */ - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) - -/* - * PLL output frequency range check. - */ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/* Calculating VOS settings, it is different for each sub-platform.*/ -#if defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ - defined(STM32F446xx) || defined(STM32F469_479xx) || \ - defined(__DOXYGEN__) -#if STM32_SYSCLK <= 120000000 -#define STM32_VOS STM32_VOS_SCALE3 -#define STM32_OVERDRIVE_REQUIRED FALSE -#elif STM32_SYSCLK <= 144000000 -#define STM32_VOS STM32_VOS_SCALE2 -#define STM32_OVERDRIVE_REQUIRED FALSE -#elif STM32_SYSCLK <= 168000000 -#define STM32_VOS STM32_VOS_SCALE1 -#define STM32_OVERDRIVE_REQUIRED FALSE -#else -#define STM32_VOS STM32_VOS_SCALE1 -#define STM32_OVERDRIVE_REQUIRED TRUE -#endif - -#elif defined(STM32F40_41xxx) -#if STM32_SYSCLK <= 144000000 -#define STM32_VOS STM32_VOS_SCALE2 -#else -#define STM32_VOS STM32_VOS_SCALE1 -#endif -#define STM32_OVERDRIVE_REQUIRED FALSE - -#elif defined(STM32F401xx) -#if STM32_SYSCLK <= 60000000 -#define STM32_VOS STM32_VOS_SCALE3 -#else -#define STM32_VOS STM32_VOS_SCALE2 -#endif -#define STM32_OVERDRIVE_REQUIRED FALSE - -#elif defined(STM32F410xx) || defined(STM32F411xx) || \ - defined(STM32F412xx) -#if STM32_SYSCLK <= 64000000 -#define STM32_VOS STM32_VOS_SCALE3 -#elif STM32_SYSCLK <= 84000000 -#define STM32_VOS STM32_VOS_SCALE2 -#else -#define STM32_VOS STM32_VOS_SCALE1 -#endif -#define STM32_OVERDRIVE_REQUIRED FALSE - -#else /* STM32F2XX */ -#define STM32_OVERDRIVE_REQUIRED FALSE -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/* - * PLLI2S enable check. - */ -#if (STM32_HAS_RCC_PLLI2S && \ - (STM32_CLOCK48_REQUIRED && \ - (STM32_HAS_RCC_CK48MSEL && \ - STM32_RCC_CK48MSEL_USES_I2S && \ - (STM32_CK48MSEL == STM32_CK48MSEL_PLLALT)) || \ - (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S))) || \ - defined(__DOXYGEN__) - -/** - * @brief PLLI2S activation flag. - */ -#define STM32_ACTIVATE_PLLI2S TRUE -#else -#define STM32_ACTIVATE_PLLI2S FALSE -#endif - -/** - * @brief STM32_PLLI2SM field. - */ -#if ((STM32_PLLI2SM_VALUE >= 2) && (STM32_PLLI2SM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SM (STM32_PLLI2SM_VALUE << 0) -#else -#error "invalid STM32_PLLI2SM_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SN field. - */ -#if ((STM32_PLLI2SN_VALUE >= 50) && (STM32_PLLI2SN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) -#else -#error "invalid STM32_PLLI2SN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SP field. - */ -#if (STM32_PLLI2SP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLI2SP STM32_PLLI2SP_DIV2 -#elif STM32_PLLI2SP_VALUE == 4 -#define STM32_PLLI2SP STM32_PLLI2SP_DIV4 -#elif STM32_PLLI2SP_VALUE == 6 -#define STM32_PLLI2SP STM32_PLLI2SP_DIV6 -#elif STM32_PLLI2SP_VALUE == 8 -#define STM32_PLLI2SP STM32_PLLI2SP_DIV8 -#else -#error "invalid STM32_PLLI2SP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SQ field. - */ -#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) -#else -#error "invalid STM32_PLLI2SQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SDIVQ field. - */ -#if ((STM32_PLLI2SDIVQ_VALUE >= 1) && (STM32_PLLI2SDIVQ_VALUE <= 32)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SDIVQ ((STM32_PLLI2SQ_VALUE - 1) << 0) -#else -#error "invalid STM32_PLLI2SDIVQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SR field. - */ -#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) -#else -#error "invalid STM32_PLLI2SR_VALUE value specified" -#endif - -/** - * @brief PLLI2S input clock frequency. - */ -#if STM32_HAS_RCC_I2SPLLSRC || defined(__DOXYGEN__) -#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLI2SM_VALUE) -#elif STM32_PLLI2SSRC == STM32_PLLI2SSRC_CKIN -#define STM32_PLLI2SCLKIN (STM32_I2SCKIN_VALUE / STM32_PLLI2SM_VALUE) -#else -#error "invalid STM32_PLLI2SSRC value specified" -#endif -#else -#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) -#endif - -/** - * @brief PLLI2S VCO frequency. - */ -#define STM32_PLLI2SVCO (STM32_PLLI2SCLKIN * STM32_PLLI2SN_VALUE) - -/* - * PLLI2S VCO frequency range check. - */ -#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLI2S P output clock frequency. - */ -#define STM32_PLLI2S_P_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SP_VALUE) - -/** - * @brief PLLI2S Q output clock frequency. - */ -#define STM32_PLLI2S_Q_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SQ_VALUE) - -/** - * @brief PLLI2S R output clock frequency. - */ -#define STM32_PLLI2S_R_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE) - -/* - * PLLSAI enable check. - */ -#if (STM32_HAS_RCC_PLLSAI && \ - (STM32_CLOCK48_REQUIRED && \ - (STM32_HAS_RCC_CK48MSEL && \ - !STM32_RCC_CK48MSEL_USES_I2S && \ - (STM32_CK48MSEL == STM32_CK48MSEL_PLLALT)) || \ - (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI))) || \ - (STM32_PLLSAIDIVR != STM32_PLLSAIDIVR_OFF) || \ - defined(__DOXYGEN__) -/** - * @brief PLLSAI activation flag. - */ -#define STM32_ACTIVATE_PLLSAI TRUE -#else -#define STM32_ACTIVATE_PLLSAI FALSE -#endif - -/** - * @brief STM32_PLLSAIM field. - */ -#if ((STM32_PLLSAIM_VALUE >= 2) && (STM32_PLLSAIM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIM (STM32_PLLSAIM_VALUE << 0) -#else -#error "invalid STM32_PLLSAIM_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIN field. - */ -#if ((STM32_PLLSAIN_VALUE >= 49) && (STM32_PLLSAIN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIN (STM32_PLLSAIN_VALUE << 6) -#else -#error "invalid STM32_PLLSAIN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIQ field. - */ -#if ((STM32_PLLSAIQ_VALUE >= 2) && (STM32_PLLSAIQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIQ (STM32_PLLSAIQ_VALUE << 24) -#else -#error "invalid STM32_PLLSAIQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIDIVQ_VALUE field. - */ -#if ((STM32_PLLSAIDIVQ_VALUE >= 1) && (STM32_PLLSAIDIVQ_VALUE <= 32)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIDIVQ ((STM32_PLLSAIDIVQ_VALUE - 1) << 8) -#else -#error "invalid STM32_PLLSAIDIVQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIR field. - */ -#if ((STM32_PLLSAIR_VALUE >= 2) && (STM32_PLLSAIR_VALUE <= 7)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIR (STM32_PLLSAIR_VALUE << 28) -#else -#error "invalid STM32_PLLSAIR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIP field. - */ - -#if (STM32_PLLSAIP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAIP STM32_PLLSAIP_DIV2 - -#elif STM32_PLLSAIP_VALUE == 4 -#define STM32_PLLSAIP STM32_PLLSAIP_DIV4 - -#elif STM32_PLLSAIP_VALUE == 6 -#define STM32_PLLSAIP STM32_PLLSAIP_DIV6 - -#elif STM32_PLLSAIP_VALUE == 8 -#define STM32_PLLSAIP STM32_PLLSAIP_DIV8 - -#else -#error "invalid STM32_PLLSAIP_VALUE value specified" -#endif - -/** - * @brief PLLSAI input clock frequency. - */ -#if defined(STM32F446xx) -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSAICLKIN (STM32_HSECLK / STM32_PLLSAIM_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLSAICLKIN (STM32_HSICLK / STM32_PLLSAIM_VALUE) -#else -#error "invalid STM32_PLLSRC value specified" -#endif -#else /* !defined(STM32F446xx) */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSAICLKIN (STM32_HSECLK / STM32_PLLM_VALUE) -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLSAICLKIN (STM32_HSICLK / STM32_PLLM_VALUE) -#else -#error "invalid STM32_PLLSRC value specified" -#endif -#endif /* defined(STM32F446xx) */ - -/** - * @brief PLLSAI VCO frequency. - */ -#define STM32_PLLSAIVCO (STM32_PLLSAICLKIN * STM32_PLLSAIN_VALUE) - -/* - * PLLSAI VCO frequency range check. - */ -#if (STM32_PLLSAIVCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLSAIVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI P output clock frequency. - */ -#define STM32_PLLSAI_P_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIP_VALUE) - -/** - * @brief PLLSAI Q output clock frequency. - */ -#define STM32_PLLSAI_Q_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIQ_VALUE) - -/** - * @brief PLLSAI R output clock frequency. - */ -#define STM32_PLLSAI_R_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIR_VALUE) - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_TYPE1_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld_type1.h + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * - STM32_VDD (as hundredths of Volt). + * . + * One of the following macros must also be defined: + * - STM32F2XX for High-performance STM32F2 devices. + * - STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, + * STM32F446xx for High-performance STM32F4 devices of + * Foundation line. + * - STM32F401xx, STM32F410xx, STM32F411xx, STM32F412xx + * for High-performance STM32F4 devices of Access line. + * - STM32F427xx, STM32F437xx, STM32F429xx, STM32F439xx, STM32F469xx, + * STM32F479xx for High-performance STM32F4 devices of Advanced line. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_TYPE1_H +#define HAL_LLD_TYPE1_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Defines the support for realtime counters in the HAL. + */ +#define HAL_IMPLEMENTS_COUNTERS TRUE + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32F205xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32F205 High Performance" + +#elif defined(STM32F207xx) +#define PLATFORM_NAME "STM32F207 High Performance" + +#elif defined(STM32F215xx) +#define PLATFORM_NAME "STM32F215 High Performance" + +#elif defined(STM32F217xx) +#define PLATFORM_NAME "STM32F217 High Performance" + +#elif defined(STM32F401xx) +#define PLATFORM_NAME "STM32F401 High Performance with DSP and FPU" + +#elif defined(STM32F405xx) +#define PLATFORM_NAME "STM32F405 High Performance with DSP and FPU" + +#elif defined(STM32F407xx) +#define PLATFORM_NAME "STM32F407 High Performance with DSP and FPU" + +#elif defined(STM32F410xx) +#define PLATFORM_NAME "STM32F410 High Performance with DSP and FPU" + +#elif defined(STM32F411xx) +#define PLATFORM_NAME "STM32F411 High Performance with DSP and FPU" + +#elif defined(STM32F412xx) +#define PLATFORM_NAME "STM32F412 High Performance with DSP and FPU" + +#elif defined(STM32F415xx) +#define PLATFORM_NAME "STM32F415 High Performance with DSP and FPU" + +#elif defined(STM32F417xx) +#define PLATFORM_NAME "STM32F417 High Performance with DSP and FPU" + +#elif defined(STM32F427xx) +#define PLATFORM_NAME "STM32F427 High Performance with DSP and FPU" + +#elif defined(STM32F429xx) +#define PLATFORM_NAME "STM32F429 High Performance with DSP and FPU" + +#elif defined(STM32F437xx) +#define PLATFORM_NAME "STM32F437 High Performance with DSP and FPU" + +#elif defined(STM32F439xx) +#define PLATFORM_NAME "STM32F439 High Performance with DSP and FPU" + +#elif defined(STM32F446xx) +#define PLATFORM_NAME "STM32F446 High Performance with DSP and FPU" + +#elif defined(STM32F469xx) +#define PLATFORM_NAME "STM32F469 High Performance with DSP and FPU" + +#elif defined(STM32F479xx) +#define PLATFORM_NAME "STM32F479 High Performance with DSP and FPU" + +#else +#error "STM32F2xx/F4xx device not specified" +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || \ + defined(STM32F429xx) || defined(STM32F439xx) || \ + defined(STM32F469xx) || defined(STM32F479xx) || defined(__DOXYGEN__) +/** + * @brief Absolute maximum system clock. + */ +#define STM32_SYSCLK_MAX 180000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 26000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 50000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency using an external source. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 2100000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 950000 + +/** + * @brief Maximum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MAX 432000000 + +/** + * @brief Minimum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MIN 192000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 180000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 24000000 + +/** + * @brief Maximum PLLI2S output clock frequency. + */ +#define STM32_PLLI2SOUT_MAX 216000000 + +/** + * @brief Maximum PLLSAI output clock frequency. + */ +#define STM32_PLLSAIOUT_MAX 216000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) + +/** + * @brief Maximum SPI/I2S clock frequency. + */ +#define STM32_SPII2S_MAX 45000000 +#endif + +#if defined(STM32F40_41xxx) +#define STM32_SYSCLK_MAX 168000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 50000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 1000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_PLLIN_MAX 2100000 +#define STM32_PLLIN_MIN 950000 +#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MIN 192000000 +#define STM32_PLLOUT_MAX 168000000 +#define STM32_PLLOUT_MIN 24000000 +#define STM32_PCLK1_MAX 42000000 +#define STM32_PCLK2_MAX 84000000 +#define STM32_SPII2S_MAX 42000000 +#endif + +#if defined(STM32F401xx) +#define STM32_SYSCLK_MAX 84000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 50000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 1000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_PLLIN_MAX 2100000 +#define STM32_PLLIN_MIN 950000 +#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MIN 192000000 +#define STM32_PLLOUT_MAX 84000000 +#define STM32_PLLOUT_MIN 24000000 +#define STM32_PCLK1_MAX 42000000 +#define STM32_PCLK2_MAX 84000000 +#define STM32_SPII2S_MAX 42000000 +#endif + +#if defined(STM32F410xx) || defined(STM32F411xx) || \ + defined(STM32F412xx) +#define STM32_SYSCLK_MAX 100000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 50000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 1000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_PLLIN_MAX 2100000 +#define STM32_PLLIN_MIN 950000 +#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MIN 100000000 +#define STM32_PLLOUT_MAX 100000000 +#define STM32_PLLOUT_MIN 24000000 +#define STM32_PCLK1_MAX 50000000 +#define STM32_PCLK2_MAX 100000000 +#define STM32_SPII2S_MAX 50000000 +#endif + +#if defined(STM32F446xx) +#define STM32_SYSCLK_MAX 180000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 50000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 1000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_PLLIN_MAX 2100000 +#define STM32_PLLIN_MIN 950000 +#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MIN 100000000 +#define STM32_PLLOUT_MAX 180000000 +#define STM32_PLLOUT_MIN 12500000 +#define STM32_PLLI2SOUT_MAX 216000000 +#define STM32_PLLSAIOUT_MAX 216000000 +#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) +#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) +#define STM32_SPII2S_MAX 45000000 +#endif + +#if defined(STM32F2XX) +#define STM32_SYSCLK_MAX 120000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 26000000 +#define STM32_HSECLK_MIN 1000000 +#define STM32_HSECLK_BYP_MIN 1000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_PLLIN_MAX 2000000 +#define STM32_PLLIN_MIN 950000 +#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MIN 192000000 +#define STM32_PLLOUT_MAX 120000000 +#define STM32_PLLOUT_MIN 24000000 +#define STM32_PCLK1_MAX 30000000 +#define STM32_PCLK2_MAX 60000000 +#define STM32_SPII2S_MAX 30000000 +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 16000000 /**< High speed internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_VOS_SCALE3 0x00004000 +#define STM32_VOS_SCALE2 0x00008000 +#define STM32_VOS_SCALE1 0x0000C000 +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ +#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ +#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ +#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ +#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW mask. */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ +#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ +#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ + +#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ + +#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ +#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ +#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ + +#define STM32_I2SSRC_MASK (1 << 23) /**< I2CSRC mask. */ +#define STM32_I2SSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */ +#define STM32_I2SSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */ + +#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ +#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ +#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ +#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ +#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ +#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ + +#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ +#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ +#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ +#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ +#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ +#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ + +#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ +#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ +#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ + +/** + * @name RCC_PLLI2SCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SM_MASK (31 << 0) /**< PLLI2SM mask. */ +#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ +#define STM32_PLLI2SP_MASK (3 << 16) /**< PLLI2SP mask. */ +#define STM32_PLLI2SP_DIV2 (0 << 16) /**< PLLI2S clock divided by 2. */ +#define STM32_PLLI2SP_DIV4 (1 << 16) /**< PLLI2S clock divided by 4. */ +#define STM32_PLLI2SP_DIV6 (2 << 16) /**< PLLI2S clock divided by 6. */ +#define STM32_PLLI2SP_DIV8 (3 << 16) /**< PLLI2S clock divided by 8. */ +#define STM32_PLLI2SSRC_MASK (1 << 22) /**< PLLI2SSRC mask. */ +#define STM32_PLLI2SSRC_PLLSRC (0 << 22) /**< PLLI2SSRC is selected PLL + source. */ +#define STM32_PLLI2SSRC_CKIN (1 << 22) /**< PLLI2SSRC is I2S_CKIN. */ +#define STM32_PLLI2SQ_MASK (15 << 24) /**< PLLI2SQ mask. */ +#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ +/** @} */ + +/** + * @name RCC_PLLSAICFGR register bits definitions + * @{ + */ +#define STM32_PLLSAIM_MASK (31 << 0) /**< PLLSAIM mask. */ +#define STM32_PLLSAIN_MASK (511 << 6) /**< PLLSAIN mask. */ +#define STM32_PLLSAIP_MASK (3 << 16) /**< PLLSAIP mask. */ +#define STM32_PLLSAIP_DIV2 (0 << 16) /**< PLLSAI clock divided by 2. */ +#define STM32_PLLSAIP_DIV4 (1 << 16) /**< PLLSAI clock divided by 4. */ +#define STM32_PLLSAIP_DIV6 (2 << 16) /**< PLLSAI clock divided by 6. */ +#define STM32_PLLSAIP_DIV8 (3 << 16) /**< PLLSAI clock divided by 8. */ +#define STM32_PLLSAIQ_MASK (15 << 24) /**< PLLSAIQ mask. */ +#define STM32_PLLSAIR_MASK (7 << 28) /**< PLLSAIR mask. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ +/** @} */ + +/** + * @name RCC_DCKCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SDIVQ_MASK (31 << 0) /**< PLLI2SDIVQ mask. */ +#define STM32_PLLSAIDIVQ_MASK (31 << 8) /**< PLLSAIDIVQ mask. */ + +#define STM32_PLLSAIDIVR_MASK (3 << 16) /**< PLLSAIDIVR mask. */ +#define STM32_PLLSAIDIVR_DIV2 (0 << 16) /**< LCD_CLK is R divided by 2. */ +#define STM32_PLLSAIDIVR_DIV4 (1 << 16) /**< LCD_CLK is R divided by 4. */ +#define STM32_PLLSAIDIVR_DIV8 (2 << 16) /**< LCD_CLK is R divided by 8. */ +#define STM32_PLLSAIDIVR_DIV16 (3 << 16) /**< LCD_CLK is R divided by 16.*/ +#define STM32_PLLSAIDIVR_OFF 0xFFFFFFFFU /**< LCD CLK is not required. */ + +#define STM32_SAI1SEL_MASK (3 << 20) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_PLLSAI (0 << 20) /**< SAI1 source is PLLSAI. */ +#define STM32_SAI1SEL_PLLI2S (1 << 20) /**< SAI1 source is PLLI2S. */ +#define STM32_SAI1SEL_PLLR (2 << 20) /**< SAI1 source is PLLR. */ +#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ + +#define STM32_SAI2SEL_MASK (3 << 22) /**< SAI2SEL mask. */ +#define STM32_SAI2SEL_PLLSAI (0 << 22) /**< SAI2 source is PLLSAI. */ +#define STM32_SAI2SEL_PLLI2S (1 << 22) /**< SAI2 source is PLLI2S. */ +#define STM32_SAI2SEL_PLLR (2 << 22) /**< SAI2 source is PLLR. */ +#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ + +#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ +#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ +#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ + +#define STM32_I2S1SEL_MASK (3 << 25) /**< I2S1SEL mask. */ +#define STM32_I2S1SEL_PLLR (0 << 25) /**< I2S1 source is PLLR. */ +#define STM32_I2S1SEL_AFIN (1 << 25) /**< I2S1 source is AF Input. */ +#define STM32_I2S1SEL_MCO1 (2 << 25) /**< I2S1 source is MCO1. */ +#define STM32_I2S1SEL_OFF 0xFFFFFFFFU /**< I2S1 clock is not required.*/ + +#define STM32_I2S2SEL_MASK (3 << 27) /**< I2S2SEL mask. */ +#define STM32_I2S2SEL_PLLR (0 << 27) /**< I2S2 source is PLLR. */ +#define STM32_I2S2SEL_AFIN (1 << 27) /**< I2S2 source is AF Input. */ +#define STM32_I2S2SEL_MCO1 (2 << 27) /**< I2S2 source is MCO1. */ +#define STM32_I2S2SEL_OFF 0xFFFFFFFFU /**< I2S2 clock is not required.*/ + +#define STM32_DSISEL_MASK (1 << 28) /**< DSISEL mask. */ +#define STM32_DSISEL_PHY (0 << 28) /**< DSI source is DSI-PSY. */ +#define STM32_DSISEL_PLLR (1 << 28) /**< DSI source is PLLR. */ +/** @} */ + +/** + * @name RCC_DCKCFGR2 register bits definitions + * @{ + */ +#define STM32_I2C1SEL_MASK (3 << 22) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK1 (0 << 22) /**< I2C1 source is APB/PCLK1. */ +#define STM32_I2C1SEL_SYSCLK (1 << 22) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI (2 << 22) /**< I2C1 source is HSI. */ + +#define STM32_CECSEL_MASK (1 << 26) /**< CECSEL mask. */ +#define STM32_CECSEL_LSE (0 << 26) /**< CEC source is LSE. */ +#define STM32_CECSEL_HSIDIV488 (1 << 26) /**< CEC source is HSI/488. */ + +#define STM32_CK48MSEL_MASK (1 << 27) /**< CK48MSEL mask. */ +#define STM32_CK48MSEL_PLL (0 << 27) /**< PLL48CLK source is PLL. */ +#define STM32_CK48MSEL_PLLSAI (1 << 27) /**< PLL48CLK source is PLLSAI. */ +#define STM32_CK48MSEL_PLLALT (1 << 27) /**< Alias. */ + +#define STM32_SDMMCSEL_MASK (1 << 28) /**< SDMMCSEL mask. */ +#define STM32_SDMMCSEL_PLL48CLK (0 << 28) /**< SDMMC source is PLL48CLK. */ +#define STM32_SDMMCSEL_SYSCLK (1 << 28) /**< SDMMC source is SYSCLK. */ + +#define STM32_SPDIFSEL_MASK (1 << 29) /**< SPDIFSEL mask. */ +#define STM32_SPDIFSEL_PLLI2S (0 << 29) /**< SPDIF source is PLLI2S. */ +#define STM32_SPDIFSEL_PLL (1 << 29) /**< SPDIF source is PLL. */ + +#define STM32_LPTIM1SEL_MASK (3 << 30) /**< LPTIM1 mask. */ +#define STM32_LPTIM1SEL_APB (0 << 30) /**< LPTIM1 source is APB. */ +#define STM32_LPTIM1SEL_HSI (1 << 30) /**< LPTIM1 source is HSI. */ +#define STM32_LPTIM1SEL_LSI (2 << 30) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_LSE (3 << 30) /**< LPTIM1 source is LSE. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables the backup RAM regulator. + */ +#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) +#define STM32_BKPRAM_ENABLE FALSE +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief USB/SDIO clock setting. + */ +#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) +#define STM32_CLOCK48_REQUIRED TRUE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +#if defined(STM32F4XX) || defined(__DOXYGEN__) +/** + * @brief Clock source for the PLLs. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 8 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 192..432. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 336 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 2 +#endif + +/** + * @brief PLLQ multiplier value. + * @note The allowed values are 2..15. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 7 +#endif + +/** + * @brief PLLR divider value. + * @note The allowed values are 2..7. + * @note The default value is calculated for a 96MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLR_VALUE 4 +#endif + +#else /* !defined(STM32F4XX) */ +/** + * @brief Clock source for the PLLs. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 8 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 192..432. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 240 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 2 +#endif + +/** + * @brief PLLQ multiplier value. + * @note The allowed values are 2..15. + * @note The default value is calculated for a 120MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 5 +#endif +#endif /* !defined(STM32F4XX) */ + +/** + * @brief I2S clock source (post-PLL). + * @note Not all devices have this setting, it is alternative to + * @p STM32_PLLI2SSRC. + */ +#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) +#define STM32_I2SSRC STM32_I2SSRC_CKIN +#endif + +/** + * @brief I2S clock source (pre-PLL). + * @note Not all devices have this setting, it is alternative to + * @p STM32_I2SSRC. + */ +#if !defined(STM32_PLLI2SSRC) || defined(__DOXYGEN__) +#define STM32_PLLI2SSRC STM32_PLLI2SSRC_CKIN +#endif + +/** + * @brief I2S external clock value, zero if not present. + * @note Not all devices have this setting. + */ +#if !defined(STM32_I2SCKIN_VALUE) || defined(__DOXYGEN__) +#define STM32_I2SCKIN_VALUE 0 +#endif + +/** + * @brief PLLI2SN multiplier value. + * @note The allowed values are 192..432, except for + * STM32F446 where values are 50...432. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SN_VALUE 192 +#endif + +/** + * @brief PLLI2SM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SM_VALUE 4 +#endif + +/** + * @brief PLLI2SR divider value. + * @note The allowed values are 2..7. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SR_VALUE 4 +#endif + +/** + * @brief PLLI2SP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SP_VALUE 4 +#endif + +/** + * @brief PLLI2SQ divider value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SQ_VALUE 4 +#endif + +/** + * @brief PLLI2SDIVQ divider value (SAI clock divider). + * @note The allowed values are 1..32. + */ +#if !defined(STM32_PLLI2SDIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SDIVQ_VALUE 1 +#endif + +/** + * @brief PLLSAIM value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIM_VALUE 4 +#endif + +/** + * @brief PLLSAIN value. + * @note The allowed values are 50..432. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIN_VALUE 192 +#endif + +/** + * @brief PLLSAIM value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIM_VALUE 4 +#endif + +/** + * @brief PLLSAIR value. + * @note The allowed values are 2..7. + */ +#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIR_VALUE 4 +#endif + +/** + * @brief PLLSAIP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLSAIP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIP_VALUE 8 +#endif + +/** + * @brief PLLSAIQ value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIQ_VALUE 4 +#endif + +/** + * @brief PLLSAIDIVR divider value (SAI clock divider). + */ +#if !defined(STM32_PLLSAIDIVR) || defined(__DOXYGEN__) +#define STM32_PLLSAIDIVR STM32_PLLSAIDIVR_OFF +#endif + +/** + * @brief PLLSAIDIVQ divider value (LCD clock divider). + * @note The allowed values are 1..32. + */ +#if !defined(STM32_PLLSAIDIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIDIVQ_VALUE 1 +#endif + +/** + * @brief SAI1SEL value (SAI1 clock source). + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#endif + +/** + * @brief SAI2SEL value (SAI2 clock source). + */ +#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#endif + +/** + * @brief TIM prescaler clock source. + */ +#if !defined(STM32_TIMPRE) || defined(__DOXYGEN__) +#define STM32_TIMPRE STM32_TIMPRE_PCLK +#endif + +/** + * @brief PLL48CLK clock source. + */ +#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) +#define STM32_CK48MSEL STM32_CK48MSEL_PLL +#endif + +/** + * @brief AHB prescaler value. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV4 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief RTC HSE prescaler value. + */ +#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#define STM32_RTCPRE_VALUE 8 +#endif + +/** + * @brief MCO1 clock source value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#endif + +/** + * @brief MCO1 prescaler value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#endif + +/** + * @brief MCO2 clock source value. + * @note The default value outputs SYSCLK / 5 on MCO2 pin. + */ +#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#endif + +/** + * @brief MCO2 prescaler value. + * @note The default value outputs SYSCLK / 5 on MCO2 pin. + */ +#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if defined(STM32F4XX) || defined(__DOXYGEN__) +/* + * Configuration-related checks. + */ +#if !defined(STM32F4xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F4xx_MCUCONF not defined" +#endif + +#if defined(STM32F405xx) && !defined(STM32F405_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F405_MCUCONF not defined" +#endif + +#if defined(STM32F415xx) && !defined(STM32F415_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F415_MCUCONF not defined" +#endif + +#if defined(STM32F407xx) && !defined(STM32F407_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F407_MCUCONF not defined" +#endif + +#if defined(STM32F417xx) && !defined(STM32F417_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F417_MCUCONF not defined" +#endif + +#else /* !defined(STM32F4XX) */ +/* + * Configuration-related checks. + */ +#if !defined(STM32F2xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F2xx_MCUCONF not defined" +#endif +#endif /* !defined(STM32F4XX) */ + +/** + * @name Maximum frequency thresholds, wait states and + * parallelism for flash access. + * @{ + */ +#if defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(STM32F40_41xxx) || defined(STM32F446xx) || \ + defined(STM32F469_479xx) || defined(__DOXYGEN__) +#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 120000000 +#define STM32_4WS_THRESHOLD 150000000 +#define STM32_5WS_THRESHOLD 180000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 120000000 +#define STM32_5WS_THRESHOLD 144000000 +#define STM32_6WS_THRESHOLD 168000000 +#define STM32_7WS_THRESHOLD 180000000 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 22000000 +#define STM32_1WS_THRESHOLD 44000000 +#define STM32_2WS_THRESHOLD 66000000 +#define STM32_3WS_THRESHOLD 88000000 +#define STM32_4WS_THRESHOLD 110000000 +#define STM32_5WS_THRESHOLD 132000000 +#define STM32_6WS_THRESHOLD 154000000 +#define STM32_7WS_THRESHOLD 176000000 +#define STM32_8WS_THRESHOLD 180000000 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 120000000 +#define STM32_6WS_THRESHOLD 140000000 +#define STM32_7WS_THRESHOLD 168000000 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 +#else +#error "invalid VDD voltage specified" +#endif + +#elif defined(STM32F412xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 64000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 100000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 100000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 170) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 100000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 +#else +#error "invalid VDD voltage specified" +#endif + +#elif defined(STM32F410xx) || defined(STM32F411xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 64000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 100000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 100000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 171) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 100000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 + +#else +#error "invalid VDD voltage specified" +#endif + +#elif defined(STM32F401xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 84000000 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 + +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 84000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 + +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 84000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 + +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 84000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 + +#else +#error "invalid VDD voltage specified" +#endif + +#else /* STM32F2XX */ +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 120000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 120000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 108000000 +#define STM32_6WS_THRESHOLD 120000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 112000000 +#define STM32_7WS_THRESHOLD 120000000 +#define STM32_FLASH_PSIZE 0 + +#else +#error "invalid VDD voltage specified" +#endif +#endif /* STM32F2XX */ +/** @} */ + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2SSRC" +#endif + +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2SSRC" +#endif + +#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SAI1SEL" +#endif + +#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SAI2SEL" +#endif +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#else /* STM32_HSECLK != 0 */ +#if defined(STM32_HSE_BYPASS) +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" +#endif +#else /* !defined(STM32_HSE_BYPASS) */ +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif +#endif /* !defined(STM32_HSE_BYPASS) */ +#endif /* STM32_HSECLK != 0 */ +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ + ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_I2SSRC" +#endif + +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_PLLI2SSRC" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief Clock frequency feeding PLLs. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSRCCLK STM32_HSECLK +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLSRCCLK STM32_HSICLK +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM (STM32_PLLM_VALUE << 0) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#define STM32_PLLCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) + +/* + * PLLs input frequency range check. + */ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_CLOCK48_REQUIRED && \ + STM32_HAS_RCC_CK48MSEL && \ + (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ + (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 64) && (STM32_PLLN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 6) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLP STM32_PLLP_DIV2 +#elif STM32_PLLP_VALUE == 4 +#define STM32_PLLP STM32_PLLP_DIV4 +#elif STM32_PLLP_VALUE == 6 +#define STM32_PLLP STM32_PLLP_DIV6 +#elif STM32_PLLP_VALUE == 8 +#define STM32_PLLP STM32_PLLP_DIV8 +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +#if defined(STM32F4XX) || defined(__DOXYGEN__) +/** + * @brief STM32_PLLR field. + */ +#if ((STM32_PLLR_VALUE >= 2) && (STM32_PLLR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLR (STM32_PLLR_VALUE << 28) +#else +#error "invalid STM32_PLLR_VALUE value specified" +#endif +#else /* !defined(STM32F4XX) */ +#define STM32_PLLR 0 +#endif /* !defined(STM32F4XX) */ + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) + +/* + * PLL output frequency range check. + */ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/* Calculating VOS settings, it is different for each sub-platform.*/ +#if defined(STM32F429_439xx) || defined(STM32F427_437xx) || \ + defined(STM32F446xx) || defined(STM32F469_479xx) || \ + defined(__DOXYGEN__) +#if STM32_SYSCLK <= 120000000 +#define STM32_VOS STM32_VOS_SCALE3 +#define STM32_OVERDRIVE_REQUIRED FALSE +#elif STM32_SYSCLK <= 144000000 +#define STM32_VOS STM32_VOS_SCALE2 +#define STM32_OVERDRIVE_REQUIRED FALSE +#elif STM32_SYSCLK <= 168000000 +#define STM32_VOS STM32_VOS_SCALE1 +#define STM32_OVERDRIVE_REQUIRED FALSE +#else +#define STM32_VOS STM32_VOS_SCALE1 +#define STM32_OVERDRIVE_REQUIRED TRUE +#endif + +#elif defined(STM32F40_41xxx) +#if STM32_SYSCLK <= 144000000 +#define STM32_VOS STM32_VOS_SCALE2 +#else +#define STM32_VOS STM32_VOS_SCALE1 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE + +#elif defined(STM32F401xx) +#if STM32_SYSCLK <= 60000000 +#define STM32_VOS STM32_VOS_SCALE3 +#else +#define STM32_VOS STM32_VOS_SCALE2 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE + +#elif defined(STM32F410xx) || defined(STM32F411xx) || \ + defined(STM32F412xx) +#if STM32_SYSCLK <= 64000000 +#define STM32_VOS STM32_VOS_SCALE3 +#elif STM32_SYSCLK <= 84000000 +#define STM32_VOS STM32_VOS_SCALE2 +#else +#define STM32_VOS STM32_VOS_SCALE1 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE + +#else /* STM32F2XX */ +#define STM32_OVERDRIVE_REQUIRED FALSE +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/* + * PLLI2S enable check. + */ +#if (STM32_HAS_RCC_PLLI2S && \ + (STM32_CLOCK48_REQUIRED && \ + (STM32_HAS_RCC_CK48MSEL && \ + STM32_RCC_CK48MSEL_USES_I2S && \ + (STM32_CK48MSEL == STM32_CK48MSEL_PLLALT)) || \ + (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S))) || \ + defined(__DOXYGEN__) + +/** + * @brief PLLI2S activation flag. + */ +#define STM32_ACTIVATE_PLLI2S TRUE +#else +#define STM32_ACTIVATE_PLLI2S FALSE +#endif + +/** + * @brief STM32_PLLI2SM field. + */ +#if ((STM32_PLLI2SM_VALUE >= 2) && (STM32_PLLI2SM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SM (STM32_PLLI2SM_VALUE << 0) +#else +#error "invalid STM32_PLLI2SM_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SN field. + */ +#if ((STM32_PLLI2SN_VALUE >= 50) && (STM32_PLLI2SN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) +#else +#error "invalid STM32_PLLI2SN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SP field. + */ +#if (STM32_PLLI2SP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLI2SP STM32_PLLI2SP_DIV2 +#elif STM32_PLLI2SP_VALUE == 4 +#define STM32_PLLI2SP STM32_PLLI2SP_DIV4 +#elif STM32_PLLI2SP_VALUE == 6 +#define STM32_PLLI2SP STM32_PLLI2SP_DIV6 +#elif STM32_PLLI2SP_VALUE == 8 +#define STM32_PLLI2SP STM32_PLLI2SP_DIV8 +#else +#error "invalid STM32_PLLI2SP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SQ field. + */ +#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) +#else +#error "invalid STM32_PLLI2SQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SDIVQ field. + */ +#if ((STM32_PLLI2SDIVQ_VALUE >= 1) && (STM32_PLLI2SDIVQ_VALUE <= 32)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SDIVQ ((STM32_PLLI2SQ_VALUE - 1) << 0) +#else +#error "invalid STM32_PLLI2SDIVQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SR field. + */ +#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) +#else +#error "invalid STM32_PLLI2SR_VALUE value specified" +#endif + +/** + * @brief PLLI2S input clock frequency. + */ +#if STM32_HAS_RCC_I2SPLLSRC || defined(__DOXYGEN__) +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLI2SM_VALUE) +#elif STM32_PLLI2SSRC == STM32_PLLI2SSRC_CKIN +#define STM32_PLLI2SCLKIN (STM32_I2SCKIN_VALUE / STM32_PLLI2SM_VALUE) +#else +#error "invalid STM32_PLLI2SSRC value specified" +#endif +#else +#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) +#endif + +/** + * @brief PLLI2S VCO frequency. + */ +#define STM32_PLLI2SVCO (STM32_PLLI2SCLKIN * STM32_PLLI2SN_VALUE) + +/* + * PLLI2S VCO frequency range check. + */ +#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ + (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLI2S P output clock frequency. + */ +#define STM32_PLLI2S_P_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SP_VALUE) + +/** + * @brief PLLI2S Q output clock frequency. + */ +#define STM32_PLLI2S_Q_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SQ_VALUE) + +/** + * @brief PLLI2S R output clock frequency. + */ +#define STM32_PLLI2S_R_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE) + +/* + * PLLSAI enable check. + */ +#if (STM32_HAS_RCC_PLLSAI && \ + (STM32_CLOCK48_REQUIRED && \ + (STM32_HAS_RCC_CK48MSEL && \ + !STM32_RCC_CK48MSEL_USES_I2S && \ + (STM32_CK48MSEL == STM32_CK48MSEL_PLLALT)) || \ + (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI))) || \ + (STM32_PLLSAIDIVR != STM32_PLLSAIDIVR_OFF) || \ + defined(__DOXYGEN__) +/** + * @brief PLLSAI activation flag. + */ +#define STM32_ACTIVATE_PLLSAI TRUE +#else +#define STM32_ACTIVATE_PLLSAI FALSE +#endif + +/** + * @brief STM32_PLLSAIM field. + */ +#if ((STM32_PLLSAIM_VALUE >= 2) && (STM32_PLLSAIM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIM (STM32_PLLSAIM_VALUE << 0) +#else +#error "invalid STM32_PLLSAIM_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIN field. + */ +#if ((STM32_PLLSAIN_VALUE >= 49) && (STM32_PLLSAIN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIN (STM32_PLLSAIN_VALUE << 6) +#else +#error "invalid STM32_PLLSAIN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIQ field. + */ +#if ((STM32_PLLSAIQ_VALUE >= 2) && (STM32_PLLSAIQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIQ (STM32_PLLSAIQ_VALUE << 24) +#else +#error "invalid STM32_PLLSAIQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIDIVQ_VALUE field. + */ +#if ((STM32_PLLSAIDIVQ_VALUE >= 1) && (STM32_PLLSAIDIVQ_VALUE <= 32)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIDIVQ ((STM32_PLLSAIDIVQ_VALUE - 1) << 8) +#else +#error "invalid STM32_PLLSAIDIVQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIR field. + */ +#if ((STM32_PLLSAIR_VALUE >= 2) && (STM32_PLLSAIR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIR (STM32_PLLSAIR_VALUE << 28) +#else +#error "invalid STM32_PLLSAIR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIP field. + */ + +#if (STM32_PLLSAIP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAIP STM32_PLLSAIP_DIV2 + +#elif STM32_PLLSAIP_VALUE == 4 +#define STM32_PLLSAIP STM32_PLLSAIP_DIV4 + +#elif STM32_PLLSAIP_VALUE == 6 +#define STM32_PLLSAIP STM32_PLLSAIP_DIV6 + +#elif STM32_PLLSAIP_VALUE == 8 +#define STM32_PLLSAIP STM32_PLLSAIP_DIV8 + +#else +#error "invalid STM32_PLLSAIP_VALUE value specified" +#endif + +/** + * @brief PLLSAI input clock frequency. + */ +#if defined(STM32F446xx) +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSAICLKIN (STM32_HSECLK / STM32_PLLSAIM_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLSAICLKIN (STM32_HSICLK / STM32_PLLSAIM_VALUE) +#else +#error "invalid STM32_PLLSRC value specified" +#endif +#else /* !defined(STM32F446xx) */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSAICLKIN (STM32_HSECLK / STM32_PLLM_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLSAICLKIN (STM32_HSICLK / STM32_PLLM_VALUE) +#else +#error "invalid STM32_PLLSRC value specified" +#endif +#endif /* defined(STM32F446xx) */ + +/** + * @brief PLLSAI VCO frequency. + */ +#define STM32_PLLSAIVCO (STM32_PLLSAICLKIN * STM32_PLLSAIN_VALUE) + +/* + * PLLSAI VCO frequency range check. + */ +#if (STM32_PLLSAIVCO < STM32_PLLVCO_MIN) || \ + (STM32_PLLSAIVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI P output clock frequency. + */ +#define STM32_PLLSAI_P_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIP_VALUE) + +/** + * @brief PLLSAI Q output clock frequency. + */ +#define STM32_PLLSAI_Q_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIQ_VALUE) + +/** + * @brief PLLSAI R output clock frequency. + */ +#define STM32_PLLSAI_R_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIR_VALUE) + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_TYPE1_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h b/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h index 6967d450e2..8a1ba6ff64 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h @@ -1,1231 +1,1235 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F4xx/hal_lld_type2.h - * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * - STM32_VDD (as hundredths of Volt). - * . - * One of the following macros must also be defined: - * - STM32F413xx for High-performance STM32F4 devices of Access line. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_TYPE2_H -#define HAL_LLD_TYPE2_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Defines the support for realtime counters in the HAL. - */ -#define HAL_IMPLEMENTS_COUNTERS TRUE - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32F413xx) -#define PLATFORM_NAME "STM32F413 High Performance with DSP and FPU" - -#else -#error "STM32F2xx/F4xx device not specified" -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ - -#if defined(STM32F413xx) || defined(__DOXYGEN__) -/** - * @brief Absolute maximum system clock. - */ -#define STM32_SYSCLK_MAX 100000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 26000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 50000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency using an external source. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 2100000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 950000 - -/** - * @brief Maximum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MAX 432000000 - -/** - * @brief Minimum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MIN 100000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 100000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 24000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 50000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 100000000 - -/** - * @brief Maximum SPI/I2S clock frequency. - */ -#define STM32_SPII2S_MAX 50000000 -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 16000000 /**< High speed internal clock. */ -#define STM32_LSICLK 32000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_VOS_SCALE3 0x00004000 -#define STM32_VOS_SCALE2 0x00008000 -#define STM32_VOS_SCALE1 0x0000C000 -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ -#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ -#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ -#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ -#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ - -#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW mask. */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ -#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ -#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ - -#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ - -#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ -#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ -#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ -#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ -#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ - -#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ -#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ -#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ -#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ -#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ -#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ - -#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ -#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ -#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ -#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ -#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ -#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ - -#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ -#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ -#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ - -/** - * @name RCC_PLLI2SCFGR register bits definitions - * @{ - */ -#define STM32_PLLI2SM_MASK (31 << 0) /**< PLLI2SM mask. */ -#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ -#define STM32_PLLI2SSRC_MASK (1 << 22) /**< PLLI2SSRC mask. */ -#define STM32_PLLI2SSRC_PLLSRC (0 << 22) /**< PLLI2SSRC is selected PLL - source. */ -#define STM32_PLLI2SSRC_CKIN (1 << 22) /**< PLLI2SSRC is I2S_CKIN. */ -#define STM32_PLLI2SQ_MASK (15 << 24) /**< PLLI2SQ mask. */ -#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ -/** @} */ - -/** - * @name RCC_DCKCFGR register bits definitions - * @{ - */ -#define STM32_PLLI2SDIVR_MASK (31 << 0) /**< PLLI2SDIVR mask. */ -#define STM32_PLLDIVR_MASK (31 << 8) /**< PLLDIVR mask. */ - -#define STM32_SAI1SEL_MASK (3 << 20) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_PLLSAI (0 << 20) /**< SAI1 source is PLLSAI. */ -#define STM32_SAI1SEL_PLLI2S (1 << 20) /**< SAI1 source is PLLI2S. */ -#define STM32_SAI1SEL_PLLR (2 << 20) /**< SAI1 source is PLLR. */ -#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ - -#define STM32_SAI2SEL_MASK (3 << 22) /**< SAI2SEL mask. */ -#define STM32_SAI2SEL_PLLSAI (0 << 22) /**< SAI2 source is PLLSAI. */ -#define STM32_SAI2SEL_PLLI2S (1 << 22) /**< SAI2 source is PLLI2S. */ -#define STM32_SAI2SEL_PLLR (2 << 22) /**< SAI2 source is PLLR. */ -#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ - -#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ -#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ -#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ - -#define STM32_I2S1SEL_MASK (3 << 25) /**< I2S1SEL mask. */ -#define STM32_I2S1SEL_PLLR (0 << 25) /**< I2S1 source is PLLR. */ -#define STM32_I2S1SEL_AFIN (1 << 25) /**< I2S1 source is AF Input. */ -#define STM32_I2S1SEL_MCO1 (2 << 25) /**< I2S1 source is MCO1. */ -#define STM32_I2S1SEL_OFF 0xFFFFFFFFU /**< I2S1 clock is not required.*/ - -#define STM32_I2S2SEL_MASK (3 << 27) /**< I2S2SEL mask. */ -#define STM32_I2S2SEL_PLLR (0 << 27) /**< I2S2 source is PLLR. */ -#define STM32_I2S2SEL_AFIN (1 << 27) /**< I2S2 source is AF Input. */ -#define STM32_I2S2SEL_MCO1 (2 << 27) /**< I2S2 source is MCO1. */ -#define STM32_I2S2SEL_OFF 0xFFFFFFFFU /**< I2S2 clock is not required.*/ -/** @} */ - -/** - * @name RCC_DCKCFGR2 register bits definitions - * @{ - */ -#define STM32_I2CFMP1SEL_MASK (3 << 22) /**< I2CFMP1SEL mask. */ -#define STM32_I2CFMP1SEL_PCLK1 (0 << 22) /**< I2C1 source is APB/PCLK1. */ -#define STM32_I2CFMP1SEL_SYSCLK (1 << 22) /**< I2C1 source is SYSCLK. */ -#define STM32_I2CFMP1SEL_HSI (2 << 22) /**< I2C1 source is HSI. */ - -#define STM32_CK48MSEL_MASK (1 << 27) /**< CK48MSEL mask. */ -#define STM32_CK48MSEL_PLL (0 << 27) /**< PLL48CLK source is PLL. */ -#define STM32_CK48MSEL_PLLI2S (1 << 27) /**< PLL48CLK source is PLLI2S. */ -#define STM32_CK48MSEL_PLLALT (1 << 27) /**< Alias. */ - -#define STM32_SDIOSEL_MASK (1 << 28) /**< SDIOSEL mask. */ -#define STM32_SDIOSEL_PLL48CLK (0 << 28) /**< SDIO source is PLL48CLK. */ -#define STM32_SDIOSEL_SYSCLK (1 << 28) /**< SDIO source is SYSCLK. */ - -#define STM32_LPTIM1SEL_MASK (3 << 30) /**< LPTIM1 mask. */ -#define STM32_LPTIM1SEL_APB (0 << 30) /**< LPTIM1 source is APB. */ -#define STM32_LPTIM1SEL_HSI (1 << 30) /**< LPTIM1 source is HSI. */ -#define STM32_LPTIM1SEL_LSI (2 << 30) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_LSE (3 << 30) /**< LPTIM1 source is LSE. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables the backup RAM regulator. - */ -#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) -#define STM32_BKPRAM_ENABLE FALSE -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief USB/SDIO clock setting. - */ -#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) -#define STM32_CLOCK48_REQUIRED TRUE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLLs. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 168MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 8 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 192..432. - * @note The default value is calculated for a 96MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 384 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 96MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 4 -#endif - -/** - * @brief PLLQ multiplier value. - * @note The allowed values are 2..15. - * @note The default value is calculated for a 96MHz system clock from - * an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 8 -#endif - -/** - * @brief AHB prescaler value. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV4 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief I2S clock source (pre-PLL). - */ -#if !defined(STM32_PLLI2SSRC) || defined(__DOXYGEN__) -#define STM32_PLLI2SSRC STM32_PLLI2SSRC_PLLSRC -#endif - -/** - * @brief I2S external clock value, zero if not present. - */ -#if !defined(STM32_I2SCKIN_VALUE) || defined(__DOXYGEN__) -#define STM32_I2SCKIN_VALUE 0 -#endif - -/** - * @brief PLLI2SM divider value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 96MHz I2S clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLI2SM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SM_VALUE 8 -#endif - -/** - * @brief PLLI2SN multiplier value. - * @note The allowed values are 192..432, except for - * STM32F446 where values are 50...432. - * @note The default value is calculated for a 96MHz I2S clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SN_VALUE 192 -#endif - -/** - * @brief PLLI2SR divider value. - * @note The allowed values are 2..7. - * @note The default value is calculated for a 96MHz I2S clock - * output from an external 8MHz HSE clock. - */ -#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SR_VALUE 4 -#endif - -/** - * @brief PLLI2SQ divider value. - * @note The allowed values are 2..15. - */ -#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SQ_VALUE 4 -#endif - -/** - * @brief PLLI2SDIVR divider value (SAI clock divider). - * @note The allowed values are 1..32. - */ -#if !defined(STM32_PLLI2SDIVR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SDIVR_VALUE 1 -#endif - -/** - * @brief PLLDIVR divider value (SAI clock divider). - * @note The allowed values are 1..32. - */ -#if !defined(STM32_PLLDIVR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLDIVR_VALUE 1 -#endif - -/** - * @brief SAI1SEL value (SAI1 clock source). - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#endif - -/** - * @brief SAI2SEL value (SAI2 clock source). - */ -#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) -#define STM32_SAI2SEL STM32_SAI2SEL_OFF -#endif - -/** - * @brief TIM prescaler clock source. - */ -#if !defined(STM32_TIMPRE) || defined(__DOXYGEN__) -#define STM32_TIMPRE STM32_TIMPRE_PCLK -#endif - -/** - * @brief PLL48CLK clock source. - */ -#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) -#define STM32_CK48MSEL STM32_CK48MSEL_PLL -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief RTC HSE prescaler value. - */ -#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) -#define STM32_RTCPRE_VALUE 8 -#endif - -/** - * @brief MCO1 clock source value. - * @note The default value outputs HSI clock on MCO1 pin. - */ -#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) -#define STM32_MCO1SEL STM32_MCO1SEL_HSI -#endif - -/** - * @brief MCO1 prescaler value. - * @note The default value outputs HSI clock on MCO1 pin. - */ -#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) -#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 -#endif - -/** - * @brief MCO2 clock source value. - * @note The default value outputs SYSCLK / 5 on MCO2 pin. - */ -#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) -#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK -#endif - -/** - * @brief MCO2 prescaler value. - * @note The default value outputs SYSCLK / 5 on MCO2 pin. - */ -#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) -#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F4xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F4xx_MCUCONF not defined" -#endif - -#if defined(STM32F413xx) && !defined(STM32F413_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F413_MCUCONF not defined" -#endif - -/** - * @name Maximum frequency thresholds, wait states and - * parallelism for flash access. - * @{ - */ -#if defined(STM32F413xx) -#if (STM32_VDD >= 270) && (STM32_VDD <= 360) -#define STM32_0WS_THRESHOLD 25000000 -#define STM32_1WS_THRESHOLD 50000000 -#define STM32_2WS_THRESHOLD 75000000 -#define STM32_3WS_THRESHOLD 100000000 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 2 -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 20000000 -#define STM32_1WS_THRESHOLD 40000000 -#define STM32_2WS_THRESHOLD 60000000 -#define STM32_3WS_THRESHOLD 80000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 0 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 18000000 -#define STM32_1WS_THRESHOLD 36000000 -#define STM32_2WS_THRESHOLD 54000000 -#define STM32_3WS_THRESHOLD 72000000 -#define STM32_4WS_THRESHOLD 90000000 -#define STM32_5WS_THRESHOLD 100000000 -#define STM32_6WS_THRESHOLD 0 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 1 -#elif (STM32_VDD >= 170) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 16000000 -#define STM32_1WS_THRESHOLD 32000000 -#define STM32_2WS_THRESHOLD 48000000 -#define STM32_3WS_THRESHOLD 64000000 -#define STM32_4WS_THRESHOLD 80000000 -#define STM32_5WS_THRESHOLD 96000000 -#define STM32_6WS_THRESHOLD 100000000 -#define STM32_7WS_THRESHOLD 0 -#define STM32_8WS_THRESHOLD 0 -#define STM32_FLASH_PSIZE 0 -#else -#error "invalid VDD voltage specified" -#endif -#define FLASH_SR_OPERR FLASH_SR_SOP -#endif /* defined(STM32F413xx) */ -/** @} */ - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ - ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCO1SEL" -#endif - -#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_MCO2SEL" -#endif - -#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_I2SSRC" -#endif - -#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SAI1SEL" -#endif - -#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SAI2SEL" -#endif -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#else /* STM32_HSECLK != 0 */ -#if defined(STM32_HSE_BYPASS) -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" -#endif -#else /* !defined(STM32_HSE_BYPASS) */ -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif -#endif /* !defined(STM32_HSE_BYPASS) */ -#endif /* STM32_HSECLK != 0 */ -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ - ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCO1SEL" -#endif - -#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ - ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCO2SEL" -#endif - -#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_PLLI2SSRC" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/** - * @brief Clock frequency feeding PLLs. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSRCCLK STM32_HSECLK -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLSRCCLK STM32_HSICLK -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM (STM32_PLLM_VALUE << 0) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#define STM32_PLLCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) - -/* - * PLLs input frequency range check. - */ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_CLOCK48_REQUIRED && \ - STM32_HAS_RCC_CK48MSEL && \ - (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ - (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 64) && (STM32_PLLN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 6) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLP STM32_PLLP_DIV2 -#elif STM32_PLLP_VALUE == 4 -#define STM32_PLLP STM32_PLLP_DIV4 -#elif STM32_PLLP_VALUE == 6 -#define STM32_PLLP STM32_PLLP_DIV6 -#elif STM32_PLLP_VALUE == 8 -#define STM32_PLLP STM32_PLLP_DIV8 -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLDIVR_VALUE field. - */ -#if ((STM32_PLLDIVR_VALUE >= 1) && (STM32_PLLDIVR_VALUE <= 32)) || \ - defined(__DOXYGEN__) -#define STM32_PLLDIVR ((STM32_PLLDIVR_VALUE - 1) << 8) -#else -#error "invalid STM32_PLLDIVR_VALUE value specified" -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) - -/* - * PLL output frequency range check. - */ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/* Calculating VOS settings, it is different for each sub-platform.*/ -#if defined(STM32F413xx) -#if STM32_SYSCLK <= 64000000 -#define STM32_VOS STM32_VOS_SCALE3 -#elif STM32_SYSCLK <= 84000000 -#define STM32_VOS STM32_VOS_SCALE2 -#else -#define STM32_VOS STM32_VOS_SCALE1 -#endif -#define STM32_OVERDRIVE_REQUIRED FALSE -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/* - * PLLI2S enable check. - */ -#if (STM32_HAS_RCC_PLLI2S && \ - (STM32_CLOCK48_REQUIRED && \ - (STM32_HAS_RCC_CK48MSEL && \ - STM32_RCC_CK48MSEL_USES_I2S && \ - (STM32_CK48MSEL == STM32_CK48MSEL_PLLI2S)) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S))) || \ - defined(__DOXYGEN__) - -/** - * @brief PLLI2S activation flag. - */ -#define STM32_ACTIVATE_PLLI2S TRUE -#else -#define STM32_ACTIVATE_PLLI2S FALSE -#endif - -/** - * @brief STM32_PLLI2SM field. - */ -#if ((STM32_PLLI2SM_VALUE >= 2) && (STM32_PLLI2SM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SM (STM32_PLLI2SM_VALUE << 0) -#else -#error "invalid STM32_PLLI2SM_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SN field. - */ -#if ((STM32_PLLI2SN_VALUE >= 50) && (STM32_PLLI2SN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) -#else -#error "invalid STM32_PLLI2SN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SQ field. - */ -#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) -#else -#error "invalid STM32_PLLI2SQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SR field. - */ -#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) -#else -#error "invalid STM32_PLLI2SR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SDIVR field. - */ -#if ((STM32_PLLI2SDIVR_VALUE >= 1) && (STM32_PLLI2SDIVR_VALUE <= 32)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SDIVR ((STM32_PLLI2SR_VALUE - 1) << 0) -#else -#error "invalid STM32_PLLI2SDIVQ_VALUE value specified" -#endif - -/** - * @brief PLLI2S input clock frequency. - */ -#if STM32_HAS_RCC_I2SPLLSRC || defined(__DOXYGEN__) -#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLI2SM_VALUE) -#elif STM32_PLLI2SSRC == STM32_PLLI2SSRC_CKIN -#define STM32_PLLI2SCLKIN (STM32_I2SCKIN_VALUE / STM32_PLLI2SM_VALUE) -#else -#error "invalid STM32_PLLI2SSRC value specified" -#endif -#else -#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) -#endif - -/** - * @brief PLLI2S VCO frequency. - */ -#define STM32_PLLI2SVCO (STM32_PLLI2SCLKIN * STM32_PLLI2SN_VALUE) - -/* - * PLLI2S VCO frequency range check. - */ -#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLI2S Q output clock frequency. - */ -#define STM32_PLLI2S_Q_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SQ_VALUE) - -/** - * @brief PLLI2S R output clock frequency. - */ -#define STM32_PLLI2S_R_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE) - -/** - * @brief PLLI2SP enable bit. - * @note Always 0, there is no PLLI2SP. - */ -#define STM32_PLLI2SP 0 - -/** - * @brief PLLSAI activation flag. - * @note Always FALSE, there is no PLLSAI. - */ -#define STM32_ACTIVATE_PLLSAI FALSE - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_TYPE2_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F4xx/hal_lld_type2.h + * @brief STM32F4xx/STM32F2xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * - STM32_VDD (as hundredths of Volt). + * . + * One of the following macros must also be defined: + * - STM32F413xx for High-performance STM32F4 devices of Access line. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_TYPE2_H +#define HAL_LLD_TYPE2_H + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Defines the support for realtime counters in the HAL. + */ +#define HAL_IMPLEMENTS_COUNTERS TRUE + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32F413xx) +#define PLATFORM_NAME "STM32F413 High Performance with DSP and FPU" + +#else +#error "STM32F2xx/F4xx device not specified" +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ + +#if defined(STM32F413xx) || defined(__DOXYGEN__) +/** + * @brief Absolute maximum system clock. + */ +#define STM32_SYSCLK_MAX 100000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 26000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 50000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency using an external source. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 2100000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 950000 + +/** + * @brief Maximum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MAX 432000000 + +/** + * @brief Minimum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MIN 100000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 100000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 24000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 50000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 100000000 + +/** + * @brief Maximum SPI/I2S clock frequency. + */ +#define STM32_SPII2S_MAX 50000000 +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 16000000 /**< High speed internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_VOS_SCALE3 0x00004000 +#define STM32_VOS_SCALE2 0x00008000 +#define STM32_VOS_SCALE1 0x0000C000 +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ +#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ +#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ +#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ +#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW mask. */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ +#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ +#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ + +#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ + +#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ +#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ +#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ + +#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ +#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ +#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ +#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ +#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ +#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ + +#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ +#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ +#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ +#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ +#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ +#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ + +#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ +#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ +#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ + +/** + * @name RCC_PLLI2SCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SM_MASK (31 << 0) /**< PLLI2SM mask. */ +#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ +#define STM32_PLLI2SSRC_MASK (1 << 22) /**< PLLI2SSRC mask. */ +#define STM32_PLLI2SSRC_PLLSRC (0 << 22) /**< PLLI2SSRC is selected PLL + source. */ +#define STM32_PLLI2SSRC_CKIN (1 << 22) /**< PLLI2SSRC is I2S_CKIN. */ +#define STM32_PLLI2SQ_MASK (15 << 24) /**< PLLI2SQ mask. */ +#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ +/** @} */ + +/** + * @name RCC_DCKCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SDIVR_MASK (31 << 0) /**< PLLI2SDIVR mask. */ +#define STM32_PLLDIVR_MASK (31 << 8) /**< PLLDIVR mask. */ + +#define STM32_SAI1SEL_MASK (3 << 20) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_PLLSAI (0 << 20) /**< SAI1 source is PLLSAI. */ +#define STM32_SAI1SEL_PLLI2S (1 << 20) /**< SAI1 source is PLLI2S. */ +#define STM32_SAI1SEL_PLLR (2 << 20) /**< SAI1 source is PLLR. */ +#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ + +#define STM32_SAI2SEL_MASK (3 << 22) /**< SAI2SEL mask. */ +#define STM32_SAI2SEL_PLLSAI (0 << 22) /**< SAI2 source is PLLSAI. */ +#define STM32_SAI2SEL_PLLI2S (1 << 22) /**< SAI2 source is PLLI2S. */ +#define STM32_SAI2SEL_PLLR (2 << 22) /**< SAI2 source is PLLR. */ +#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ + +#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ +#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ +#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ + +#define STM32_I2S1SEL_MASK (3 << 25) /**< I2S1SEL mask. */ +#define STM32_I2S1SEL_PLLR (0 << 25) /**< I2S1 source is PLLR. */ +#define STM32_I2S1SEL_AFIN (1 << 25) /**< I2S1 source is AF Input. */ +#define STM32_I2S1SEL_MCO1 (2 << 25) /**< I2S1 source is MCO1. */ +#define STM32_I2S1SEL_OFF 0xFFFFFFFFU /**< I2S1 clock is not required.*/ + +#define STM32_I2S2SEL_MASK (3 << 27) /**< I2S2SEL mask. */ +#define STM32_I2S2SEL_PLLR (0 << 27) /**< I2S2 source is PLLR. */ +#define STM32_I2S2SEL_AFIN (1 << 27) /**< I2S2 source is AF Input. */ +#define STM32_I2S2SEL_MCO1 (2 << 27) /**< I2S2 source is MCO1. */ +#define STM32_I2S2SEL_OFF 0xFFFFFFFFU /**< I2S2 clock is not required.*/ +/** @} */ + +/** + * @name RCC_DCKCFGR2 register bits definitions + * @{ + */ +#define STM32_I2CFMP1SEL_MASK (3 << 22) /**< I2CFMP1SEL mask. */ +#define STM32_I2CFMP1SEL_PCLK1 (0 << 22) /**< I2C1 source is APB/PCLK1. */ +#define STM32_I2CFMP1SEL_SYSCLK (1 << 22) /**< I2C1 source is SYSCLK. */ +#define STM32_I2CFMP1SEL_HSI (2 << 22) /**< I2C1 source is HSI. */ + +#define STM32_CK48MSEL_MASK (1 << 27) /**< CK48MSEL mask. */ +#define STM32_CK48MSEL_PLL (0 << 27) /**< PLL48CLK source is PLL. */ +#define STM32_CK48MSEL_PLLI2S (1 << 27) /**< PLL48CLK source is PLLI2S. */ +#define STM32_CK48MSEL_PLLALT (1 << 27) /**< Alias. */ + +#define STM32_SDIOSEL_MASK (1 << 28) /**< SDIOSEL mask. */ +#define STM32_SDIOSEL_PLL48CLK (0 << 28) /**< SDIO source is PLL48CLK. */ +#define STM32_SDIOSEL_SYSCLK (1 << 28) /**< SDIO source is SYSCLK. */ + +#define STM32_LPTIM1SEL_MASK (3 << 30) /**< LPTIM1 mask. */ +#define STM32_LPTIM1SEL_APB (0 << 30) /**< LPTIM1 source is APB. */ +#define STM32_LPTIM1SEL_HSI (1 << 30) /**< LPTIM1 source is HSI. */ +#define STM32_LPTIM1SEL_LSI (2 << 30) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_LSE (3 << 30) /**< LPTIM1 source is LSE. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables the backup RAM regulator. + */ +#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) +#define STM32_BKPRAM_ENABLE FALSE +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief USB/SDIO clock setting. + */ +#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) +#define STM32_CLOCK48_REQUIRED TRUE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLLs. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 168MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 8 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 192..432. + * @note The default value is calculated for a 96MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 384 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 96MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 4 +#endif + +/** + * @brief PLLQ multiplier value. + * @note The allowed values are 2..15. + * @note The default value is calculated for a 96MHz system clock from + * an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 8 +#endif + +/** + * @brief AHB prescaler value. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV4 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief I2S clock source (pre-PLL). + */ +#if !defined(STM32_PLLI2SSRC) || defined(__DOXYGEN__) +#define STM32_PLLI2SSRC STM32_PLLI2SSRC_PLLSRC +#endif + +/** + * @brief I2S external clock value, zero if not present. + */ +#if !defined(STM32_I2SCKIN_VALUE) || defined(__DOXYGEN__) +#define STM32_I2SCKIN_VALUE 0 +#endif + +/** + * @brief PLLI2SM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SM_VALUE 8 +#endif + +/** + * @brief PLLI2SN multiplier value. + * @note The allowed values are 192..432, except for + * STM32F446 where values are 50...432. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SN_VALUE 192 +#endif + +/** + * @brief PLLI2SR divider value. + * @note The allowed values are 2..7. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SR_VALUE 4 +#endif + +/** + * @brief PLLI2SQ divider value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SQ_VALUE 4 +#endif + +/** + * @brief PLLI2SDIVR divider value (SAI clock divider). + * @note The allowed values are 1..32. + */ +#if !defined(STM32_PLLI2SDIVR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SDIVR_VALUE 1 +#endif + +/** + * @brief PLLDIVR divider value (SAI clock divider). + * @note The allowed values are 1..32. + */ +#if !defined(STM32_PLLDIVR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLDIVR_VALUE 1 +#endif + +/** + * @brief SAI1SEL value (SAI1 clock source). + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#endif + +/** + * @brief SAI2SEL value (SAI2 clock source). + */ +#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#endif + +/** + * @brief TIM prescaler clock source. + */ +#if !defined(STM32_TIMPRE) || defined(__DOXYGEN__) +#define STM32_TIMPRE STM32_TIMPRE_PCLK +#endif + +/** + * @brief PLL48CLK clock source. + */ +#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) +#define STM32_CK48MSEL STM32_CK48MSEL_PLL +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief RTC HSE prescaler value. + */ +#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#define STM32_RTCPRE_VALUE 8 +#endif + +/** + * @brief MCO1 clock source value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#endif + +/** + * @brief MCO1 prescaler value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#endif + +/** + * @brief MCO2 clock source value. + * @note The default value outputs SYSCLK / 5 on MCO2 pin. + */ +#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#endif + +/** + * @brief MCO2 prescaler value. + * @note The default value outputs SYSCLK / 5 on MCO2 pin. + */ +#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F4xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F4xx_MCUCONF not defined" +#endif + +#if defined(STM32F413xx) && !defined(STM32F413_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F413_MCUCONF not defined" +#endif + +/** + * @name Maximum frequency thresholds, wait states and + * parallelism for flash access. + * @{ + */ +#if defined(STM32F413xx) +#if (STM32_VDD >= 270) && (STM32_VDD <= 360) +#define STM32_0WS_THRESHOLD 25000000 +#define STM32_1WS_THRESHOLD 50000000 +#define STM32_2WS_THRESHOLD 75000000 +#define STM32_3WS_THRESHOLD 100000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 2 +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 0 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 18000000 +#define STM32_1WS_THRESHOLD 36000000 +#define STM32_2WS_THRESHOLD 54000000 +#define STM32_3WS_THRESHOLD 72000000 +#define STM32_4WS_THRESHOLD 90000000 +#define STM32_5WS_THRESHOLD 100000000 +#define STM32_6WS_THRESHOLD 0 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 1 +#elif (STM32_VDD >= 170) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +#define STM32_4WS_THRESHOLD 80000000 +#define STM32_5WS_THRESHOLD 96000000 +#define STM32_6WS_THRESHOLD 100000000 +#define STM32_7WS_THRESHOLD 0 +#define STM32_8WS_THRESHOLD 0 +#define STM32_FLASH_PSIZE 0 +#else +#error "invalid VDD voltage specified" +#endif +#define FLASH_SR_OPERR FLASH_SR_SOP +#endif /* defined(STM32F413xx) */ +/** @} */ + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2SSRC" +#endif + +#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SAI1SEL" +#endif + +#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SAI2SEL" +#endif +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#else /* STM32_HSECLK != 0 */ +#if defined(STM32_HSE_BYPASS) +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" +#endif +#else /* !defined(STM32_HSE_BYPASS) */ +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif +#endif /* !defined(STM32_HSE_BYPASS) */ +#endif /* STM32_HSECLK != 0 */ +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ + ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_PLLI2SSRC" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief Clock frequency feeding PLLs. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSRCCLK STM32_HSECLK +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLSRCCLK STM32_HSICLK +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM (STM32_PLLM_VALUE << 0) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#define STM32_PLLCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) + +/* + * PLLs input frequency range check. + */ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_CLOCK48_REQUIRED && \ + STM32_HAS_RCC_CK48MSEL && \ + (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ + (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 64) && (STM32_PLLN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 6) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLP STM32_PLLP_DIV2 +#elif STM32_PLLP_VALUE == 4 +#define STM32_PLLP STM32_PLLP_DIV4 +#elif STM32_PLLP_VALUE == 6 +#define STM32_PLLP STM32_PLLP_DIV6 +#elif STM32_PLLP_VALUE == 8 +#define STM32_PLLP STM32_PLLP_DIV8 +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLDIVR_VALUE field. + */ +#if ((STM32_PLLDIVR_VALUE >= 1) && (STM32_PLLDIVR_VALUE <= 32)) || \ + defined(__DOXYGEN__) +#define STM32_PLLDIVR ((STM32_PLLDIVR_VALUE - 1) << 8) +#else +#error "invalid STM32_PLLDIVR_VALUE value specified" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) + +/* + * PLL output frequency range check. + */ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/* Calculating VOS settings, it is different for each sub-platform.*/ +#if defined(STM32F413xx) +#if STM32_SYSCLK <= 64000000 +#define STM32_VOS STM32_VOS_SCALE3 +#elif STM32_SYSCLK <= 84000000 +#define STM32_VOS STM32_VOS_SCALE2 +#else +#define STM32_VOS STM32_VOS_SCALE1 +#endif +#define STM32_OVERDRIVE_REQUIRED FALSE +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/* + * PLLI2S enable check. + */ +#if (STM32_HAS_RCC_PLLI2S && \ + (STM32_CLOCK48_REQUIRED && \ + (STM32_HAS_RCC_CK48MSEL && \ + STM32_RCC_CK48MSEL_USES_I2S && \ + (STM32_CK48MSEL == STM32_CK48MSEL_PLLI2S)) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLI2S) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLI2S))) || \ + defined(__DOXYGEN__) + +/** + * @brief PLLI2S activation flag. + */ +#define STM32_ACTIVATE_PLLI2S TRUE +#else +#define STM32_ACTIVATE_PLLI2S FALSE +#endif + +/** + * @brief STM32_PLLI2SM field. + */ +#if ((STM32_PLLI2SM_VALUE >= 2) && (STM32_PLLI2SM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SM (STM32_PLLI2SM_VALUE << 0) +#else +#error "invalid STM32_PLLI2SM_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SN field. + */ +#if ((STM32_PLLI2SN_VALUE >= 50) && (STM32_PLLI2SN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) +#else +#error "invalid STM32_PLLI2SN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SQ field. + */ +#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) +#else +#error "invalid STM32_PLLI2SQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SR field. + */ +#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) +#else +#error "invalid STM32_PLLI2SR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SDIVR field. + */ +#if ((STM32_PLLI2SDIVR_VALUE >= 1) && (STM32_PLLI2SDIVR_VALUE <= 32)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SDIVR ((STM32_PLLI2SR_VALUE - 1) << 0) +#else +#error "invalid STM32_PLLI2SDIVQ_VALUE value specified" +#endif + +/** + * @brief PLLI2S input clock frequency. + */ +#if STM32_HAS_RCC_I2SPLLSRC || defined(__DOXYGEN__) +#if (STM32_PLLI2SSRC == STM32_PLLI2SSRC_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLI2SM_VALUE) +#elif STM32_PLLI2SSRC == STM32_PLLI2SSRC_CKIN +#define STM32_PLLI2SCLKIN (STM32_I2SCKIN_VALUE / STM32_PLLI2SM_VALUE) +#else +#error "invalid STM32_PLLI2SSRC value specified" +#endif +#else +#define STM32_PLLI2SCLKIN (STM32_PLLSRCCLK / STM32_PLLM_VALUE) +#endif + +/** + * @brief PLLI2S VCO frequency. + */ +#define STM32_PLLI2SVCO (STM32_PLLI2SCLKIN * STM32_PLLI2SN_VALUE) + +/* + * PLLI2S VCO frequency range check. + */ +#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ + (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLI2S Q output clock frequency. + */ +#define STM32_PLLI2S_Q_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SQ_VALUE) + +/** + * @brief PLLI2S R output clock frequency. + */ +#define STM32_PLLI2S_R_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE) + +/** + * @brief PLLI2SP enable bit. + * @note Always 0, there is no PLLI2SP. + */ +#define STM32_PLLI2SP 0 + +/** + * @brief PLLSAI activation flag. + * @note Always FALSE, there is no PLLSAI. + */ +#define STM32_ACTIVATE_PLLSAI FALSE + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_TYPE2_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.c b/os/hal/ports/STM32/STM32F7xx/hal_lld.c index f57e097bc5..60db2e8038 100644 --- a/os/hal/ports/STM32/STM32F7xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.c @@ -1,318 +1,318 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F7xx/hal_lld.c - * @brief STM32F7xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f7xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ - -#if STM32_BKPRAM_ENABLE - rccEnableBKPSRAM(true); - - PWR->CSR1 |= PWR_CSR1_BRE; - while ((PWR->CSR1 & PWR_CSR1_BRR) == 0) - ; /* Waits until the regulator is stable */ -#else - PWR->CSR1 &= ~PWR_CSR1_BRE; -#endif /* STM32_BKPRAM_ENABLE */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. AHB3 is not reseted because it could have - been initialized in the board initialization file (board.c). - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~STM32_GPIO_EN_MASK); - rccResetAHB2(~0); - rccResetAPB1(~RCC_APB1RSTR_PWRRST); - rccResetAPB2(~0); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - -#if STM32_SRAM2_NOCACHE - /* The SRAM2 bank can optionally made a non cache-able area for use by - DMA engines.*/ - mpuConfigureRegion(MPU_REGION_7, - SRAM2_BASE, - MPU_RASR_ATTR_AP_RW_RW | - MPU_RASR_ATTR_NON_CACHEABLE | - MPU_RASR_SIZE_16K | - MPU_RASR_ENABLE); - mpuEnable(MPU_CTRL_PRIVDEFENA); - - /* Invalidating data cache to make sure that the MPU settings are taken - immediately.*/ - SCB_CleanInvalidateDCache(); -#endif - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR1 |= PWR_CR1_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ -} - -/** - * @brief STM32F2xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enabled.*/ -#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR_RTCEN) - RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_RTCEN; -#else - RCC->APB1ENR = RCC_APB1ENR_PWREN; -#endif - - /* PWR initialization.*/ - PWR->CR1 = STM32_VOS; - - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. Clearing the register has to be postponed after HSI is the - new source.*/ - RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers finally cleared to reset values.*/ - RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ - RCC->CFGR = 0; /* CFGR reset value. */ - -#if STM32_HSE_ENABLED - /* HSE activation.*/ -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - /* No HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON; -#endif - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | - STM32_PLLM; - RCC->CR |= RCC_CR_PLLON; - - /* Synchronization with voltage regulator stabilization.*/ - while ((PWR->CSR1 & PWR_CSR1_VOSRDY) == 0) - ; /* Waits until power regulator is stable. */ - -#if STM32_OVERDRIVE_REQUIRED - /* Overdrive activation performed after activating the PLL in order to save - time as recommended in RM in "Entering Over-drive mode" paragraph.*/ - PWR->CR1 |= PWR_CR1_ODEN; - while (!(PWR->CSR1 & PWR_CSR1_ODRDY)) - ; - PWR->CR1 |= PWR_CR1_ODSWEN; - while (!(PWR->CSR1 & PWR_CSR1_ODSWRDY)) - ; -#endif /* STM32_OVERDRIVE_REQUIRED */ - - /* Waiting for PLL lock.*/ - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; -#endif /* STM32_OVERDRIVE_REQUIRED */ - -#if STM32_ACTIVATE_PLLI2S - /* PLLI2S activation.*/ - RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SQ | STM32_PLLI2SP | - STM32_PLLI2SN; - RCC->CR |= RCC_CR_PLLI2SON; - - /* Waiting for PLL lock.*/ - while (!(RCC->CR & RCC_CR_PLLI2SRDY)) - ; -#endif - -#if STM32_ACTIVATE_PLLSAI - /* PLLSAI activation.*/ - RCC->PLLSAICFGR = STM32_PLLSAIR | STM32_PLLSAIQ | STM32_PLLSAIP | - STM32_PLLSAIN; - RCC->CR |= RCC_CR_PLLSAION; - - /* Waiting for PLL lock.*/ - while (!(RCC->CR & RCC_CR_PLLSAIRDY)) - ; -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CFGR = STM32_MCO2SEL | STM32_MCO2PRE | STM32_MCO1PRE | STM32_I2SSRC | - STM32_MCO1SEL | STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | - STM32_HPRE; - - /* DCKCFGR1 register initialization, note, must take care of the _OFF - pseudo settings.*/ - { - uint32_t dckcfgr1 = STM32_PLLI2SDIVQ | STM32_PLLSAIDIVQ | STM32_PLLSAIDIVR; -#if STM32_SAI2SEL != STM32_SAI2SEL_OFF - dckcfgr1 |= STM32_SAI2SEL; -#endif -#if STM32_SAI1SEL != STM32_SAI1SEL_OFF - dckcfgr1 |= STM32_SAI1SEL; -#endif -#if STM32_TIMPRE_ENABLE == TRUE - dckcfgr1 |= RCC_DCKCFGR1_TIMPRE; -#endif - RCC->DCKCFGR1 = dckcfgr1; - } - - /* Peripheral clock sources.*/ - RCC->DCKCFGR2 = STM32_SDMMC2SEL | STM32_SDMMC1SEL | STM32_CK48MSEL | - STM32_CECSEL | STM32_LPTIM1SEL | STM32_I2C4SEL | - STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | - STM32_UART8SEL | STM32_UART7SEL | STM32_USART6SEL | - STM32_UART5SEL | STM32_UART4SEL | STM32_USART3SEL | - STM32_USART2SEL | STM32_USART1SEL; - - /* Flash setup.*/ - FLASH->ACR = FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured clock source if it is different from HSI.*/ -#if (STM32_SW != STM32_SW_HSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F7xx/hal_lld.c + * @brief STM32F7xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f7xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + +#if STM32_BKPRAM_ENABLE + rccEnableBKPSRAM(true); + + PWR->CSR1 |= PWR_CSR1_BRE; + while ((PWR->CSR1 & PWR_CSR1_BRR) == 0) + ; /* Waits until the regulator is stable */ +#else + PWR->CSR1 &= ~PWR_CSR1_BRE; +#endif /* STM32_BKPRAM_ENABLE */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. AHB3 is not reseted because it could have + been initialized in the board initialization file (board.c). + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~STM32_GPIO_EN_MASK); + rccResetAHB2(~0); + rccResetAPB1(~RCC_APB1RSTR_PWRRST); + rccResetAPB2(~0); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + +#if STM32_SRAM2_NOCACHE + /* The SRAM2 bank can optionally made a non cache-able area for use by + DMA engines.*/ + mpuConfigureRegion(MPU_REGION_7, + SRAM2_BASE, + MPU_RASR_ATTR_AP_RW_RW | + MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_SIZE_16K | + MPU_RASR_ENABLE); + mpuEnable(MPU_CTRL_PRIVDEFENA); + + /* Invalidating data cache to make sure that the MPU settings are taken + immediately.*/ + SCB_CleanInvalidateDCache(); +#endif + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR1 |= PWR_CR1_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32F2xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enabled.*/ +#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR_RTCEN) + RCC->APB1ENR = RCC_APB1ENR_PWREN | RCC_APB1ENR_RTCEN; +#else + RCC->APB1ENR = RCC_APB1ENR_PWREN; +#endif + + /* PWR initialization.*/ + PWR->CR1 = STM32_VOS; + + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. Clearing the register has to be postponed after HSI is the + new source.*/ + RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers finally cleared to reset values.*/ + RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ + RCC->CFGR = 0; /* CFGR reset value. */ + +#if STM32_HSE_ENABLED + /* HSE activation.*/ +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + /* No HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON; +#endif + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN | + STM32_PLLM; + RCC->CR |= RCC_CR_PLLON; + + /* Synchronization with voltage regulator stabilization.*/ + while ((PWR->CSR1 & PWR_CSR1_VOSRDY) == 0) + ; /* Waits until power regulator is stable. */ + +#if STM32_OVERDRIVE_REQUIRED + /* Overdrive activation performed after activating the PLL in order to save + time as recommended in RM in "Entering Over-drive mode" paragraph.*/ + PWR->CR1 |= PWR_CR1_ODEN; + while (!(PWR->CSR1 & PWR_CSR1_ODRDY)) + ; + PWR->CR1 |= PWR_CR1_ODSWEN; + while (!(PWR->CSR1 & PWR_CSR1_ODSWRDY)) + ; +#endif /* STM32_OVERDRIVE_REQUIRED */ + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; +#endif /* STM32_OVERDRIVE_REQUIRED */ + +#if STM32_ACTIVATE_PLLI2S + /* PLLI2S activation.*/ + RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SQ | STM32_PLLI2SP | + STM32_PLLI2SN; + RCC->CR |= RCC_CR_PLLI2SON; + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLI2SRDY)) + ; +#endif + +#if STM32_ACTIVATE_PLLSAI + /* PLLSAI activation.*/ + RCC->PLLSAICFGR = STM32_PLLSAIR | STM32_PLLSAIQ | STM32_PLLSAIP | + STM32_PLLSAIN; + RCC->CR |= RCC_CR_PLLSAION; + + /* Waiting for PLL lock.*/ + while (!(RCC->CR & RCC_CR_PLLSAIRDY)) + ; +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR = STM32_MCO2SEL | STM32_MCO2PRE | STM32_MCO1PRE | STM32_I2SSRC | + STM32_MCO1SEL | STM32_RTCPRE | STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; + + /* DCKCFGR1 register initialization, note, must take care of the _OFF + pseudo settings.*/ + { + uint32_t dckcfgr1 = STM32_PLLI2SDIVQ | STM32_PLLSAIDIVQ | STM32_PLLSAIDIVR; +#if STM32_SAI2SEL != STM32_SAI2SEL_OFF + dckcfgr1 |= STM32_SAI2SEL; +#endif +#if STM32_SAI1SEL != STM32_SAI1SEL_OFF + dckcfgr1 |= STM32_SAI1SEL; +#endif +#if STM32_TIMPRE_ENABLE == TRUE + dckcfgr1 |= RCC_DCKCFGR1_TIMPRE; +#endif + RCC->DCKCFGR1 = dckcfgr1; + } + + /* Peripheral clock sources.*/ + RCC->DCKCFGR2 = STM32_SDMMC2SEL | STM32_SDMMC1SEL | STM32_CK48MSEL | + STM32_CECSEL | STM32_LPTIM1SEL | STM32_I2C4SEL | + STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | + STM32_UART8SEL | STM32_UART7SEL | STM32_USART6SEL | + STM32_UART5SEL | STM32_UART4SEL | STM32_USART3SEL | + STM32_USART2SEL | STM32_USART1SEL; + + /* Flash setup.*/ + FLASH->ACR = FLASH_ACR_ARTEN | FLASH_ACR_PRFTEN | STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured clock source if it is different from HSI.*/ +#if (STM32_SW != STM32_SW_HSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.h b/os/hal/ports/STM32/STM32F7xx/hal_lld.h index e0848775f0..74d1548986 100644 --- a/os/hal/ports/STM32/STM32F7xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.h @@ -1,2200 +1,2204 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32F7xx/hal_lld.h - * @brief STM32F7xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * - STM32_VDD (as hundredths of Volt). - * . - * One of the following macros must also be defined: - * - STM32F722xx, STM32F723xx very high-performance MCUs. - * - STM32F732xx, STM32F733xx very high-performance MCUs. - * - STM32F745xx, STM32F746xx, STM32F756xx very high-performance MCUs. - * - STM32F765xx, STM32F767xx, STM32F769xx very high-performance MCUs. - * - STM32F777xx, STM32F779xx very high-performance MCUs. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief Defines the support for realtime counters in the HAL. - */ -#define HAL_IMPLEMENTS_COUNTERS TRUE - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32F722xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" - -#elif defined(STM32F723xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" - -#elif defined(STM32F732xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" - -#elif defined(STM32F733xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" - -#elif defined(STM32F745xx) -#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" - -#elif defined(STM32F746xx) -#define PLATFORM_NAME "STM32F746 Very High Performance with DSP and FPU" - -#elif defined(STM32F756xx) -#define PLATFORM_NAME "STM32F756 Very High Performance with DSP and FPU" - -#elif defined(STM32F765xx) -#define PLATFORM_NAME "STM32F767 Very High Performance with DSP and DP FPU" - -#elif defined(STM32F767xx) -#define PLATFORM_NAME "STM32F767 Very High Performance with DSP and DP FPU" - -#elif defined(STM32F769xx) -#define PLATFORM_NAME "STM32F769 Very High Performance with DSP and DP FPU" - -#elif defined(STM32F777xx) -#define PLATFORM_NAME "STM32F767 Very High Performance with DSP and DP FPU" - -#elif defined(STM32F779xx) -#define PLATFORM_NAME "STM32F769 Very High Performance with DSP and DP FPU" - -#else -#error "STM32F7xx device not specified" -#endif -/** @} */ - -/** - * @name Sub-family identifier - */ -#if !defined(STM32F7XX) || defined(__DOXYGEN__) -#define STM32F7XX -#endif -/** @} */ - -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Absolute maximum system clock. - */ -#define STM32_SYSCLK_MAX 216000000 - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 26000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 50000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_BYP_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 2100000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 950000 - -/** - * @brief Maximum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MAX 432000000 - -/** - * @brief Minimum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MIN 192000000 - -/** - * @brief Maximum PLL output clock frequency. - */ -#define STM32_PLLOUT_MAX 216000000 - -/** - * @brief Minimum PLL output clock frequency. - */ -#define STM32_PLLOUT_MIN 24000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) - -/** - * @brief Maximum SPI/I2S clock frequency. - */ -#define STM32_SPII2S_MAX 54000000 -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 16000000 /**< High speed internal clock. */ -#define STM32_LSICLK 32000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_VOS_SCALE3 (PWR_CR1_VOS_0) -#define STM32_VOS_SCALE2 (PWR_CR1_VOS_1) -#define STM32_VOS_SCALE1 (PWR_CR1_VOS_1 | PWR_CR1_VOS_0) - -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ -#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ -#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ -#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ -#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ - -#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW mask. */ -#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ -#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ -#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ - -#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ - -#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ -#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ -#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ -#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ -#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ - -#define STM32_I2SSRC_MASK (1 << 23) /**< I2CSRC mask. */ -#define STM32_I2SSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */ -#define STM32_I2SSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */ -#define STM32_I2SSRC_OFF (1 << 23) /**< ISS clock not required. */ - -#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ -#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ -#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ -#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ -#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ -#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ - -#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ -#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ -#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ -#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ -#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ -#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ - -#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ -#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ -#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ -#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ -/** @} */ - -/** - * @name RCC_PLLI2SCFGR register bits definitions - * @{ - */ -#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ -#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ -/** @} */ - -/** - * @name RCC_DCKCFGR1 register bits definitions - * @{ - */ -#define STM32_PLLSAIDIVR_MASK (3 << 16) /**< PLLSAIDIVR mask. */ -#define STM32_PLLSAIDIVR_DIV2 (0 << 16) /**< LCD_CLK is R divided by 2. */ -#define STM32_PLLSAIDIVR_DIV4 (1 << 16) /**< LCD_CLK is R divided by 4. */ -#define STM32_PLLSAIDIVR_DIV8 (2 << 16) /**< LCD_CLK is R divided by 8. */ -#define STM32_PLLSAIDIVR_DIV16 (3 << 16) /**< LCD_CLK is R divided by 16.*/ - -#define STM32_SAI1SEL_MASK (3 << 20) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_SAIPLL (0 << 20) /**< SAI1 source is SAIPLL. */ -#define STM32_SAI1SEL_I2SPLL (1 << 20) /**< SAI1 source is I2SPLL. */ -#define STM32_SAI1SEL_CKIN (2 << 20) /**< SAI1 source is I2S_CKIN. */ -#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ - -#define STM32_SAI2SEL_MASK (3 << 22) /**< SAI2SEL mask. */ -#define STM32_SAI2SEL_SAIPLL (0 << 22) /**< SAI2 source is SAIPLL. */ -#define STM32_SAI2SEL_I2SPLL (1 << 22) /**< SAI2 source is I2SPLL. */ -#define STM32_SAI2SEL_CKIN (2 << 22) /**< SAI2 source is I2S_CKIN. */ -#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ - -#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ -#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ -#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ -/** @} */ - -/** - * @name RCC_DCKCFGR2 register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ -#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ -#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ -#define STM32_USART1SEL_HSI (2 << 0) /**< USART1 source is HSI. */ -#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ - -#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ -#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ -#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ -#define STM32_USART2SEL_HSI (2 << 2) /**< USART2 source is HSI. */ -#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ - -#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ -#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ -#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ -#define STM32_USART3SEL_HSI (2 << 4) /**< USART3 source is HSI. */ -#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ - -#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ -#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ -#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ -#define STM32_UART4SEL_HSI (2 << 6) /**< UART4 source is HSI. */ -#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ - -#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ -#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ -#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ -#define STM32_UART5SEL_HSI (2 << 8) /**< UART5 source is HSI. */ -#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ - -#define STM32_USART6SEL_MASK (3 << 10) /**< USART6SEL mask. */ -#define STM32_USART6SEL_PCLK2 (0 << 10) /**< USART6 source is PCLK2. */ -#define STM32_USART6SEL_SYSCLK (1 << 10) /**< USART6 source is SYSCLK. */ -#define STM32_USART6SEL_HSI (2 << 10) /**< USART6 source is HSI. */ -#define STM32_USART6SEL_LSE (3 << 10) /**< USART6 source is LSE. */ - -#define STM32_UART7SEL_MASK (3 << 12) /**< UART7 mask. */ -#define STM32_UART7SEL_PCLK1 (0 << 12) /**< UART7 source is PCLK1. */ -#define STM32_UART7SEL_SYSCLK (1 << 12) /**< UART7 source is SYSCLK. */ -#define STM32_UART7SEL_HSI (2 << 12) /**< UART7 source is HSI. */ -#define STM32_UART7SEL_LSE (3 << 12) /**< UART7 source is LSE. */ - -#define STM32_UART8SEL_MASK (3 << 14) /**< UART8 mask. */ -#define STM32_UART8SEL_PCLK1 (0 << 14) /**< UART8 source is PCLK1. */ -#define STM32_UART8SEL_SYSCLK (1 << 14) /**< UART8 source is SYSCLK. */ -#define STM32_UART8SEL_HSI (2 << 14) /**< UART8 source is HSI. */ -#define STM32_UART8SEL_LSE (3 << 14) /**< UART8 source is LSE. */ - -#define STM32_I2C1SEL_MASK (3 << 16) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK1 (0 << 16) /**< I2C1 source is PCLK1. */ -#define STM32_I2C1SEL_SYSCLK (1 << 16) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI (2 << 16) /**< I2C1 source is HSI. */ -#define STM32_I2C1SEL_LSE (3 << 16) /**< I2C1 source is LSE. */ - -#define STM32_I2C2SEL_MASK (3 << 18) /**< I2C2SEL mask. */ -#define STM32_I2C2SEL_PCLK1 (0 << 18) /**< I2C2 source is PCLK1. */ -#define STM32_I2C2SEL_SYSCLK (1 << 18) /**< I2C2 source is SYSCLK. */ -#define STM32_I2C2SEL_HSI (2 << 18) /**< I2C2 source is HSI. */ -#define STM32_I2C2SEL_LSE (3 << 18) /**< I2C2 source is LSE. */ - -#define STM32_I2C3SEL_MASK (3 << 20) /**< I2C3SEL mask. */ -#define STM32_I2C3SEL_PCLK1 (0 << 20) /**< I2C3 source is PCLK1. */ -#define STM32_I2C3SEL_SYSCLK (1 << 20) /**< I2C3 source is SYSCLK. */ -#define STM32_I2C3SEL_HSI (2 << 20) /**< I2C3 source is HSI. */ -#define STM32_I2C3SEL_LSE (3 << 20) /**< I2C3 source is LSE. */ - -#define STM32_I2C4SEL_MASK (3 << 22) /**< I2C4SEL mask. */ -#define STM32_I2C4SEL_PCLK1 (0 << 22) /**< I2C4 source is PCLK1. */ -#define STM32_I2C4SEL_SYSCLK (1 << 22) /**< I2C4 source is SYSCLK. */ -#define STM32_I2C4SEL_HSI (2 << 22) /**< I2C4 source is HSI. */ -#define STM32_I2C4SEL_LSE (3 << 22) /**< I2C4 source is LSE. */ - -#define STM32_LPTIM1SEL_MASK (3 << 24) /**< LPTIM1SEL mask. */ -#define STM32_LPTIM1SEL_PCLK1 (0 << 24) /**< LPTIM1 source is PCLK1. */ -#define STM32_LPTIM1SEL_LSI (1 << 24) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_HSI (2 << 24) /**< LPTIM1 source is HSI. */ -#define STM32_LPTIM1SEL_LSE (3 << 24) /**< LPTIM1 source is LSE. */ - -#define STM32_CECSEL_MASK (1 << 26) /**< CECSEL mask. */ -#define STM32_CECSEL_LSE (0 << 26) /**< CEC source is LSE. */ -#define STM32_CECSEL_HSIDIV488 (1 << 26) /**< CEC source is HSI/488. */ - -#define STM32_CK48MSEL_MASK (1 << 27) /**< CK48MSEL mask. */ -#define STM32_CK48MSEL_PLL (0 << 27) /**< PLL48CLK source is PLL. */ -#define STM32_CK48MSEL_PLLSAI (1 << 27) /**< PLL48CLK source is PLLSAI. */ - -#define STM32_SDMMC1SEL_MASK (1 << 28) /**< SDMMC1SEL mask. */ -#define STM32_SDMMC1SEL_PLL48CLK (0 << 28) /**< SDMMC1 source is PLL48CLK. */ -#define STM32_SDMMC1SEL_SYSCLK (1 << 28) /**< SDMMC1 source is SYSCLK. */ - -#define STM32_SDMMC2SEL_MASK (1 << 29) /**< SDMMC2SEL mask. */ -#define STM32_SDMMC2SEL_PLL48CLK (0 << 29) /**< SDMMC2 source is PLL48CLK. */ -#define STM32_SDMMC2SEL_SYSCLK (1 << 29) /**< SDMMC2 source is SYSCLK. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables the backup RAM regulator. - */ -#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) -#define STM32_BKPRAM_ENABLE FALSE -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED TRUE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief USB/SDIO clock setting. - */ -#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) -#define STM32_CLOCK48_REQUIRED TRUE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 216MHz system clock from - * an external 25MHz HSE clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLLs. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 216MHz system clock from - * an external 25MHz HSE clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 2..63. - * @note The default value is calculated for a 216MHz system clock from - * an external 25MHz HSE clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 25 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 192..432. - * @note The default value is calculated for a 216MHz system clock from - * an external 25MHz HSE clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 432 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 216MHz system clock from - * an external 25MHz HSE clock. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 2 -#endif - -/** - * @brief PLLQ divider value. - * @note The allowed values are 2..15. - * @note The default value is calculated for a 216MHz system clock from - * an external 25MHz HSE clock. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 9 -#endif - -/** - * @brief AHB prescaler value. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV4 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV2 -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief RTC HSE prescaler value. - * @note The allowed values are 2..31. - */ -#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) -#define STM32_RTCPRE_VALUE 25 -#endif - -/** - * @brief MCO1 clock source value. - * @note The default value outputs HSI clock on MCO1 pin. - */ -#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) -#define STM32_MCO1SEL STM32_MCO1SEL_HSI -#endif - -/** - * @brief MCO1 prescaler value. - * @note The default value outputs HSI clock on MCO1 pin. - */ -#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) -#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 -#endif - -/** - * @brief MCO2 clock source value. - * @note The default value outputs SYSCLK / 4 on MCO2 pin. - */ -#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) -#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK -#endif - -/** - * @brief MCO2 prescaler value. - * @note The default value outputs SYSCLK / 4 on MCO2 pin. - */ -#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) -#define STM32_MCO2PRE STM32_MCO2PRE_DIV4 -#endif - -/** - * @brief TIM clock prescaler selection. - */ -#if !defined(STM32_TIMPRE_ENABLE) || defined(__DOXYGEN__) -#define STM32_TIMPRE_ENABLE FALSE -#endif - -/** - * @brief I2S clock source. - */ -#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) -#define STM32_I2SSRC STM32_I2SSRC_PLLI2S -#endif - -/** - * @brief PLLI2SN multiplier value. - * @note The allowed values are 49..432. - */ -#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SN_VALUE 192 -#endif - -/** - * @brief PLLI2SP divider value. - * @note The allowed values are 2, 4, 6 and 8. - */ -#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SP_VALUE 4 -#endif - -/** - * @brief PLLI2SQ divider value. - * @note The allowed values are 2..15. - */ -#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SQ_VALUE 4 -#endif - -/** - * @brief PLLI2SDIVQ divider value (SAI clock divider). - */ -#if !defined(STM32_PLLI2SDIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SDIVQ_VALUE 2 -#endif - -/** - * @brief PLLI2SR divider value. - * @note The allowed values are 2..7. - */ -#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SR_VALUE 4 -#endif - -/** - * @brief PLLSAIN multiplier value. - * @note The allowed values are 49..432. - */ -#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIN_VALUE 192 -#endif - -/** - * @brief PLLSAIP divider value. - * @note The allowed values are 2, 4, 6 and 8. - */ -#if !defined(STM32_PLLSAIP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIP_VALUE 4 -#endif - -/** - * @brief PLLSAIQ divider value. - * @note The allowed values are 2..15. - */ -#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIQ_VALUE 4 -#endif - -/** - * @brief PLLSAIR divider value. - * @note The allowed values are 2..7. - */ -#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIR_VALUE 4 -#endif - -/** - * @brief PLLSAIDIVQ divider value (SAI clock divider). - */ -#if !defined(STM32_PLLSAIDIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIDIVQ_VALUE 2 -#endif - -/** - * @brief PLLSAIDIVR divider value (LCD clock divider). - */ -#if !defined(STM32_PLLSAIDIVR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIDIVR_VALUE 2 -#endif - -/** - * @brief SAI1SEL value (SAI1 clock source). - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#endif - -/** - * @brief SAI2SEL value (SAI2 clock source). - */ -#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) -#define STM32_SAI2SEL STM32_SAI2SEL_OFF -#endif - -/** - * @brief LCD-TFT clock enable switch. - */ -#if !defined(STM32_LCDTFT_REQUIRED) || defined(__DOXYGEN__) -#define STM32_LCDTFT_REQUIRED FALSE -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_PCLK2 -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_PCLK1 -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) -#define STM32_USART3SEL STM32_USART3SEL_PCLK1 -#endif - -/** - * @brief UART4 clock source. - */ -#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) -#define STM32_UART4SEL STM32_UART4SEL_PCLK1 -#endif - -/** - * @brief UART5 clock source. - */ -#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) -#define STM32_UART5SEL STM32_UART5SEL_PCLK1 -#endif - -/** - * @brief USART6 clock source. - */ -#if !defined(STM32_USART6SEL) || defined(__DOXYGEN__) -#define STM32_USART6SEL STM32_USART6SEL_PCLK2 -#endif - -/** - * @brief UART7 clock source. - */ -#if !defined(STM32_UART7SEL) || defined(__DOXYGEN__) -#define STM32_UART7SEL STM32_UART7SEL_PCLK1 -#endif - -/** - * @brief UART8 clock source. - */ -#if !defined(STM32_UART8SEL) || defined(__DOXYGEN__) -#define STM32_UART8SEL STM32_UART8SEL_PCLK1 -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_PCLK1 -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) -#define STM32_I2C2SEL STM32_I2C2SEL_PCLK1 -#endif - -/** - * @brief I2C3 clock source. - */ -#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) -#define STM32_I2C3SEL STM32_I2C3SEL_PCLK1 -#endif - -/** - * @brief I2C4 clock source. - */ -#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) -#define STM32_I2C4SEL STM32_I2C4SEL_PCLK1 -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 -#endif - -/** - * @brief CEC clock source. - */ -#if !defined(STM32_CECSEL) || defined(__DOXYGEN__) -#define STM32_CECSEL STM32_CECSEL_LSE -#endif - -/** - * @brief PLL48CLK clock source. - */ -#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) -#define STM32_CK48MSEL STM32_CK48MSEL_PLL -#endif - -/** - * @brief SDMMC1 clock source. - */ -#if !defined(STM32_SDMMC1SEL) || defined(__DOXYGEN__) -#define STM32_SDMMC1SEL STM32_SDMMC1SEL_PLL48CLK -#endif - -/** - * @brief SDMMC2 clock source. - */ -#if !defined(STM32_SDMMC2SEL) || defined(__DOXYGEN__) -#define STM32_SDMMC2SEL STM32_SDMMC2SEL_PLL48CLK -#endif - -/** - * @brief SRAM2 cache-ability. - * @note This setting uses the MPU region 7 if at @p TRUE. - */ -#if !defined(STM32_SRAM2_NOCACHE) || defined(__DOXYGEN__) -#define STM32_SRAM2_NOCACHE FALSE -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32F7xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F7xx_MCUCONF not defined" -#endif - -#if defined(STM32F722xx) && !defined(STM32F722_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F722_MCUCONF not defined" -#endif - -#if defined(STM32F732xx) && !defined(STM32F732_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F732_MCUCONF not defined" -#endif - -#if defined(STM32F723xx) && !defined(STM32F723_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F723_MCUCONF not defined" -#endif - -#if defined(STM32F733xx) && !defined(STM32F733_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F733_MCUCONF not defined" -#endif - -#if defined(STM32F746xx) && !defined(STM32F746_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F746_MCUCONF not defined" -#endif - -#if defined(STM32F756xx) && !defined(STM32F756_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F756_MCUCONF not defined" -#endif - -#if defined(STM32F765xx) && !defined(STM32F765_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F765_MCUCONF not defined" -#endif - -#if defined(STM32F767xx) && !defined(STM32F767_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F767_MCUCONF not defined" -#endif - -#if defined(STM32F777xx) && !defined(STM32F777_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F777_MCUCONF not defined" -#endif - -#if defined(STM32F769xx) && !defined(STM32F769_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F769_MCUCONF not defined" -#endif - -#if defined(STM32F779xx) && !defined(STM32F779_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32F779_MCUCONF not defined" -#endif - -/* - * Board file checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif -#if !defined(STM32_VDD) -#error "STM32_VDD not defined in board.h" -#endif - -/** - * @brief Maximum frequency thresholds and wait states for flash access. - * @note The values are valid for 2.7V to 3.6V supply range. - */ -#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__) -#define STM32_0WS_THRESHOLD 30000000 -#define STM32_1WS_THRESHOLD 60000000 -#define STM32_2WS_THRESHOLD 90000000 -#define STM32_3WS_THRESHOLD 120000000 -#define STM32_4WS_THRESHOLD 150000000 -#define STM32_5WS_THRESHOLD 180000000 -#define STM32_6WS_THRESHOLD 210000000 -#define STM32_7WS_THRESHOLD STM32_SYSCLK_MAX -#define STM32_8WS_THRESHOLD 0 -#define STM32_9WS_THRESHOLD 0 - -#elif (STM32_VDD >= 240) && (STM32_VDD < 270) -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 72000000 -#define STM32_3WS_THRESHOLD 96000000 -#define STM32_4WS_THRESHOLD 120000000 -#define STM32_5WS_THRESHOLD 144000000 -#define STM32_6WS_THRESHOLD 168000000 -#define STM32_7WS_THRESHOLD 192000000 -#define STM32_8WS_THRESHOLD STM32_SYSCLK_MAX -#define STM32_9WS_THRESHOLD 0 - -#elif (STM32_VDD >= 210) && (STM32_VDD < 240) -#define STM32_0WS_THRESHOLD 22000000 -#define STM32_1WS_THRESHOLD 44000000 -#define STM32_2WS_THRESHOLD 66000000 -#define STM32_3WS_THRESHOLD 88000000 -#define STM32_4WS_THRESHOLD 110000000 -#define STM32_5WS_THRESHOLD 132000000 -#define STM32_6WS_THRESHOLD 154000000 -#define STM32_7WS_THRESHOLD 176000000 -#define STM32_8WS_THRESHOLD 198000000 -#define STM32_9WS_THRESHOLD STM32_SYSCLK_MAX - -#elif (STM32_VDD >= 180) && (STM32_VDD < 210) -#define STM32_0WS_THRESHOLD 20000000 -#define STM32_1WS_THRESHOLD 40000000 -#define STM32_2WS_THRESHOLD 60000000 -#define STM32_3WS_THRESHOLD 80000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 120000000 -#define STM32_6WS_THRESHOLD 140000000 -#define STM32_7WS_THRESHOLD 160000000 -#define STM32_8WS_THRESHOLD 180000000 -#define STM32_9WS_THRESHOLD 0 - -#else -#error "invalid VDD voltage specified" -#endif - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#else /* !STM32_HSI_ENABLED */ - -#if STM32_SW == STM32_SW_HSI -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ - ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "HSI not enabled, required by STM32_MCO1SEL" -#endif - -#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_MCO2SEL" -#endif - -#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_I2SSRC" -#endif - -#if ((STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SAI1SEL" -#endif - -#if ((STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_SAI2SEL" -#endif - -#if STM32_LCDTFT_REQUIRED && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI) -#error "HSI not enabled, required by STM32_LCDTFT_REQUIRED" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if STM32_HSECLK == 0 -#error "HSE frequency not defined" -#else /* STM32_HSECLK != 0 */ -#if defined(STM32_HSE_BYPASS) -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" -#endif -#else /* !defined(STM32_HSE_BYPASS) */ -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif -#endif /* !defined(STM32_HSE_BYPASS) */ -#endif /* STM32_HSECLK != 0 */ -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ - ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCO1SEL" -#endif - -#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ - ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_MCO2SEL" -#endif - -#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_I2SSRC" -#endif - -#if ((STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL) | \ - (STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SAI1SEL" -#endif - -#if ((STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL) | \ - (STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_SAI2SEL" -#endif - -#if STM32_LCDTFT_REQUIRED && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) -#error "HSE not enabled, required by STM32_LCDTFT_REQUIRED" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if (STM32_LSECLK == 0) -#error "LSE frequency not defined" -#endif - -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined" -#endif - -#if (STM32_LSEDRV >> 3) > 3 -#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#if STM32_MCO1SEL == STM32_MCO1SEL_LSE -#error "LSE not enabled, required by STM32_MCO1SEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM (STM32_PLLM_VALUE << 0) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLLs input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PLLM_VALUE) - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLLs input frequency range check. - */ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_CLOCK48_REQUIRED && (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ - (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 64) && (STM32_PLLN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 6) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLP (0 << 16) - -#elif STM32_PLLP_VALUE == 4 -#define STM32_PLLP (1 << 16) - -#elif STM32_PLLP_VALUE == 6 -#define STM32_PLLP (2 << 16) - -#elif STM32_PLLP_VALUE == 8 -#define STM32_PLLP (3 << 16) - -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL P output clock frequency. - */ -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) - -/** - * @brief PLL Q output clock frequency. - */ -#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) - -/* - * PLL output frequency range check. - */ -#if (STM32_PLL_P_CLKOUT < STM32_PLLOUT_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_HSICLK - -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK - -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK - -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLL_P_CLKOUT - -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/* Calculating VOS settings.*/ -#if STM32_SYSCLK <= 144000000 -#define STM32_VOS STM32_VOS_SCALE3 -#define STM32_OVERDRIVE_REQUIRED FALSE - -#elif STM32_SYSCLK <= 168000000 -#define STM32_VOS STM32_VOS_SCALE2 -#define STM32_OVERDRIVE_REQUIRED FALSE - -#elif STM32_SYSCLK <= 180000000 -#define STM32_VOS STM32_VOS_SCALE1 -#define STM32_OVERDRIVE_REQUIRED FALSE - -#else -#define STM32_VOS STM32_VOS_SCALE1 -#define STM32_OVERDRIVE_REQUIRED TRUE -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) - -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) - -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) - -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) - -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) - -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) - -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) - -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) - -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) - -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/* - * PLLI2S enable check. - */ -#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL) || \ - defined(__DOXYGEN__) -/** - * @brief PLLI2S activation flag. - */ -#define STM32_ACTIVATE_PLLI2S TRUE -#else -#define STM32_ACTIVATE_PLLI2S FALSE -#endif - -/** - * @brief STM32_PLLI2SN field. - */ -#if ((STM32_PLLI2SN_VALUE >= 49) && (STM32_PLLI2SN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) -#else -#error "invalid STM32_PLLI2SN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SQ field. - */ -#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) -#else -#error "invalid STM32_PLLI2SQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SR field. - */ -#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ - defined(__DOXYGEN__) -#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) -#else -#error "invalid STM32_PLLI2SR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLI2SP field. - */ -#if (STM32_PLLI2SP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLI2SP (0 << 16) - -#elif STM32_PLLI2SP_VALUE == 4 -#define STM32_PLLI2SP (1 << 16) - -#elif STM32_PLLI2SP_VALUE == 6 -#define STM32_PLLI2SP (2 << 16) - -#elif STM32_PLLI2SP_VALUE == 8 -#define STM32_PLLI2SP (3 << 16) - -#else -#error "invalid STM32_PLLI2SP_VALUE value specified" -#endif - -/** - * @brief PLLI2S VCO frequency. - */ -#define STM32_PLLI2SVCO (STM32_PLLCLKIN * STM32_PLLI2SN_VALUE) - -/* - * PLLI2S VCO frequency range check. - */ -#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLI2S P output clock frequency. - */ -#define STM32_PLLI2S_P_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SP_VALUE) - -/** - * @brief PLLI2S Q output clock frequency. - */ -#define STM32_PLLI2S_Q_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SQ_VALUE) - -/** - * @brief PLLI2S R output clock frequency. - */ -#define STM32_PLLI2S_R_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE) - -/** - * @brief STM32_PLLI2SDIVQ field. - */ -#if (STM32_PLLI2SDIVQ_VALUE < 1) || (STM32_PLLI2SDIVQ_VALUE > 32) -#error "STM32_PLLI2SDIVQ_VALUE out of acceptable range" -#endif -#define STM32_PLLI2SDIVQ ((STM32_PLLI2SDIVQ_VALUE - 1) << 0) - -/** - * @brief PLLI2S Q output clock frequency after divisor. - */ -#define STM32_PLLI2SDIVQ_CLKOUT (STM32_PLLI2S_Q_CLKOUT / STM32_PLLI2SDIVQ_VALUE) - -/* - * PLLSAI enable check. - */ -#if (STM32_CLOCK48_REQUIRED && (STM32_CK48MSEL == STM32_CK48MSEL_PLLSAI)) | \ - STM32_LCDTFT_REQUIRED || \ - (STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL) || \ - defined(__DOXYGEN__) -/** - * @brief PLLSAI activation flag. - */ -#define STM32_ACTIVATE_PLLSAI TRUE -#else -#define STM32_ACTIVATE_PLLSAI FALSE -#endif - -/** - * @brief STM32_PLLSAIN field. - */ -#if ((STM32_PLLSAIN_VALUE >= 49) && (STM32_PLLSAIN_VALUE <= 432)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIN (STM32_PLLSAIN_VALUE << 6) -#else -#error "invalid STM32_PLLSAIN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIQ field. - */ -#if ((STM32_PLLSAIQ_VALUE >= 2) && (STM32_PLLSAIQ_VALUE <= 15)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIQ (STM32_PLLSAIQ_VALUE << 24) -#else -#error "invalid STM32_PLLSAIR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIR field. - */ -#if ((STM32_PLLSAIR_VALUE >= 2) && (STM32_PLLSAIR_VALUE <= 7)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAIR (STM32_PLLSAIR_VALUE << 28) -#else -#error "invalid STM32_PLLSAIR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAIP field. - */ -#if (STM32_PLLSAIP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAIP (0 << 16) - -#elif STM32_PLLSAIP_VALUE == 4 -#define STM32_PLLSAIP (1 << 16) - -#elif STM32_PLLSAIP_VALUE == 6 -#define STM32_PLLSAIP (2 << 16) - -#elif STM32_PLLSAIP_VALUE == 8 -#define STM32_PLLSAIP (3 << 16) - -#else -#error "invalid STM32_PLLSAIP_VALUE value specified" -#endif - -/** - * @brief PLLSAI VCO frequency. - */ -#define STM32_PLLSAIVCO (STM32_PLLCLKIN * STM32_PLLSAIN_VALUE) - -/* - * PLLSAI VCO frequency range check. - */ -#if (STM32_PLLSAIVCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLSAIVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI P output clock frequency. - */ -#define STM32_PLLSAI_P_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIP_VALUE) - -/** - * @brief PLLSAI Q output clock frequency. - */ -#define STM32_PLLSAI_Q_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIQ_VALUE) - -/** - * @brief PLLSAI R output clock frequency. - */ -#define STM32_PLLSAI_R_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIR_VALUE) - -/** - * @brief STM32_PLLSAIDIVQ field. - */ -#if (STM32_PLLSAIDIVQ_VALUE < 1) || (STM32_PLLSAIDIVQ_VALUE > 32) -#error "STM32_PLLSAIDIVQ_VALUE out of acceptable range" -#endif -#define STM32_PLLSAIDIVQ ((STM32_PLLSAIDIVQ_VALUE - 1) << 8) - -/** - * @brief PLLSAI Q output clock frequency after divisor. - */ -#define STM32_PLLSAIDIVQ_CLKOUT (STM32_PLLSAI_Q_CLKOUT / STM32_PLLSAIDIVQ_VALUE) - -/* - * STM32_PLLSAIDIVR field. - */ -#if (STM32_PLLSAIDIVR_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAIDIVR (0 << 16) - -#elif STM32_PLLSAIDIVR_VALUE == 4 -#define STM32_PLLSAIDIVR (1 << 16) - -#elif STM32_PLLSAIDIVR_VALUE == 8 -#define STM32_PLLSAIDIVR (2 << 16) - -#elif STM32_PLLSAIDIVR_VALUE == 16 -#define STM32_PLLSAIDIVR (3 << 16) - -#else -#error "invalid STM32_PLLSAIDIVR_VALUE value specified" -#endif - -/** - * @brief PLLSAI R output clock frequency after divisor. - */ -#define STM32_PLLSAIDIVR_CLKOUT (STM32_PLLSAI_R_CLKOUT / STM32_PLLSAIDIVR_VALUE) - -/** - * @brief MCO1 divider clock. - */ -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || defined(__DOXYGEN__) -#define STM32_MCO1DIVCLK STM32_HSICLK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE -#define STM32_MCO1DIVCLK STM32_LSECLK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE -#define STM32_MCO1DIVCLK STM32_HSECLK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL -#define STM32_MCO1DIVCLK STM32_PLL_P_CLKOUT - -#else -#error "invalid STM32_MCO1SEL value specified" -#endif - -/** - * @brief MCO1 output pin clock. - */ -#if (STM32_MCO1PRE == STM32_MCO1PRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCO1CLK STM32_MCO1DIVCLK - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV2 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 2) - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV3 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 3) - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV4 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 4) - -#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV5 -#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 5) - -#else -#error "invalid STM32_MCO1PRE value specified" -#endif - -/** - * @brief MCO2 divider clock. - */ -#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || defined(__DOXYGEN__) -#define STM32_MCO2DIVCLK STM32_HSECLK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL -#define STM32_MCO2DIVCLK STM32_PLL_P_CLKOUT - -#elif STM32_MCO2SEL == STM32_MCO2SEL_SYSCLK -#define STM32_MCO2DIVCLK STM32_SYSCLK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S -#define STM32_MCO2DIVCLK STM32_PLLI2S - -#else -#error "invalid STM32_MCO2SEL value specified" -#endif - -/** - * @brief MCO2 output pin clock. - */ -#if (STM32_MCO2PRE == STM32_MCO2PRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCO2CLK STM32_MCO2DIVCLK - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV2 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 2) - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV3 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 3) - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV4 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 4) - -#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV5 -#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 5) - -#else -#error "invalid STM32_MCO2PRE value specified" -#endif - -/** - * @brief RTC HSE divider setting. - */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) -#else -#error "invalid STM32_RTCPRE value specified" -#endif - -/** - * @brief HSE divider toward RTC clock. - */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) -#else -#error "invalid STM32_RTCPRE value specified" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK STM32_HSEDIVCLK - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK2 -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SEL == STM32_USART1SEL_HSI -#define STM32_USART1CLK STM32_HSICLK -#elif STM32_USART1SEL == STM32_USART1SEL_LSE -#define STM32_USART1CLK STM32_LSECLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 frequency. - */ -#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART2CLK STM32_PCLK1 -#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK -#elif STM32_USART2SEL == STM32_USART2SEL_HSI -#define STM32_USART2CLK STM32_HSICLK -#elif STM32_USART2SEL == STM32_USART2SEL_LSE -#define STM32_USART2CLK STM32_LSECLK -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 frequency. - */ -#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART3CLK STM32_PCLK1 -#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK -#define STM32_USART3CLK STM32_SYSCLK -#elif STM32_USART3SEL == STM32_USART3SEL_HSI -#define STM32_USART3CLK STM32_HSICLK -#elif STM32_USART3SEL == STM32_USART3SEL_LSE -#define STM32_USART3CLK STM32_LSECLK -#else -#error "invalid source selected for USART3 clock" -#endif - -/** - * @brief UART4 frequency. - */ -#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART4CLK STM32_PCLK1 -#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK -#define STM32_UART4CLK STM32_SYSCLK -#elif STM32_UART4SEL == STM32_UART4SEL_HSI -#define STM32_UART4CLK STM32_HSICLK -#elif STM32_UART4SEL == STM32_UART4SEL_LSE -#define STM32_UART4CLK STM32_LSECLK -#else -#error "invalid source selected for UART4 clock" -#endif - -/** - * @brief UART5 frequency. - */ -#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART5CLK STM32_PCLK1 -#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK -#define STM32_UART5CLK STM32_SYSCLK -#elif STM32_UART5SEL == STM32_UART5SEL_HSI -#define STM32_UART5CLK STM32_HSICLK -#elif STM32_UART5SEL == STM32_UART5SEL_LSE -#define STM32_UART5CLK STM32_LSECLK -#else -#error "invalid source selected for UART5 clock" -#endif - -/** - * @brief USART6 frequency. - */ -#if (STM32_USART6SEL == STM32_USART6SEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_USART6CLK STM32_PCLK2 -#elif STM32_USART6SEL == STM32_USART6SEL_SYSCLK -#define STM32_USART6CLK STM32_SYSCLK -#elif STM32_USART6SEL == STM32_USART6SEL_HSI -#define STM32_USART6CLK STM32_HSICLK -#elif STM32_USART6SEL == STM32_USART6SEL_LSE -#define STM32_USART6CLK STM32_LSECLK -#else -#error "invalid source selected for USART6 clock" -#endif - -/** - * @brief UART7 frequency. - */ -#if (STM32_UART7SEL == STM32_UART7SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART7CLK STM32_PCLK1 -#elif STM32_UART7SEL == STM32_UART7SEL_SYSCLK -#define STM32_UART7CLK STM32_SYSCLK -#elif STM32_UART7SEL == STM32_UART7SEL_HSI -#define STM32_UART7CLK STM32_HSICLK -#elif STM32_UART7SEL == STM32_UART7SEL_LSE -#define STM32_UART7CLK STM32_LSECLK -#else -#error "invalid source selected for UART7 clock" -#endif - -/** - * @brief UART8 frequency. - */ -#if (STM32_UART8SEL == STM32_UART8SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART8CLK STM32_PCLK1 -#elif STM32_UART8SEL == STM32_UART8SEL_SYSCLK -#define STM32_UART8CLK STM32_SYSCLK -#elif STM32_UART8SEL == STM32_UART8SEL_HSI -#define STM32_UART8CLK STM32_HSICLK -#elif STM32_UART8SEL == STM32_UART8SEL_LSE -#define STM32_UART8CLK STM32_LSECLK -#else -#error "invalid source selected for UART8 clock" -#endif - -/** - * @brief I2C1 frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_PCLK1 -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI -#define STM32_I2C1CLK STM32_HSICLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 frequency. - */ -#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C2CLK STM32_PCLK1 -#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK -#define STM32_I2C2CLK STM32_SYSCLK -#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI -#define STM32_I2C2CLK STM32_HSICLK -#else -#error "invalid source selected for I2C2 clock" -#endif - -/** - * @brief I2C3 frequency. - */ -#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C3CLK STM32_PCLK1 -#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK -#define STM32_I2C3CLK STM32_SYSCLK -#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI -#define STM32_I2C3CLK STM32_HSICLK -#else -#error "invalid source selected for I2C3 clock" -#endif - -/** - * @brief I2C4 frequency. - */ -#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C4CLK STM32_PCLK1 -#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK -#define STM32_I2C4CLK STM32_SYSCLK -#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI -#define STM32_I2C4CLK STM32_HSICLK -#else -#error "invalid source selected for I2C4 clock" -#endif - -/** - * @brief LPTIM1 frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM1CLK STM32_PCLK1 -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI -#define STM32_LPTIM1CLK STM32_LSICLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI -#define STM32_LPTIM1CLK STM32_HSICLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE -#define STM32_LPTIM1CLK STM32_LSECLK -#else -#error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief 48MHz frequency. - */ -#if STM32_CLOCK48_REQUIRED || defined(__DOXYGEN__) -#if (STM32_CK48MSEL == STM32_CK48MSEL_PLL) || defined(__DOXYGEN__) -#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) -#elif STM32_CK48MSEL == STM32_CK48MSEL_PLLSAI -#define STM32_PLL48CLK (STM32_PLLSAIVCO / STM32_PLLSAIP_VALUE) -#else -#error "invalid source selected for PLL48CLK clock" -#endif -#else /* !STM32_CLOCK48_REQUIRED */ -#define STM32_PLL48CLK 0 -#endif /* !STM32_CLOCK48_REQUIRED */ - -/** - * @brief I2S frequency. - */ -#if (STM32_I2SSRC == STM32_I2SSRC_OFF) || defined(__DOXYGEN__) -#define STM32_I2SCLK 0 -#elif STM32_I2SSRC == STM32_I2SSRC_CKIN -#define STM32_I2SCLK 0 /* Unknown, would require a board value */ -#elif STM32_I2SSRC == STM32_I2SSRC_PLLI2S -#define STM32_I2SCLK STM32_PLLI2S_R_CLKOUT -#else -#error "invalid source selected for I2S clock" -#endif - -/** - * @brief SAI1 frequency. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_OFF) || defined(__DOXYGEN__) -#define STM32_SAI1CLK 0 -#elif STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL -#define STM32_SAI1CLK STM32_PLLSAIDIVQ_CLKOUT -#elif STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL -#define STM32_SAI1CLK STM32_PLLI2SDIVQ_CLKOUT -#elif STM32_SAI1SEL == STM32_SAI1SEL_CKIN -#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ -#else -#error "invalid source selected for SAI1 clock" -#endif - -/** - * @brief SAI2 frequency. - */ -#if (STM32_SAI2SEL == STM32_SAI2SEL_OFF) || defined(__DOXYGEN__) -#define STM32_SAI2CLK 0 -#elif STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL -#define STM32_SAI2CLK STM32_PLLSAIDIVQ_CLKOUT -#elif STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL -#define STM32_SAI2CLK STM32_PLLI2SDIVQ_CLKOUT -#elif STM32_SAI2SEL == STM32_SAI2SEL_CKIN -#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ -#else -#error "invalid source selected for SAI2 clock" -#endif - -/** - * @brief SDMMC1 frequency. - */ -#if (STM32_SDMMC1SEL == STM32_SDMMC1SEL_PLL48CLK) || defined(__DOXYGEN__) -#define STM32_SDMMC1CLK STM32_PLL48CLK -#elif STM32_SDMMC1SEL == STM32_SDMMC1SEL_SYSCLK -#define STM32_SDMMC1CLK STM32_SYSCLK -#else -#error "invalid source selected for SDMMC1 clock" -#endif - -/** - * @brief SDMMC2 frequency. - */ -#if (STM32_SDMMC2SEL == STM32_SDMMC2SEL_PLL48CLK) || defined(__DOXYGEN__) -#define STM32_SDMMC2CLK STM32_PLL48CLK -#elif STM32_SDMMC2SEL == STM32_SDMMC2SEL_SYSCLK -#define STM32_SDMMC2CLK STM32_SYSCLK -#else -#error "invalid source selected for SDMMC2 clock" -#endif - -/** - * @brief Clock of timers connected to APB1 - */ -#if (STM32_TIMPRE_ENABLE == FALSE) || defined(__DOXYGEN__) -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif -#else -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || \ - (STM32_PPRE1 == STM32_PPRE1_DIV2) || \ - (STM32_PPRE1 == STM32_PPRE1_DIV4) -#define STM32_TIMCLK1 (STM32_HCLK * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 4) -#endif -#endif - -/** - * @brief Clock of timers connected to APB2. - */ -#if (STM32_TIMPRE_ENABLE == FALSE) || defined(__DOXYGEN__) -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif -#else -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || \ - (STM32_PPRE2 == STM32_PPRE2_DIV2) || \ - (STM32_PPRE2 == STM32_PPRE2_DIV4) -#define STM32_TIMCLK2 (STM32_HCLK * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 4) -#endif -#endif - -/** - * @brief RNG clock point. - */ -#define STM32_RNGCLK STM32_PLL48CLK - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000000 - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS 0x00000001 - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS 0x00000002 - -#elif STM32_HCLK <= STM32_3WS_THRESHOLD -#define STM32_FLASHBITS 0x00000003 - -#elif STM32_HCLK <= STM32_4WS_THRESHOLD -#define STM32_FLASHBITS 0x00000004 - -#elif STM32_HCLK <= STM32_5WS_THRESHOLD -#define STM32_FLASHBITS 0x00000005 - -#elif STM32_HCLK <= STM32_6WS_THRESHOLD -#define STM32_FLASHBITS 0x00000006 - -#elif STM32_HCLK <= STM32_7WS_THRESHOLD -#define STM32_FLASHBITS 0x00000007 - -#elif STM32_HCLK <= STM32_8WS_THRESHOLD -#define STM32_FLASHBITS 0x00000008 - -#elif STM32_HCLK <= STM32_9WS_THRESHOLD -#define STM32_FLASHBITS 0x00000009 - -#else -#error "invalid frequency at specified VDD level" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32F7xx/hal_lld.h + * @brief STM32F7xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * - STM32_VDD (as hundredths of Volt). + * . + * One of the following macros must also be defined: + * - STM32F722xx, STM32F723xx very high-performance MCUs. + * - STM32F732xx, STM32F733xx very high-performance MCUs. + * - STM32F745xx, STM32F746xx, STM32F756xx very high-performance MCUs. + * - STM32F765xx, STM32F767xx, STM32F769xx very high-performance MCUs. + * - STM32F777xx, STM32F779xx very high-performance MCUs. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Defines the support for realtime counters in the HAL. + */ +#define HAL_IMPLEMENTS_COUNTERS TRUE + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32F722xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" + +#elif defined(STM32F723xx) +#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" + +#elif defined(STM32F732xx) +#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" + +#elif defined(STM32F733xx) +#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" + +#elif defined(STM32F745xx) +#define PLATFORM_NAME "STM32F745 Very High Performance with DSP and FPU" + +#elif defined(STM32F746xx) +#define PLATFORM_NAME "STM32F746 Very High Performance with DSP and FPU" + +#elif defined(STM32F756xx) +#define PLATFORM_NAME "STM32F756 Very High Performance with DSP and FPU" + +#elif defined(STM32F765xx) +#define PLATFORM_NAME "STM32F767 Very High Performance with DSP and DP FPU" + +#elif defined(STM32F767xx) +#define PLATFORM_NAME "STM32F767 Very High Performance with DSP and DP FPU" + +#elif defined(STM32F769xx) +#define PLATFORM_NAME "STM32F769 Very High Performance with DSP and DP FPU" + +#elif defined(STM32F777xx) +#define PLATFORM_NAME "STM32F767 Very High Performance with DSP and DP FPU" + +#elif defined(STM32F779xx) +#define PLATFORM_NAME "STM32F769 Very High Performance with DSP and DP FPU" + +#else +#error "STM32F7xx device not specified" +#endif +/** @} */ + +/** + * @name Sub-family identifier + */ +#if !defined(STM32F7XX) || defined(__DOXYGEN__) +#define STM32F7XX +#endif +/** @} */ + +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Absolute maximum system clock. + */ +#define STM32_SYSCLK_MAX 216000000 + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 26000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 50000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_BYP_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 2100000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 950000 + +/** + * @brief Maximum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MAX 432000000 + +/** + * @brief Minimum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MIN 192000000 + +/** + * @brief Maximum PLL output clock frequency. + */ +#define STM32_PLLOUT_MAX 216000000 + +/** + * @brief Minimum PLL output clock frequency. + */ +#define STM32_PLLOUT_MIN 24000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) + +/** + * @brief Maximum SPI/I2S clock frequency. + */ +#define STM32_SPII2S_MAX 54000000 +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 16000000 /**< High speed internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_VOS_SCALE3 (PWR_CR1_VOS_0) +#define STM32_VOS_SCALE2 (PWR_CR1_VOS_1) +#define STM32_VOS_SCALE1 (PWR_CR1_VOS_1 | PWR_CR1_VOS_0) + +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLP_MASK (3 << 16) /**< PLLP mask. */ +#define STM32_PLLP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ +#define STM32_PLLP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ +#define STM32_PLLP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ +#define STM32_PLLP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ + +#define STM32_PLLSRC_HSI (0 << 22) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 22) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW mask. */ +#define STM32_SW_HSI (0 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (1 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (2 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 10) /**< PPRE1 mask. */ +#define STM32_PPRE1_DIV1 (0 << 10) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 10) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 10) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 10) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 10) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 13) /**< PPRE2 mask. */ +#define STM32_PPRE2_DIV1 (0 << 13) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 13) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 13) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 13) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 13) /**< HCLK divided by 16. */ + +#define STM32_RTCPRE_MASK (31 << 16) /**< RTCPRE mask. */ + +#define STM32_MCO1SEL_MASK (3 << 21) /**< MCO1 mask. */ +#define STM32_MCO1SEL_HSI (0 << 21) /**< HSI clock on MCO1 pin. */ +#define STM32_MCO1SEL_LSE (1 << 21) /**< LSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_HSE (2 << 21) /**< HSE clock on MCO1 pin. */ +#define STM32_MCO1SEL_PLL (3 << 21) /**< PLL clock on MCO1 pin. */ + +#define STM32_I2SSRC_MASK (1 << 23) /**< I2CSRC mask. */ +#define STM32_I2SSRC_PLLI2S (0 << 23) /**< I2SSRC is PLLI2S. */ +#define STM32_I2SSRC_CKIN (1 << 23) /**< I2S_CKIN is PLLI2S. */ +#define STM32_I2SSRC_OFF (1 << 23) /**< ISS clock not required. */ + +#define STM32_MCO1PRE_MASK (7 << 24) /**< MCO1PRE mask. */ +#define STM32_MCO1PRE_DIV1 (0 << 24) /**< MCO1 divided by 1. */ +#define STM32_MCO1PRE_DIV2 (4 << 24) /**< MCO1 divided by 2. */ +#define STM32_MCO1PRE_DIV3 (5 << 24) /**< MCO1 divided by 3. */ +#define STM32_MCO1PRE_DIV4 (6 << 24) /**< MCO1 divided by 4. */ +#define STM32_MCO1PRE_DIV5 (7 << 24) /**< MCO1 divided by 5. */ + +#define STM32_MCO2PRE_MASK (7 << 27) /**< MCO2PRE mask. */ +#define STM32_MCO2PRE_DIV1 (0 << 27) /**< MCO2 divided by 1. */ +#define STM32_MCO2PRE_DIV2 (4 << 27) /**< MCO2 divided by 2. */ +#define STM32_MCO2PRE_DIV3 (5 << 27) /**< MCO2 divided by 3. */ +#define STM32_MCO2PRE_DIV4 (6 << 27) /**< MCO2 divided by 4. */ +#define STM32_MCO2PRE_DIV5 (7 << 27) /**< MCO2 divided by 5. */ + +#define STM32_MCO2SEL_MASK (3 << 30) /**< MCO2 mask. */ +#define STM32_MCO2SEL_SYSCLK (0 << 30) /**< SYSCLK clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLLI2S (1 << 30) /**< PLLI2S clock on MCO2 pin. */ +#define STM32_MCO2SEL_HSE (2 << 30) /**< HSE clock on MCO2 pin. */ +#define STM32_MCO2SEL_PLL (3 << 30) /**< PLL clock on MCO2 pin. */ +/** @} */ + +/** + * @name RCC_PLLI2SCFGR register bits definitions + * @{ + */ +#define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ +#define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ +/** @} */ + +/** + * @name RCC_DCKCFGR1 register bits definitions + * @{ + */ +#define STM32_PLLSAIDIVR_MASK (3 << 16) /**< PLLSAIDIVR mask. */ +#define STM32_PLLSAIDIVR_DIV2 (0 << 16) /**< LCD_CLK is R divided by 2. */ +#define STM32_PLLSAIDIVR_DIV4 (1 << 16) /**< LCD_CLK is R divided by 4. */ +#define STM32_PLLSAIDIVR_DIV8 (2 << 16) /**< LCD_CLK is R divided by 8. */ +#define STM32_PLLSAIDIVR_DIV16 (3 << 16) /**< LCD_CLK is R divided by 16.*/ + +#define STM32_SAI1SEL_MASK (3 << 20) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_SAIPLL (0 << 20) /**< SAI1 source is SAIPLL. */ +#define STM32_SAI1SEL_I2SPLL (1 << 20) /**< SAI1 source is I2SPLL. */ +#define STM32_SAI1SEL_CKIN (2 << 20) /**< SAI1 source is I2S_CKIN. */ +#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ + +#define STM32_SAI2SEL_MASK (3 << 22) /**< SAI2SEL mask. */ +#define STM32_SAI2SEL_SAIPLL (0 << 22) /**< SAI2 source is SAIPLL. */ +#define STM32_SAI2SEL_I2SPLL (1 << 22) /**< SAI2 source is I2SPLL. */ +#define STM32_SAI2SEL_CKIN (2 << 22) /**< SAI2 source is I2S_CKIN. */ +#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ + +#define STM32_TIMPRE_MASK (1 << 24) /**< TIMPRE mask. */ +#define STM32_TIMPRE_PCLK (0 << 24) /**< TIM clocks from PCLKx. */ +#define STM32_TIMPRE_HCLK (1 << 24) /**< TIM clocks from HCLK. */ +/** @} */ + +/** + * @name RCC_DCKCFGR2 register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ +#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ +#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ +#define STM32_USART1SEL_HSI (2 << 0) /**< USART1 source is HSI. */ +#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ + +#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ +#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ +#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ +#define STM32_USART2SEL_HSI (2 << 2) /**< USART2 source is HSI. */ +#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ + +#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ +#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ +#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ +#define STM32_USART3SEL_HSI (2 << 4) /**< USART3 source is HSI. */ +#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ + +#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ +#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ +#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ +#define STM32_UART4SEL_HSI (2 << 6) /**< UART4 source is HSI. */ +#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ + +#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ +#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ +#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ +#define STM32_UART5SEL_HSI (2 << 8) /**< UART5 source is HSI. */ +#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ + +#define STM32_USART6SEL_MASK (3 << 10) /**< USART6SEL mask. */ +#define STM32_USART6SEL_PCLK2 (0 << 10) /**< USART6 source is PCLK2. */ +#define STM32_USART6SEL_SYSCLK (1 << 10) /**< USART6 source is SYSCLK. */ +#define STM32_USART6SEL_HSI (2 << 10) /**< USART6 source is HSI. */ +#define STM32_USART6SEL_LSE (3 << 10) /**< USART6 source is LSE. */ + +#define STM32_UART7SEL_MASK (3 << 12) /**< UART7 mask. */ +#define STM32_UART7SEL_PCLK1 (0 << 12) /**< UART7 source is PCLK1. */ +#define STM32_UART7SEL_SYSCLK (1 << 12) /**< UART7 source is SYSCLK. */ +#define STM32_UART7SEL_HSI (2 << 12) /**< UART7 source is HSI. */ +#define STM32_UART7SEL_LSE (3 << 12) /**< UART7 source is LSE. */ + +#define STM32_UART8SEL_MASK (3 << 14) /**< UART8 mask. */ +#define STM32_UART8SEL_PCLK1 (0 << 14) /**< UART8 source is PCLK1. */ +#define STM32_UART8SEL_SYSCLK (1 << 14) /**< UART8 source is SYSCLK. */ +#define STM32_UART8SEL_HSI (2 << 14) /**< UART8 source is HSI. */ +#define STM32_UART8SEL_LSE (3 << 14) /**< UART8 source is LSE. */ + +#define STM32_I2C1SEL_MASK (3 << 16) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK1 (0 << 16) /**< I2C1 source is PCLK1. */ +#define STM32_I2C1SEL_SYSCLK (1 << 16) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI (2 << 16) /**< I2C1 source is HSI. */ +#define STM32_I2C1SEL_LSE (3 << 16) /**< I2C1 source is LSE. */ + +#define STM32_I2C2SEL_MASK (3 << 18) /**< I2C2SEL mask. */ +#define STM32_I2C2SEL_PCLK1 (0 << 18) /**< I2C2 source is PCLK1. */ +#define STM32_I2C2SEL_SYSCLK (1 << 18) /**< I2C2 source is SYSCLK. */ +#define STM32_I2C2SEL_HSI (2 << 18) /**< I2C2 source is HSI. */ +#define STM32_I2C2SEL_LSE (3 << 18) /**< I2C2 source is LSE. */ + +#define STM32_I2C3SEL_MASK (3 << 20) /**< I2C3SEL mask. */ +#define STM32_I2C3SEL_PCLK1 (0 << 20) /**< I2C3 source is PCLK1. */ +#define STM32_I2C3SEL_SYSCLK (1 << 20) /**< I2C3 source is SYSCLK. */ +#define STM32_I2C3SEL_HSI (2 << 20) /**< I2C3 source is HSI. */ +#define STM32_I2C3SEL_LSE (3 << 20) /**< I2C3 source is LSE. */ + +#define STM32_I2C4SEL_MASK (3 << 22) /**< I2C4SEL mask. */ +#define STM32_I2C4SEL_PCLK1 (0 << 22) /**< I2C4 source is PCLK1. */ +#define STM32_I2C4SEL_SYSCLK (1 << 22) /**< I2C4 source is SYSCLK. */ +#define STM32_I2C4SEL_HSI (2 << 22) /**< I2C4 source is HSI. */ +#define STM32_I2C4SEL_LSE (3 << 22) /**< I2C4 source is LSE. */ + +#define STM32_LPTIM1SEL_MASK (3 << 24) /**< LPTIM1SEL mask. */ +#define STM32_LPTIM1SEL_PCLK1 (0 << 24) /**< LPTIM1 source is PCLK1. */ +#define STM32_LPTIM1SEL_LSI (1 << 24) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_HSI (2 << 24) /**< LPTIM1 source is HSI. */ +#define STM32_LPTIM1SEL_LSE (3 << 24) /**< LPTIM1 source is LSE. */ + +#define STM32_CECSEL_MASK (1 << 26) /**< CECSEL mask. */ +#define STM32_CECSEL_LSE (0 << 26) /**< CEC source is LSE. */ +#define STM32_CECSEL_HSIDIV488 (1 << 26) /**< CEC source is HSI/488. */ + +#define STM32_CK48MSEL_MASK (1 << 27) /**< CK48MSEL mask. */ +#define STM32_CK48MSEL_PLL (0 << 27) /**< PLL48CLK source is PLL. */ +#define STM32_CK48MSEL_PLLSAI (1 << 27) /**< PLL48CLK source is PLLSAI. */ + +#define STM32_SDMMC1SEL_MASK (1 << 28) /**< SDMMC1SEL mask. */ +#define STM32_SDMMC1SEL_PLL48CLK (0 << 28) /**< SDMMC1 source is PLL48CLK. */ +#define STM32_SDMMC1SEL_SYSCLK (1 << 28) /**< SDMMC1 source is SYSCLK. */ + +#define STM32_SDMMC2SEL_MASK (1 << 29) /**< SDMMC2SEL mask. */ +#define STM32_SDMMC2SEL_PLL48CLK (0 << 29) /**< SDMMC2 source is PLL48CLK. */ +#define STM32_SDMMC2SEL_SYSCLK (1 << 29) /**< SDMMC2 source is SYSCLK. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables the backup RAM regulator. + */ +#if !defined(STM32_BKPRAM_ENABLE) || defined(__DOXYGEN__) +#define STM32_BKPRAM_ENABLE FALSE +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED TRUE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief USB/SDIO clock setting. + */ +#if !defined(STM32_CLOCK48_REQUIRED) || defined(__DOXYGEN__) +#define STM32_CLOCK48_REQUIRED TRUE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 216MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLLs. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 216MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 216MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 25 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 192..432. + * @note The default value is calculated for a 216MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 432 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 216MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 2 +#endif + +/** + * @brief PLLQ divider value. + * @note The allowed values are 2..15. + * @note The default value is calculated for a 216MHz system clock from + * an external 25MHz HSE clock. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 9 +#endif + +/** + * @brief AHB prescaler value. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV4 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief RTC HSE prescaler value. + * @note The allowed values are 2..31. + */ +#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#define STM32_RTCPRE_VALUE 25 +#endif + +/** + * @brief MCO1 clock source value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#endif + +/** + * @brief MCO1 prescaler value. + * @note The default value outputs HSI clock on MCO1 pin. + */ +#if !defined(STM32_MCO1PRE) || defined(__DOXYGEN__) +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#endif + +/** + * @brief MCO2 clock source value. + * @note The default value outputs SYSCLK / 4 on MCO2 pin. + */ +#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#endif + +/** + * @brief MCO2 prescaler value. + * @note The default value outputs SYSCLK / 4 on MCO2 pin. + */ +#if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) +#define STM32_MCO2PRE STM32_MCO2PRE_DIV4 +#endif + +/** + * @brief TIM clock prescaler selection. + */ +#if !defined(STM32_TIMPRE_ENABLE) || defined(__DOXYGEN__) +#define STM32_TIMPRE_ENABLE FALSE +#endif + +/** + * @brief I2S clock source. + */ +#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) +#define STM32_I2SSRC STM32_I2SSRC_PLLI2S +#endif + +/** + * @brief PLLI2SN multiplier value. + * @note The allowed values are 49..432. + */ +#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SN_VALUE 192 +#endif + +/** + * @brief PLLI2SP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SP_VALUE 4 +#endif + +/** + * @brief PLLI2SQ divider value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SQ_VALUE 4 +#endif + +/** + * @brief PLLI2SDIVQ divider value (SAI clock divider). + */ +#if !defined(STM32_PLLI2SDIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SDIVQ_VALUE 2 +#endif + +/** + * @brief PLLI2SR divider value. + * @note The allowed values are 2..7. + */ +#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SR_VALUE 4 +#endif + +/** + * @brief PLLSAIN multiplier value. + * @note The allowed values are 49..432. + */ +#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIN_VALUE 192 +#endif + +/** + * @brief PLLSAIP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLSAIP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIP_VALUE 4 +#endif + +/** + * @brief PLLSAIQ divider value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIQ_VALUE 4 +#endif + +/** + * @brief PLLSAIR divider value. + * @note The allowed values are 2..7. + */ +#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIR_VALUE 4 +#endif + +/** + * @brief PLLSAIDIVQ divider value (SAI clock divider). + */ +#if !defined(STM32_PLLSAIDIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIDIVQ_VALUE 2 +#endif + +/** + * @brief PLLSAIDIVR divider value (LCD clock divider). + */ +#if !defined(STM32_PLLSAIDIVR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIDIVR_VALUE 2 +#endif + +/** + * @brief SAI1SEL value (SAI1 clock source). + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#endif + +/** + * @brief SAI2SEL value (SAI2 clock source). + */ +#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#endif + +/** + * @brief LCD-TFT clock enable switch. + */ +#if !defined(STM32_LCDTFT_REQUIRED) || defined(__DOXYGEN__) +#define STM32_LCDTFT_REQUIRED FALSE +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_PCLK2 +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_PCLK1 +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) +#define STM32_USART3SEL STM32_USART3SEL_PCLK1 +#endif + +/** + * @brief UART4 clock source. + */ +#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) +#define STM32_UART4SEL STM32_UART4SEL_PCLK1 +#endif + +/** + * @brief UART5 clock source. + */ +#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) +#define STM32_UART5SEL STM32_UART5SEL_PCLK1 +#endif + +/** + * @brief USART6 clock source. + */ +#if !defined(STM32_USART6SEL) || defined(__DOXYGEN__) +#define STM32_USART6SEL STM32_USART6SEL_PCLK2 +#endif + +/** + * @brief UART7 clock source. + */ +#if !defined(STM32_UART7SEL) || defined(__DOXYGEN__) +#define STM32_UART7SEL STM32_UART7SEL_PCLK1 +#endif + +/** + * @brief UART8 clock source. + */ +#if !defined(STM32_UART8SEL) || defined(__DOXYGEN__) +#define STM32_UART8SEL STM32_UART8SEL_PCLK1 +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_PCLK1 +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) +#define STM32_I2C2SEL STM32_I2C2SEL_PCLK1 +#endif + +/** + * @brief I2C3 clock source. + */ +#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) +#define STM32_I2C3SEL STM32_I2C3SEL_PCLK1 +#endif + +/** + * @brief I2C4 clock source. + */ +#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) +#define STM32_I2C4SEL STM32_I2C4SEL_PCLK1 +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#endif + +/** + * @brief CEC clock source. + */ +#if !defined(STM32_CECSEL) || defined(__DOXYGEN__) +#define STM32_CECSEL STM32_CECSEL_LSE +#endif + +/** + * @brief PLL48CLK clock source. + */ +#if !defined(STM32_CK48MSEL) || defined(__DOXYGEN__) +#define STM32_CK48MSEL STM32_CK48MSEL_PLL +#endif + +/** + * @brief SDMMC1 clock source. + */ +#if !defined(STM32_SDMMC1SEL) || defined(__DOXYGEN__) +#define STM32_SDMMC1SEL STM32_SDMMC1SEL_PLL48CLK +#endif + +/** + * @brief SDMMC2 clock source. + */ +#if !defined(STM32_SDMMC2SEL) || defined(__DOXYGEN__) +#define STM32_SDMMC2SEL STM32_SDMMC2SEL_PLL48CLK +#endif + +/** + * @brief SRAM2 cache-ability. + * @note This setting uses the MPU region 7 if at @p TRUE. + */ +#if !defined(STM32_SRAM2_NOCACHE) || defined(__DOXYGEN__) +#define STM32_SRAM2_NOCACHE FALSE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32F7xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F7xx_MCUCONF not defined" +#endif + +#if defined(STM32F722xx) && !defined(STM32F722_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F722_MCUCONF not defined" +#endif + +#if defined(STM32F732xx) && !defined(STM32F732_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F732_MCUCONF not defined" +#endif + +#if defined(STM32F723xx) && !defined(STM32F723_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F723_MCUCONF not defined" +#endif + +#if defined(STM32F733xx) && !defined(STM32F733_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F733_MCUCONF not defined" +#endif + +#if defined(STM32F746xx) && !defined(STM32F746_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F746_MCUCONF not defined" +#endif + +#if defined(STM32F756xx) && !defined(STM32F756_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F756_MCUCONF not defined" +#endif + +#if defined(STM32F765xx) && !defined(STM32F765_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F765_MCUCONF not defined" +#endif + +#if defined(STM32F767xx) && !defined(STM32F767_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F767_MCUCONF not defined" +#endif + +#if defined(STM32F777xx) && !defined(STM32F777_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F777_MCUCONF not defined" +#endif + +#if defined(STM32F769xx) && !defined(STM32F769_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F769_MCUCONF not defined" +#endif + +#if defined(STM32F779xx) && !defined(STM32F779_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32F779_MCUCONF not defined" +#endif + +/* + * Board file checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif +#if !defined(STM32_VDD) +#error "STM32_VDD not defined in board.h" +#endif + +/** + * @brief Maximum frequency thresholds and wait states for flash access. + * @note The values are valid for 2.7V to 3.6V supply range. + */ +#if ((STM32_VDD >= 270) && (STM32_VDD <= 360)) || defined(__DOXYGEN__) +#define STM32_0WS_THRESHOLD 30000000 +#define STM32_1WS_THRESHOLD 60000000 +#define STM32_2WS_THRESHOLD 90000000 +#define STM32_3WS_THRESHOLD 120000000 +#define STM32_4WS_THRESHOLD 150000000 +#define STM32_5WS_THRESHOLD 180000000 +#define STM32_6WS_THRESHOLD 210000000 +#define STM32_7WS_THRESHOLD STM32_SYSCLK_MAX +#define STM32_8WS_THRESHOLD 0 +#define STM32_9WS_THRESHOLD 0 + +#elif (STM32_VDD >= 240) && (STM32_VDD < 270) +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 72000000 +#define STM32_3WS_THRESHOLD 96000000 +#define STM32_4WS_THRESHOLD 120000000 +#define STM32_5WS_THRESHOLD 144000000 +#define STM32_6WS_THRESHOLD 168000000 +#define STM32_7WS_THRESHOLD 192000000 +#define STM32_8WS_THRESHOLD STM32_SYSCLK_MAX +#define STM32_9WS_THRESHOLD 0 + +#elif (STM32_VDD >= 210) && (STM32_VDD < 240) +#define STM32_0WS_THRESHOLD 22000000 +#define STM32_1WS_THRESHOLD 44000000 +#define STM32_2WS_THRESHOLD 66000000 +#define STM32_3WS_THRESHOLD 88000000 +#define STM32_4WS_THRESHOLD 110000000 +#define STM32_5WS_THRESHOLD 132000000 +#define STM32_6WS_THRESHOLD 154000000 +#define STM32_7WS_THRESHOLD 176000000 +#define STM32_8WS_THRESHOLD 198000000 +#define STM32_9WS_THRESHOLD STM32_SYSCLK_MAX + +#elif (STM32_VDD >= 180) && (STM32_VDD < 210) +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 120000000 +#define STM32_6WS_THRESHOLD 140000000 +#define STM32_7WS_THRESHOLD 160000000 +#define STM32_8WS_THRESHOLD 180000000 +#define STM32_9WS_THRESHOLD 0 + +#else +#error "invalid VDD voltage specified" +#endif + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#else /* !STM32_HSI_ENABLED */ + +#if STM32_SW == STM32_SW_HSI +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "HSI not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_I2SSRC" +#endif + +#if ((STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SAI1SEL" +#endif + +#if ((STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_SAI2SEL" +#endif + +#if STM32_LCDTFT_REQUIRED && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI) +#error "HSI not enabled, required by STM32_LCDTFT_REQUIRED" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if STM32_HSECLK == 0 +#error "HSE frequency not defined" +#else /* STM32_HSECLK != 0 */ +#if defined(STM32_HSE_BYPASS) +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_BYP_MAX)" +#endif +#else /* !defined(STM32_HSE_BYPASS) */ +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif +#endif /* !defined(STM32_HSE_BYPASS) */ +#endif /* STM32_HSECLK != 0 */ +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSE) || \ + ((STM32_MCO1SEL == STM32_MCO1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO1SEL" +#endif + +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || \ + ((STM32_MCO2SEL == STM32_MCO2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_MCO2SEL" +#endif + +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_I2SSRC" +#endif + +#if ((STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL) | \ + (STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SAI1SEL" +#endif + +#if ((STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL) | \ + (STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_SAI2SEL" +#endif + +#if STM32_LCDTFT_REQUIRED && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) +#error "HSE not enabled, required by STM32_LCDTFT_REQUIRED" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if (STM32_LSECLK == 0) +#error "LSE frequency not defined" +#endif + +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined" +#endif + +#if (STM32_LSEDRV >> 3) > 3 +#error "STM32_LSEDRV outside acceptable range ((0<<3)...(3<<3))" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#if STM32_MCO1SEL == STM32_MCO1SEL_LSE +#error "LSE not enabled, required by STM32_MCO1SEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 2) && (STM32_PLLM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM (STM32_PLLM_VALUE << 0) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLLs input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PLLM_VALUE) + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLLs input frequency range check. + */ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_CLOCK48_REQUIRED && (STM32_CK48MSEL == STM32_CK48MSEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCO1SEL == STM32_MCO1SEL_PLL) || \ + (STM32_MCO2SEL == STM32_MCO2SEL_PLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 64) && (STM32_PLLN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 6) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLP (0 << 16) + +#elif STM32_PLLP_VALUE == 4 +#define STM32_PLLP (1 << 16) + +#elif STM32_PLLP_VALUE == 6 +#define STM32_PLLP (2 << 16) + +#elif STM32_PLLP_VALUE == 8 +#define STM32_PLLP (3 << 16) + +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLQ (STM32_PLLQ_VALUE << 24) +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL P output clock frequency. + */ +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) + +/** + * @brief PLL Q output clock frequency. + */ +#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) + +/* + * PLL output frequency range check. + */ +#if (STM32_PLL_P_CLKOUT < STM32_PLLOUT_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_HSICLK + +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK + +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK + +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLL_P_CLKOUT + +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/* Calculating VOS settings.*/ +#if STM32_SYSCLK <= 144000000 +#define STM32_VOS STM32_VOS_SCALE3 +#define STM32_OVERDRIVE_REQUIRED FALSE + +#elif STM32_SYSCLK <= 168000000 +#define STM32_VOS STM32_VOS_SCALE2 +#define STM32_OVERDRIVE_REQUIRED FALSE + +#elif STM32_SYSCLK <= 180000000 +#define STM32_VOS STM32_VOS_SCALE1 +#define STM32_OVERDRIVE_REQUIRED FALSE + +#else +#define STM32_VOS STM32_VOS_SCALE1 +#define STM32_OVERDRIVE_REQUIRED TRUE +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) + +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) + +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) + +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) + +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) + +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) + +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) + +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) + +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) + +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/* + * PLLI2S enable check. + */ +#if (STM32_I2SSRC == STM32_I2SSRC_PLLI2S) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLLI2S activation flag. + */ +#define STM32_ACTIVATE_PLLI2S TRUE +#else +#define STM32_ACTIVATE_PLLI2S FALSE +#endif + +/** + * @brief STM32_PLLI2SN field. + */ +#if ((STM32_PLLI2SN_VALUE >= 49) && (STM32_PLLI2SN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) +#else +#error "invalid STM32_PLLI2SN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SQ field. + */ +#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) +#else +#error "invalid STM32_PLLI2SQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SR field. + */ +#if ((STM32_PLLI2SR_VALUE >= 2) && (STM32_PLLI2SR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SR (STM32_PLLI2SR_VALUE << 28) +#else +#error "invalid STM32_PLLI2SR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SP field. + */ +#if (STM32_PLLI2SP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLI2SP (0 << 16) + +#elif STM32_PLLI2SP_VALUE == 4 +#define STM32_PLLI2SP (1 << 16) + +#elif STM32_PLLI2SP_VALUE == 6 +#define STM32_PLLI2SP (2 << 16) + +#elif STM32_PLLI2SP_VALUE == 8 +#define STM32_PLLI2SP (3 << 16) + +#else +#error "invalid STM32_PLLI2SP_VALUE value specified" +#endif + +/** + * @brief PLLI2S VCO frequency. + */ +#define STM32_PLLI2SVCO (STM32_PLLCLKIN * STM32_PLLI2SN_VALUE) + +/* + * PLLI2S VCO frequency range check. + */ +#if (STM32_PLLI2SVCO < STM32_PLLVCO_MIN) || \ + (STM32_PLLI2SVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLI2SVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLI2S P output clock frequency. + */ +#define STM32_PLLI2S_P_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SP_VALUE) + +/** + * @brief PLLI2S Q output clock frequency. + */ +#define STM32_PLLI2S_Q_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SQ_VALUE) + +/** + * @brief PLLI2S R output clock frequency. + */ +#define STM32_PLLI2S_R_CLKOUT (STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE) + +/** + * @brief STM32_PLLI2SDIVQ field. + */ +#if (STM32_PLLI2SDIVQ_VALUE < 1) || (STM32_PLLI2SDIVQ_VALUE > 32) +#error "STM32_PLLI2SDIVQ_VALUE out of acceptable range" +#endif +#define STM32_PLLI2SDIVQ ((STM32_PLLI2SDIVQ_VALUE - 1) << 0) + +/** + * @brief PLLI2S Q output clock frequency after divisor. + */ +#define STM32_PLLI2SDIVQ_CLKOUT (STM32_PLLI2S_Q_CLKOUT / STM32_PLLI2SDIVQ_VALUE) + +/* + * PLLSAI enable check. + */ +#if (STM32_CLOCK48_REQUIRED && (STM32_CK48MSEL == STM32_CK48MSEL_PLLSAI)) | \ + STM32_LCDTFT_REQUIRED || \ + (STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLLSAI activation flag. + */ +#define STM32_ACTIVATE_PLLSAI TRUE +#else +#define STM32_ACTIVATE_PLLSAI FALSE +#endif + +/** + * @brief STM32_PLLSAIN field. + */ +#if ((STM32_PLLSAIN_VALUE >= 49) && (STM32_PLLSAIN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIN (STM32_PLLSAIN_VALUE << 6) +#else +#error "invalid STM32_PLLSAIN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIQ field. + */ +#if ((STM32_PLLSAIQ_VALUE >= 2) && (STM32_PLLSAIQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIQ (STM32_PLLSAIQ_VALUE << 24) +#else +#error "invalid STM32_PLLSAIR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIR field. + */ +#if ((STM32_PLLSAIR_VALUE >= 2) && (STM32_PLLSAIR_VALUE <= 7)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAIR (STM32_PLLSAIR_VALUE << 28) +#else +#error "invalid STM32_PLLSAIR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAIP field. + */ +#if (STM32_PLLSAIP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAIP (0 << 16) + +#elif STM32_PLLSAIP_VALUE == 4 +#define STM32_PLLSAIP (1 << 16) + +#elif STM32_PLLSAIP_VALUE == 6 +#define STM32_PLLSAIP (2 << 16) + +#elif STM32_PLLSAIP_VALUE == 8 +#define STM32_PLLSAIP (3 << 16) + +#else +#error "invalid STM32_PLLSAIP_VALUE value specified" +#endif + +/** + * @brief PLLSAI VCO frequency. + */ +#define STM32_PLLSAIVCO (STM32_PLLCLKIN * STM32_PLLSAIN_VALUE) + +/* + * PLLSAI VCO frequency range check. + */ +#if (STM32_PLLSAIVCO < STM32_PLLVCO_MIN) || \ + (STM32_PLLSAIVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI P output clock frequency. + */ +#define STM32_PLLSAI_P_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIP_VALUE) + +/** + * @brief PLLSAI Q output clock frequency. + */ +#define STM32_PLLSAI_Q_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIQ_VALUE) + +/** + * @brief PLLSAI R output clock frequency. + */ +#define STM32_PLLSAI_R_CLKOUT (STM32_PLLSAIVCO / STM32_PLLSAIR_VALUE) + +/** + * @brief STM32_PLLSAIDIVQ field. + */ +#if (STM32_PLLSAIDIVQ_VALUE < 1) || (STM32_PLLSAIDIVQ_VALUE > 32) +#error "STM32_PLLSAIDIVQ_VALUE out of acceptable range" +#endif +#define STM32_PLLSAIDIVQ ((STM32_PLLSAIDIVQ_VALUE - 1) << 8) + +/** + * @brief PLLSAI Q output clock frequency after divisor. + */ +#define STM32_PLLSAIDIVQ_CLKOUT (STM32_PLLSAI_Q_CLKOUT / STM32_PLLSAIDIVQ_VALUE) + +/* + * STM32_PLLSAIDIVR field. + */ +#if (STM32_PLLSAIDIVR_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAIDIVR (0 << 16) + +#elif STM32_PLLSAIDIVR_VALUE == 4 +#define STM32_PLLSAIDIVR (1 << 16) + +#elif STM32_PLLSAIDIVR_VALUE == 8 +#define STM32_PLLSAIDIVR (2 << 16) + +#elif STM32_PLLSAIDIVR_VALUE == 16 +#define STM32_PLLSAIDIVR (3 << 16) + +#else +#error "invalid STM32_PLLSAIDIVR_VALUE value specified" +#endif + +/** + * @brief PLLSAI R output clock frequency after divisor. + */ +#define STM32_PLLSAIDIVR_CLKOUT (STM32_PLLSAI_R_CLKOUT / STM32_PLLSAIDIVR_VALUE) + +/** + * @brief MCO1 divider clock. + */ +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI) || defined(__DOXYGEN__) +#define STM32_MCO1DIVCLK STM32_HSICLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE +#define STM32_MCO1DIVCLK STM32_LSECLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE +#define STM32_MCO1DIVCLK STM32_HSECLK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL +#define STM32_MCO1DIVCLK STM32_PLL_P_CLKOUT + +#else +#error "invalid STM32_MCO1SEL value specified" +#endif + +/** + * @brief MCO1 output pin clock. + */ +#if (STM32_MCO1PRE == STM32_MCO1PRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCO1CLK STM32_MCO1DIVCLK + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV2 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 2) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV3 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 3) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV4 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 4) + +#elif STM32_MCO1PRE == STM32_MCO1PRE_DIV5 +#define STM32_MCO1CLK (STM32_MCO1DIVCLK / 5) + +#else +#error "invalid STM32_MCO1PRE value specified" +#endif + +/** + * @brief MCO2 divider clock. + */ +#if (STM32_MCO2SEL == STM32_MCO2SEL_HSE) || defined(__DOXYGEN__) +#define STM32_MCO2DIVCLK STM32_HSECLK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL +#define STM32_MCO2DIVCLK STM32_PLL_P_CLKOUT + +#elif STM32_MCO2SEL == STM32_MCO2SEL_SYSCLK +#define STM32_MCO2DIVCLK STM32_SYSCLK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLLI2S +#define STM32_MCO2DIVCLK STM32_PLLI2S + +#else +#error "invalid STM32_MCO2SEL value specified" +#endif + +/** + * @brief MCO2 output pin clock. + */ +#if (STM32_MCO2PRE == STM32_MCO2PRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCO2CLK STM32_MCO2DIVCLK + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV2 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 2) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV3 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 3) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV4 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 4) + +#elif STM32_MCO2PRE == STM32_MCO2PRE_DIV5 +#define STM32_MCO2CLK (STM32_MCO2DIVCLK / 5) + +#else +#error "invalid STM32_MCO2PRE value specified" +#endif + +/** + * @brief RTC HSE divider setting. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_RTCPRE (STM32_RTCPRE_VALUE << 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief HSE divider toward RTC clock. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / STM32_RTCPRE_VALUE) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK STM32_HSEDIVCLK + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK2 +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SEL == STM32_USART1SEL_HSI +#define STM32_USART1CLK STM32_HSICLK +#elif STM32_USART1SEL == STM32_USART1SEL_LSE +#define STM32_USART1CLK STM32_LSECLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 frequency. + */ +#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART2CLK STM32_PCLK1 +#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK +#elif STM32_USART2SEL == STM32_USART2SEL_HSI +#define STM32_USART2CLK STM32_HSICLK +#elif STM32_USART2SEL == STM32_USART2SEL_LSE +#define STM32_USART2CLK STM32_LSECLK +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 frequency. + */ +#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART3CLK STM32_PCLK1 +#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK +#define STM32_USART3CLK STM32_SYSCLK +#elif STM32_USART3SEL == STM32_USART3SEL_HSI +#define STM32_USART3CLK STM32_HSICLK +#elif STM32_USART3SEL == STM32_USART3SEL_LSE +#define STM32_USART3CLK STM32_LSECLK +#else +#error "invalid source selected for USART3 clock" +#endif + +/** + * @brief UART4 frequency. + */ +#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART4CLK STM32_PCLK1 +#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK +#define STM32_UART4CLK STM32_SYSCLK +#elif STM32_UART4SEL == STM32_UART4SEL_HSI +#define STM32_UART4CLK STM32_HSICLK +#elif STM32_UART4SEL == STM32_UART4SEL_LSE +#define STM32_UART4CLK STM32_LSECLK +#else +#error "invalid source selected for UART4 clock" +#endif + +/** + * @brief UART5 frequency. + */ +#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART5CLK STM32_PCLK1 +#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK +#define STM32_UART5CLK STM32_SYSCLK +#elif STM32_UART5SEL == STM32_UART5SEL_HSI +#define STM32_UART5CLK STM32_HSICLK +#elif STM32_UART5SEL == STM32_UART5SEL_LSE +#define STM32_UART5CLK STM32_LSECLK +#else +#error "invalid source selected for UART5 clock" +#endif + +/** + * @brief USART6 frequency. + */ +#if (STM32_USART6SEL == STM32_USART6SEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_USART6CLK STM32_PCLK2 +#elif STM32_USART6SEL == STM32_USART6SEL_SYSCLK +#define STM32_USART6CLK STM32_SYSCLK +#elif STM32_USART6SEL == STM32_USART6SEL_HSI +#define STM32_USART6CLK STM32_HSICLK +#elif STM32_USART6SEL == STM32_USART6SEL_LSE +#define STM32_USART6CLK STM32_LSECLK +#else +#error "invalid source selected for USART6 clock" +#endif + +/** + * @brief UART7 frequency. + */ +#if (STM32_UART7SEL == STM32_UART7SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART7CLK STM32_PCLK1 +#elif STM32_UART7SEL == STM32_UART7SEL_SYSCLK +#define STM32_UART7CLK STM32_SYSCLK +#elif STM32_UART7SEL == STM32_UART7SEL_HSI +#define STM32_UART7CLK STM32_HSICLK +#elif STM32_UART7SEL == STM32_UART7SEL_LSE +#define STM32_UART7CLK STM32_LSECLK +#else +#error "invalid source selected for UART7 clock" +#endif + +/** + * @brief UART8 frequency. + */ +#if (STM32_UART8SEL == STM32_UART8SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART8CLK STM32_PCLK1 +#elif STM32_UART8SEL == STM32_UART8SEL_SYSCLK +#define STM32_UART8CLK STM32_SYSCLK +#elif STM32_UART8SEL == STM32_UART8SEL_HSI +#define STM32_UART8CLK STM32_HSICLK +#elif STM32_UART8SEL == STM32_UART8SEL_LSE +#define STM32_UART8CLK STM32_LSECLK +#else +#error "invalid source selected for UART8 clock" +#endif + +/** + * @brief I2C1 frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_PCLK1 +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI +#define STM32_I2C1CLK STM32_HSICLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 frequency. + */ +#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C2CLK STM32_PCLK1 +#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK +#define STM32_I2C2CLK STM32_SYSCLK +#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI +#define STM32_I2C2CLK STM32_HSICLK +#else +#error "invalid source selected for I2C2 clock" +#endif + +/** + * @brief I2C3 frequency. + */ +#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C3CLK STM32_PCLK1 +#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK +#define STM32_I2C3CLK STM32_SYSCLK +#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI +#define STM32_I2C3CLK STM32_HSICLK +#else +#error "invalid source selected for I2C3 clock" +#endif + +/** + * @brief I2C4 frequency. + */ +#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C4CLK STM32_PCLK1 +#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK +#define STM32_I2C4CLK STM32_SYSCLK +#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI +#define STM32_I2C4CLK STM32_HSICLK +#else +#error "invalid source selected for I2C4 clock" +#endif + +/** + * @brief LPTIM1 frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM1CLK STM32_PCLK1 +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI +#define STM32_LPTIM1CLK STM32_LSICLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI +#define STM32_LPTIM1CLK STM32_HSICLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE +#define STM32_LPTIM1CLK STM32_LSECLK +#else +#error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief 48MHz frequency. + */ +#if STM32_CLOCK48_REQUIRED || defined(__DOXYGEN__) +#if (STM32_CK48MSEL == STM32_CK48MSEL_PLL) || defined(__DOXYGEN__) +#define STM32_PLL48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#elif STM32_CK48MSEL == STM32_CK48MSEL_PLLSAI +#define STM32_PLL48CLK (STM32_PLLSAIVCO / STM32_PLLSAIP_VALUE) +#else +#error "invalid source selected for PLL48CLK clock" +#endif +#else /* !STM32_CLOCK48_REQUIRED */ +#define STM32_PLL48CLK 0 +#endif /* !STM32_CLOCK48_REQUIRED */ + +/** + * @brief I2S frequency. + */ +#if (STM32_I2SSRC == STM32_I2SSRC_OFF) || defined(__DOXYGEN__) +#define STM32_I2SCLK 0 +#elif STM32_I2SSRC == STM32_I2SSRC_CKIN +#define STM32_I2SCLK 0 /* Unknown, would require a board value */ +#elif STM32_I2SSRC == STM32_I2SSRC_PLLI2S +#define STM32_I2SCLK STM32_PLLI2S_R_CLKOUT +#else +#error "invalid source selected for I2S clock" +#endif + +/** + * @brief SAI1 frequency. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_OFF) || defined(__DOXYGEN__) +#define STM32_SAI1CLK 0 +#elif STM32_SAI1SEL == STM32_SAI1SEL_SAIPLL +#define STM32_SAI1CLK STM32_PLLSAIDIVQ_CLKOUT +#elif STM32_SAI1SEL == STM32_SAI1SEL_I2SPLL +#define STM32_SAI1CLK STM32_PLLI2SDIVQ_CLKOUT +#elif STM32_SAI1SEL == STM32_SAI1SEL_CKIN +#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ +#else +#error "invalid source selected for SAI1 clock" +#endif + +/** + * @brief SAI2 frequency. + */ +#if (STM32_SAI2SEL == STM32_SAI2SEL_OFF) || defined(__DOXYGEN__) +#define STM32_SAI2CLK 0 +#elif STM32_SAI2SEL == STM32_SAI2SEL_SAIPLL +#define STM32_SAI2CLK STM32_PLLSAIDIVQ_CLKOUT +#elif STM32_SAI2SEL == STM32_SAI2SEL_I2SPLL +#define STM32_SAI2CLK STM32_PLLI2SDIVQ_CLKOUT +#elif STM32_SAI2SEL == STM32_SAI2SEL_CKIN +#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ +#else +#error "invalid source selected for SAI2 clock" +#endif + +/** + * @brief SDMMC1 frequency. + */ +#if (STM32_SDMMC1SEL == STM32_SDMMC1SEL_PLL48CLK) || defined(__DOXYGEN__) +#define STM32_SDMMC1CLK STM32_PLL48CLK +#elif STM32_SDMMC1SEL == STM32_SDMMC1SEL_SYSCLK +#define STM32_SDMMC1CLK STM32_SYSCLK +#else +#error "invalid source selected for SDMMC1 clock" +#endif + +/** + * @brief SDMMC2 frequency. + */ +#if (STM32_SDMMC2SEL == STM32_SDMMC2SEL_PLL48CLK) || defined(__DOXYGEN__) +#define STM32_SDMMC2CLK STM32_PLL48CLK +#elif STM32_SDMMC2SEL == STM32_SDMMC2SEL_SYSCLK +#define STM32_SDMMC2CLK STM32_SYSCLK +#else +#error "invalid source selected for SDMMC2 clock" +#endif + +/** + * @brief Clock of timers connected to APB1 + */ +#if (STM32_TIMPRE_ENABLE == FALSE) || defined(__DOXYGEN__) +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif +#else +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || \ + (STM32_PPRE1 == STM32_PPRE1_DIV2) || \ + (STM32_PPRE1 == STM32_PPRE1_DIV4) +#define STM32_TIMCLK1 (STM32_HCLK * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 4) +#endif +#endif + +/** + * @brief Clock of timers connected to APB2. + */ +#if (STM32_TIMPRE_ENABLE == FALSE) || defined(__DOXYGEN__) +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif +#else +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || \ + (STM32_PPRE2 == STM32_PPRE2_DIV2) || \ + (STM32_PPRE2 == STM32_PPRE2_DIV4) +#define STM32_TIMCLK2 (STM32_HCLK * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 4) +#endif +#endif + +/** + * @brief RNG clock point. + */ +#define STM32_RNGCLK STM32_PLL48CLK + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000000 + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS 0x00000001 + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS 0x00000002 + +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS 0x00000003 + +#elif STM32_HCLK <= STM32_4WS_THRESHOLD +#define STM32_FLASHBITS 0x00000004 + +#elif STM32_HCLK <= STM32_5WS_THRESHOLD +#define STM32_FLASHBITS 0x00000005 + +#elif STM32_HCLK <= STM32_6WS_THRESHOLD +#define STM32_FLASHBITS 0x00000006 + +#elif STM32_HCLK <= STM32_7WS_THRESHOLD +#define STM32_FLASHBITS 0x00000007 + +#elif STM32_HCLK <= STM32_8WS_THRESHOLD +#define STM32_FLASHBITS 0x00000008 + +#elif STM32_HCLK <= STM32_9WS_THRESHOLD +#define STM32_FLASHBITS 0x00000009 + +#else +#error "invalid frequency at specified VDD level" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32G0xx/hal_lld.c b/os/hal/ports/STM32/STM32G0xx/hal_lld.c index 960cad5c2e..dc68db2112 100644 --- a/os/hal/ports/STM32/STM32G0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.c @@ -1,253 +1,253 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32G0xx+/hal_lld.c - * @brief STM32G0xx+ HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32l4xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing RTC clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ - - /* Low speed output mode.*/ - RCC->BDCR |= STM32_LSCOSEL; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals.*/ - rccResetAHB(~0); - rccResetAPBR1(~RCC_APBRSTR1_PWRRST); - rccResetAPBR2(~0); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector settings.*/ - PWR->CR2 = STM32_PWR_CR2; -} - -/** - * @brief STM32G0xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enable.*/ -#if defined(HAL_USE_RTC) && defined(RCC_APBENR1_RTCAPBEN) - RCC->APBENR1 = RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN; -#else - RCC->APBENR1 = RCC_APBENR1_PWREN; -#endif - - /* Core voltage setup.*/ - PWR->CR1 = STM32_VOS; - while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ - ; /* stable. */ - -#if STM32_HSI16_ENABLED - /* HSI activation.*/ - RCC->CR |= RCC_CR_HSION | STM32_HSIDIV; - while ((RCC->CR & RCC_CR_HSIRDY) == 0) - ; /* Wait until HSI16 is stable. */ -#endif - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Wait until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Wait until LSI is stable. */ -#endif - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - while (rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable or times out. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLLM and PLLSRC are common to all PLLs.*/ - RCC->PLLCFGR = STM32_PLLR | STM32_PLLREN | - STM32_PLLQ | STM32_PLLQEN | - STM32_PLLP | STM32_PLLPEN | - STM32_PLLN | STM32_PLLM | - STM32_PLLSRC; -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLRDY) == 0) - ; -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_PPRE | STM32_HPRE; - - /* CCIPR register initialization, note, must take care of the _OFF - pseudo settings.*/ - RCC->CCIPR = STM32_ADCSEL | STM32_RNGDIV | STM32_RNGSEL | - STM32_TIM15SEL | STM32_TIM1SEL | STM32_LPTIM2SEL | - STM32_LPTIM1SEL | STM32_I2S1SEL | STM32_I2C1SEL | - STM32_CECSEL | STM32_USART2SEL | STM32_USART1SEL | - STM32_LPUART1SEL; - - /* Set flash WS's for SYSCLK source */ - FLASH->ACR = FLASH_ACR_DBG_SWEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | - STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured SYSCLK source if it is different from HSI16.*/ -#if STM32_SW != STM32_SW_HSISYS - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - /* Wait until SYSCLK is stable.*/ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3)) - ; -#endif - -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPBR2(RCC_APBENR2_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32G0xx+/hal_lld.c + * @brief STM32G0xx+ HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32l4xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing RTC clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int rusefiLseCounter = 0; + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + + /* Low speed output mode.*/ + RCC->BDCR |= STM32_LSCOSEL; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals.*/ + rccResetAHB(~0); + rccResetAPBR1(~RCC_APBRSTR1_PWRRST); + rccResetAPBR2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector settings.*/ + PWR->CR2 = STM32_PWR_CR2; +} + +/** + * @brief STM32G0xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ +#if defined(HAL_USE_RTC) && defined(RCC_APBENR1_RTCAPBEN) + RCC->APBENR1 = RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN; +#else + RCC->APBENR1 = RCC_APBENR1_PWREN; +#endif + + /* Core voltage setup.*/ + PWR->CR1 = STM32_VOS; + while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ + ; /* stable. */ + +#if STM32_HSI16_ENABLED + /* HSI activation.*/ + RCC->CR |= RCC_CR_HSION | STM32_HSIDIV; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Wait until HSI16 is stable. */ +#endif + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Wait until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Wait until LSI is stable. */ +#endif + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + +#if STM32_LSE_ENABLED + int rusefiLseCounter = 0; + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + while (rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Waits until LSE is stable or times out. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLLM and PLLSRC are common to all PLLs.*/ + RCC->PLLCFGR = STM32_PLLR | STM32_PLLREN | + STM32_PLLQ | STM32_PLLQEN | + STM32_PLLP | STM32_PLLPEN | + STM32_PLLN | STM32_PLLM | + STM32_PLLSRC; +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLRDY) == 0) + ; +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_PPRE | STM32_HPRE; + + /* CCIPR register initialization, note, must take care of the _OFF + pseudo settings.*/ + RCC->CCIPR = STM32_ADCSEL | STM32_RNGDIV | STM32_RNGSEL | + STM32_TIM15SEL | STM32_TIM1SEL | STM32_LPTIM2SEL | + STM32_LPTIM1SEL | STM32_I2S1SEL | STM32_I2C1SEL | + STM32_CECSEL | STM32_USART2SEL | STM32_USART1SEL | + STM32_LPUART1SEL; + + /* Set flash WS's for SYSCLK source */ + FLASH->ACR = FLASH_ACR_DBG_SWEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | + STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured SYSCLK source if it is different from HSI16.*/ +#if STM32_SW != STM32_SW_HSISYS + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + /* Wait until SYSCLK is stable.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3)) + ; +#endif + +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPBR2(RCC_APBENR2_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32G0xx/hal_lld.h b/os/hal/ports/STM32/STM32G0xx/hal_lld.h index f9db68820e..6e4dea4332 100644 --- a/os/hal/ports/STM32/STM32G0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.h @@ -1,1591 +1,1591 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32G0xx/hal_lld.h - * @brief STM32G0xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32G070xx. - * - STM32G071xx, STM32G081xx. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(STM32G070xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32G0 Entry-level Value Line" - -#elif defined(STM32G071xx) -#define PLATFORM_NAME "STM32G0 Entry-level" - -#elif defined(STM32G081xx) -#define PLATFORM_NAME "STM32G0 Entry-level with Crypto" - -#else -#error "STM32G0 device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32G0XX) || defined(__DOXYGEN__) -#define STM32G0XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSI16CLK 16000000U /**< 16MHz internal clock. */ -#define STM32_LSICLK 32000U /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR1 register bits definitions - * @{ - */ -#define STM32_VOS_MASK (3U << 9U) /**< Core voltage mask. */ -#define STM32_VOS_RANGE1 (1U << 9U) /**< Core voltage 1.2 Volts. */ -#define STM32_VOS_RANGE2 (2U << 9U) /**< Core voltage 1.0 Volts. */ -/** @} */ - -/** - * @name PWR_CR2 register bits definitions - * @{ - */ -#define STM32_PVDE_DISABLED (0U << 1U) /**< PVD enable bit off. */ -#define STM32_PVDE_ENABLED (1U << 1U) /**< PVD enable bit on. */ - -#define STM32_PVDFT_MASK (7U << 1U) /**< PVDFT bits mask. */ -#define STM32_PVDFT(n) ((n) << 1U) /**< PVDFT level. */ -#define STM32_PVDFT_LEV0 STM32_PVDFT(0U) /**< PVDFT level 0. */ -#define STM32_PVDFT_LEV1 STM32_PVDFT(1U) /**< PVDFT level 1. */ -#define STM32_PVDFT_LEV2 STM32_PVDFT(2U) /**< PVDFT level 2. */ -#define STM32_PVDFT_LEV3 STM32_PVDFT(3U) /**< PVDFT level 3. */ -#define STM32_PVDFT_LEV4 STM32_PVDFT(4U) /**< PVDFT level 4. */ -#define STM32_PVDFT_LEV5 STM32_PVDFT(5U) /**< PVDFT level 5. */ -#define STM32_PVDFT_LEV6 STM32_PVDFT(6U) /**< PVDFT level 6. */ -#define STM32_PVDFT_LEV7 STM32_PVDFT(7U) /**< PVDFT level 7. */ - -#define STM32_PVDRT_MASK (7U << 4U) /**< PVDRT bits mask. */ -#define STM32_PVDRT(n) ((n) << 4U) /**< PVDRT level. */ -#define STM32_PVDRT_LEV0 STM32_PVDRT(0U) /**< PVDRT level 0. */ -#define STM32_PVDRT_LEV1 STM32_PVDRT(1U) /**< PVDRT level 1. */ -#define STM32_PVDRT_LEV2 STM32_PVDRT(2U) /**< PVDRT level 2. */ -#define STM32_PVDRT_LEV3 STM32_PVDRT(3U) /**< PVDRT level 3. */ -#define STM32_PVDRT_LEV4 STM32_PVDRT(4U) /**< PVDRT level 4. */ -#define STM32_PVDRT_LEV5 STM32_PVDRT(5U) /**< PVDRT level 5. */ -#define STM32_PVDRT_LEV6 STM32_PVDRT(6U) /**< PVDRT level 6. */ -#define STM32_PVDRT_LEV7 STM32_PVDRT(7U) /**< PVDRT level 7. */ -/** @} */ - -/** - * @name RCC_CR register bits definitions - * @{ - */ -#define STM32_HSIDIV_MASK (7U << 11U) /**< HSIDIV field mask. */ -#define STM32_HSIDIV_FIELD(n) ((n) << 11U) /**< HSIDIV field value. */ -#define STM32_HSIDIV_1 STM32_HSIDIV_FIELD(0U) -#define STM32_HSIDIV_2 STM32_HSIDIV_FIELD(1U) -#define STM32_HSIDIV_4 STM32_HSIDIV_FIELD(2U) -#define STM32_HSIDIV_8 STM32_HSIDIV_FIELD(3U) -#define STM32_HSIDIV_16 STM32_HSIDIV_FIELD(4U) -#define STM32_HSIDIV_32 STM32_HSIDIV_FIELD(5U) -#define STM32_HSIDIV_64 STM32_HSIDIV_FIELD(6U) -#define STM32_HSIDIV_128 STM32_HSIDIV_FIELD(7U) -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (7U << 0U) /**< SW field mask. */ -#define STM32_SW_HSISYS (0U << 0U) /**< SYSCLK source is HSISYS. */ -#define STM32_SW_HSE (1U << 0U) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLLRCLK (2U << 0U) /**< SYSCLK source is PLL. */ -#define STM32_SW_LSI (3U << 0U) /**< SYSCLK source is LSI. */ -#define STM32_SW_LSE (4U << 0U) /**< SYSCLK source is LSE. */ - -#define STM32_HPRE_MASK (15U << 8U) /**< HPRE field mask. */ -#define STM32_HPRE_FIELD(n) ((n) << 8U) /**< HPRE field value. */ -#define STM32_HPRE_DIV1 STM32_HPRE_FIELD(0U) -#define STM32_HPRE_DIV2 STM32_HPRE_FIELD(8U) -#define STM32_HPRE_DIV4 STM32_HPRE_FIELD(9U) -#define STM32_HPRE_DIV8 STM32_HPRE_FIELD(10U) -#define STM32_HPRE_DIV16 STM32_HPRE_FIELD(11U) -#define STM32_HPRE_DIV64 STM32_HPRE_FIELD(12U) -#define STM32_HPRE_DIV128 STM32_HPRE_FIELD(13U) -#define STM32_HPRE_DIV256 STM32_HPRE_FIELD(14U) -#define STM32_HPRE_DIV512 STM32_HPRE_FIELD(15U) - -#define STM32_PPRE_MASK (7U << 12U) /**< PPRE field mask. */ -#define STM32_PPRE_FIELD(n) ((n) << 12U) /**< PPRE field value. */ -#define STM32_PPRE_DIV1 STM32_PPRE_FIELD(0U) -#define STM32_PPRE_DIV2 STM32_PPRE_FIELD(4U) -#define STM32_PPRE_DIV4 STM32_PPRE_FIELD(5U) -#define STM32_PPRE_DIV8 STM32_PPRE_FIELD(6U) -#define STM32_PPRE_DIV16 STM32_PPRE_FIELD(7U) - -#define STM32_MCOSEL_MASK (7U << 24U) /**< MCOSEL field mask. */ -#define STM32_MCOSEL_NOCLOCK (0U << 24U) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1U << 24U) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI16 (3U << 24U) /**< HSI16 clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4U << 24U) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLRCLK (5U << 24U) /**< PLLR clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6U << 24U) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7U << 24U) /**< LSE clock on MCO pin. */ - -#define STM32_MCOPRE_MASK (7U << 28U) /**< MCOPRE field mask. */ -#define STM32_MCOPRE_FIELD(n) ((n) << 28U)/**< MCOPRE field value */ -#define STM32_MCOPRE_DIV1 STM32_MCOPRE_FIELD(0U) -#define STM32_MCOPRE_DIV2 STM32_MCOPRE_FIELD(1U) -#define STM32_MCOPRE_DIV4 STM32_MCOPRE_FIELD(2U) -#define STM32_MCOPRE_DIV8 STM32_MCOPRE_FIELD(3U) -#define STM32_MCOPRE_DIV16 STM32_MCOPRE_FIELD(4U) -#define STM32_MCOPRE_DIV32 STM32_MCOPRE_FIELD(5U) -#define STM32_MCOPRE_DIV64 STM32_MCOPRE_FIELD(6U) -#define STM32_MCOPRE_DIV128 STM32_MCOPRE_FIELD(7U) -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CCIPR register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3U << 0U) /**< USART1SEL mask. */ -#define STM32_USART1SEL_PCLK (0U << 0U) /**< USART1 source is PCLK. */ -#define STM32_USART1SEL_SYSCLK (1U << 0U) /**< USART1 source is SYSCLK. */ -#define STM32_USART1SEL_HSI16 (2U << 0U) /**< USART1 source is HSI16. */ -#define STM32_USART1SEL_LSE (3U << 0U) /**< USART1 source is LSE. */ - -#define STM32_USART2SEL_MASK (3U << 2U) /**< USART2 mask. */ -#define STM32_USART2SEL_PCLK (0U << 2U) /**< USART2 source is PCLK. */ -#define STM32_USART2SEL_SYSCLK (1U << 2U) /**< USART2 source is SYSCLK. */ -#define STM32_USART2SEL_HSI16 (2U << 2U) /**< USART2 source is HSI16. */ -#define STM32_USART2SEL_LSE (3U << 2U) /**< USART2 source is LSE. */ - -#define STM32_CECSEL_MASK (1U << 6U) /**< CEC mask. */ -#define STM32_CECSEL_HSI16DIV (0U << 6U) /**< CEC source is HSI16/448. */ -#define STM32_CECSEL_LSE (1U << 6U) /**< CEC source is LSE. */ - -#define STM32_LPUART1SEL_MASK (3U << 10U) /**< LPUART1 mask. */ -#define STM32_LPUART1SEL_PCLK (0U << 10U) /**< LPUART1 source is PCLK. */ -#define STM32_LPUART1SEL_SYSCLK (1U << 10U) /**< LPUART1 source is SYSCLK. */ -#define STM32_LPUART1SEL_HSI16 (2U << 10U) /**< LPUART1 source is HSI16. */ -#define STM32_LPUART1SEL_LSE (3U << 10U) /**< LPUART1 source is LSE. */ - -#define STM32_I2C1SEL_MASK (3U << 12U) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK (0U << 12U) /**< I2C1 source is PCLK. */ -#define STM32_I2C1SEL_SYSCLK (1U << 12U) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI16 (2U << 12U) /**< I2C1 source is HSI16. */ - -#define STM32_I2S1SEL_MASK (3U << 14U) /**< I2S1SEL mask. */ -#define STM32_I2S1SEL_SYSCLK (0U << 14U) /**< I2S1 source is SYSCLK. */ -#define STM32_I2S1SEL_PLLPCLK (1U << 14U) /**< I2S1 source is PLLPCLK. */ -#define STM32_I2S1SEL_HSI16 (2U << 14U) /**< I2S1 source is HSI16. */ -#define STM32_I2S1SEL_CKIN (3U << 14U) /**< I2S1 source is CKIN. */ - -#define STM32_LPTIM1SEL_MASK (3U << 18U) /**< LPTIM1SEL mask. */ -#define STM32_LPTIM1SEL_PCLK (0U << 18U) /**< LPTIM1 source is PCLK. */ -#define STM32_LPTIM1SEL_LSI (1U << 18U) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_HSI16 (2U << 18U) /**< LPTIM1 source is HSI16. */ -#define STM32_LPTIM1SEL_LSE (3U << 18U) /**< LPTIM1 source is LSE. */ - -#define STM32_LPTIM2SEL_MASK (3U << 20U) /**< LPTIM2SEL mask. */ -#define STM32_LPTIM2SEL_PCLK (0U << 20U) /**< LPTIM2 source is PCLK. */ -#define STM32_LPTIM2SEL_LSI (1U << 20U) /**< LPTIM2 source is LSI. */ -#define STM32_LPTIM2SEL_HSI16 (2U << 20U) /**< LPTIM2 source is HSI16. */ -#define STM32_LPTIM2SEL_LSE (3U << 20U) /**< LPTIM2 source is LSE. */ - -#define STM32_TIM1SEL_MASK (1U << 22U) /**< TIM1SEL mask. */ -#define STM32_TIM1SEL_TIMPCLK (0U << 22U) /**< TIM1SEL source is TIMPCLK. */ -#define STM32_TIM1SEL_PLLQCLK (1U << 22U) /**< TIM1SEL source is PLLQCLK. */ - -#define STM32_TIM15SEL_MASK (1U << 24U) /**< TIM15SEL mask. */ -#define STM32_TIM15SEL_TIMPCLK (0U << 24U) /**< TIM15SEL source is TIMPCLK.*/ -#define STM32_TIM15SEL_PLLQCLK (1U << 24U) /**< TIM15SEL source is PLLQCLK.*/ - -#define STM32_RNGSEL_MASK (3U << 26U) /**< RNGSEL mask. */ -#define STM32_RNGSEL_NOCLOCK (0U << 26U) /**< RNG source is disabled. */ -#define STM32_RNGSEL_HSI16 (1U << 26U) /**< RNG source is HSI16. */ -#define STM32_RNGSEL_SYSCLK (2U << 26U) /**< RNG source is SYSCLK. */ -#define STM32_RNGSEL_PLLQCLK (3U << 26U) /**< RNG source is PLLQCLK. */ - -#define STM32_RNGDIV_MASK (3U << 28U) /**< RNGDIV field mask. */ -#define STM32_RNGDIV_FIELD(n) ((n) << 28U)/**< RNGDIV field value */ -#define STM32_RNGDIV_1 STM32_RNGDIV_FIELD(0U) -#define STM32_RNGDIV_2 STM32_RNGDIV_FIELD(1U) -#define STM32_RNGDIV_4 STM32_RNGDIV_FIELD(2U) -#define STM32_RNGDIV_8 STM32_RNGDIV_FIELD(3U) - -#define STM32_ADCSEL_MASK (3U << 30U) /**< ADCSEL mask. */ -#define STM32_ADCSEL_SYSCLK (0U << 30U) /**< ADC source is SYSCLK. */ -#define STM32_ADCSEL_PLLPCLK (1U << 30U) /**< ADC source is PLLPCLK. */ -#define STM32_ADCSEL_HSI16 (2U << 30U) /**< ADC source is HSI16. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3U << 8U) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0U << 8U) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1U << 8U) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2U << 8U) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3U << 8U) /**< RTC source is HSE divided. */ - -#define STM32_LSCOSEL_MASK (3U << 24U) /**< LSCO pin clock source. */ -#define STM32_LSCOSEL_NOCLOCK (0U << 24U) /**< No clock on LSCO pin. */ -#define STM32_LSCOSEL_LSI (1U << 24U) /**< LSI on LSCO pin. */ -#define STM32_LSCOSEL_LSE (3U << 24U) /**< LSE on LSCO pin. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_RANGE1 -#endif - -/** - * @brief PWR CR2 register initialization value. - */ -#if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__) -#define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | \ - STM32_PVDFT_LEV0 | \ - STM32_PVDE_DISABLED) -#endif - -/** - * @brief HSI16 divider value. - * @note The allowed values are 1, 2, 4, 8, 16, 32, 64, 128. - */ -#if !defined(STM32_HSIDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_HSIDIV_VALUE 1 -#endif - -/** - * @brief Enables or disables the HSI16 clock source. - */ -#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 64MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLLRCLK -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 64MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSI16 -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 1..8. - * @note The default value is calculated for a 64MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 2 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 8..86. - * @note The default value is calculated for a 64MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 16 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 2..32. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 2 -#endif - -/** - * @brief PLLQ divider value. - * @note The allowed values are 2..8. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 4 -#endif - -/** - * @brief PLLR divider value. - * @note The allowed values are 2..8. - * @note The default value is calculated for a 64MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLR_VALUE 2 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 64MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB prescaler value. - */ -#if !defined(STM32_PPRE) || defined(__DOXYGEN__) -#define STM32_PPRE STM32_PPRE_DIV1 -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief LSCO clock source. - */ -#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) -#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_SYSCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_SYSCLK -#endif - -/** - * @brief LPUART1 clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK -#endif - -/** - * @brief CEC clock source. - */ -#if !defined(STM32_CECSEL) || defined(__DOXYGEN__) -#define STM32_CECSEL STM32_CECSEL_HSI16DIV -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_PCLK -#endif - -/** - * @brief I2S1 clock source. - */ -#if !defined(STM32_I2S1SEL) || defined(__DOXYGEN__) -#define STM32_I2S1SEL STM32_I2S1SEL_SYSCLK -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK -#endif - -/** - * @brief LPTIM2 clock source. - */ -#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK -#endif - -/** - * @brief TIM1 clock source. - */ -#if !defined(STM32_TIM1SEL) || defined(__DOXYGEN__) -#define STM32_TIM1SEL STM32_TIM1SEL_TIMPCLK -#endif - -/** - * @brief TIM15 clock source. - */ -#if !defined(STM32_TIM15SEL) || defined(__DOXYGEN__) -#define STM32_TIM15SEL STM32_TIM15SEL_TIMPCLK -#endif - -/** - * @brief RNG clock source. - */ -#if !defined(STM32_RNGSEL) || defined(__DOXYGEN__) -#define STM32_RNGSEL STM32_RNGSEL_HSI16 -#endif - -/** - * @brief RNG divider value. - */ -#if !defined(STM32_RNGDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_RNGDIV_VALUE 1 -#endif - -/** - * @brief ADC clock source. - */ -#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) -#define STM32_ADCSEL STM32_ADCSEL_PLLPCLK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32G0xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G0xx_MCUCONF not defined" -#endif - -#if defined(STM32G070xx) && !defined(STM32G070_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G070_MCUCONF not defined" - -#elif defined(STM32G071xx) && !defined(STM32G071_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G071_MCUCONF not defined" - -#elif defined(STM32G081xx) && !defined(STM32G081_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G071_MCUCONF not defined" - -#endif - -/* - * Board files sanity checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif - -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) -/** - * @name System Limits - * @{ - */ -/** - * @brief Maximum SYSCLK clock frequency. - */ -#define STM32_SYSCLK_MAX 64000000 - -/** - * @brief Maximum HSE clock frequency at current voltage setting. - */ -#define STM32_HSECLK_MAX 48000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 48000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MIN 8000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 16000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 2660000 - -/** - * @brief Maximum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MAX 344000000 - -/** - * @brief Minimum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MIN 64000000 - -/** - * @brief Maximum PLL-P output clock frequency. - */ -#define STM32_PLLP_MAX 128000000 - -/** - * @brief Minimum PLL-P output clock frequency. - */ -#define STM32_PLLP_MIN 3090000 - -/** - * @brief Maximum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MAX 128000000 - -/** - * @brief Minimum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MIN 12000000 - -/** - * @brief Maximum PLL-R output clock frequency. - */ -#define STM32_PLLR_MAX 64000000 - -/** - * @brief Minimum PLL-R output clock frequency. - */ -#define STM32_PLLR_MIN 12000000 - -/** - * @brief Maximum APB clock frequency. - */ -#define STM32_PCLK_MAX 64000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 350000000 -/** @} */ - -/** - * @name Flash Wait states - * @{ - */ -#define STM32_0WS_THRESHOLD 24000000 -#define STM32_1WS_THRESHOLD 48000000 -#define STM32_2WS_THRESHOLD 64000000 -#define STM32_3WS_THRESHOLD 0 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 -/** @} */ - -#elif STM32_VOS == STM32_VOS_RANGE2 -#define STM32_SYSCLK_MAX 16000000 -#define STM32_HSECLK_MAX 16000000 -#define STM32_HSECLK_BYP_MAX 16000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 8000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_LSECLK_BYP_MIN 32768 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLIN_MIN 2660000 -#define STM32_PLLVCO_MAX 128000000 -#define STM32_PLLVCO_MIN 96000000 -#define STM32_PLLP_MAX 40000000 -#define STM32_PLLP_MIN 3090000 -#define STM32_PLLQ_MAX 32000000 -#define STM32_PLLQ_MIN 12000000 -#define STM32_PLLR_MAX 16000000 -#define STM32_PLLR_MIN 12000000 -#define STM32_PCLK_MAX 16000000 -#define STM32_ADCCLK_MAX 16000000 - -#define STM32_0WS_THRESHOLD 8000000 -#define STM32_1WS_THRESHOLD 16000000 -#define STM32_2WS_THRESHOLD 0 -#define STM32_3WS_THRESHOLD 0 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 - -#else -#error "invalid STM32_VOS value specified" -#endif - -/* - * HSI16 related checks. - */ -#if STM32_HSI16_ENABLED -#else /* !STM32_HSI16_ENABLED */ - -#if STM32_SW == STM32_SW_HSISYS -#error "HSI16 not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -/* NOTE: Missing checks on the HSI16 pre-muxes, it is also required for newer - L4 devices.*/ - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16)) -#error "HSI16 not enabled, required by STM32_MCOSEL" -#endif - -#if (STM32_USART1SEL == STM32_USART1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART1SEL" -#endif -#if (STM32_USART2SEL == STM32_USART2SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART2SEL" -#endif -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_LPUART1SEL" -#endif - -#if (STM32_CECSEL == STM32_CECSEL_HSI16DIV) -#error "HSI16 not enabled, required by STM32_CECSEL" -#endif - -#if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_I2C1SEL" -#endif -#if (STM32_I2S1SEL == STM32_I2S1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_I2S1SEL" -#endif - -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_LPTIM1SEL" -#endif -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) -#error "HSI16 not enabled, required by STM32_LPTIM2SEL" -#endif - -#if (STM32_RNGSEL == STM32_RNGSEL_HSI16) -#error "HSI16 not enabled, required by STM32_RNGSEL" -#endif - -#if (STM32_ADCSEL == STM32_ADCSEL_HSI16) -#error "HSI16 not enabled, required by STM32_ADCSEL" -#endif - -#endif /* !STM32_HSI16_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - - #if STM32_HSECLK == 0 - #error "HSE frequency not defined" - #else /* STM32_HSECLK != 0 */ - #if defined(STM32_HSE_BYPASS) - #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" - #endif - #else /* !defined(STM32_HSE_BYPASS) */ - #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" - #endif - #endif /* !defined(STM32_HSE_BYPASS) */ - #endif /* STM32_HSECLK != 0 */ - - #else /* !STM32_HSE_ENABLED */ - - #if STM32_SW == STM32_SW_HSE - #error "HSE not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) - #error "HSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV - #error "HSE not enabled, required by STM32_RTCSEL" - #endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - - #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) - #error "LSI not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSI - #error "LSI not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSI - #error "LSI not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - - #if (STM32_LSECLK == 0) - #error "LSE frequency not defined" - #endif - - #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) - #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" - #endif - -#else /* !STM32_LSE_ENABLED */ - - #if STM32_RTCSEL == STM32_RTCSEL_LSE - #error "LSE not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSE - #error "LSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSE - #error "LSE not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSE_ENABLED */ - -/** - * @brief STM32_HSIDIV field. - */ -#if (STM32_HSIDIV_VALUE == 1) || defined(__DOXYGEN__) -#define STM32_HSIDIV STM32_HSIDIV_1 -#elif STM32_HSIDIV_VALUE == 2 -#define STM32_HSIDIV STM32_HSIDIV_2 -#elif STM32_HSIDIV_VALUE == 4 -#define STM32_HSIDIV STM32_HSIDIV_4 -#elif STM32_HSIDIV_VALUE == 8 -#define STM32_HSIDIV STM32_HSIDIV_8 -#elif STM32_HSIDIV_VALUE == 16 -#define STM32_HSIDIV STM32_HSIDIV_16 -#elif STM32_HSIDIV_VALUE == 32 -#define STM32_HSIDIV STM32_HSIDIV_32 -#elif STM32_HSIDIV_VALUE == 64 -#define STM32_HSIDIV STM32_HSIDIV_64 -#elif STM32_HSIDIV_VALUE == 128 -#define STM32_HSIDIV STM32_HSIDIV_128 -#else -#error "invalid STM32_HSIDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 8)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 -#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK -#define STM32_PLLCLKIN 0 - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLL input frequency range check. - */ -#if (STM32_PLLCLKIN != 0) && \ - ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_SW == STM32_SW_PLLRCLK) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ - (STM32_TIM1SEL == STM32_TIM1SEL_PLLQCLK) || \ - (STM32_TIM15SEL == STM32_TIM15SEL_PLLQCLK) || \ - (STM32_RNGSEL == STM32_RNGSEL_PLLQCLK) || \ - (STM32_ADCSEL == STM32_ADCSEL_PLLPCLK) || \ - (STM32_I2S1SEL == STM32_I2S1SEL_PLLPCLK) || \ - defined(__DOXYGEN__) - -#if STM32_PLLCLKIN == 0 -#error "PLL activation required but no PLL clock selected" -#endif - -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 86)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 8) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLR field. - */ -#if ((STM32_PLLR_VALUE >= 2) && (STM32_PLLR_VALUE <= 8)) || \ - defined(__DOXYGEN__) -#define STM32_PLLR ((STM32_PLLR_VALUE - 1) << 29) -#else -#error "invalid STM32_PLLR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 8)) || \ - defined(__DOXYGEN__) -#define STM32_PLLQ ((STM32_PLLQ_VALUE - 1) << 25) -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if ((STM32_PLLP_VALUE >= 2) && (STM32_PLLP_VALUE <= 32)) || \ - defined(__DOXYGEN__) -#define STM32_PLLP ((STM32_PLLP_VALUE - 1) << 17) -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLREN field. - */ -#if (STM32_SW == STM32_SW_PLLRCLK) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ - defined(__DOXYGEN__) -#define STM32_PLLREN (1 << 28) -#else -#define STM32_PLLREN (0 << 28) -#endif - -/** - * @brief STM32_PLLQEN field. - */ -#if (STM32_TIM1SEL == STM32_TIM1SEL_PLLQCLK) || \ - (STM32_TIM15SEL == STM32_TIM15SEL_PLLQCLK) || \ - (STM32_RNGSEL == STM32_RNGSEL_PLLQCLK) || \ - defined(__DOXYGEN__) -#define STM32_PLLQEN (1 << 24) -#else -#define STM32_PLLQEN (0 << 24) -#endif - -/** - * @brief STM32_PLLPEN field. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_PLLPCLK) || \ - (STM32_I2S1SEL == STM32_I2S1SEL_PLLPCLK) || \ - defined(__DOXYGEN__) -#define STM32_PLLPEN (1 << 16) -#else -#define STM32_PLLPEN (0 << 16) -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL R output clock frequency. - */ -#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) - -/** - * @brief PLL Q output clock frequency. - */ -#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) - -/** - * @brief PLL P output clock frequency. - */ -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) - -/* - * PLL-R output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/* - * PLL-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLL-P output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/** - * @brief HSISYS clock frequency. - */ -#define STM32_HSISYSCLK (STM32_HSI16CLK / STM32_HSIDIV_VALUE) - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_HSISYSCLK - -#elif (STM32_SW == STM32_SW_HSISYS) -#define STM32_SYSCLK STM32_HSISYSCLK - -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK - -#elif (STM32_SW == STM32_SW_PLLRCLK) -#define STM32_SYSCLK STM32_PLL_R_CLKOUT - -#elif (STM32_SW == STM32_SW_LSI) -#define STM32_SYSCLK STM32_LSICLK - -#elif (STM32_SW == STM32_SW_LSE) -#define STM32_SYSCLK STM32_LSECLK - -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) - -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) - -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) - -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) - -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) - -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) - -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) - -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) - -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) - -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB frequency. - */ -#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK (STM32_HCLK / 1) - -#elif STM32_PPRE == STM32_PPRE_DIV2 -#define STM32_PCLK (STM32_HCLK / 2) - -#elif STM32_PPRE == STM32_PPRE_DIV4 -#define STM32_PCLK (STM32_HCLK / 4) - -#elif STM32_PPRE == STM32_PPRE_DIV8 -#define STM32_PCLK (STM32_HCLK / 8) - -#elif STM32_PPRE == STM32_PPRE_DIV16 -#define STM32_PCLK (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE value specified" -#endif - -/* - * Compatibility definitions. - */ -#define STM32_PCLK1 STM32_PCLK -#define STM32_PCLK2 STM32_PCLK - -/* - * APB frequency check. - */ -#if STM32_PCLK > STM32_PCLK_MAX -#error "STM32_PCLK exceeding maximum frequency (STM32_PCLK_MAX)" -#endif - -/** - * @brief MCO divider clock frequency. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 - -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK -#define STM32_MCODIVCLK STM32_SYSCLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 -#define STM32_MCODIVCLK STM32_HSI16CLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_PLLRCLK -#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT - -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK - -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock frequency. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV32 -#define STM32_MCOCLK (STM32_MCODIVCLK / 32) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV64 -#define STM32_MCOCLK (STM32_MCODIVCLK / 64) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV128 -#define STM32_MCOCLK (STM32_MCODIVCLK / 128) - -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief RTC clock frequency. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 clock frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_PCLK) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 -#define STM32_USART1CLK STM32_HSI16CLK -#elif STM32_USART1SEL == STM32_USART1SEL_LSE -#define STM32_USART1CLK STM32_LSECLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 clock frequency. - */ -#if (STM32_USART2SEL == STM32_USART2SEL_PCLK) || defined(__DOXYGEN__) -#define STM32_USART2CLK STM32_PCLK -#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK -#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 -#define STM32_USART2CLK STM32_HSI16CLK -#elif STM32_USART2SEL == STM32_USART2SEL_LSE -#define STM32_USART2CLK STM32_LSECLK -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 frequency. - */ -#define STM32_USART3CLK STM32_PCLK - -/** - * @brief UART4 frequency. - */ -#define STM32_UART4CLK STM32_PCLK - -/** - * @brief UART5 frequency. - */ -#define STM32_UART5CLK STM32_PCLK - -/** - * @brief LPUART1 clock frequency. - */ -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK) || defined(__DOXYGEN__) -#define STM32_LPUART1CLK STM32_PCLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK -#define STM32_LPUART1CLK STM32_SYSCLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 -#define STM32_LPUART1CLK STM32_HSI16CLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE -#define STM32_LPUART1CLK STM32_LSECLK -#else -#error "invalid source selected for LPUART1 clock" -#endif - -/** - * @brief CEC clock frequency. - */ -#if (STM32_CECSEL == STM32_CECSEL_HSI16DIV) || defined(__DOXYGEN__) -#define STM32_CECCLK (STM32_HSI16CLK / 448) -#elif STM32_CECSEL == STM32_CECSEL_LSE -#define STM32_CECCLK STM32_LSECLK -#else -#error "invalid source selected for CEC clock" -#endif - -/** - * @brief I2C1 clock frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_PCLK -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 -#define STM32_I2C1CLK STM32_HSI16CLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2S1 clock frequency. - */ -#if (STM32_I2S1SEL == STM32_I2S1SEL_SYSCLK) || defined(__DOXYGEN__) -#define STM32_I2S1CLK STM32_SYSCLK -#elif STM32_I2S1SEL == STM32_I2S1SEL_PLLPCLK -#define STM32_I2S1CLK STM32_PLL_P_CLKOUT -#elif STM32_I2S1SEL == STM32_I2S1SEL_HSI16 -#define STM32_I2S1CLK STM32_HSI16CLK -#elif STM32_I2S1SEL == STM32_I2S1SEL_CKIN -#define STM32_I2S1CLK 0 /* Unknown, would require a board value */ -#else -#error "invalid source selected for I2S1 clock" -#endif - -/** - * @brief LPTIM1 clock frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK) || defined(__DOXYGEN__) -#define STM32_LPTIM1CLK STM32_PCLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI -#define STM32_LPTIM1CLK STM32_LSICLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 -#define STM32_LPTIM1CLK STM32_HSI16CLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE -#define STM32_LPTIM1CLK STM32_LSECLK -#else -#error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief LPTIM2 clock frequency. - */ -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK) || defined(__DOXYGEN__) -#define STM32_LPTIM2CLK STM32_PCLK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI -#define STM32_LPTIM2CLK STM32_LSICLK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 -#define STM32_LPTIM2CLK STM32_HSI16CLK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE -#define STM32_LPTIM2CLK STM32_LSECLK -#else -#error "invalid source selected for LPTIM2 clock" -#endif - -/** - * @brief RNGDIV field. - */ -#if (STM32_RNGDIV_VALUE == 1) || defined(__DOXYGEN__) -#define STM32_RNGDIV (0U << 28U) -#elif STM32_RNGDIV_VALUE == 2 -#define STM32_RNGDIV (1U << 28U) -#elif STM32_RNGDIV_VALUE == 4 -#define STM32_RNGDIV (2U << 28U) -#elif STM32_RNGDIV_VALUE == 8 -#define STM32_RNGDIV (3U << 28U) -#else -#error "invalid STM32_RNGDIV_VALUE value specified" -#endif - -/** - * @brief RNG clock frequency. - */ -#if (STM32_RNGSEL == STM32_RNGSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RNGCLK 0 -#elif STM32_RNGSEL == STM32_RNGSEL_HSI16 -#define STM32_RNGCLK (STM32_HSI16CLK / STM32_RNGDIV_VALUE) -#elif STM32_RNGSEL == STM32_RNGSEL_SYSCLK -#define STM32_RNGCLK (STM32_SYSCLK / STM32_RNGDIV_VALUE) -#elif STM32_RNGSEL == STM32_RNGSEL_PLLQCLK -#define STM32_RNGCLK (STM32_PLL_Q_CLKOUT / STM32_RNGDIV_VALUE) -#else -#error "invalid source selected for RNG clock" -#endif - -/** - * @brief ADC clock frequency. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_SYSCLK) || defined(__DOXYGEN__) -#define STM32_ADCCLK STM32_SYSCLK -#elif STM32_ADCSEL == STM32_ADCSEL_PLLPCLK -#define STM32_ADCCLK STM32_PLL_P_CLKOUT -#elif STM32_ADCSEL == STM32_ADCSEL_HSI16 -#define STM32_ADCCLK STM32_HSI16CLK -#else -#error "invalid source selected for ADC clock" -#endif - -/** - * @brief TIMPCLK clock frequency. - */ -#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMPCLK (STM32_PCLK * 1) -#else -#define STM32_TIMPCLK (STM32_PCLK * 2) -#endif - -/** - * @brief TIM1 clock frequency. - */ -#if (STM32_TIM1SEL == STM32_TIM1SEL_TIMPCLK) || defined(__DOXYGEN__) -#define STM32_TIM1CLK STM32_TIMPCLK -#elif STM32_TIM1SEL == STM32_TIM1SEL_PLLQCLK -#define STM32_TIM1CLK STM32_PLL_Q_CLKOUT -#else -#error "invalid source selected for TIM1 clock" -#endif - -/** - * @brief TIM15 clock frequency. - */ -#if (STM32_TIM15SEL == STM32_TIM15SEL_TIMPCLK) || defined(__DOXYGEN__) -#define STM32_TIM15CLK STM32_TIMPCLK -#elif STM32_TIM15SEL == STM32_TIM15SEL_PLLQCLK -#define STM32_TIM15CLK STM32_PLL_Q_CLKOUT -#else -#error "invalid source selected for TIM15 clock" -#endif - -/** - * @brief Clock of timers connected to APB1. - */ -#define STM32_TIMCLK1 STM32_TIMPCLK - -/** - * @brief Clock of timers connected to APB2. - */ -#define STM32_TIMCLK2 STM32_TIMPCLK - -#if STM32_HAS_TIM1617_ERRATA -/* TIM16 and TIM17 require special handling and checks on some devices, see - the errata: "TIM16 and TIM17 are unduly clocked by SYSCLK".*/ -#define STM32_TIM16CLK hal_lld_get_clock_point(CLK_SYSCLK) -#define STM32_TIM17CLK hal_lld_get_clock_point(CLK_SYSCLK) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0 - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_0 - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_1 - -#else -#define STM32_FLASHBITS (FLASH_ACR_LATENCY_1 | FLASH_ACR_LATENCY_0) -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32G0xx/hal_lld.h + * @brief STM32G0xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32G070xx. + * - STM32G071xx, STM32G081xx. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(STM32G070xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32G0 Entry-level Value Line" + +#elif defined(STM32G071xx) +#define PLATFORM_NAME "STM32G0 Entry-level" + +#elif defined(STM32G081xx) +#define PLATFORM_NAME "STM32G0 Entry-level with Crypto" + +#else +#error "STM32G0 device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32G0XX) || defined(__DOXYGEN__) +#define STM32G0XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSI16CLK 16000000U /**< 16MHz internal clock. */ +#define STM32_LSICLK 32000U /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR1 register bits definitions + * @{ + */ +#define STM32_VOS_MASK (3U << 9U) /**< Core voltage mask. */ +#define STM32_VOS_RANGE1 (1U << 9U) /**< Core voltage 1.2 Volts. */ +#define STM32_VOS_RANGE2 (2U << 9U) /**< Core voltage 1.0 Volts. */ +/** @} */ + +/** + * @name PWR_CR2 register bits definitions + * @{ + */ +#define STM32_PVDE_DISABLED (0U << 1U) /**< PVD enable bit off. */ +#define STM32_PVDE_ENABLED (1U << 1U) /**< PVD enable bit on. */ + +#define STM32_PVDFT_MASK (7U << 1U) /**< PVDFT bits mask. */ +#define STM32_PVDFT(n) ((n) << 1U) /**< PVDFT level. */ +#define STM32_PVDFT_LEV0 STM32_PVDFT(0U) /**< PVDFT level 0. */ +#define STM32_PVDFT_LEV1 STM32_PVDFT(1U) /**< PVDFT level 1. */ +#define STM32_PVDFT_LEV2 STM32_PVDFT(2U) /**< PVDFT level 2. */ +#define STM32_PVDFT_LEV3 STM32_PVDFT(3U) /**< PVDFT level 3. */ +#define STM32_PVDFT_LEV4 STM32_PVDFT(4U) /**< PVDFT level 4. */ +#define STM32_PVDFT_LEV5 STM32_PVDFT(5U) /**< PVDFT level 5. */ +#define STM32_PVDFT_LEV6 STM32_PVDFT(6U) /**< PVDFT level 6. */ +#define STM32_PVDFT_LEV7 STM32_PVDFT(7U) /**< PVDFT level 7. */ + +#define STM32_PVDRT_MASK (7U << 4U) /**< PVDRT bits mask. */ +#define STM32_PVDRT(n) ((n) << 4U) /**< PVDRT level. */ +#define STM32_PVDRT_LEV0 STM32_PVDRT(0U) /**< PVDRT level 0. */ +#define STM32_PVDRT_LEV1 STM32_PVDRT(1U) /**< PVDRT level 1. */ +#define STM32_PVDRT_LEV2 STM32_PVDRT(2U) /**< PVDRT level 2. */ +#define STM32_PVDRT_LEV3 STM32_PVDRT(3U) /**< PVDRT level 3. */ +#define STM32_PVDRT_LEV4 STM32_PVDRT(4U) /**< PVDRT level 4. */ +#define STM32_PVDRT_LEV5 STM32_PVDRT(5U) /**< PVDRT level 5. */ +#define STM32_PVDRT_LEV6 STM32_PVDRT(6U) /**< PVDRT level 6. */ +#define STM32_PVDRT_LEV7 STM32_PVDRT(7U) /**< PVDRT level 7. */ +/** @} */ + +/** + * @name RCC_CR register bits definitions + * @{ + */ +#define STM32_HSIDIV_MASK (7U << 11U) /**< HSIDIV field mask. */ +#define STM32_HSIDIV_FIELD(n) ((n) << 11U) /**< HSIDIV field value. */ +#define STM32_HSIDIV_1 STM32_HSIDIV_FIELD(0U) +#define STM32_HSIDIV_2 STM32_HSIDIV_FIELD(1U) +#define STM32_HSIDIV_4 STM32_HSIDIV_FIELD(2U) +#define STM32_HSIDIV_8 STM32_HSIDIV_FIELD(3U) +#define STM32_HSIDIV_16 STM32_HSIDIV_FIELD(4U) +#define STM32_HSIDIV_32 STM32_HSIDIV_FIELD(5U) +#define STM32_HSIDIV_64 STM32_HSIDIV_FIELD(6U) +#define STM32_HSIDIV_128 STM32_HSIDIV_FIELD(7U) +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (7U << 0U) /**< SW field mask. */ +#define STM32_SW_HSISYS (0U << 0U) /**< SYSCLK source is HSISYS. */ +#define STM32_SW_HSE (1U << 0U) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLLRCLK (2U << 0U) /**< SYSCLK source is PLL. */ +#define STM32_SW_LSI (3U << 0U) /**< SYSCLK source is LSI. */ +#define STM32_SW_LSE (4U << 0U) /**< SYSCLK source is LSE. */ + +#define STM32_HPRE_MASK (15U << 8U) /**< HPRE field mask. */ +#define STM32_HPRE_FIELD(n) ((n) << 8U) /**< HPRE field value. */ +#define STM32_HPRE_DIV1 STM32_HPRE_FIELD(0U) +#define STM32_HPRE_DIV2 STM32_HPRE_FIELD(8U) +#define STM32_HPRE_DIV4 STM32_HPRE_FIELD(9U) +#define STM32_HPRE_DIV8 STM32_HPRE_FIELD(10U) +#define STM32_HPRE_DIV16 STM32_HPRE_FIELD(11U) +#define STM32_HPRE_DIV64 STM32_HPRE_FIELD(12U) +#define STM32_HPRE_DIV128 STM32_HPRE_FIELD(13U) +#define STM32_HPRE_DIV256 STM32_HPRE_FIELD(14U) +#define STM32_HPRE_DIV512 STM32_HPRE_FIELD(15U) + +#define STM32_PPRE_MASK (7U << 12U) /**< PPRE field mask. */ +#define STM32_PPRE_FIELD(n) ((n) << 12U) /**< PPRE field value. */ +#define STM32_PPRE_DIV1 STM32_PPRE_FIELD(0U) +#define STM32_PPRE_DIV2 STM32_PPRE_FIELD(4U) +#define STM32_PPRE_DIV4 STM32_PPRE_FIELD(5U) +#define STM32_PPRE_DIV8 STM32_PPRE_FIELD(6U) +#define STM32_PPRE_DIV16 STM32_PPRE_FIELD(7U) + +#define STM32_MCOSEL_MASK (7U << 24U) /**< MCOSEL field mask. */ +#define STM32_MCOSEL_NOCLOCK (0U << 24U) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1U << 24U) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI16 (3U << 24U) /**< HSI16 clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4U << 24U) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLRCLK (5U << 24U) /**< PLLR clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6U << 24U) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7U << 24U) /**< LSE clock on MCO pin. */ + +#define STM32_MCOPRE_MASK (7U << 28U) /**< MCOPRE field mask. */ +#define STM32_MCOPRE_FIELD(n) ((n) << 28U)/**< MCOPRE field value */ +#define STM32_MCOPRE_DIV1 STM32_MCOPRE_FIELD(0U) +#define STM32_MCOPRE_DIV2 STM32_MCOPRE_FIELD(1U) +#define STM32_MCOPRE_DIV4 STM32_MCOPRE_FIELD(2U) +#define STM32_MCOPRE_DIV8 STM32_MCOPRE_FIELD(3U) +#define STM32_MCOPRE_DIV16 STM32_MCOPRE_FIELD(4U) +#define STM32_MCOPRE_DIV32 STM32_MCOPRE_FIELD(5U) +#define STM32_MCOPRE_DIV64 STM32_MCOPRE_FIELD(6U) +#define STM32_MCOPRE_DIV128 STM32_MCOPRE_FIELD(7U) +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CCIPR register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3U << 0U) /**< USART1SEL mask. */ +#define STM32_USART1SEL_PCLK (0U << 0U) /**< USART1 source is PCLK. */ +#define STM32_USART1SEL_SYSCLK (1U << 0U) /**< USART1 source is SYSCLK. */ +#define STM32_USART1SEL_HSI16 (2U << 0U) /**< USART1 source is HSI16. */ +#define STM32_USART1SEL_LSE (3U << 0U) /**< USART1 source is LSE. */ + +#define STM32_USART2SEL_MASK (3U << 2U) /**< USART2 mask. */ +#define STM32_USART2SEL_PCLK (0U << 2U) /**< USART2 source is PCLK. */ +#define STM32_USART2SEL_SYSCLK (1U << 2U) /**< USART2 source is SYSCLK. */ +#define STM32_USART2SEL_HSI16 (2U << 2U) /**< USART2 source is HSI16. */ +#define STM32_USART2SEL_LSE (3U << 2U) /**< USART2 source is LSE. */ + +#define STM32_CECSEL_MASK (1U << 6U) /**< CEC mask. */ +#define STM32_CECSEL_HSI16DIV (0U << 6U) /**< CEC source is HSI16/448. */ +#define STM32_CECSEL_LSE (1U << 6U) /**< CEC source is LSE. */ + +#define STM32_LPUART1SEL_MASK (3U << 10U) /**< LPUART1 mask. */ +#define STM32_LPUART1SEL_PCLK (0U << 10U) /**< LPUART1 source is PCLK. */ +#define STM32_LPUART1SEL_SYSCLK (1U << 10U) /**< LPUART1 source is SYSCLK. */ +#define STM32_LPUART1SEL_HSI16 (2U << 10U) /**< LPUART1 source is HSI16. */ +#define STM32_LPUART1SEL_LSE (3U << 10U) /**< LPUART1 source is LSE. */ + +#define STM32_I2C1SEL_MASK (3U << 12U) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK (0U << 12U) /**< I2C1 source is PCLK. */ +#define STM32_I2C1SEL_SYSCLK (1U << 12U) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI16 (2U << 12U) /**< I2C1 source is HSI16. */ + +#define STM32_I2S1SEL_MASK (3U << 14U) /**< I2S1SEL mask. */ +#define STM32_I2S1SEL_SYSCLK (0U << 14U) /**< I2S1 source is SYSCLK. */ +#define STM32_I2S1SEL_PLLPCLK (1U << 14U) /**< I2S1 source is PLLPCLK. */ +#define STM32_I2S1SEL_HSI16 (2U << 14U) /**< I2S1 source is HSI16. */ +#define STM32_I2S1SEL_CKIN (3U << 14U) /**< I2S1 source is CKIN. */ + +#define STM32_LPTIM1SEL_MASK (3U << 18U) /**< LPTIM1SEL mask. */ +#define STM32_LPTIM1SEL_PCLK (0U << 18U) /**< LPTIM1 source is PCLK. */ +#define STM32_LPTIM1SEL_LSI (1U << 18U) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_HSI16 (2U << 18U) /**< LPTIM1 source is HSI16. */ +#define STM32_LPTIM1SEL_LSE (3U << 18U) /**< LPTIM1 source is LSE. */ + +#define STM32_LPTIM2SEL_MASK (3U << 20U) /**< LPTIM2SEL mask. */ +#define STM32_LPTIM2SEL_PCLK (0U << 20U) /**< LPTIM2 source is PCLK. */ +#define STM32_LPTIM2SEL_LSI (1U << 20U) /**< LPTIM2 source is LSI. */ +#define STM32_LPTIM2SEL_HSI16 (2U << 20U) /**< LPTIM2 source is HSI16. */ +#define STM32_LPTIM2SEL_LSE (3U << 20U) /**< LPTIM2 source is LSE. */ + +#define STM32_TIM1SEL_MASK (1U << 22U) /**< TIM1SEL mask. */ +#define STM32_TIM1SEL_TIMPCLK (0U << 22U) /**< TIM1SEL source is TIMPCLK. */ +#define STM32_TIM1SEL_PLLQCLK (1U << 22U) /**< TIM1SEL source is PLLQCLK. */ + +#define STM32_TIM15SEL_MASK (1U << 24U) /**< TIM15SEL mask. */ +#define STM32_TIM15SEL_TIMPCLK (0U << 24U) /**< TIM15SEL source is TIMPCLK.*/ +#define STM32_TIM15SEL_PLLQCLK (1U << 24U) /**< TIM15SEL source is PLLQCLK.*/ + +#define STM32_RNGSEL_MASK (3U << 26U) /**< RNGSEL mask. */ +#define STM32_RNGSEL_NOCLOCK (0U << 26U) /**< RNG source is disabled. */ +#define STM32_RNGSEL_HSI16 (1U << 26U) /**< RNG source is HSI16. */ +#define STM32_RNGSEL_SYSCLK (2U << 26U) /**< RNG source is SYSCLK. */ +#define STM32_RNGSEL_PLLQCLK (3U << 26U) /**< RNG source is PLLQCLK. */ + +#define STM32_RNGDIV_MASK (3U << 28U) /**< RNGDIV field mask. */ +#define STM32_RNGDIV_FIELD(n) ((n) << 28U)/**< RNGDIV field value */ +#define STM32_RNGDIV_1 STM32_RNGDIV_FIELD(0U) +#define STM32_RNGDIV_2 STM32_RNGDIV_FIELD(1U) +#define STM32_RNGDIV_4 STM32_RNGDIV_FIELD(2U) +#define STM32_RNGDIV_8 STM32_RNGDIV_FIELD(3U) + +#define STM32_ADCSEL_MASK (3U << 30U) /**< ADCSEL mask. */ +#define STM32_ADCSEL_SYSCLK (0U << 30U) /**< ADC source is SYSCLK. */ +#define STM32_ADCSEL_PLLPCLK (1U << 30U) /**< ADC source is PLLPCLK. */ +#define STM32_ADCSEL_HSI16 (2U << 30U) /**< ADC source is HSI16. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3U << 8U) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0U << 8U) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1U << 8U) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2U << 8U) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3U << 8U) /**< RTC source is HSE divided. */ + +#define STM32_LSCOSEL_MASK (3U << 24U) /**< LSCO pin clock source. */ +#define STM32_LSCOSEL_NOCLOCK (0U << 24U) /**< No clock on LSCO pin. */ +#define STM32_LSCOSEL_LSI (1U << 24U) /**< LSI on LSCO pin. */ +#define STM32_LSCOSEL_LSE (3U << 24U) /**< LSE on LSCO pin. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_RANGE1 +#endif + +/** + * @brief PWR CR2 register initialization value. + */ +#if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__) +#define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | \ + STM32_PVDFT_LEV0 | \ + STM32_PVDE_DISABLED) +#endif + +/** + * @brief HSI16 divider value. + * @note The allowed values are 1, 2, 4, 8, 16, 32, 64, 128. + */ +#if !defined(STM32_HSIDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_HSIDIV_VALUE 1 +#endif + +/** + * @brief Enables or disables the HSI16 clock source. + */ +#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 64MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLLRCLK +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 64MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSI16 +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 1..8. + * @note The default value is calculated for a 64MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 2 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 8..86. + * @note The default value is calculated for a 64MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 16 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 2..32. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 2 +#endif + +/** + * @brief PLLQ divider value. + * @note The allowed values are 2..8. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 4 +#endif + +/** + * @brief PLLR divider value. + * @note The allowed values are 2..8. + * @note The default value is calculated for a 64MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLR_VALUE 2 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 64MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB prescaler value. + */ +#if !defined(STM32_PPRE) || defined(__DOXYGEN__) +#define STM32_PPRE STM32_PPRE_DIV1 +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief LSCO clock source. + */ +#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#endif + +/** + * @brief LPUART1 clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#endif + +/** + * @brief CEC clock source. + */ +#if !defined(STM32_CECSEL) || defined(__DOXYGEN__) +#define STM32_CECSEL STM32_CECSEL_HSI16DIV +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_PCLK +#endif + +/** + * @brief I2S1 clock source. + */ +#if !defined(STM32_I2S1SEL) || defined(__DOXYGEN__) +#define STM32_I2S1SEL STM32_I2S1SEL_SYSCLK +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK +#endif + +/** + * @brief LPTIM2 clock source. + */ +#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK +#endif + +/** + * @brief TIM1 clock source. + */ +#if !defined(STM32_TIM1SEL) || defined(__DOXYGEN__) +#define STM32_TIM1SEL STM32_TIM1SEL_TIMPCLK +#endif + +/** + * @brief TIM15 clock source. + */ +#if !defined(STM32_TIM15SEL) || defined(__DOXYGEN__) +#define STM32_TIM15SEL STM32_TIM15SEL_TIMPCLK +#endif + +/** + * @brief RNG clock source. + */ +#if !defined(STM32_RNGSEL) || defined(__DOXYGEN__) +#define STM32_RNGSEL STM32_RNGSEL_HSI16 +#endif + +/** + * @brief RNG divider value. + */ +#if !defined(STM32_RNGDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_RNGDIV_VALUE 1 +#endif + +/** + * @brief ADC clock source. + */ +#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) +#define STM32_ADCSEL STM32_ADCSEL_PLLPCLK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32G0xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G0xx_MCUCONF not defined" +#endif + +#if defined(STM32G070xx) && !defined(STM32G070_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G070_MCUCONF not defined" + +#elif defined(STM32G071xx) && !defined(STM32G071_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G071_MCUCONF not defined" + +#elif defined(STM32G081xx) && !defined(STM32G081_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G071_MCUCONF not defined" + +#endif + +/* + * Board files sanity checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif + +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) +/** + * @name System Limits + * @{ + */ +/** + * @brief Maximum SYSCLK clock frequency. + */ +#define STM32_SYSCLK_MAX 64000000 + +/** + * @brief Maximum HSE clock frequency at current voltage setting. + */ +#define STM32_HSECLK_MAX 48000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 48000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 8000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 2660000 + +/** + * @brief Maximum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MAX 344000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 64000000 + +/** + * @brief Maximum PLL-P output clock frequency. + */ +#define STM32_PLLP_MAX 128000000 + +/** + * @brief Minimum PLL-P output clock frequency. + */ +#define STM32_PLLP_MIN 3090000 + +/** + * @brief Maximum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MAX 128000000 + +/** + * @brief Minimum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MIN 12000000 + +/** + * @brief Maximum PLL-R output clock frequency. + */ +#define STM32_PLLR_MAX 64000000 + +/** + * @brief Minimum PLL-R output clock frequency. + */ +#define STM32_PLLR_MIN 12000000 + +/** + * @brief Maximum APB clock frequency. + */ +#define STM32_PCLK_MAX 64000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 350000000 +/** @} */ + +/** + * @name Flash Wait states + * @{ + */ +#define STM32_0WS_THRESHOLD 24000000 +#define STM32_1WS_THRESHOLD 48000000 +#define STM32_2WS_THRESHOLD 64000000 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 +/** @} */ + +#elif STM32_VOS == STM32_VOS_RANGE2 +#define STM32_SYSCLK_MAX 16000000 +#define STM32_HSECLK_MAX 16000000 +#define STM32_HSECLK_BYP_MAX 16000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 8000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_LSECLK_BYP_MIN 32768 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLIN_MIN 2660000 +#define STM32_PLLVCO_MAX 128000000 +#define STM32_PLLVCO_MIN 96000000 +#define STM32_PLLP_MAX 40000000 +#define STM32_PLLP_MIN 3090000 +#define STM32_PLLQ_MAX 32000000 +#define STM32_PLLQ_MIN 12000000 +#define STM32_PLLR_MAX 16000000 +#define STM32_PLLR_MIN 12000000 +#define STM32_PCLK_MAX 16000000 +#define STM32_ADCCLK_MAX 16000000 + +#define STM32_0WS_THRESHOLD 8000000 +#define STM32_1WS_THRESHOLD 16000000 +#define STM32_2WS_THRESHOLD 0 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 + +#else +#error "invalid STM32_VOS value specified" +#endif + +/* + * HSI16 related checks. + */ +#if STM32_HSI16_ENABLED +#else /* !STM32_HSI16_ENABLED */ + +#if STM32_SW == STM32_SW_HSISYS +#error "HSI16 not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +/* NOTE: Missing checks on the HSI16 pre-muxes, it is also required for newer + L4 devices.*/ + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16)) +#error "HSI16 not enabled, required by STM32_MCOSEL" +#endif + +#if (STM32_USART1SEL == STM32_USART1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART1SEL" +#endif +#if (STM32_USART2SEL == STM32_USART2SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART2SEL" +#endif +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_LPUART1SEL" +#endif + +#if (STM32_CECSEL == STM32_CECSEL_HSI16DIV) +#error "HSI16 not enabled, required by STM32_CECSEL" +#endif + +#if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_I2C1SEL" +#endif +#if (STM32_I2S1SEL == STM32_I2S1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_I2S1SEL" +#endif + +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_LPTIM1SEL" +#endif +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) +#error "HSI16 not enabled, required by STM32_LPTIM2SEL" +#endif + +#if (STM32_RNGSEL == STM32_RNGSEL_HSI16) +#error "HSI16 not enabled, required by STM32_RNGSEL" +#endif + +#if (STM32_ADCSEL == STM32_ADCSEL_HSI16) +#error "HSI16 not enabled, required by STM32_ADCSEL" +#endif + +#endif /* !STM32_HSI16_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + + #if STM32_HSECLK == 0 + #error "HSE frequency not defined" + #else /* STM32_HSECLK != 0 */ + #if defined(STM32_HSE_BYPASS) + #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" + #endif + #else /* !defined(STM32_HSE_BYPASS) */ + #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" + #endif + #endif /* !defined(STM32_HSE_BYPASS) */ + #endif /* STM32_HSECLK != 0 */ + + #else /* !STM32_HSE_ENABLED */ + + #if STM32_SW == STM32_SW_HSE + #error "HSE not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) + #error "HSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV + #error "HSE not enabled, required by STM32_RTCSEL" + #endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + + #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) + #error "LSI not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSI + #error "LSI not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSI + #error "LSI not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + + #if (STM32_LSECLK == 0) + #error "LSE frequency not defined" + #endif + + #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) + #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" + #endif + +#else /* !STM32_LSE_ENABLED */ + + #if STM32_RTCSEL == STM32_RTCSEL_LSE + #error "LSE not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSE + #error "LSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSE + #error "LSE not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief STM32_HSIDIV field. + */ +#if (STM32_HSIDIV_VALUE == 1) || defined(__DOXYGEN__) +#define STM32_HSIDIV STM32_HSIDIV_1 +#elif STM32_HSIDIV_VALUE == 2 +#define STM32_HSIDIV STM32_HSIDIV_2 +#elif STM32_HSIDIV_VALUE == 4 +#define STM32_HSIDIV STM32_HSIDIV_4 +#elif STM32_HSIDIV_VALUE == 8 +#define STM32_HSIDIV STM32_HSIDIV_8 +#elif STM32_HSIDIV_VALUE == 16 +#define STM32_HSIDIV STM32_HSIDIV_16 +#elif STM32_HSIDIV_VALUE == 32 +#define STM32_HSIDIV STM32_HSIDIV_32 +#elif STM32_HSIDIV_VALUE == 64 +#define STM32_HSIDIV STM32_HSIDIV_64 +#elif STM32_HSIDIV_VALUE == 128 +#define STM32_HSIDIV STM32_HSIDIV_128 +#else +#error "invalid STM32_HSIDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 8)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 +#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK +#define STM32_PLLCLKIN 0 + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLL input frequency range check. + */ +#if (STM32_PLLCLKIN != 0) && \ + ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_SW == STM32_SW_PLLRCLK) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ + (STM32_TIM1SEL == STM32_TIM1SEL_PLLQCLK) || \ + (STM32_TIM15SEL == STM32_TIM15SEL_PLLQCLK) || \ + (STM32_RNGSEL == STM32_RNGSEL_PLLQCLK) || \ + (STM32_ADCSEL == STM32_ADCSEL_PLLPCLK) || \ + (STM32_I2S1SEL == STM32_I2S1SEL_PLLPCLK) || \ + defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLL activation required but no PLL clock selected" +#endif + +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 86)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 8) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLR field. + */ +#if ((STM32_PLLR_VALUE >= 2) && (STM32_PLLR_VALUE <= 8)) || \ + defined(__DOXYGEN__) +#define STM32_PLLR ((STM32_PLLR_VALUE - 1) << 29) +#else +#error "invalid STM32_PLLR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if ((STM32_PLLQ_VALUE >= 2) && (STM32_PLLQ_VALUE <= 8)) || \ + defined(__DOXYGEN__) +#define STM32_PLLQ ((STM32_PLLQ_VALUE - 1) << 25) +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if ((STM32_PLLP_VALUE >= 2) && (STM32_PLLP_VALUE <= 32)) || \ + defined(__DOXYGEN__) +#define STM32_PLLP ((STM32_PLLP_VALUE - 1) << 17) +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLREN field. + */ +#if (STM32_SW == STM32_SW_PLLRCLK) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ + defined(__DOXYGEN__) +#define STM32_PLLREN (1 << 28) +#else +#define STM32_PLLREN (0 << 28) +#endif + +/** + * @brief STM32_PLLQEN field. + */ +#if (STM32_TIM1SEL == STM32_TIM1SEL_PLLQCLK) || \ + (STM32_TIM15SEL == STM32_TIM15SEL_PLLQCLK) || \ + (STM32_RNGSEL == STM32_RNGSEL_PLLQCLK) || \ + defined(__DOXYGEN__) +#define STM32_PLLQEN (1 << 24) +#else +#define STM32_PLLQEN (0 << 24) +#endif + +/** + * @brief STM32_PLLPEN field. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_PLLPCLK) || \ + (STM32_I2S1SEL == STM32_I2S1SEL_PLLPCLK) || \ + defined(__DOXYGEN__) +#define STM32_PLLPEN (1 << 16) +#else +#define STM32_PLLPEN (0 << 16) +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL R output clock frequency. + */ +#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) + +/** + * @brief PLL Q output clock frequency. + */ +#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) + +/** + * @brief PLL P output clock frequency. + */ +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) + +/* + * PLL-R output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/* + * PLL-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLL-P output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/** + * @brief HSISYS clock frequency. + */ +#define STM32_HSISYSCLK (STM32_HSI16CLK / STM32_HSIDIV_VALUE) + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_HSISYSCLK + +#elif (STM32_SW == STM32_SW_HSISYS) +#define STM32_SYSCLK STM32_HSISYSCLK + +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK + +#elif (STM32_SW == STM32_SW_PLLRCLK) +#define STM32_SYSCLK STM32_PLL_R_CLKOUT + +#elif (STM32_SW == STM32_SW_LSI) +#define STM32_SYSCLK STM32_LSICLK + +#elif (STM32_SW == STM32_SW_LSE) +#define STM32_SYSCLK STM32_LSECLK + +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) + +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) + +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) + +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) + +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) + +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) + +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) + +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) + +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) + +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB frequency. + */ +#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK (STM32_HCLK / 1) + +#elif STM32_PPRE == STM32_PPRE_DIV2 +#define STM32_PCLK (STM32_HCLK / 2) + +#elif STM32_PPRE == STM32_PPRE_DIV4 +#define STM32_PCLK (STM32_HCLK / 4) + +#elif STM32_PPRE == STM32_PPRE_DIV8 +#define STM32_PCLK (STM32_HCLK / 8) + +#elif STM32_PPRE == STM32_PPRE_DIV16 +#define STM32_PCLK (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE value specified" +#endif + +/* + * Compatibility definitions. + */ +#define STM32_PCLK1 STM32_PCLK +#define STM32_PCLK2 STM32_PCLK + +/* + * APB frequency check. + */ +#if STM32_PCLK > STM32_PCLK_MAX +#error "STM32_PCLK exceeding maximum frequency (STM32_PCLK_MAX)" +#endif + +/** + * @brief MCO divider clock frequency. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 + +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK +#define STM32_MCODIVCLK STM32_SYSCLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 +#define STM32_MCODIVCLK STM32_HSI16CLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_PLLRCLK +#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT + +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK + +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock frequency. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV32 +#define STM32_MCOCLK (STM32_MCODIVCLK / 32) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV64 +#define STM32_MCOCLK (STM32_MCODIVCLK / 64) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV128 +#define STM32_MCOCLK (STM32_MCODIVCLK / 128) + +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief RTC clock frequency. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 clock frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_PCLK) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 +#define STM32_USART1CLK STM32_HSI16CLK +#elif STM32_USART1SEL == STM32_USART1SEL_LSE +#define STM32_USART1CLK STM32_LSECLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 clock frequency. + */ +#if (STM32_USART2SEL == STM32_USART2SEL_PCLK) || defined(__DOXYGEN__) +#define STM32_USART2CLK STM32_PCLK +#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK +#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 +#define STM32_USART2CLK STM32_HSI16CLK +#elif STM32_USART2SEL == STM32_USART2SEL_LSE +#define STM32_USART2CLK STM32_LSECLK +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 frequency. + */ +#define STM32_USART3CLK STM32_PCLK + +/** + * @brief UART4 frequency. + */ +#define STM32_UART4CLK STM32_PCLK + +/** + * @brief UART5 frequency. + */ +#define STM32_UART5CLK STM32_PCLK + +/** + * @brief LPUART1 clock frequency. + */ +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK) || defined(__DOXYGEN__) +#define STM32_LPUART1CLK STM32_PCLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK +#define STM32_LPUART1CLK STM32_SYSCLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 +#define STM32_LPUART1CLK STM32_HSI16CLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE +#define STM32_LPUART1CLK STM32_LSECLK +#else +#error "invalid source selected for LPUART1 clock" +#endif + +/** + * @brief CEC clock frequency. + */ +#if (STM32_CECSEL == STM32_CECSEL_HSI16DIV) || defined(__DOXYGEN__) +#define STM32_CECCLK (STM32_HSI16CLK / 448) +#elif STM32_CECSEL == STM32_CECSEL_LSE +#define STM32_CECCLK STM32_LSECLK +#else +#error "invalid source selected for CEC clock" +#endif + +/** + * @brief I2C1 clock frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_PCLK +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 +#define STM32_I2C1CLK STM32_HSI16CLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2S1 clock frequency. + */ +#if (STM32_I2S1SEL == STM32_I2S1SEL_SYSCLK) || defined(__DOXYGEN__) +#define STM32_I2S1CLK STM32_SYSCLK +#elif STM32_I2S1SEL == STM32_I2S1SEL_PLLPCLK +#define STM32_I2S1CLK STM32_PLL_P_CLKOUT +#elif STM32_I2S1SEL == STM32_I2S1SEL_HSI16 +#define STM32_I2S1CLK STM32_HSI16CLK +#elif STM32_I2S1SEL == STM32_I2S1SEL_CKIN +#define STM32_I2S1CLK 0 /* Unknown, would require a board value */ +#else +#error "invalid source selected for I2S1 clock" +#endif + +/** + * @brief LPTIM1 clock frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK) || defined(__DOXYGEN__) +#define STM32_LPTIM1CLK STM32_PCLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI +#define STM32_LPTIM1CLK STM32_LSICLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 +#define STM32_LPTIM1CLK STM32_HSI16CLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE +#define STM32_LPTIM1CLK STM32_LSECLK +#else +#error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief LPTIM2 clock frequency. + */ +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK) || defined(__DOXYGEN__) +#define STM32_LPTIM2CLK STM32_PCLK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI +#define STM32_LPTIM2CLK STM32_LSICLK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 +#define STM32_LPTIM2CLK STM32_HSI16CLK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE +#define STM32_LPTIM2CLK STM32_LSECLK +#else +#error "invalid source selected for LPTIM2 clock" +#endif + +/** + * @brief RNGDIV field. + */ +#if (STM32_RNGDIV_VALUE == 1) || defined(__DOXYGEN__) +#define STM32_RNGDIV (0U << 28U) +#elif STM32_RNGDIV_VALUE == 2 +#define STM32_RNGDIV (1U << 28U) +#elif STM32_RNGDIV_VALUE == 4 +#define STM32_RNGDIV (2U << 28U) +#elif STM32_RNGDIV_VALUE == 8 +#define STM32_RNGDIV (3U << 28U) +#else +#error "invalid STM32_RNGDIV_VALUE value specified" +#endif + +/** + * @brief RNG clock frequency. + */ +#if (STM32_RNGSEL == STM32_RNGSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RNGCLK 0 +#elif STM32_RNGSEL == STM32_RNGSEL_HSI16 +#define STM32_RNGCLK (STM32_HSI16CLK / STM32_RNGDIV_VALUE) +#elif STM32_RNGSEL == STM32_RNGSEL_SYSCLK +#define STM32_RNGCLK (STM32_SYSCLK / STM32_RNGDIV_VALUE) +#elif STM32_RNGSEL == STM32_RNGSEL_PLLQCLK +#define STM32_RNGCLK (STM32_PLL_Q_CLKOUT / STM32_RNGDIV_VALUE) +#else +#error "invalid source selected for RNG clock" +#endif + +/** + * @brief ADC clock frequency. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_SYSCLK) || defined(__DOXYGEN__) +#define STM32_ADCCLK STM32_SYSCLK +#elif STM32_ADCSEL == STM32_ADCSEL_PLLPCLK +#define STM32_ADCCLK STM32_PLL_P_CLKOUT +#elif STM32_ADCSEL == STM32_ADCSEL_HSI16 +#define STM32_ADCCLK STM32_HSI16CLK +#else +#error "invalid source selected for ADC clock" +#endif + +/** + * @brief TIMPCLK clock frequency. + */ +#if (STM32_PPRE == STM32_PPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMPCLK (STM32_PCLK * 1) +#else +#define STM32_TIMPCLK (STM32_PCLK * 2) +#endif + +/** + * @brief TIM1 clock frequency. + */ +#if (STM32_TIM1SEL == STM32_TIM1SEL_TIMPCLK) || defined(__DOXYGEN__) +#define STM32_TIM1CLK STM32_TIMPCLK +#elif STM32_TIM1SEL == STM32_TIM1SEL_PLLQCLK +#define STM32_TIM1CLK STM32_PLL_Q_CLKOUT +#else +#error "invalid source selected for TIM1 clock" +#endif + +/** + * @brief TIM15 clock frequency. + */ +#if (STM32_TIM15SEL == STM32_TIM15SEL_TIMPCLK) || defined(__DOXYGEN__) +#define STM32_TIM15CLK STM32_TIMPCLK +#elif STM32_TIM15SEL == STM32_TIM15SEL_PLLQCLK +#define STM32_TIM15CLK STM32_PLL_Q_CLKOUT +#else +#error "invalid source selected for TIM15 clock" +#endif + +/** + * @brief Clock of timers connected to APB1. + */ +#define STM32_TIMCLK1 STM32_TIMPCLK + +/** + * @brief Clock of timers connected to APB2. + */ +#define STM32_TIMCLK2 STM32_TIMPCLK + +#if STM32_HAS_TIM1617_ERRATA +/* TIM16 and TIM17 require special handling and checks on some devices, see + the errata: "TIM16 and TIM17 are unduly clocked by SYSCLK".*/ +#define STM32_TIM16CLK hal_lld_get_clock_point(CLK_SYSCLK) +#define STM32_TIM17CLK hal_lld_get_clock_point(CLK_SYSCLK) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0 + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_0 + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_1 + +#else +#define STM32_FLASHBITS (FLASH_ACR_LATENCY_1 | FLASH_ACR_LATENCY_0) +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32G4xx/hal_lld.c b/os/hal/ports/STM32/STM32G4xx/hal_lld.c index 61d1e8f01b..32715d4709 100644 --- a/os/hal/ports/STM32/STM32G4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32G4xx/hal_lld.c @@ -1,284 +1,284 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32G4xx/hal_lld.c - * @brief STM32G4xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32g4xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing RTC clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ - - /* Low speed output mode.*/ - RCC->BDCR |= STM32_LSCOSEL; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector settings.*/ - PWR->CR2 = STM32_PWR_CR2; -} - -/** - * @brief STM32L4xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~0); - rccResetAHB2(~STM32_GPIO_EN_MASK); - rccResetAHB3(~0); - rccResetAPB1R1(~0); - rccResetAPB1R2(~0); - rccResetAPB2(~0); - - /* PWR clock enable.*/ -#if (HAL_USE_RTC == TRUE) && defined(RCC_APBENR1_RTCAPBEN) - rccEnableAPB1R1(RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN, false) -#else - rccEnableAPB1R1(RCC_APB1ENR1_PWREN, false) -#endif - - /* Core voltage setup.*/ - PWR->CR1 = STM32_VOS; - while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ - ; /* stable. */ - - /* Additional PWR configurations.*/ - PWR->CR2 = STM32_PWR_CR2; - PWR->CR3 = STM32_PWR_CR3; - PWR->CR4 = STM32_PWR_CR4; - PWR->CR5 = STM32_CR5BITS; - PWR->PUCRA = STM32_PWR_PUCRA; - PWR->PDCRA = STM32_PWR_PDCRA; - PWR->PUCRB = STM32_PWR_PUCRB; - PWR->PDCRB = STM32_PWR_PDCRB; - PWR->PUCRC = STM32_PWR_PUCRC; - PWR->PDCRC = STM32_PWR_PDCRC; - PWR->PUCRD = STM32_PWR_PUCRD; - PWR->PDCRD = STM32_PWR_PDCRD; - PWR->PUCRE = STM32_PWR_PUCRE; - PWR->PDCRE = STM32_PWR_PDCRE; - PWR->PUCRF = STM32_PWR_PUCRF; - PWR->PDCRF = STM32_PWR_PDCRF; - PWR->PUCRG = STM32_PWR_PUCRG; - PWR->PDCRG = STM32_PWR_PDCRG; - -#if STM32_HSI16_ENABLED - /* HSI activation.*/ - RCC->CR |= RCC_CR_HSION; - while ((RCC->CR & RCC_CR_HSIRDY) == 0) - ; /* Wait until HSI16 is stable. */ -#endif - -#if STM32_HSI48_ENABLED - /* HSI activation.*/ - RCC->CRRCR |= RCC_CRRCR_HSI48ON; - while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0) - ; /* Wait until HSI48 is stable. */ -#endif - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Wait until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Wait until LSI is stable. */ -#endif - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - -#if STM32_LSE_ENABLED - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Wait until LSE is stable. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLLM and PLLSRC are common to all PLLs.*/ - RCC->PLLCFGR = STM32_PLLPDIV | - STM32_PLLR | STM32_PLLREN | - STM32_PLLQ | STM32_PLLQEN | - STM32_PLLP | STM32_PLLPEN | - STM32_PLLN | STM32_PLLM | - STM32_PLLSRC; -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLRDY) == 0) - ; -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_PPRE2 | STM32_PPRE1 | - STM32_HPRE; - - /* CCIPR registers initialization, note.*/ - RCC->CCIPR = STM32_ADC345SEL | STM32_ADC12SEL | STM32_CLK48SEL | - STM32_FDCANSEL | STM32_I2S23SEL | STM32_SAI1SEL | - STM32_LPTIM1SEL | STM32_I2C3SEL | STM32_I2C2SEL | - STM32_I2C1SEL | STM32_LPUART1SEL | STM32_UART5SEL | - STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | - STM32_USART1SEL; - RCC->CCIPR2 = STM32_QSPISEL | STM32_I2C4SEL; - - /* Set flash WS's for SYSCLK source */ - FLASH->ACR = FLASH_ACR_DBG_SWEN | FLASH_ACR_DCEN | FLASH_ACR_ICEN | - FLASH_ACR_PRFTEN | STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - - /* Switching to the configured SYSCLK source if it is different from HSI16.*/ -#if STM32_SW != STM32_SW_HSI16 - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - /* Wait until SYSCLK is stable.*/ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif - -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32G4xx/hal_lld.c + * @brief STM32G4xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32g4xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing RTC clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int rusefiLseCounter = 0; + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + + /* Low speed output mode.*/ + RCC->BDCR |= STM32_LSCOSEL; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector settings.*/ + PWR->CR2 = STM32_PWR_CR2; +} + +/** + * @brief STM32L4xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~0); + rccResetAHB2(~STM32_GPIO_EN_MASK); + rccResetAHB3(~0); + rccResetAPB1R1(~0); + rccResetAPB1R2(~0); + rccResetAPB2(~0); + + /* PWR clock enable.*/ +#if (HAL_USE_RTC == TRUE) && defined(RCC_APBENR1_RTCAPBEN) + rccEnableAPB1R1(RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN, false) +#else + rccEnableAPB1R1(RCC_APB1ENR1_PWREN, false) +#endif + + /* Core voltage setup.*/ + PWR->CR1 = STM32_VOS; + while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ + ; /* stable. */ + + /* Additional PWR configurations.*/ + PWR->CR2 = STM32_PWR_CR2; + PWR->CR3 = STM32_PWR_CR3; + PWR->CR4 = STM32_PWR_CR4; + PWR->CR5 = STM32_CR5BITS; + PWR->PUCRA = STM32_PWR_PUCRA; + PWR->PDCRA = STM32_PWR_PDCRA; + PWR->PUCRB = STM32_PWR_PUCRB; + PWR->PDCRB = STM32_PWR_PDCRB; + PWR->PUCRC = STM32_PWR_PUCRC; + PWR->PDCRC = STM32_PWR_PDCRC; + PWR->PUCRD = STM32_PWR_PUCRD; + PWR->PDCRD = STM32_PWR_PDCRD; + PWR->PUCRE = STM32_PWR_PUCRE; + PWR->PDCRE = STM32_PWR_PDCRE; + PWR->PUCRF = STM32_PWR_PUCRF; + PWR->PDCRF = STM32_PWR_PDCRF; + PWR->PUCRG = STM32_PWR_PUCRG; + PWR->PDCRG = STM32_PWR_PDCRG; + +#if STM32_HSI16_ENABLED + /* HSI activation.*/ + RCC->CR |= RCC_CR_HSION; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Wait until HSI16 is stable. */ +#endif + +#if STM32_HSI48_ENABLED + /* HSI activation.*/ + RCC->CRRCR |= RCC_CRRCR_HSI48ON; + while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0) + ; /* Wait until HSI48 is stable. */ +#endif + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Wait until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Wait until LSI is stable. */ +#endif + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + +#if STM32_LSE_ENABLED + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Wait until LSE is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLLM and PLLSRC are common to all PLLs.*/ + RCC->PLLCFGR = STM32_PLLPDIV | + STM32_PLLR | STM32_PLLREN | + STM32_PLLQ | STM32_PLLQEN | + STM32_PLLP | STM32_PLLPEN | + STM32_PLLN | STM32_PLLM | + STM32_PLLSRC; +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLRDY) == 0) + ; +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_PPRE2 | STM32_PPRE1 | + STM32_HPRE; + + /* CCIPR registers initialization, note.*/ + RCC->CCIPR = STM32_ADC345SEL | STM32_ADC12SEL | STM32_CLK48SEL | + STM32_FDCANSEL | STM32_I2S23SEL | STM32_SAI1SEL | + STM32_LPTIM1SEL | STM32_I2C3SEL | STM32_I2C2SEL | + STM32_I2C1SEL | STM32_LPUART1SEL | STM32_UART5SEL | + STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | + STM32_USART1SEL; + RCC->CCIPR2 = STM32_QSPISEL | STM32_I2C4SEL; + + /* Set flash WS's for SYSCLK source */ + FLASH->ACR = FLASH_ACR_DBG_SWEN | FLASH_ACR_DCEN | FLASH_ACR_ICEN | + FLASH_ACR_PRFTEN | STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + + /* Switching to the configured SYSCLK source if it is different from HSI16.*/ +#if STM32_SW != STM32_SW_HSI16 + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + /* Wait until SYSCLK is stable.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif + +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32G4xx/hal_lld.h b/os/hal/ports/STM32/STM32G4xx/hal_lld.h index 8dec55553c..47ed7866c2 100644 --- a/os/hal/ports/STM32/STM32G4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32G4xx/hal_lld.h @@ -1,2004 +1,2004 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32G4xx/hal_lld.h - * @brief STM32G4xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32G431xx, STM32G441xx, STM32G471xx. - * - STM32G473xx, STM32G483xx. - * - STM32G474xx, STM32G484xx. - * - STM32GBK1CB. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(STM32G431xx) || defined(STM32G441xx) || defined(STM32G471xx) || \ - defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32G4 Access Line" - -#elif defined(STM32G473xx) -#define PLATFORM_NAME "STM32G4 Performance Line" - -#elif defined(STM32G483xx) -#define PLATFORM_NAME "STM32G4 Performance Line with Crypto" - -#elif defined(STM32G474xx) -#define PLATFORM_NAME "STM32G4 Hi-resolution Line" - -#elif defined(STM32G484xx) -#define PLATFORM_NAME "STM32G4 Hi-resolution Line with Crypto" - -#elif defined(STM32GBK1CB) -#define PLATFORM_NAME "STM32G4 Mystery Line" - -#else -#error "STM32G4 device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32G4XX) || defined(__DOXYGEN__) -#define STM32G4XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSI16CLK 16000000U /**< 16MHz internal clock. */ -#define STM32_HSI48CLK 48000000U /**< 48MHz internal clock. */ -#define STM32_LSICLK 32000U /**< Low speed internal clock. */ -/** @} */ - -/** - * @name VOS field definitions - * @{ - */ -#define STM32_VOS_MASK (3U << 9U) /**< Core voltage mask. */ -#define STM32_VOS_RANGE1 (1U << 9U) /**< Core voltage 1.2 Volts. */ -#define STM32_VOS_RANGE2 (2U << 9U) /**< Core voltage 1.0 Volts. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3U << 0U) /**< SW field mask. */ -#define STM32_SW_HSI16 (1U << 0U) /**< SYSCLK source is HSI16. */ -#define STM32_SW_HSE (2U << 0U) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLLRCLK (3U << 0U) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15U << 4U) /**< HPRE field mask. */ -#define STM32_HPRE_FIELD(n) ((n) << 4U) /**< HPRE field value. */ -#define STM32_HPRE_DIV1 STM32_HPRE_FIELD(0U) -#define STM32_HPRE_DIV2 STM32_HPRE_FIELD(8U) -#define STM32_HPRE_DIV4 STM32_HPRE_FIELD(9U) -#define STM32_HPRE_DIV8 STM32_HPRE_FIELD(10U) -#define STM32_HPRE_DIV16 STM32_HPRE_FIELD(11U) -#define STM32_HPRE_DIV64 STM32_HPRE_FIELD(12U) -#define STM32_HPRE_DIV128 STM32_HPRE_FIELD(13U) -#define STM32_HPRE_DIV256 STM32_HPRE_FIELD(14U) -#define STM32_HPRE_DIV512 STM32_HPRE_FIELD(15U) - -#define STM32_PPRE1_MASK (7U << 8U) /**< PPRE1 field mask. */ -#define STM32_PPRE1_FIELD(n) ((n) << 8U) /**< PPRE1 field value. */ -#define STM32_PPRE1_DIV1 STM32_PPRE1_FIELD(0U) -#define STM32_PPRE1_DIV2 STM32_PPRE1_FIELD(4U) -#define STM32_PPRE1_DIV4 STM32_PPRE1_FIELD(5U) -#define STM32_PPRE1_DIV8 STM32_PPRE1_FIELD(6U) -#define STM32_PPRE1_DIV16 STM32_PPRE1_FIELD(7U) - -#define STM32_PPRE2_MASK (7U << 11U) /**< PPRE2 field mask. */ -#define STM32_PPRE2_FIELD(n) ((n) << 11U) /**< PPRE2 field value. */ -#define STM32_PPRE2_DIV1 STM32_PPRE2_FIELD(0U) -#define STM32_PPRE2_DIV2 STM32_PPRE2_FIELD(4U) -#define STM32_PPRE2_DIV4 STM32_PPRE2_FIELD(5U) -#define STM32_PPRE2_DIV8 STM32_PPRE2_FIELD(6U) -#define STM32_PPRE2_DIV16 STM32_PPRE2_FIELD(7U) - -#define STM32_MCOSEL_MASK (15U << 24U)/**< MCOSEL field mask. */ -#define STM32_MCOSEL_NOCLOCK (0U << 24U) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1U << 24U) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI16 (3U << 24U) /**< HSI16 clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4U << 24U) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLLRCLK (5U << 24U) /**< PLLR clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6U << 24U) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7U << 24U) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_HSI48 (8U << 24U) /**< HSI48 clock on MCO pin. */ - -#define STM32_MCOPRE_MASK (7U << 28U) /**< MCOPRE field mask. */ -#define STM32_MCOPRE_FIELD(n) ((n) << 28U)/**< MCOPRE field value */ -#define STM32_MCOPRE_DIV1 STM32_MCOPRE_FIELD(0U) -#define STM32_MCOPRE_DIV2 STM32_MCOPRE_FIELD(1U) -#define STM32_MCOPRE_DIV4 STM32_MCOPRE_FIELD(2U) -#define STM32_MCOPRE_DIV8 STM32_MCOPRE_FIELD(3U) -#define STM32_MCOPRE_DIV16 STM32_MCOPRE_FIELD(4U) -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CCIPR register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3U << 0U) /**< USART1SEL mask. */ -#define STM32_USART1SEL_PCLK2 (0U << 0U) /**< USART1 source is PCLK2. */ -#define STM32_USART1SEL_SYSCLK (1U << 0U) /**< USART1 source is SYSCLK. */ -#define STM32_USART1SEL_HSI16 (2U << 0U) /**< USART1 source is HSI16. */ -#define STM32_USART1SEL_LSE (3U << 0U) /**< USART1 source is LSE. */ - -#define STM32_USART2SEL_MASK (3U << 2U) /**< USART2 mask. */ -#define STM32_USART2SEL_PCLK1 (0U << 2U) /**< USART2 source is PCLK1. */ -#define STM32_USART2SEL_SYSCLK (1U << 2U) /**< USART2 source is SYSCLK. */ -#define STM32_USART2SEL_HSI16 (2U << 2U) /**< USART2 source is HSI16. */ -#define STM32_USART2SEL_LSE (3U << 2U) /**< USART2 source is LSE. */ - -#define STM32_USART3SEL_MASK (3U << 4U) /**< USART3 mask. */ -#define STM32_USART3SEL_PCLK1 (0U << 4U) /**< USART3 source is PCLK1. */ -#define STM32_USART3SEL_SYSCLK (1U << 4U) /**< USART3 source is SYSCLK. */ -#define STM32_USART3SEL_HSI16 (2U << 4U) /**< USART3 source is HSI16. */ -#define STM32_USART3SEL_LSE (3U << 4U) /**< USART3 source is LSE. */ - -#define STM32_UART4SEL_MASK (3U << 6U) /**< UART4 mask. */ -#define STM32_UART4SEL_PCLK1 (0U << 6U) /**< UART4 source is PCLK1. */ -#define STM32_UART4SEL_SYSCLK (1U << 6U) /**< UART4 source is SYSCLK. */ -#define STM32_UART4SEL_HSI16 (2U << 6U) /**< UART4 source is HSI16. */ -#define STM32_UART4SEL_LSE (3U << 6U) /**< UART4 source is LSE. */ - -#define STM32_UART5SEL_MASK (3U << 8U) /**< UART5 mask. */ -#define STM32_UART5SEL_PCLK1 (0U << 8U) /**< UART5 source is PCLK1. */ -#define STM32_UART5SEL_SYSCLK (1U << 8U) /**< UART5 source is SYSCLK. */ -#define STM32_UART5SEL_HSI16 (2U << 8U) /**< UART5 source is HSI16. */ -#define STM32_UART5SEL_LSE (3U << 8U) /**< UART5 source is LSE. */ - -#define STM32_LPUART1SEL_MASK (3U << 10U) /**< LPUART1 mask. */ -#define STM32_LPUART1SEL_PCLK1 (0U << 10U) /**< LPUART1 source is PCLK1. */ -#define STM32_LPUART1SEL_SYSCLK (1U << 10U) /**< LPUART1 source is SYSCLK. */ -#define STM32_LPUART1SEL_HSI16 (2U << 10U) /**< LPUART1 source is HSI16. */ -#define STM32_LPUART1SEL_LSE (3U << 10U) /**< LPUART1 source is LSE. */ - -#define STM32_I2C1SEL_MASK (3U << 12U) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK1 (0U << 12U) /**< I2C1 source is PCLK1. */ -#define STM32_I2C1SEL_SYSCLK (1U << 12U) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI16 (2U << 12U) /**< I2C1 source is HSI16. */ - -#define STM32_I2C2SEL_MASK (3U << 14U) /**< I2C2SEL mask. */ -#define STM32_I2C2SEL_PCLK1 (0U << 14U) /**< I2C2 source is PCLK1. */ -#define STM32_I2C2SEL_SYSCLK (1U << 14U) /**< I2C2 source is SYSCLK. */ -#define STM32_I2C2SEL_HSI16 (2U << 14U) /**< I2C2 source is HSI16. */ - -#define STM32_I2C3SEL_MASK (3U << 16U) /**< I2C3SEL mask. */ -#define STM32_I2C3SEL_PCLK1 (0U << 16U) /**< I2C3 source is PCLK1. */ -#define STM32_I2C3SEL_SYSCLK (1U << 16U) /**< I2C3 source is SYSCLK. */ -#define STM32_I2C3SEL_HSI16 (2U << 16U) /**< I2C3 source is HSI16. */ - -#define STM32_LPTIM1SEL_MASK (3U << 18U) /**< LPTIM1SEL mask. */ -#define STM32_LPTIM1SEL_PCLK1 (0U << 18U) /**< LPTIM1 source is PCLK1. */ -#define STM32_LPTIM1SEL_LSI (1U << 18U) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_HSI16 (2U << 18U) /**< LPTIM1 source is HSI16. */ -#define STM32_LPTIM1SEL_LSE (3U << 18U) /**< LPTIM1 source is LSE. */ - -#define STM32_SAI1SEL_MASK (3U << 20U) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_SYSCLK (0U << 20U) /**< SAI1 source is SYSCLK. */ -#define STM32_SAI1SEL_PLLQCLK (1U << 20U) /**< SAI1 source is PLLQCLK. */ -#define STM32_SAI1SEL_CKIN (2U << 20U) /**< SAI1 source is CKIN. */ -#define STM32_SAI1SEL_HSI16 (3U << 20U) /**< SAI1 source is HSI16. */ - -#define STM32_I2S23SEL_MASK (3U << 22U) /**< I2S23SEL mask. */ -#define STM32_I2S23SEL_SYSCLK (0U << 22U) /**< I2S23 source is SYSCLK. */ -#define STM32_I2S23SEL_PLLQCLK (1U << 22U) /**< I2S23 source is PLLQCLK. */ -#define STM32_I2S23SEL_CKIN (2U << 22U) /**< I2S23 source is CKIN. */ -#define STM32_I2S23SEL_HSI16 (3U << 22U) /**< I2S23 source is HSI16. */ - -#define STM32_FDCANSEL_MASK (3U << 24U) /**< FDCANSEL mask. */ -#define STM32_FDCANSEL_HSE (0U << 24U) /**< FDCAN source is HSE. */ -#define STM32_FDCANSEL_PLLQCLK (1U << 24U) /**< FDCAN source is PLLQCLK. */ -#define STM32_FDCANSEL_PCLK1 (2U << 24U) /**< FDCAN source is PCLK1. */ - -#define STM32_CLK48SEL_MASK (3U << 26U) /**< CLK48SEL mask. */ -#define STM32_CLK48SEL_HSI48 (0U << 26U) /**< CLK48 source is HSI48. */ -#define STM32_CLK48SEL_PLLQCLK (2U << 26U) /**< CLK48 source is PLLQCLK. */ - -#define STM32_ADC12SEL_MASK (3U << 28U) /**< ADC12SEL mask. */ -#define STM32_ADC12SEL_NOCLK (0U << 28U) /**< ADC12 source is none. */ -#define STM32_ADC12SEL_PLLPCLK (1U << 28U) /**< ADC12 source is PLLPCLK. */ -#define STM32_ADC12SEL_SYSCLK (2U << 28U) /**< ADC12 source is SYSCLK. */ - -#define STM32_ADC345SEL_MASK (3U << 30U) /**< ADC345SEL mask. */ -#define STM32_ADC345SEL_NOCLK (0U << 30U) /**< ADC345 source is none. */ -#define STM32_ADC345SEL_PLLPCLK (1U << 30U) /**< ADC345 source is PLLPCLK. */ -#define STM32_ADC345SEL_SYSCLK (2U << 30U) /**< ADC345 source is SYSCLK. */ -/** @} */ - -/** - * @name RCC_CCIPR2 register bits definitions - * @{ - */ -#define STM32_I2C4SEL_MASK (3U << 0U) /**< I2C4SEL mask. */ -#define STM32_I2C4SEL_PCLK1 (0U << 0U) /**< I2C4 source is PCLK1. */ -#define STM32_I2C4SEL_SYSCLK (1U << 0U) /**< I2C4 source is SYSCLK. */ -#define STM32_I2C4SEL_HSI16 (2U << 0U) /**< I2C4 source is HSI16. */ - -#define STM32_QSPISEL_MASK (3U << 20U) /**< QSPISEL mask. */ -#define STM32_QSPISEL_SYSCLK (0U << 20U) /**< QSPI source is SYSCLK. */ -#define STM32_QSPISEL_HSI16 (1U << 20U) /**< QSPI source is HSI16. */ -#define STM32_QSPISEL_PLLQCLK (2U << 20U) /**< QSPI source is PLLQCLK. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3U << 8U) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0U << 8U) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1U << 8U) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2U << 8U) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3U << 8U) /**< RTC source is HSE divided. */ - -#define STM32_LSCOSEL_MASK (3U << 24U) /**< LSCO pin clock source. */ -#define STM32_LSCOSEL_NOCLOCK (0U << 24U) /**< No clock on LSCO pin. */ -#define STM32_LSCOSEL_LSI (1U << 24U) /**< LSI on LSCO pin. */ -#define STM32_LSCOSEL_LSE (3U << 24U) /**< LSE on LSCO pin. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_RANGE1 -#endif - -/** - * @brief Core voltage boost. - * @note The boost can only be used when STM32_VOS==STM32_VOS_RANGE1. - */ -#if !defined(STM32_PWR_BOOST) || defined(__DOXYGEN__) -#define STM32_PWR_BOOST TRUE -#endif - -/** - * @brief PWR CR2 register initialization value. - */ -#if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__) -#define STM32_PWR_CR2 (PWR_CR2_PLS_LEV0) -#endif - -/** - * @brief PWR CR3 register initialization value. - */ -#if !defined(STM32_PWR_CR3) || defined(__DOXYGEN__) -#define STM32_PWR_CR3 (PWR_CR3_EIWF) -#endif - -/** - * @brief PWR CR4 register initialization value. - */ -#if !defined(STM32_PWR_CR4) || defined(__DOXYGEN__) -#define STM32_PWR_CR4 (0U) -#endif - -/** - * @brief PWR PUCRA register initialization value. - */ -#if !defined(STM32_PWR_PUCRA) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRA (0U) -#endif - -/** - * @brief PWR PDCRA register initialization value. - */ -#if !defined(STM32_PWR_PDCRA) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRA (0U) -#endif - -/** - * @brief PWR PUCRB register initialization value. - */ -#if !defined(STM32_PWR_PUCRB) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRB (0U) -#endif - -/** - * @brief PWR PDCRB register initialization value. - */ -#if !defined(STM32_PWR_PDCRB) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRB (0U) -#endif - -/** - * @brief PWR PUCRC register initialization value. - */ -#if !defined(STM32_PWR_PUCRC) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRC (0U) -#endif - -/** - * @brief PWR PDCRC register initialization value. - */ -#if !defined(STM32_PWR_PDCRC) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRC (0U) -#endif - -/** - * @brief PWR PUCRD register initialization value. - */ -#if !defined(STM32_PWR_PUCRD) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRD (0U) -#endif - -/** - * @brief PWR PDCRD register initialization value. - */ -#if !defined(STM32_PWR_PDCRD) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRD (0U) -#endif - -/** - * @brief PWR PUCRE register initialization value. - */ -#if !defined(STM32_PWR_PUCRE) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRE (0U) -#endif - -/** - * @brief PWR PDCRE register initialization value. - */ -#if !defined(STM32_PWR_PDCRE) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRE (0U) -#endif - -/** - * @brief PWR PUCRF register initialization value. - */ -#if !defined(STM32_PWR_PUCRF) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRF (0U) -#endif - -/** - * @brief PWR PDCRF register initialization value. - */ -#if !defined(STM32_PWR_PDCRF) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRF (0U) -#endif - -/** - * @brief PWR PUCRG register initialization value. - */ -#if !defined(STM32_PWR_PUCRG) || defined(__DOXYGEN__) -#define STM32_PWR_PUCRG (0U) -#endif - -/** - * @brief PWR PDCRG register initialization value. - */ -#if !defined(STM32_PWR_PDCRG) || defined(__DOXYGEN__) -#define STM32_PWR_PDCRG (0U) -#endif - -/** - * @brief Enables or disables the HSI16 clock source. - */ -#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSI48 clock source. - */ -#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI48_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 170MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLLRCLK -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 170MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSI16 -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 170MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 4 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 8..127. - * @note The default value is calculated for a 170MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 84 -#endif - -/** - * @brief PLLPDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLPDIV_VALUE 0 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 7 -#endif - -/** - * @brief PLLQ divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 8 -#endif - -/** - * @brief PLLR divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 170MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLR_VALUE 2 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 170MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV2 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief LSCO clock source. - */ -#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) -#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_SYSCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_SYSCLK -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) -#define STM32_USART3SEL STM32_USART3SEL_SYSCLK -#endif - -/** - * @brief UART4 clock source. - */ -#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) -#define STM32_UART4SEL STM32_UART4SEL_SYSCLK -#endif - -/** - * @brief UART5 clock source. - */ -#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) -#define STM32_UART5SEL STM32_UART5SEL_SYSCLK -#endif - -/** - * @brief LPUART1 clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_PCLK1 -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) -#define STM32_I2C2SEL STM32_I2C2SEL_PCLK1 -#endif - -/** - * @brief I2C3 clock source. - */ -#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) -#define STM32_I2C3SEL STM32_I2C3SEL_PCLK1 -#endif - -/** - * @brief I2C4 clock source. - */ -#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) -#define STM32_I2C4SEL STM32_I2C4SEL_PCLK1 -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 -#endif - -/** - * @brief SAI1 clock source. - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_SYSCLK -#endif - -/** - * @brief I2S23 clock source. - */ -#if !defined(STM32_I2S23SEL) || defined(__DOXYGEN__) -#define STM32_I2S23SEL STM32_I2S23SEL_SYSCLK -#endif - -/** - * @brief FDCAN clock source. - */ -#if !defined(STM32_FDCANSEL) || defined(__DOXYGEN__) -#define STM32_FDCANSEL STM32_FDCANSEL_HSE -#endif - -/** - * @brief CLK48 clock source. - */ -#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) -#define STM32_CLK48SEL STM32_CLK48SEL_HSI48 -#endif - -/** - * @brief ADC12 clock source. - */ -#if !defined(STM32_ADC12SEL) || defined(__DOXYGEN__) -#define STM32_ADC12SEL STM32_ADC12SEL_PLLPCLK -#endif - -/** - * @brief ADC34 clock source. - */ -#if !defined(STM32_ADC345SEL) || defined(__DOXYGEN__) -#define STM32_ADC345SEL STM32_ADC345SEL_PLLPCLK -#endif - -/** - * @brief QSPI clock source. - */ -#if !defined(STM32_QSPISEL) || defined(__DOXYGEN__) -#define STM32_QSPISEL STM32_QSPISEL_SYSCLK -#endif - -/** - * @brief RTC clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* Boost mode checks.*/ -#if STM32_PWR_BOOST && (STM32_VOS != STM32_VOS_RANGE1) -#error "STM32_PWR_BOOST requires STM32_VOS_RANGE1" -#endif - -/* - * Configuration-related checks. - */ -#if !defined(STM32G4xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G4xx_MCUCONF not defined" -#endif - -#if defined(STM32G431xx) && !defined(STM32G431_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G431_MCUCONF not defined" - -#elif defined(STM32G441xx) && !defined(STM32G441_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G441_MCUCONF not defined" - -#elif defined(STM32G471xx) && !defined(STM32G471_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G471_MCUCONF not defined" - -#elif defined(STM32G473xx) && !defined(STM32G473_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G473_MCUCONF not defined" - -#elif defined(STM32G483xx) && !defined(STM32G473_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G483_MCUCONF not defined" - -#elif defined(STM32G474xx) && !defined(STM32G474_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G474_MCUCONF not defined" - -#elif defined(STM32G484xx) && !defined(STM32G484_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32G484_MCUCONF not defined" - -#elif defined(STM32GBK1CB) && !defined(STM32GBK1CB_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32GBK1CB_MCUCONF not defined" - -#endif - -/* - * Board files sanity checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif - -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/** - * @name System Limits for VOS range 1 with boost - * @{ - */ -#define STM32_BOOST_SYSCLK_MAX 170000000 -#define STM32_BOOST_HSECLK_MAX 48000000 -#define STM32_BOOST_HSECLK_BYP_MAX 48000000 -#define STM32_BOOST_HSECLK_MIN 8000000 -#define STM32_BOOST_HSECLK_BYP_MIN 8000000 -#define STM32_BOOST_LSECLK_MAX 32768 -#define STM32_BOOST_LSECLK_BYP_MAX 1000000 -#define STM32_BOOST_LSECLK_MIN 32768 -#define STM32_BOOST_LSECLK_BYP_MIN 32768 -#define STM32_BOOST_PLLIN_MAX 16000000 -#define STM32_BOOST_PLLIN_MIN 2660000 -#define STM32_BOOST_PLLVCO_MAX 344000000 -#define STM32_BOOST_PLLVCO_MIN 96000000 -#define STM32_BOOST_PLLP_MAX 170000000 -#define STM32_BOOST_PLLP_MIN 2064500 -#define STM32_BOOST_PLLQ_MAX 170000000 -#define STM32_BOOST_PLLQ_MIN 8000000 -#define STM32_BOOST_PLLR_MAX 170000000 -#define STM32_BOOST_PLLR_MIN 8000000 -#define STM32_BOOST_PCLK1_MAX 170000000 -#define STM32_BOOST_PCLK2_MAX 170000000 -#define STM32_BOOST_ADCCLK_MAX 60000000 - -#define STM32_BOOST_0WS_THRESHOLD 34000000 -#define STM32_BOOST_1WS_THRESHOLD 68000000 -#define STM32_BOOST_2WS_THRESHOLD 102000000 -#define STM32_BOOST_3WS_THRESHOLD 136000000 -#define STM32_BOOST_4WS_THRESHOLD 170000000 -/** @} */ - -/** - * @name System Limits for VOS range 1 without boost - * @{ - */ -#define STM32_VOS1_SYSCLK_MAX 150000000 -#define STM32_VOS1_HSECLK_MAX 48000000 -#define STM32_VOS1_HSECLK_BYP_MAX 48000000 -#define STM32_VOS1_HSECLK_MIN 8000000 -#define STM32_VOS1_HSECLK_BYP_MIN 8000000 -#define STM32_VOS1_LSECLK_MAX 32768 -#define STM32_VOS1_LSECLK_BYP_MAX 1000000 -#define STM32_VOS1_LSECLK_MIN 32768 -#define STM32_VOS1_LSECLK_BYP_MIN 32768 -#define STM32_VOS1_PLLIN_MAX 16000000 -#define STM32_VOS1_PLLIN_MIN 2660000 -#define STM32_VOS1_PLLVCO_MAX 344000000 -#define STM32_VOS1_PLLVCO_MIN 96000000 -#define STM32_VOS1_PLLP_MAX 150000000 -#define STM32_VOS1_PLLP_MIN 2064500 -#define STM32_VOS1_PLLQ_MAX 150000000 -#define STM32_VOS1_PLLQ_MIN 8000000 -#define STM32_VOS1_PLLR_MAX 150000000 -#define STM32_VOS1_PLLR_MIN 8000000 -#define STM32_VOS1_PCLK1_MAX 150000000 -#define STM32_VOS1_PCLK2_MAX 150000000 -#define STM32_VOS1_ADCCLK_MAX 60000000 - -#define STM32_VOS1_0WS_THRESHOLD 30000000 -#define STM32_VOS1_1WS_THRESHOLD 60000000 -#define STM32_VOS1_2WS_THRESHOLD 90000000 -#define STM32_VOS1_3WS_THRESHOLD 120000000 -#define STM32_VOS1_4WS_THRESHOLD 150000000 -/** @} */ - -/** - * @name System Limits for VOS range 2 - * @{ - */ -#define STM32_VOS2_SYSCLK_MAX 26000000 -#define STM32_VOS2_HSECLK_MAX 26000000 -#define STM32_VOS2_HSECLK_BYP_MAX 26000000 -#define STM32_VOS2_HSECLK_MIN 8000000 -#define STM32_VOS2_HSECLK_BYP_MIN 8000000 -#define STM32_VOS2_LSECLK_MAX 32768 -#define STM32_VOS2_LSECLK_BYP_MAX 1000000 -#define STM32_VOS2_LSECLK_MIN 32768 -#define STM32_VOS2_LSECLK_BYP_MIN 32768 -#define STM32_VOS2_PLLIN_MAX 16000000 -#define STM32_VOS2_PLLIN_MIN 2660000 -#define STM32_VOS2_PLLVCO_MAX 128000000 -#define STM32_VOS2_PLLVCO_MIN 96000000 -#define STM32_VOS2_PLLP_MAX 26000000 -#define STM32_VOS2_PLLP_MIN 2064500 -#define STM32_VOS2_PLLQ_MAX 26000000 -#define STM32_VOS2_PLLQ_MIN 8000000 -#define STM32_VOS2_PLLR_MAX 26000000 -#define STM32_VOS2_PLLR_MIN 8000000 -#define STM32_VOS2_PCLK1_MAX 26000000 -#define STM32_VOS2_PCLK2_MAX 26000000 -#define STM32_VOS2_ADCCLK_MAX 26000000 - -#define STM32_VOS2_0WS_THRESHOLD 12000000 -#define STM32_VOS2_1WS_THRESHOLD 24000000 -#define STM32_VOS2_2WS_THRESHOLD 26000000 -#define STM32_VOS2_3WS_THRESHOLD 0 -#define STM32_VOS2_4WS_THRESHOLD 0 -/** @} */ - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) -#if STM32_PWR_BOOST || defined(__DOXYGEN__) -#define STM32_SYSCLK_MAX STM32_BOOST_SYSCLK_MAX -#define STM32_HSECLK_MAX STM32_BOOST_HSECLK_MAX -#define STM32_HSECLK_BYP_MAX STM32_BOOST_HSECLK_BYP_MAX -#define STM32_HSECLK_MIN STM32_BOOST_HSECLK_MIN -#define STM32_HSECLK_BYP_MIN STM32_BOOST_HSECLK_BYP_MIN -#define STM32_LSECLK_MAX STM32_BOOST_LSECLK_MAX -#define STM32_LSECLK_BYP_MAX STM32_BOOST_LSECLK_BYP_MAX -#define STM32_LSECLK_MIN STM32_BOOST_LSECLK_MIN -#define STM32_LSECLK_BYP_MIN STM32_BOOST_LSECLK_BYP_MIN -#define STM32_PLLIN_MAX STM32_BOOST_PLLIN_MAX -#define STM32_PLLIN_MIN STM32_BOOST_PLLIN_MIN -#define STM32_PLLVCO_MAX STM32_BOOST_PLLVCO_MAX -#define STM32_PLLVCO_MIN STM32_BOOST_PLLVCO_MIN -#define STM32_PLLP_MAX STM32_BOOST_PLLP_MAX -#define STM32_PLLP_MIN STM32_BOOST_PLLP_MIN -#define STM32_PLLQ_MAX STM32_BOOST_PLLQ_MAX -#define STM32_PLLQ_MIN STM32_BOOST_PLLQ_MIN -#define STM32_PLLR_MAX STM32_BOOST_PLLR_MAX -#define STM32_PLLR_MIN STM32_BOOST_PLLR_MIN -#define STM32_PCLK1_MAX STM32_BOOST_PCLK1_MAX -#define STM32_PCLK2_MAX STM32_BOOST_PCLK2_MAX -#define STM32_ADCCLK_MAX STM32_BOOST_ADCCLK_MAX - -#define STM32_0WS_THRESHOLD STM32_BOOST_0WS_THRESHOLD -#define STM32_1WS_THRESHOLD STM32_BOOST_1WS_THRESHOLD -#define STM32_2WS_THRESHOLD STM32_BOOST_2WS_THRESHOLD -#define STM32_3WS_THRESHOLD STM32_BOOST_3WS_THRESHOLD -#define STM32_4WS_THRESHOLD STM32_BOOST_4WS_THRESHOLD -#define STM32_5WS_THRESHOLD STM32_BOOST_5WS_THRESHOLD -#define STM32_6WS_THRESHOLD STM32_BOOST_6WS_THRESHOLD -#define STM32_7WS_THRESHOLD STM32_BOOST_7WS_THRESHOLD -#define STM32_8WS_THRESHOLD STM32_BOOST_8WS_THRESHOLD - -#else /* !STM32_PWR_BOOST */ -#define STM32_SYSCLK_MAX STM32_VOS1_SYSCLK_MAX_NOBOOST -#define STM32_HSECLK_MAX STM32_VOS1_HSECLK_MAX -#define STM32_HSECLK_BYP_MAX STM32_VOS1_HSECLK_BYP_MAX -#define STM32_HSECLK_MIN STM32_VOS1_HSECLK_MIN -#define STM32_HSECLK_BYP_MIN STM32_VOS1_HSECLK_BYP_MIN -#define STM32_LSECLK_MAX STM32_VOS1_LSECLK_MAX -#define STM32_LSECLK_BYP_MAX STM32_VOS1_LSECLK_BYP_MAX -#define STM32_LSECLK_MIN STM32_VOS1_LSECLK_MIN -#define STM32_LSECLK_BYP_MIN STM32_VOS1_LSECLK_BYP_MIN -#define STM32_PLLIN_MAX STM32_VOS1_PLLIN_MAX -#define STM32_PLLIN_MIN STM32_VOS1_PLLIN_MIN -#define STM32_PLLVCO_MAX STM32_VOS1_PLLVCO_MAX -#define STM32_PLLVCO_MIN STM32_VOS1_PLLVCO_MIN -#define STM32_PLLP_MAX STM32_VOS1_PLLP_MAX -#define STM32_PLLP_MIN STM32_VOS1_PLLP_MIN -#define STM32_PLLQ_MAX STM32_VOS1_PLLQ_MAX -#define STM32_PLLQ_MIN STM32_VOS1_PLLQ_MIN -#define STM32_PLLR_MAX STM32_VOS1_PLLR_MAX -#define STM32_PLLR_MIN STM32_VOS1_PLLR_MIN -#define STM32_PCLK1_MAX STM32_VOS1_PCLK1_MAX -#define STM32_PCLK2_MAX STM32_VOS1_PCLK2_MAX -#define STM32_ADCCLK_MAX STM32_VOS1_ADCCLK_MAX - -#define STM32_0WS_THRESHOLD STM32_VOS1_0WS_THRESHOLD -#define STM32_1WS_THRESHOLD STM32_VOS1_1WS_THRESHOLD -#define STM32_2WS_THRESHOLD STM32_VOS1_2WS_THRESHOLD -#define STM32_3WS_THRESHOLD STM32_VOS1_3WS_THRESHOLD -#define STM32_4WS_THRESHOLD STM32_VOS1_4WS_THRESHOLD -#define STM32_5WS_THRESHOLD STM32_VOS1_5WS_THRESHOLD -#define STM32_6WS_THRESHOLD STM32_VOS1_6WS_THRESHOLD -#define STM32_7WS_THRESHOLD STM32_VOS1_7WS_THRESHOLD -#define STM32_8WS_THRESHOLD STM32_VOS1_8WS_THRESHOLD -#endif /* !STM32_PWR_BOOST */ - -#elif STM32_VOS == STM32_VOS_RANGE2 -#define STM32_SYSCLK_MAX STM32_VOS2_SYSCLK_MAX -#define STM32_SYSCLK_MAX_NOBOOST STM32_VOS2_SYSCLK_MAX_NOBOOST -#define STM32_HSECLK_MAX STM32_VOS2_HSECLK_MAX -#define STM32_HSECLK_BYP_MAX STM32_VOS2_HSECLK_BYP_MAX -#define STM32_HSECLK_MIN STM32_VOS2_HSECLK_MIN -#define STM32_HSECLK_BYP_MIN STM32_VOS2_HSECLK_BYP_MIN -#define STM32_LSECLK_MAX STM32_VOS2_LSECLK_MAX -#define STM32_LSECLK_BYP_MAX STM32_VOS2_LSECLK_BYP_MAX -#define STM32_LSECLK_MIN STM32_VOS2_LSECLK_MIN -#define STM32_LSECLK_BYP_MIN STM32_VOS2_LSECLK_BYP_MIN -#define STM32_PLLIN_MAX STM32_VOS2_PLLIN_MAX -#define STM32_PLLIN_MIN STM32_VOS2_PLLIN_MIN -#define STM32_PLLVCO_MAX STM32_VOS2_PLLVCO_MAX -#define STM32_PLLVCO_MIN STM32_VOS2_PLLVCO_MIN -#define STM32_PLLP_MAX STM32_VOS2_PLLP_MAX -#define STM32_PLLP_MIN STM32_VOS2_PLLP_MIN -#define STM32_PLLQ_MAX STM32_VOS2_PLLQ_MAX -#define STM32_PLLQ_MIN STM32_VOS2_PLLQ_MIN -#define STM32_PLLR_MAX STM32_VOS2_PLLR_MAX -#define STM32_PLLR_MIN STM32_VOS2_PLLR_MIN -#define STM32_PCLK1_MAX STM32_VOS2_PCLK1_MAX -#define STM32_PCLK2_MAX STM32_VOS2_PCLK2_MAX -#define STM32_ADCCLK_MAX STM32_VOS2_ADCCLK_MAX - -#define STM32_0WS_THRESHOLD STM32_VOS2_0WS_THRESHOLD -#define STM32_1WS_THRESHOLD STM32_VOS2_1WS_THRESHOLD -#define STM32_2WS_THRESHOLD STM32_VOS2_2WS_THRESHOLD -#define STM32_3WS_THRESHOLD STM32_VOS2_3WS_THRESHOLD -#define STM32_4WS_THRESHOLD STM32_VOS2_4WS_THRESHOLD -#define STM32_5WS_THRESHOLD STM32_VOS2_5WS_THRESHOLD -#define STM32_6WS_THRESHOLD STM32_VOS2_6WS_THRESHOLD -#define STM32_7WS_THRESHOLD STM32_VOS2_7WS_THRESHOLD -#define STM32_8WS_THRESHOLD STM32_VOS2_8WS_THRESHOLD - -#else -#error "invalid STM32_VOS value specified" -#endif - -/* - * HSI16 related checks. - */ -#if STM32_HSI16_ENABLED -#else /* !STM32_HSI16_ENABLED */ - - #if STM32_SW == STM32_SW_HSI16 - #error "HSI16 not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) - #error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - #if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16)) - #error "HSI16 not enabled, required by STM32_MCOSEL" - #endif - - #if (STM32_USART1SEL == STM32_USART1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_USART1SEL" - #endif - #if (STM32_USART2SEL == STM32_USART2SEL_HSI16) - #error "HSI16 not enabled, required by STM32_USART2SEL" - #endif - #if (STM32_USART3SEL == STM32_USART3SEL_HSI16) - #error "HSI16 not enabled, required by STM32_USART3SEL" - #endif - #if (STM32_UART4SEL == STM32_UART4SEL_HSI16) - #error "HSI16 not enabled, required by STM32_UART4SEL_HSI16" - #endif - #if (STM32_UART5SEL == STM32_UART5SEL_HSI16) - #error "HSI16 not enabled, required by STM32_UART5SEL_HSI16" - #endif - #if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_LPUART1SEL" - #endif - - #if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_I2C1SEL" - #endif - #if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) - #error "HSI16 not enabled, required by STM32_I2C2SEL" - #endif - #if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) - #error "HSI16 not enabled, required by STM32_I2C3SEL" - #endif - #if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) - #error "HSI16 not enabled, required by STM32_I2C4SEL" - #endif - - #if (STM32_SAI1SEL == STM32_SAI1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_SAI1SEL" - #endif - #if (STM32_I2S23SEL == STM32_I2S23SEL_HSI16) - #error "HSI16 not enabled, required by STM32_I2S23SEL" - #endif - - #if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_LPTIM1SEL" - #endif - - #if (STM32_QSPISEL == STM32_QSPISEL_HSI16) - #error "HSI16 not enabled, required by STM32_QSPISEL_HSI16" - #endif - -#endif /* !STM32_HSI16_ENABLED */ - -/* - * HSI48 related checks. - */ -#if STM32_HSI48_ENABLED -#else /* !STM32_HSI48_ENABLED */ - - #if STM32_MCOSEL == STM32_MCOSEL_HSI48 - #error "HSI48 not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 - #error "HSI48 not enabled, required by STM32_CLK48SEL" - #endif - -#endif /* !STM32_HSI48_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#else /* !STM32_HSE_ENABLED */ - - #if STM32_SW == STM32_SW_HSE - #error "HSE not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) - #error "HSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV - #error "HSE not enabled, required by STM32_RTCSEL" - #endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - - #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) - #error "LSI not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSI - #error "LSI not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSI - #error "LSI not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - - #if (STM32_LSECLK == 0) - #error "LSE frequency not defined" - #endif - - #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) - #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" - #endif - -#else /* !STM32_LSE_ENABLED */ - - #if STM32_RTCSEL == STM32_RTCSEL_LSE - #error "LSE not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSE - #error "LSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSE - #error "LSE not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSE_ENABLED */ - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 16)) || \ - defined(__DOXYGEN__) - #define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) -#else - #error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) - #define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 - #define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK - #define STM32_PLLCLKIN 0 - -#else - #error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLL input frequency range check. - */ -#if (STM32_PLLCLKIN != 0) && \ - ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) - #error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_SW == STM32_SW_PLLRCLK) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ - (STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK) || \ - (STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK) || \ - (STM32_I2S23SEL == STM32_I2S23SEL_PLLQCLK) || \ - (STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK) || \ - (STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK) || \ - (STM32_QSPISEL == STM32_QSPISEL_PLLQCLK) || \ - defined(__DOXYGEN__) - - #if STM32_PLLCLKIN == 0 - #error "PLL activation required but no PLL clock selected" - #endif - - /** - * @brief PLL activation flag. - */ - #define STM32_ACTIVATE_PLL TRUE -#else - - #define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 127)) || \ - defined(__DOXYGEN__) - #define STM32_PLLN (STM32_PLLN_VALUE << 8) -#else - #error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) - #define STM32_PLLP (0 << 17) - -#elif STM32_PLLP_VALUE == 17 - #define STM32_PLLP (1 << 17) - -#else - #error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) - #define STM32_PLLQ (0 << 21) - -#elif STM32_PLLQ_VALUE == 4 - #define STM32_PLLQ (1 << 21) - -#elif STM32_PLLQ_VALUE == 6 - #define STM32_PLLQ (2 << 21) - -#elif STM32_PLLQ_VALUE == 8 - #define STM32_PLLQ (3 << 21) - -#else - #error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLR field. - */ -#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) - #define STM32_PLLR (0 << 25) - -#elif STM32_PLLR_VALUE == 4 - #define STM32_PLLR (1 << 25) - -#elif STM32_PLLR_VALUE == 6 - #define STM32_PLLR (2 << 25) - -#elif STM32_PLLR_VALUE == 8 - #define STM32_PLLR (3 << 25) - -#else - #error "invalid STM32_PLLR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLPDIV field. - */ -#if (STM32_PLLPDIV_VALUE == 0) || \ - ((STM32_PLLPDIV_VALUE >= 2) && (STM32_PLLPDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) -#else -#error "invalid STM32_PLLPDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLPEN field. - */ -#if (STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK) || \ - (STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK) || \ - defined(__DOXYGEN__) - #define STM32_PLLPEN (1 << 16) - -#else - #define STM32_PLLPEN (0 << 16) -#endif - -/** - * @brief STM32_PLLQEN field. - */ -#if (STM32_QSPISEL == STM32_QSPISEL_PLLQCLK) || \ - (STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK) || \ - (STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK) || \ - (STM32_I2S23SEL == STM32_I2S23SEL_PLLQCLK) || \ - defined(__DOXYGEN__) - #define STM32_PLLQEN (1 << 20) - -#else - #define STM32_PLLQEN (0 << 20) -#endif - -/** - * @brief STM32_PLLREN field. - */ -#if (STM32_SW == STM32_SW_PLLRCLK) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ - defined(__DOXYGEN__) - #define STM32_PLLREN (1 << 24) - -#else - #define STM32_PLLREN (0 << 24) -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) - #error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL P output clock frequency. - */ -#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) - #define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) -#else - #define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) -#endif - -/** - * @brief PLL Q output clock frequency. - */ -#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) - -/** - * @brief PLL R output clock frequency. - */ -#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) - -/* - * PLL-P output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) - #error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLL-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) - #error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLL-R output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) - #error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) - #define STM32_SYSCLK STM32_HSI16CLK - -#elif (STM32_SW == STM32_SW_HSI16) - #define STM32_SYSCLK STM32_HSI16CLK - -#elif (STM32_SW == STM32_SW_HSE) - #define STM32_SYSCLK STM32_HSECLK - -#elif (STM32_SW == STM32_SW_PLLRCLK) - #define STM32_SYSCLK STM32_PLL_R_CLKOUT - -#else - #error "invalid STM32_SW value specified" -#endif - -/* - * Check on the system clock. - */ -#if STM32_SYSCLK > STM32_SYSCLK_MAX - #error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) - #define STM32_HCLK (STM32_SYSCLK / 1) - -#elif STM32_HPRE == STM32_HPRE_DIV2 - #define STM32_HCLK (STM32_SYSCLK / 2) - -#elif STM32_HPRE == STM32_HPRE_DIV4 - #define STM32_HCLK (STM32_SYSCLK / 4) - -#elif STM32_HPRE == STM32_HPRE_DIV8 - #define STM32_HCLK (STM32_SYSCLK / 8) - -#elif STM32_HPRE == STM32_HPRE_DIV16 - #define STM32_HCLK (STM32_SYSCLK / 16) - -#elif STM32_HPRE == STM32_HPRE_DIV64 - #define STM32_HCLK (STM32_SYSCLK / 64) - -#elif STM32_HPRE == STM32_HPRE_DIV128 - #define STM32_HCLK (STM32_SYSCLK / 128) - -#elif STM32_HPRE == STM32_HPRE_DIV256 - #define STM32_HCLK (STM32_SYSCLK / 256) - -#elif STM32_HPRE == STM32_HPRE_DIV512 - #define STM32_HCLK (STM32_SYSCLK / 512) - -#else - #error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX - #error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) - #define STM32_PCLK1 (STM32_HCLK / 1) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 - #define STM32_PCLK1 (STM32_HCLK / 2) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 - #define STM32_PCLK1 (STM32_HCLK / 4) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 - #define STM32_PCLK1 (STM32_HCLK / 8) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 - #define STM32_PCLK1 (STM32_HCLK / 16) - -#else - #error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) - #define STM32_PCLK2 (STM32_HCLK / 1) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 - #define STM32_PCLK2 (STM32_HCLK / 2) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 - #define STM32_PCLK2 (STM32_HCLK / 4) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 - #define STM32_PCLK2 (STM32_HCLK / 8) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 - #define STM32_PCLK2 (STM32_HCLK / 16) - -#else - #error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief MCO divider clock frequency. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) - #define STM32_MCODIVCLK 0 - -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK - #define STM32_MCODIVCLK STM32_SYSCLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 - #define STM32_MCODIVCLK STM32_HSI16CLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSE - #define STM32_MCODIVCLK STM32_HSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_PLLRCLK - #define STM32_MCODIVCLK STM32_PLL_R_CLKOUT - -#elif STM32_MCOSEL == STM32_MCOSEL_LSI - #define STM32_MCODIVCLK STM32_LSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_LSE - #define STM32_MCODIVCLK STM32_LSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 - #define STM32_MCODIVCLK STM32_HSI48CLK - -#else - #error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock frequency. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) - #define STM32_MCOCLK STM32_MCODIVCLK - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 - #define STM32_MCOCLK (STM32_MCODIVCLK / 2) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 - #define STM32_MCOCLK (STM32_MCODIVCLK / 4) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 - #define STM32_MCOCLK (STM32_MCODIVCLK / 8) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 - #define STM32_MCOCLK (STM32_MCODIVCLK / 16) - -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief RTC clock frequency. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) - #define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE - #define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI - #define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV - #define STM32_RTCCLK (STM32_HSECLK / 32) - -#else - #error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 clock frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) - #define STM32_USART1CLK STM32_PCLK2 - -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK - #define STM32_USART1CLK STM32_SYSCLK - -#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 - #define STM32_USART1CLK STM32_HSI16CLK - -#elif STM32_USART1SEL == STM32_USART1SEL_LSE - #define STM32_USART1CLK STM32_LSECLK - -#else - #error "invalid source selected for USART1 clock" -#endif - - /** - * @brief USART2 clock frequency. - */ - #if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_USART2CLK STM32_PCLK1 - - #elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK - #define STM32_USART2CLK STM32_SYSCLK - - #elif STM32_USART2SEL == STM32_USART2SEL_HSI16 - #define STM32_USART2CLK STM32_HSI16CLK - - #elif STM32_USART2SEL == STM32_USART2SEL_LSE - #define STM32_USART2CLK STM32_LSECLK - - #else - #error "invalid source selected for USART2 clock" - #endif - - /** - * @brief USART3 clock frequency. - */ - #if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_USART3CLK STM32_PCLK1 - - #elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK - #define STM32_USART3CLK STM32_SYSCLK - - #elif STM32_USART3SEL == STM32_USART3SEL_HSI16 - #define STM32_USART3CLK STM32_HSI16CLK - - #elif STM32_USART3SEL == STM32_USART3SEL_LSE - #define STM32_USART3CLK STM32_LSECLK - - #else - #error "invalid source selected for USART3 clock" - #endif - -/** - * @brief UART4 clock frequency. - */ -#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_UART4CLK STM32_PCLK1 - -#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK - #define STM32_UART4CLK STM32_SYSCLK - -#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 - #define STM32_UART4CLK STM32_HSI16CLK - -#elif STM32_UART4SEL == STM32_UART4SEL_LSE - #define STM32_UART4CLK STM32_LSECLK - -#else - #error "invalid source selected for UART4 clock" -#endif - -/** - * @brief UART5 clock frequency. - */ -#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_UART5CLK STM32_PCLK1 - -#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK - #define STM32_UART5CLK STM32_SYSCLK - -#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 - #define STM32_UART5CLK STM32_HSI16CLK - -#elif STM32_UART5SEL == STM32_UART5SEL_LSE - #define STM32_UART5CLK STM32_LSECLK - -#else - #error "invalid source selected for UART5 clock" -#endif - -/** - * @brief LPUART1 clock frequency. - */ -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_LPUART1CLK STM32_PCLK1 - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK - #define STM32_LPUART1CLK STM32_SYSCLK - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 - #define STM32_LPUART1CLK STM32_HSI16CLK - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE - #define STM32_LPUART1CLK STM32_LSECLK - -#else -#error "invalid source selected for LPUART1 clock" -#endif - -/** - * @brief I2C1 clock frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_I2C1CLK STM32_PCLK1 - -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK - #define STM32_I2C1CLK STM32_SYSCLK - -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 - #define STM32_I2C1CLK STM32_HSI16CLK - -#else - #error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 clock frequency. - */ -#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_I2C2CLK STM32_PCLK1 - -#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK - #define STM32_I2C2CLK STM32_SYSCLK - -#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 - #define STM32_I2C2CLK STM32_HSI16CLK - -#else - #error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C3 clock frequency. - */ -#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_I2C3CLK STM32_PCLK1 - -#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK - #define STM32_I2C3CLK STM32_SYSCLK - -#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 - #define STM32_I2C3CLK STM32_HSI16CLK - -#else - #error "invalid source selected for I2C3 clock" -#endif - -/** - * @brief I2C4 clock frequency. - */ -#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_I2C4CLK STM32_PCLK1 - -#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK - #define STM32_I2C4CLK STM32_SYSCLK - -#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 - #define STM32_I2C4CLK STM32_HSI16CLK - -#else - #error "invalid source selected for I2C4 clock" -#endif - -/** - * @brief LPTIM1 clock frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) - #define STM32_LPTIM1CLK STM32_PCLK1 - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI - #define STM32_LPTIM1CLK STM32_LSICLK - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 - #define STM32_LPTIM1CLK STM32_HSI16CLK - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE - #define STM32_LPTIM1CLK STM32_LSECLK - -#else - #error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief SAI1 clock frequency. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_SYSCLK) || defined(__DOXYGEN__) - #define STM32_SAI1CLK STM32_SYSCLK - -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK - #define STM32_SAI1CLK STM32_PLL_Q_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16 - #define STM32_SAI1CLK STM32_HSI16CLK - -#elif STM32_SAI1SEL == STM32_SAI1SEL_CKIN - #define STM32_SAI1CLK 0 /* Unknown, would require a board value */ - -#else - #error "invalid source selected for SAI1 clock" -#endif - -/** - * @brief I2S23 clock frequency. - */ -#if (STM32_I2S23SEL == STM32_I2S23SEL_SYSCLK) || defined(__DOXYGEN__) - #define STM32_I2S23CLK STM32_SYSCLK - -#elif STM32_I2S23SEL == STM32_I2S23SEL_PLLPCLK - #define STM32_I2S23CLK STM32_PLL_P_CLKOUT - -#elif STM32_I2S23SEL == STM32_I2S23SEL_HSI16 - #define STM32_I2S23CLK STM32_HSI16CLK - -#elif STM32_I2S23SEL == STM32_I2S23SEL_CKIN - #define STM32_I2S23CLK 0 /* Unknown, would require a board value */ - -#else - #error "invalid source selected for SAI1 clock" -#endif - -/** - * @brief FDCAN clock frequency. - */ -#if (STM32_FDCANSEL == STM32_FDCANSEL_HSE) || defined(__DOXYGEN__) - #define STM32_FDCANCLK STM32_HSECLK - -#elif STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK - #define STM32_FDCANCLK STM32_PLL_Q_CLKOUT - -#elif STM32_FDCANSEL == STM32_FDCANSEL_PCLK1 - #define STM32_FDCANCLK STM32_PCLK1 - -#else - #error "invalid source selected for FDCAN clock" -#endif - -/** - * @brief 48MHz clock frequency. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) - #define STM32_48CLK STM32_HSI48CLK - -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK - #define STM32_48CLK STM32_PLL_Q_CLKOUT - -#else - #error "invalid source selected for 48MHz clock" -#endif - -/** - * @brief ADC clock frequency. - */ -#if (STM32_ADC12SEL == STM32_ADC12SEL_NOCLK) || defined(__DOXYGEN__) - #define STM32_ADC12CLK 0 - -#elif STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK - #define STM32_ADC12CLK STM32_PLL_P_CLKOUT - -#elif STM32_ADC12SEL == STM32_ADC12SEL_SYSCLK - #define STM32_ADC12CLK STM32_SYSCLK - -#else - #error "invalid source selected for ADC clock" -#endif - -/** - * @brief ADC clock frequency. - */ -#if (STM32_ADC345SEL == STM32_ADC345SEL_NOCLK) || defined(__DOXYGEN__) - #define STM32_ADC345CLK 0 - -#elif STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK - #define STM32_ADC345CLK STM32_PLL_P_CLKOUT - -#elif STM32_ADC345SEL == STM32_ADC345SEL_SYSCLK - #define STM32_ADC345CLK STM32_SYSCLK - -#else - #error "invalid source selected for ADC clock" -#endif - -/** - * @brief TIMP1CLK clock frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) - #define STM32_TIMP1CLK (STM32_PCLK1 * 1) -#else - #define STM32_TIMP1CLK (STM32_PCLK1 * 2) -#endif - -/** - * @brief TIMP2CLK clock frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) - #define STM32_TIMP2CLK (STM32_PCLK2 * 1) -#else - #define STM32_TIMP2CLK (STM32_PCLK2 * 2) -#endif - -/** - * @brief Clock of timers connected to APB1. - */ -#define STM32_TIMCLK1 STM32_TIMP1CLK - -/** - * @brief Clock of timers connected to APB2. - */ -#define STM32_TIMCLK2 STM32_TIMP2CLK - -/** - * @brief RNG clock point. - */ -#define STM32_RNGCLK STM32_48CLK - -/** - * @brief USB clock point. - */ -#define STM32_USBCLK STM32_48CLK - -/** - * @brief Voltage boost settings. - */ -#if STM32_PWR_BOOST || defined(__DOXYGEN__) -#define STM32_CR5BITS PWR_CR5_R1MODE -#else -#define STM32_CR5BITS 0U -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) - #define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD - #define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD - #define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_HCLK <= STM32_3WS_THRESHOLD - #define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS - -#elif STM32_HCLK <= STM32_4WS_THRESHOLD - #define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS - -#else - #define STM32_FLASHBITS FLASH_ACR_LATENCY_5WS -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32G4xx/hal_lld.h + * @brief STM32G4xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32G431xx, STM32G441xx, STM32G471xx. + * - STM32G473xx, STM32G483xx. + * - STM32G474xx, STM32G484xx. + * - STM32GBK1CB. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(STM32G431xx) || defined(STM32G441xx) || defined(STM32G471xx) || \ + defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32G4 Access Line" + +#elif defined(STM32G473xx) +#define PLATFORM_NAME "STM32G4 Performance Line" + +#elif defined(STM32G483xx) +#define PLATFORM_NAME "STM32G4 Performance Line with Crypto" + +#elif defined(STM32G474xx) +#define PLATFORM_NAME "STM32G4 Hi-resolution Line" + +#elif defined(STM32G484xx) +#define PLATFORM_NAME "STM32G4 Hi-resolution Line with Crypto" + +#elif defined(STM32GBK1CB) +#define PLATFORM_NAME "STM32G4 Mystery Line" + +#else +#error "STM32G4 device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32G4XX) || defined(__DOXYGEN__) +#define STM32G4XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSI16CLK 16000000U /**< 16MHz internal clock. */ +#define STM32_HSI48CLK 48000000U /**< 48MHz internal clock. */ +#define STM32_LSICLK 32000U /**< Low speed internal clock. */ +/** @} */ + +/** + * @name VOS field definitions + * @{ + */ +#define STM32_VOS_MASK (3U << 9U) /**< Core voltage mask. */ +#define STM32_VOS_RANGE1 (1U << 9U) /**< Core voltage 1.2 Volts. */ +#define STM32_VOS_RANGE2 (2U << 9U) /**< Core voltage 1.0 Volts. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3U << 0U) /**< SW field mask. */ +#define STM32_SW_HSI16 (1U << 0U) /**< SYSCLK source is HSI16. */ +#define STM32_SW_HSE (2U << 0U) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLLRCLK (3U << 0U) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15U << 4U) /**< HPRE field mask. */ +#define STM32_HPRE_FIELD(n) ((n) << 4U) /**< HPRE field value. */ +#define STM32_HPRE_DIV1 STM32_HPRE_FIELD(0U) +#define STM32_HPRE_DIV2 STM32_HPRE_FIELD(8U) +#define STM32_HPRE_DIV4 STM32_HPRE_FIELD(9U) +#define STM32_HPRE_DIV8 STM32_HPRE_FIELD(10U) +#define STM32_HPRE_DIV16 STM32_HPRE_FIELD(11U) +#define STM32_HPRE_DIV64 STM32_HPRE_FIELD(12U) +#define STM32_HPRE_DIV128 STM32_HPRE_FIELD(13U) +#define STM32_HPRE_DIV256 STM32_HPRE_FIELD(14U) +#define STM32_HPRE_DIV512 STM32_HPRE_FIELD(15U) + +#define STM32_PPRE1_MASK (7U << 8U) /**< PPRE1 field mask. */ +#define STM32_PPRE1_FIELD(n) ((n) << 8U) /**< PPRE1 field value. */ +#define STM32_PPRE1_DIV1 STM32_PPRE1_FIELD(0U) +#define STM32_PPRE1_DIV2 STM32_PPRE1_FIELD(4U) +#define STM32_PPRE1_DIV4 STM32_PPRE1_FIELD(5U) +#define STM32_PPRE1_DIV8 STM32_PPRE1_FIELD(6U) +#define STM32_PPRE1_DIV16 STM32_PPRE1_FIELD(7U) + +#define STM32_PPRE2_MASK (7U << 11U) /**< PPRE2 field mask. */ +#define STM32_PPRE2_FIELD(n) ((n) << 11U) /**< PPRE2 field value. */ +#define STM32_PPRE2_DIV1 STM32_PPRE2_FIELD(0U) +#define STM32_PPRE2_DIV2 STM32_PPRE2_FIELD(4U) +#define STM32_PPRE2_DIV4 STM32_PPRE2_FIELD(5U) +#define STM32_PPRE2_DIV8 STM32_PPRE2_FIELD(6U) +#define STM32_PPRE2_DIV16 STM32_PPRE2_FIELD(7U) + +#define STM32_MCOSEL_MASK (15U << 24U)/**< MCOSEL field mask. */ +#define STM32_MCOSEL_NOCLOCK (0U << 24U) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1U << 24U) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI16 (3U << 24U) /**< HSI16 clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4U << 24U) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLLRCLK (5U << 24U) /**< PLLR clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6U << 24U) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7U << 24U) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_HSI48 (8U << 24U) /**< HSI48 clock on MCO pin. */ + +#define STM32_MCOPRE_MASK (7U << 28U) /**< MCOPRE field mask. */ +#define STM32_MCOPRE_FIELD(n) ((n) << 28U)/**< MCOPRE field value */ +#define STM32_MCOPRE_DIV1 STM32_MCOPRE_FIELD(0U) +#define STM32_MCOPRE_DIV2 STM32_MCOPRE_FIELD(1U) +#define STM32_MCOPRE_DIV4 STM32_MCOPRE_FIELD(2U) +#define STM32_MCOPRE_DIV8 STM32_MCOPRE_FIELD(3U) +#define STM32_MCOPRE_DIV16 STM32_MCOPRE_FIELD(4U) +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CCIPR register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3U << 0U) /**< USART1SEL mask. */ +#define STM32_USART1SEL_PCLK2 (0U << 0U) /**< USART1 source is PCLK2. */ +#define STM32_USART1SEL_SYSCLK (1U << 0U) /**< USART1 source is SYSCLK. */ +#define STM32_USART1SEL_HSI16 (2U << 0U) /**< USART1 source is HSI16. */ +#define STM32_USART1SEL_LSE (3U << 0U) /**< USART1 source is LSE. */ + +#define STM32_USART2SEL_MASK (3U << 2U) /**< USART2 mask. */ +#define STM32_USART2SEL_PCLK1 (0U << 2U) /**< USART2 source is PCLK1. */ +#define STM32_USART2SEL_SYSCLK (1U << 2U) /**< USART2 source is SYSCLK. */ +#define STM32_USART2SEL_HSI16 (2U << 2U) /**< USART2 source is HSI16. */ +#define STM32_USART2SEL_LSE (3U << 2U) /**< USART2 source is LSE. */ + +#define STM32_USART3SEL_MASK (3U << 4U) /**< USART3 mask. */ +#define STM32_USART3SEL_PCLK1 (0U << 4U) /**< USART3 source is PCLK1. */ +#define STM32_USART3SEL_SYSCLK (1U << 4U) /**< USART3 source is SYSCLK. */ +#define STM32_USART3SEL_HSI16 (2U << 4U) /**< USART3 source is HSI16. */ +#define STM32_USART3SEL_LSE (3U << 4U) /**< USART3 source is LSE. */ + +#define STM32_UART4SEL_MASK (3U << 6U) /**< UART4 mask. */ +#define STM32_UART4SEL_PCLK1 (0U << 6U) /**< UART4 source is PCLK1. */ +#define STM32_UART4SEL_SYSCLK (1U << 6U) /**< UART4 source is SYSCLK. */ +#define STM32_UART4SEL_HSI16 (2U << 6U) /**< UART4 source is HSI16. */ +#define STM32_UART4SEL_LSE (3U << 6U) /**< UART4 source is LSE. */ + +#define STM32_UART5SEL_MASK (3U << 8U) /**< UART5 mask. */ +#define STM32_UART5SEL_PCLK1 (0U << 8U) /**< UART5 source is PCLK1. */ +#define STM32_UART5SEL_SYSCLK (1U << 8U) /**< UART5 source is SYSCLK. */ +#define STM32_UART5SEL_HSI16 (2U << 8U) /**< UART5 source is HSI16. */ +#define STM32_UART5SEL_LSE (3U << 8U) /**< UART5 source is LSE. */ + +#define STM32_LPUART1SEL_MASK (3U << 10U) /**< LPUART1 mask. */ +#define STM32_LPUART1SEL_PCLK1 (0U << 10U) /**< LPUART1 source is PCLK1. */ +#define STM32_LPUART1SEL_SYSCLK (1U << 10U) /**< LPUART1 source is SYSCLK. */ +#define STM32_LPUART1SEL_HSI16 (2U << 10U) /**< LPUART1 source is HSI16. */ +#define STM32_LPUART1SEL_LSE (3U << 10U) /**< LPUART1 source is LSE. */ + +#define STM32_I2C1SEL_MASK (3U << 12U) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK1 (0U << 12U) /**< I2C1 source is PCLK1. */ +#define STM32_I2C1SEL_SYSCLK (1U << 12U) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI16 (2U << 12U) /**< I2C1 source is HSI16. */ + +#define STM32_I2C2SEL_MASK (3U << 14U) /**< I2C2SEL mask. */ +#define STM32_I2C2SEL_PCLK1 (0U << 14U) /**< I2C2 source is PCLK1. */ +#define STM32_I2C2SEL_SYSCLK (1U << 14U) /**< I2C2 source is SYSCLK. */ +#define STM32_I2C2SEL_HSI16 (2U << 14U) /**< I2C2 source is HSI16. */ + +#define STM32_I2C3SEL_MASK (3U << 16U) /**< I2C3SEL mask. */ +#define STM32_I2C3SEL_PCLK1 (0U << 16U) /**< I2C3 source is PCLK1. */ +#define STM32_I2C3SEL_SYSCLK (1U << 16U) /**< I2C3 source is SYSCLK. */ +#define STM32_I2C3SEL_HSI16 (2U << 16U) /**< I2C3 source is HSI16. */ + +#define STM32_LPTIM1SEL_MASK (3U << 18U) /**< LPTIM1SEL mask. */ +#define STM32_LPTIM1SEL_PCLK1 (0U << 18U) /**< LPTIM1 source is PCLK1. */ +#define STM32_LPTIM1SEL_LSI (1U << 18U) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_HSI16 (2U << 18U) /**< LPTIM1 source is HSI16. */ +#define STM32_LPTIM1SEL_LSE (3U << 18U) /**< LPTIM1 source is LSE. */ + +#define STM32_SAI1SEL_MASK (3U << 20U) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_SYSCLK (0U << 20U) /**< SAI1 source is SYSCLK. */ +#define STM32_SAI1SEL_PLLQCLK (1U << 20U) /**< SAI1 source is PLLQCLK. */ +#define STM32_SAI1SEL_CKIN (2U << 20U) /**< SAI1 source is CKIN. */ +#define STM32_SAI1SEL_HSI16 (3U << 20U) /**< SAI1 source is HSI16. */ + +#define STM32_I2S23SEL_MASK (3U << 22U) /**< I2S23SEL mask. */ +#define STM32_I2S23SEL_SYSCLK (0U << 22U) /**< I2S23 source is SYSCLK. */ +#define STM32_I2S23SEL_PLLQCLK (1U << 22U) /**< I2S23 source is PLLQCLK. */ +#define STM32_I2S23SEL_CKIN (2U << 22U) /**< I2S23 source is CKIN. */ +#define STM32_I2S23SEL_HSI16 (3U << 22U) /**< I2S23 source is HSI16. */ + +#define STM32_FDCANSEL_MASK (3U << 24U) /**< FDCANSEL mask. */ +#define STM32_FDCANSEL_HSE (0U << 24U) /**< FDCAN source is HSE. */ +#define STM32_FDCANSEL_PLLQCLK (1U << 24U) /**< FDCAN source is PLLQCLK. */ +#define STM32_FDCANSEL_PCLK1 (2U << 24U) /**< FDCAN source is PCLK1. */ + +#define STM32_CLK48SEL_MASK (3U << 26U) /**< CLK48SEL mask. */ +#define STM32_CLK48SEL_HSI48 (0U << 26U) /**< CLK48 source is HSI48. */ +#define STM32_CLK48SEL_PLLQCLK (2U << 26U) /**< CLK48 source is PLLQCLK. */ + +#define STM32_ADC12SEL_MASK (3U << 28U) /**< ADC12SEL mask. */ +#define STM32_ADC12SEL_NOCLK (0U << 28U) /**< ADC12 source is none. */ +#define STM32_ADC12SEL_PLLPCLK (1U << 28U) /**< ADC12 source is PLLPCLK. */ +#define STM32_ADC12SEL_SYSCLK (2U << 28U) /**< ADC12 source is SYSCLK. */ + +#define STM32_ADC345SEL_MASK (3U << 30U) /**< ADC345SEL mask. */ +#define STM32_ADC345SEL_NOCLK (0U << 30U) /**< ADC345 source is none. */ +#define STM32_ADC345SEL_PLLPCLK (1U << 30U) /**< ADC345 source is PLLPCLK. */ +#define STM32_ADC345SEL_SYSCLK (2U << 30U) /**< ADC345 source is SYSCLK. */ +/** @} */ + +/** + * @name RCC_CCIPR2 register bits definitions + * @{ + */ +#define STM32_I2C4SEL_MASK (3U << 0U) /**< I2C4SEL mask. */ +#define STM32_I2C4SEL_PCLK1 (0U << 0U) /**< I2C4 source is PCLK1. */ +#define STM32_I2C4SEL_SYSCLK (1U << 0U) /**< I2C4 source is SYSCLK. */ +#define STM32_I2C4SEL_HSI16 (2U << 0U) /**< I2C4 source is HSI16. */ + +#define STM32_QSPISEL_MASK (3U << 20U) /**< QSPISEL mask. */ +#define STM32_QSPISEL_SYSCLK (0U << 20U) /**< QSPI source is SYSCLK. */ +#define STM32_QSPISEL_HSI16 (1U << 20U) /**< QSPI source is HSI16. */ +#define STM32_QSPISEL_PLLQCLK (2U << 20U) /**< QSPI source is PLLQCLK. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3U << 8U) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0U << 8U) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1U << 8U) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2U << 8U) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3U << 8U) /**< RTC source is HSE divided. */ + +#define STM32_LSCOSEL_MASK (3U << 24U) /**< LSCO pin clock source. */ +#define STM32_LSCOSEL_NOCLOCK (0U << 24U) /**< No clock on LSCO pin. */ +#define STM32_LSCOSEL_LSI (1U << 24U) /**< LSI on LSCO pin. */ +#define STM32_LSCOSEL_LSE (3U << 24U) /**< LSE on LSCO pin. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_RANGE1 +#endif + +/** + * @brief Core voltage boost. + * @note The boost can only be used when STM32_VOS==STM32_VOS_RANGE1. + */ +#if !defined(STM32_PWR_BOOST) || defined(__DOXYGEN__) +#define STM32_PWR_BOOST TRUE +#endif + +/** + * @brief PWR CR2 register initialization value. + */ +#if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__) +#define STM32_PWR_CR2 (PWR_CR2_PLS_LEV0) +#endif + +/** + * @brief PWR CR3 register initialization value. + */ +#if !defined(STM32_PWR_CR3) || defined(__DOXYGEN__) +#define STM32_PWR_CR3 (PWR_CR3_EIWF) +#endif + +/** + * @brief PWR CR4 register initialization value. + */ +#if !defined(STM32_PWR_CR4) || defined(__DOXYGEN__) +#define STM32_PWR_CR4 (0U) +#endif + +/** + * @brief PWR PUCRA register initialization value. + */ +#if !defined(STM32_PWR_PUCRA) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRA (0U) +#endif + +/** + * @brief PWR PDCRA register initialization value. + */ +#if !defined(STM32_PWR_PDCRA) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRA (0U) +#endif + +/** + * @brief PWR PUCRB register initialization value. + */ +#if !defined(STM32_PWR_PUCRB) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRB (0U) +#endif + +/** + * @brief PWR PDCRB register initialization value. + */ +#if !defined(STM32_PWR_PDCRB) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRB (0U) +#endif + +/** + * @brief PWR PUCRC register initialization value. + */ +#if !defined(STM32_PWR_PUCRC) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRC (0U) +#endif + +/** + * @brief PWR PDCRC register initialization value. + */ +#if !defined(STM32_PWR_PDCRC) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRC (0U) +#endif + +/** + * @brief PWR PUCRD register initialization value. + */ +#if !defined(STM32_PWR_PUCRD) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRD (0U) +#endif + +/** + * @brief PWR PDCRD register initialization value. + */ +#if !defined(STM32_PWR_PDCRD) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRD (0U) +#endif + +/** + * @brief PWR PUCRE register initialization value. + */ +#if !defined(STM32_PWR_PUCRE) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRE (0U) +#endif + +/** + * @brief PWR PDCRE register initialization value. + */ +#if !defined(STM32_PWR_PDCRE) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRE (0U) +#endif + +/** + * @brief PWR PUCRF register initialization value. + */ +#if !defined(STM32_PWR_PUCRF) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRF (0U) +#endif + +/** + * @brief PWR PDCRF register initialization value. + */ +#if !defined(STM32_PWR_PDCRF) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRF (0U) +#endif + +/** + * @brief PWR PUCRG register initialization value. + */ +#if !defined(STM32_PWR_PUCRG) || defined(__DOXYGEN__) +#define STM32_PWR_PUCRG (0U) +#endif + +/** + * @brief PWR PDCRG register initialization value. + */ +#if !defined(STM32_PWR_PDCRG) || defined(__DOXYGEN__) +#define STM32_PWR_PDCRG (0U) +#endif + +/** + * @brief Enables or disables the HSI16 clock source. + */ +#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSI48 clock source. + */ +#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI48_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 170MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLLRCLK +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 170MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSI16 +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 170MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 4 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 8..127. + * @note The default value is calculated for a 170MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 84 +#endif + +/** + * @brief PLLPDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLPDIV_VALUE 0 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 7 +#endif + +/** + * @brief PLLQ divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 8 +#endif + +/** + * @brief PLLR divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 170MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLR_VALUE 2 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 170MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV2 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief LSCO clock source. + */ +#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) +#define STM32_USART3SEL STM32_USART3SEL_SYSCLK +#endif + +/** + * @brief UART4 clock source. + */ +#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) +#define STM32_UART4SEL STM32_UART4SEL_SYSCLK +#endif + +/** + * @brief UART5 clock source. + */ +#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) +#define STM32_UART5SEL STM32_UART5SEL_SYSCLK +#endif + +/** + * @brief LPUART1 clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_PCLK1 +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) +#define STM32_I2C2SEL STM32_I2C2SEL_PCLK1 +#endif + +/** + * @brief I2C3 clock source. + */ +#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) +#define STM32_I2C3SEL STM32_I2C3SEL_PCLK1 +#endif + +/** + * @brief I2C4 clock source. + */ +#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) +#define STM32_I2C4SEL STM32_I2C4SEL_PCLK1 +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#endif + +/** + * @brief SAI1 clock source. + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_SYSCLK +#endif + +/** + * @brief I2S23 clock source. + */ +#if !defined(STM32_I2S23SEL) || defined(__DOXYGEN__) +#define STM32_I2S23SEL STM32_I2S23SEL_SYSCLK +#endif + +/** + * @brief FDCAN clock source. + */ +#if !defined(STM32_FDCANSEL) || defined(__DOXYGEN__) +#define STM32_FDCANSEL STM32_FDCANSEL_HSE +#endif + +/** + * @brief CLK48 clock source. + */ +#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) +#define STM32_CLK48SEL STM32_CLK48SEL_HSI48 +#endif + +/** + * @brief ADC12 clock source. + */ +#if !defined(STM32_ADC12SEL) || defined(__DOXYGEN__) +#define STM32_ADC12SEL STM32_ADC12SEL_PLLPCLK +#endif + +/** + * @brief ADC34 clock source. + */ +#if !defined(STM32_ADC345SEL) || defined(__DOXYGEN__) +#define STM32_ADC345SEL STM32_ADC345SEL_PLLPCLK +#endif + +/** + * @brief QSPI clock source. + */ +#if !defined(STM32_QSPISEL) || defined(__DOXYGEN__) +#define STM32_QSPISEL STM32_QSPISEL_SYSCLK +#endif + +/** + * @brief RTC clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_NOCLOCK +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Boost mode checks.*/ +#if STM32_PWR_BOOST && (STM32_VOS != STM32_VOS_RANGE1) +#error "STM32_PWR_BOOST requires STM32_VOS_RANGE1" +#endif + +/* + * Configuration-related checks. + */ +#if !defined(STM32G4xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G4xx_MCUCONF not defined" +#endif + +#if defined(STM32G431xx) && !defined(STM32G431_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G431_MCUCONF not defined" + +#elif defined(STM32G441xx) && !defined(STM32G441_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G441_MCUCONF not defined" + +#elif defined(STM32G471xx) && !defined(STM32G471_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G471_MCUCONF not defined" + +#elif defined(STM32G473xx) && !defined(STM32G473_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G473_MCUCONF not defined" + +#elif defined(STM32G483xx) && !defined(STM32G473_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G483_MCUCONF not defined" + +#elif defined(STM32G474xx) && !defined(STM32G474_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G474_MCUCONF not defined" + +#elif defined(STM32G484xx) && !defined(STM32G484_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32G484_MCUCONF not defined" + +#elif defined(STM32GBK1CB) && !defined(STM32GBK1CB_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32GBK1CB_MCUCONF not defined" + +#endif + +/* + * Board files sanity checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif + +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/** + * @name System Limits for VOS range 1 with boost + * @{ + */ +#define STM32_BOOST_SYSCLK_MAX 170000000 +#define STM32_BOOST_HSECLK_MAX 48000000 +#define STM32_BOOST_HSECLK_BYP_MAX 48000000 +#define STM32_BOOST_HSECLK_MIN 8000000 +#define STM32_BOOST_HSECLK_BYP_MIN 8000000 +#define STM32_BOOST_LSECLK_MAX 32768 +#define STM32_BOOST_LSECLK_BYP_MAX 1000000 +#define STM32_BOOST_LSECLK_MIN 32768 +#define STM32_BOOST_LSECLK_BYP_MIN 32768 +#define STM32_BOOST_PLLIN_MAX 16000000 +#define STM32_BOOST_PLLIN_MIN 2660000 +#define STM32_BOOST_PLLVCO_MAX 344000000 +#define STM32_BOOST_PLLVCO_MIN 96000000 +#define STM32_BOOST_PLLP_MAX 170000000 +#define STM32_BOOST_PLLP_MIN 2064500 +#define STM32_BOOST_PLLQ_MAX 170000000 +#define STM32_BOOST_PLLQ_MIN 8000000 +#define STM32_BOOST_PLLR_MAX 170000000 +#define STM32_BOOST_PLLR_MIN 8000000 +#define STM32_BOOST_PCLK1_MAX 170000000 +#define STM32_BOOST_PCLK2_MAX 170000000 +#define STM32_BOOST_ADCCLK_MAX 60000000 + +#define STM32_BOOST_0WS_THRESHOLD 34000000 +#define STM32_BOOST_1WS_THRESHOLD 68000000 +#define STM32_BOOST_2WS_THRESHOLD 102000000 +#define STM32_BOOST_3WS_THRESHOLD 136000000 +#define STM32_BOOST_4WS_THRESHOLD 170000000 +/** @} */ + +/** + * @name System Limits for VOS range 1 without boost + * @{ + */ +#define STM32_VOS1_SYSCLK_MAX 150000000 +#define STM32_VOS1_HSECLK_MAX 48000000 +#define STM32_VOS1_HSECLK_BYP_MAX 48000000 +#define STM32_VOS1_HSECLK_MIN 8000000 +#define STM32_VOS1_HSECLK_BYP_MIN 8000000 +#define STM32_VOS1_LSECLK_MAX 32768 +#define STM32_VOS1_LSECLK_BYP_MAX 1000000 +#define STM32_VOS1_LSECLK_MIN 32768 +#define STM32_VOS1_LSECLK_BYP_MIN 32768 +#define STM32_VOS1_PLLIN_MAX 16000000 +#define STM32_VOS1_PLLIN_MIN 2660000 +#define STM32_VOS1_PLLVCO_MAX 344000000 +#define STM32_VOS1_PLLVCO_MIN 96000000 +#define STM32_VOS1_PLLP_MAX 150000000 +#define STM32_VOS1_PLLP_MIN 2064500 +#define STM32_VOS1_PLLQ_MAX 150000000 +#define STM32_VOS1_PLLQ_MIN 8000000 +#define STM32_VOS1_PLLR_MAX 150000000 +#define STM32_VOS1_PLLR_MIN 8000000 +#define STM32_VOS1_PCLK1_MAX 150000000 +#define STM32_VOS1_PCLK2_MAX 150000000 +#define STM32_VOS1_ADCCLK_MAX 60000000 + +#define STM32_VOS1_0WS_THRESHOLD 30000000 +#define STM32_VOS1_1WS_THRESHOLD 60000000 +#define STM32_VOS1_2WS_THRESHOLD 90000000 +#define STM32_VOS1_3WS_THRESHOLD 120000000 +#define STM32_VOS1_4WS_THRESHOLD 150000000 +/** @} */ + +/** + * @name System Limits for VOS range 2 + * @{ + */ +#define STM32_VOS2_SYSCLK_MAX 26000000 +#define STM32_VOS2_HSECLK_MAX 26000000 +#define STM32_VOS2_HSECLK_BYP_MAX 26000000 +#define STM32_VOS2_HSECLK_MIN 8000000 +#define STM32_VOS2_HSECLK_BYP_MIN 8000000 +#define STM32_VOS2_LSECLK_MAX 32768 +#define STM32_VOS2_LSECLK_BYP_MAX 1000000 +#define STM32_VOS2_LSECLK_MIN 32768 +#define STM32_VOS2_LSECLK_BYP_MIN 32768 +#define STM32_VOS2_PLLIN_MAX 16000000 +#define STM32_VOS2_PLLIN_MIN 2660000 +#define STM32_VOS2_PLLVCO_MAX 128000000 +#define STM32_VOS2_PLLVCO_MIN 96000000 +#define STM32_VOS2_PLLP_MAX 26000000 +#define STM32_VOS2_PLLP_MIN 2064500 +#define STM32_VOS2_PLLQ_MAX 26000000 +#define STM32_VOS2_PLLQ_MIN 8000000 +#define STM32_VOS2_PLLR_MAX 26000000 +#define STM32_VOS2_PLLR_MIN 8000000 +#define STM32_VOS2_PCLK1_MAX 26000000 +#define STM32_VOS2_PCLK2_MAX 26000000 +#define STM32_VOS2_ADCCLK_MAX 26000000 + +#define STM32_VOS2_0WS_THRESHOLD 12000000 +#define STM32_VOS2_1WS_THRESHOLD 24000000 +#define STM32_VOS2_2WS_THRESHOLD 26000000 +#define STM32_VOS2_3WS_THRESHOLD 0 +#define STM32_VOS2_4WS_THRESHOLD 0 +/** @} */ + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) +#if STM32_PWR_BOOST || defined(__DOXYGEN__) +#define STM32_SYSCLK_MAX STM32_BOOST_SYSCLK_MAX +#define STM32_HSECLK_MAX STM32_BOOST_HSECLK_MAX +#define STM32_HSECLK_BYP_MAX STM32_BOOST_HSECLK_BYP_MAX +#define STM32_HSECLK_MIN STM32_BOOST_HSECLK_MIN +#define STM32_HSECLK_BYP_MIN STM32_BOOST_HSECLK_BYP_MIN +#define STM32_LSECLK_MAX STM32_BOOST_LSECLK_MAX +#define STM32_LSECLK_BYP_MAX STM32_BOOST_LSECLK_BYP_MAX +#define STM32_LSECLK_MIN STM32_BOOST_LSECLK_MIN +#define STM32_LSECLK_BYP_MIN STM32_BOOST_LSECLK_BYP_MIN +#define STM32_PLLIN_MAX STM32_BOOST_PLLIN_MAX +#define STM32_PLLIN_MIN STM32_BOOST_PLLIN_MIN +#define STM32_PLLVCO_MAX STM32_BOOST_PLLVCO_MAX +#define STM32_PLLVCO_MIN STM32_BOOST_PLLVCO_MIN +#define STM32_PLLP_MAX STM32_BOOST_PLLP_MAX +#define STM32_PLLP_MIN STM32_BOOST_PLLP_MIN +#define STM32_PLLQ_MAX STM32_BOOST_PLLQ_MAX +#define STM32_PLLQ_MIN STM32_BOOST_PLLQ_MIN +#define STM32_PLLR_MAX STM32_BOOST_PLLR_MAX +#define STM32_PLLR_MIN STM32_BOOST_PLLR_MIN +#define STM32_PCLK1_MAX STM32_BOOST_PCLK1_MAX +#define STM32_PCLK2_MAX STM32_BOOST_PCLK2_MAX +#define STM32_ADCCLK_MAX STM32_BOOST_ADCCLK_MAX + +#define STM32_0WS_THRESHOLD STM32_BOOST_0WS_THRESHOLD +#define STM32_1WS_THRESHOLD STM32_BOOST_1WS_THRESHOLD +#define STM32_2WS_THRESHOLD STM32_BOOST_2WS_THRESHOLD +#define STM32_3WS_THRESHOLD STM32_BOOST_3WS_THRESHOLD +#define STM32_4WS_THRESHOLD STM32_BOOST_4WS_THRESHOLD +#define STM32_5WS_THRESHOLD STM32_BOOST_5WS_THRESHOLD +#define STM32_6WS_THRESHOLD STM32_BOOST_6WS_THRESHOLD +#define STM32_7WS_THRESHOLD STM32_BOOST_7WS_THRESHOLD +#define STM32_8WS_THRESHOLD STM32_BOOST_8WS_THRESHOLD + +#else /* !STM32_PWR_BOOST */ +#define STM32_SYSCLK_MAX STM32_VOS1_SYSCLK_MAX_NOBOOST +#define STM32_HSECLK_MAX STM32_VOS1_HSECLK_MAX +#define STM32_HSECLK_BYP_MAX STM32_VOS1_HSECLK_BYP_MAX +#define STM32_HSECLK_MIN STM32_VOS1_HSECLK_MIN +#define STM32_HSECLK_BYP_MIN STM32_VOS1_HSECLK_BYP_MIN +#define STM32_LSECLK_MAX STM32_VOS1_LSECLK_MAX +#define STM32_LSECLK_BYP_MAX STM32_VOS1_LSECLK_BYP_MAX +#define STM32_LSECLK_MIN STM32_VOS1_LSECLK_MIN +#define STM32_LSECLK_BYP_MIN STM32_VOS1_LSECLK_BYP_MIN +#define STM32_PLLIN_MAX STM32_VOS1_PLLIN_MAX +#define STM32_PLLIN_MIN STM32_VOS1_PLLIN_MIN +#define STM32_PLLVCO_MAX STM32_VOS1_PLLVCO_MAX +#define STM32_PLLVCO_MIN STM32_VOS1_PLLVCO_MIN +#define STM32_PLLP_MAX STM32_VOS1_PLLP_MAX +#define STM32_PLLP_MIN STM32_VOS1_PLLP_MIN +#define STM32_PLLQ_MAX STM32_VOS1_PLLQ_MAX +#define STM32_PLLQ_MIN STM32_VOS1_PLLQ_MIN +#define STM32_PLLR_MAX STM32_VOS1_PLLR_MAX +#define STM32_PLLR_MIN STM32_VOS1_PLLR_MIN +#define STM32_PCLK1_MAX STM32_VOS1_PCLK1_MAX +#define STM32_PCLK2_MAX STM32_VOS1_PCLK2_MAX +#define STM32_ADCCLK_MAX STM32_VOS1_ADCCLK_MAX + +#define STM32_0WS_THRESHOLD STM32_VOS1_0WS_THRESHOLD +#define STM32_1WS_THRESHOLD STM32_VOS1_1WS_THRESHOLD +#define STM32_2WS_THRESHOLD STM32_VOS1_2WS_THRESHOLD +#define STM32_3WS_THRESHOLD STM32_VOS1_3WS_THRESHOLD +#define STM32_4WS_THRESHOLD STM32_VOS1_4WS_THRESHOLD +#define STM32_5WS_THRESHOLD STM32_VOS1_5WS_THRESHOLD +#define STM32_6WS_THRESHOLD STM32_VOS1_6WS_THRESHOLD +#define STM32_7WS_THRESHOLD STM32_VOS1_7WS_THRESHOLD +#define STM32_8WS_THRESHOLD STM32_VOS1_8WS_THRESHOLD +#endif /* !STM32_PWR_BOOST */ + +#elif STM32_VOS == STM32_VOS_RANGE2 +#define STM32_SYSCLK_MAX STM32_VOS2_SYSCLK_MAX +#define STM32_SYSCLK_MAX_NOBOOST STM32_VOS2_SYSCLK_MAX_NOBOOST +#define STM32_HSECLK_MAX STM32_VOS2_HSECLK_MAX +#define STM32_HSECLK_BYP_MAX STM32_VOS2_HSECLK_BYP_MAX +#define STM32_HSECLK_MIN STM32_VOS2_HSECLK_MIN +#define STM32_HSECLK_BYP_MIN STM32_VOS2_HSECLK_BYP_MIN +#define STM32_LSECLK_MAX STM32_VOS2_LSECLK_MAX +#define STM32_LSECLK_BYP_MAX STM32_VOS2_LSECLK_BYP_MAX +#define STM32_LSECLK_MIN STM32_VOS2_LSECLK_MIN +#define STM32_LSECLK_BYP_MIN STM32_VOS2_LSECLK_BYP_MIN +#define STM32_PLLIN_MAX STM32_VOS2_PLLIN_MAX +#define STM32_PLLIN_MIN STM32_VOS2_PLLIN_MIN +#define STM32_PLLVCO_MAX STM32_VOS2_PLLVCO_MAX +#define STM32_PLLVCO_MIN STM32_VOS2_PLLVCO_MIN +#define STM32_PLLP_MAX STM32_VOS2_PLLP_MAX +#define STM32_PLLP_MIN STM32_VOS2_PLLP_MIN +#define STM32_PLLQ_MAX STM32_VOS2_PLLQ_MAX +#define STM32_PLLQ_MIN STM32_VOS2_PLLQ_MIN +#define STM32_PLLR_MAX STM32_VOS2_PLLR_MAX +#define STM32_PLLR_MIN STM32_VOS2_PLLR_MIN +#define STM32_PCLK1_MAX STM32_VOS2_PCLK1_MAX +#define STM32_PCLK2_MAX STM32_VOS2_PCLK2_MAX +#define STM32_ADCCLK_MAX STM32_VOS2_ADCCLK_MAX + +#define STM32_0WS_THRESHOLD STM32_VOS2_0WS_THRESHOLD +#define STM32_1WS_THRESHOLD STM32_VOS2_1WS_THRESHOLD +#define STM32_2WS_THRESHOLD STM32_VOS2_2WS_THRESHOLD +#define STM32_3WS_THRESHOLD STM32_VOS2_3WS_THRESHOLD +#define STM32_4WS_THRESHOLD STM32_VOS2_4WS_THRESHOLD +#define STM32_5WS_THRESHOLD STM32_VOS2_5WS_THRESHOLD +#define STM32_6WS_THRESHOLD STM32_VOS2_6WS_THRESHOLD +#define STM32_7WS_THRESHOLD STM32_VOS2_7WS_THRESHOLD +#define STM32_8WS_THRESHOLD STM32_VOS2_8WS_THRESHOLD + +#else +#error "invalid STM32_VOS value specified" +#endif + +/* + * HSI16 related checks. + */ +#if STM32_HSI16_ENABLED +#else /* !STM32_HSI16_ENABLED */ + + #if STM32_SW == STM32_SW_HSI16 + #error "HSI16 not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) + #error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + #if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16)) + #error "HSI16 not enabled, required by STM32_MCOSEL" + #endif + + #if (STM32_USART1SEL == STM32_USART1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_USART1SEL" + #endif + #if (STM32_USART2SEL == STM32_USART2SEL_HSI16) + #error "HSI16 not enabled, required by STM32_USART2SEL" + #endif + #if (STM32_USART3SEL == STM32_USART3SEL_HSI16) + #error "HSI16 not enabled, required by STM32_USART3SEL" + #endif + #if (STM32_UART4SEL == STM32_UART4SEL_HSI16) + #error "HSI16 not enabled, required by STM32_UART4SEL_HSI16" + #endif + #if (STM32_UART5SEL == STM32_UART5SEL_HSI16) + #error "HSI16 not enabled, required by STM32_UART5SEL_HSI16" + #endif + #if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_LPUART1SEL" + #endif + + #if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_I2C1SEL" + #endif + #if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) + #error "HSI16 not enabled, required by STM32_I2C2SEL" + #endif + #if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) + #error "HSI16 not enabled, required by STM32_I2C3SEL" + #endif + #if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) + #error "HSI16 not enabled, required by STM32_I2C4SEL" + #endif + + #if (STM32_SAI1SEL == STM32_SAI1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_SAI1SEL" + #endif + #if (STM32_I2S23SEL == STM32_I2S23SEL_HSI16) + #error "HSI16 not enabled, required by STM32_I2S23SEL" + #endif + + #if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_LPTIM1SEL" + #endif + + #if (STM32_QSPISEL == STM32_QSPISEL_HSI16) + #error "HSI16 not enabled, required by STM32_QSPISEL_HSI16" + #endif + +#endif /* !STM32_HSI16_ENABLED */ + +/* + * HSI48 related checks. + */ +#if STM32_HSI48_ENABLED +#else /* !STM32_HSI48_ENABLED */ + + #if STM32_MCOSEL == STM32_MCOSEL_HSI48 + #error "HSI48 not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 + #error "HSI48 not enabled, required by STM32_CLK48SEL" + #endif + +#endif /* !STM32_HSI48_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#else /* !STM32_HSE_ENABLED */ + + #if STM32_SW == STM32_SW_HSE + #error "HSE not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLLRCLK) && (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) + #error "HSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV + #error "HSE not enabled, required by STM32_RTCSEL" + #endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + + #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) + #error "LSI not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSI + #error "LSI not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSI + #error "LSI not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + + #if (STM32_LSECLK == 0) + #error "LSE frequency not defined" + #endif + + #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) + #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" + #endif + +#else /* !STM32_LSE_ENABLED */ + + #if STM32_RTCSEL == STM32_RTCSEL_LSE + #error "LSE not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSE + #error "LSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSE + #error "LSE not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 16)) || \ + defined(__DOXYGEN__) + #define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) +#else + #error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) + #define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 + #define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK + #define STM32_PLLCLKIN 0 + +#else + #error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLL input frequency range check. + */ +#if (STM32_PLLCLKIN != 0) && \ + ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) + #error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_SW == STM32_SW_PLLRCLK) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ + (STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK) || \ + (STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK) || \ + (STM32_I2S23SEL == STM32_I2S23SEL_PLLQCLK) || \ + (STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK) || \ + (STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK) || \ + (STM32_QSPISEL == STM32_QSPISEL_PLLQCLK) || \ + defined(__DOXYGEN__) + + #if STM32_PLLCLKIN == 0 + #error "PLL activation required but no PLL clock selected" + #endif + + /** + * @brief PLL activation flag. + */ + #define STM32_ACTIVATE_PLL TRUE +#else + + #define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 127)) || \ + defined(__DOXYGEN__) + #define STM32_PLLN (STM32_PLLN_VALUE << 8) +#else + #error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) + #define STM32_PLLP (0 << 17) + +#elif STM32_PLLP_VALUE == 17 + #define STM32_PLLP (1 << 17) + +#else + #error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) + #define STM32_PLLQ (0 << 21) + +#elif STM32_PLLQ_VALUE == 4 + #define STM32_PLLQ (1 << 21) + +#elif STM32_PLLQ_VALUE == 6 + #define STM32_PLLQ (2 << 21) + +#elif STM32_PLLQ_VALUE == 8 + #define STM32_PLLQ (3 << 21) + +#else + #error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLR field. + */ +#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) + #define STM32_PLLR (0 << 25) + +#elif STM32_PLLR_VALUE == 4 + #define STM32_PLLR (1 << 25) + +#elif STM32_PLLR_VALUE == 6 + #define STM32_PLLR (2 << 25) + +#elif STM32_PLLR_VALUE == 8 + #define STM32_PLLR (3 << 25) + +#else + #error "invalid STM32_PLLR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLPDIV field. + */ +#if (STM32_PLLPDIV_VALUE == 0) || \ + ((STM32_PLLPDIV_VALUE >= 2) && (STM32_PLLPDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) +#else +#error "invalid STM32_PLLPDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLPEN field. + */ +#if (STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK) || \ + (STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK) || \ + defined(__DOXYGEN__) + #define STM32_PLLPEN (1 << 16) + +#else + #define STM32_PLLPEN (0 << 16) +#endif + +/** + * @brief STM32_PLLQEN field. + */ +#if (STM32_QSPISEL == STM32_QSPISEL_PLLQCLK) || \ + (STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK) || \ + (STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK) || \ + (STM32_I2S23SEL == STM32_I2S23SEL_PLLQCLK) || \ + defined(__DOXYGEN__) + #define STM32_PLLQEN (1 << 20) + +#else + #define STM32_PLLQEN (0 << 20) +#endif + +/** + * @brief STM32_PLLREN field. + */ +#if (STM32_SW == STM32_SW_PLLRCLK) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) || \ + defined(__DOXYGEN__) + #define STM32_PLLREN (1 << 24) + +#else + #define STM32_PLLREN (0 << 24) +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) + #error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL P output clock frequency. + */ +#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) + #define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) +#else + #define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) +#endif + +/** + * @brief PLL Q output clock frequency. + */ +#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) + +/** + * @brief PLL R output clock frequency. + */ +#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) + +/* + * PLL-P output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) + #error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLL-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) + #error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLL-R output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) + #error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) + #define STM32_SYSCLK STM32_HSI16CLK + +#elif (STM32_SW == STM32_SW_HSI16) + #define STM32_SYSCLK STM32_HSI16CLK + +#elif (STM32_SW == STM32_SW_HSE) + #define STM32_SYSCLK STM32_HSECLK + +#elif (STM32_SW == STM32_SW_PLLRCLK) + #define STM32_SYSCLK STM32_PLL_R_CLKOUT + +#else + #error "invalid STM32_SW value specified" +#endif + +/* + * Check on the system clock. + */ +#if STM32_SYSCLK > STM32_SYSCLK_MAX + #error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) + #define STM32_HCLK (STM32_SYSCLK / 1) + +#elif STM32_HPRE == STM32_HPRE_DIV2 + #define STM32_HCLK (STM32_SYSCLK / 2) + +#elif STM32_HPRE == STM32_HPRE_DIV4 + #define STM32_HCLK (STM32_SYSCLK / 4) + +#elif STM32_HPRE == STM32_HPRE_DIV8 + #define STM32_HCLK (STM32_SYSCLK / 8) + +#elif STM32_HPRE == STM32_HPRE_DIV16 + #define STM32_HCLK (STM32_SYSCLK / 16) + +#elif STM32_HPRE == STM32_HPRE_DIV64 + #define STM32_HCLK (STM32_SYSCLK / 64) + +#elif STM32_HPRE == STM32_HPRE_DIV128 + #define STM32_HCLK (STM32_SYSCLK / 128) + +#elif STM32_HPRE == STM32_HPRE_DIV256 + #define STM32_HCLK (STM32_SYSCLK / 256) + +#elif STM32_HPRE == STM32_HPRE_DIV512 + #define STM32_HCLK (STM32_SYSCLK / 512) + +#else + #error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX + #error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) + #define STM32_PCLK1 (STM32_HCLK / 1) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 + #define STM32_PCLK1 (STM32_HCLK / 2) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 + #define STM32_PCLK1 (STM32_HCLK / 4) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 + #define STM32_PCLK1 (STM32_HCLK / 8) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 + #define STM32_PCLK1 (STM32_HCLK / 16) + +#else + #error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) + #define STM32_PCLK2 (STM32_HCLK / 1) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 + #define STM32_PCLK2 (STM32_HCLK / 2) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 + #define STM32_PCLK2 (STM32_HCLK / 4) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 + #define STM32_PCLK2 (STM32_HCLK / 8) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 + #define STM32_PCLK2 (STM32_HCLK / 16) + +#else + #error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief MCO divider clock frequency. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) + #define STM32_MCODIVCLK 0 + +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK + #define STM32_MCODIVCLK STM32_SYSCLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 + #define STM32_MCODIVCLK STM32_HSI16CLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSE + #define STM32_MCODIVCLK STM32_HSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_PLLRCLK + #define STM32_MCODIVCLK STM32_PLL_R_CLKOUT + +#elif STM32_MCOSEL == STM32_MCOSEL_LSI + #define STM32_MCODIVCLK STM32_LSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_LSE + #define STM32_MCODIVCLK STM32_LSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 + #define STM32_MCODIVCLK STM32_HSI48CLK + +#else + #error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock frequency. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) + #define STM32_MCOCLK STM32_MCODIVCLK + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 + #define STM32_MCOCLK (STM32_MCODIVCLK / 2) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 + #define STM32_MCOCLK (STM32_MCODIVCLK / 4) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 + #define STM32_MCOCLK (STM32_MCODIVCLK / 8) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 + #define STM32_MCOCLK (STM32_MCODIVCLK / 16) + +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief RTC clock frequency. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) + #define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE + #define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI + #define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV + #define STM32_RTCCLK (STM32_HSECLK / 32) + +#else + #error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 clock frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) + #define STM32_USART1CLK STM32_PCLK2 + +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK + #define STM32_USART1CLK STM32_SYSCLK + +#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 + #define STM32_USART1CLK STM32_HSI16CLK + +#elif STM32_USART1SEL == STM32_USART1SEL_LSE + #define STM32_USART1CLK STM32_LSECLK + +#else + #error "invalid source selected for USART1 clock" +#endif + + /** + * @brief USART2 clock frequency. + */ + #if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_USART2CLK STM32_PCLK1 + + #elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK + #define STM32_USART2CLK STM32_SYSCLK + + #elif STM32_USART2SEL == STM32_USART2SEL_HSI16 + #define STM32_USART2CLK STM32_HSI16CLK + + #elif STM32_USART2SEL == STM32_USART2SEL_LSE + #define STM32_USART2CLK STM32_LSECLK + + #else + #error "invalid source selected for USART2 clock" + #endif + + /** + * @brief USART3 clock frequency. + */ + #if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_USART3CLK STM32_PCLK1 + + #elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK + #define STM32_USART3CLK STM32_SYSCLK + + #elif STM32_USART3SEL == STM32_USART3SEL_HSI16 + #define STM32_USART3CLK STM32_HSI16CLK + + #elif STM32_USART3SEL == STM32_USART3SEL_LSE + #define STM32_USART3CLK STM32_LSECLK + + #else + #error "invalid source selected for USART3 clock" + #endif + +/** + * @brief UART4 clock frequency. + */ +#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_UART4CLK STM32_PCLK1 + +#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK + #define STM32_UART4CLK STM32_SYSCLK + +#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 + #define STM32_UART4CLK STM32_HSI16CLK + +#elif STM32_UART4SEL == STM32_UART4SEL_LSE + #define STM32_UART4CLK STM32_LSECLK + +#else + #error "invalid source selected for UART4 clock" +#endif + +/** + * @brief UART5 clock frequency. + */ +#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_UART5CLK STM32_PCLK1 + +#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK + #define STM32_UART5CLK STM32_SYSCLK + +#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 + #define STM32_UART5CLK STM32_HSI16CLK + +#elif STM32_UART5SEL == STM32_UART5SEL_LSE + #define STM32_UART5CLK STM32_LSECLK + +#else + #error "invalid source selected for UART5 clock" +#endif + +/** + * @brief LPUART1 clock frequency. + */ +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_LPUART1CLK STM32_PCLK1 + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK + #define STM32_LPUART1CLK STM32_SYSCLK + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 + #define STM32_LPUART1CLK STM32_HSI16CLK + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE + #define STM32_LPUART1CLK STM32_LSECLK + +#else +#error "invalid source selected for LPUART1 clock" +#endif + +/** + * @brief I2C1 clock frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_I2C1CLK STM32_PCLK1 + +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK + #define STM32_I2C1CLK STM32_SYSCLK + +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 + #define STM32_I2C1CLK STM32_HSI16CLK + +#else + #error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 clock frequency. + */ +#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_I2C2CLK STM32_PCLK1 + +#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK + #define STM32_I2C2CLK STM32_SYSCLK + +#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 + #define STM32_I2C2CLK STM32_HSI16CLK + +#else + #error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C3 clock frequency. + */ +#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_I2C3CLK STM32_PCLK1 + +#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK + #define STM32_I2C3CLK STM32_SYSCLK + +#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 + #define STM32_I2C3CLK STM32_HSI16CLK + +#else + #error "invalid source selected for I2C3 clock" +#endif + +/** + * @brief I2C4 clock frequency. + */ +#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_I2C4CLK STM32_PCLK1 + +#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK + #define STM32_I2C4CLK STM32_SYSCLK + +#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 + #define STM32_I2C4CLK STM32_HSI16CLK + +#else + #error "invalid source selected for I2C4 clock" +#endif + +/** + * @brief LPTIM1 clock frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) + #define STM32_LPTIM1CLK STM32_PCLK1 + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI + #define STM32_LPTIM1CLK STM32_LSICLK + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 + #define STM32_LPTIM1CLK STM32_HSI16CLK + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE + #define STM32_LPTIM1CLK STM32_LSECLK + +#else + #error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief SAI1 clock frequency. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_SYSCLK) || defined(__DOXYGEN__) + #define STM32_SAI1CLK STM32_SYSCLK + +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLQCLK + #define STM32_SAI1CLK STM32_PLL_Q_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16 + #define STM32_SAI1CLK STM32_HSI16CLK + +#elif STM32_SAI1SEL == STM32_SAI1SEL_CKIN + #define STM32_SAI1CLK 0 /* Unknown, would require a board value */ + +#else + #error "invalid source selected for SAI1 clock" +#endif + +/** + * @brief I2S23 clock frequency. + */ +#if (STM32_I2S23SEL == STM32_I2S23SEL_SYSCLK) || defined(__DOXYGEN__) + #define STM32_I2S23CLK STM32_SYSCLK + +#elif STM32_I2S23SEL == STM32_I2S23SEL_PLLPCLK + #define STM32_I2S23CLK STM32_PLL_P_CLKOUT + +#elif STM32_I2S23SEL == STM32_I2S23SEL_HSI16 + #define STM32_I2S23CLK STM32_HSI16CLK + +#elif STM32_I2S23SEL == STM32_I2S23SEL_CKIN + #define STM32_I2S23CLK 0 /* Unknown, would require a board value */ + +#else + #error "invalid source selected for SAI1 clock" +#endif + +/** + * @brief FDCAN clock frequency. + */ +#if (STM32_FDCANSEL == STM32_FDCANSEL_HSE) || defined(__DOXYGEN__) + #define STM32_FDCANCLK STM32_HSECLK + +#elif STM32_FDCANSEL == STM32_FDCANSEL_PLLQCLK + #define STM32_FDCANCLK STM32_PLL_Q_CLKOUT + +#elif STM32_FDCANSEL == STM32_FDCANSEL_PCLK1 + #define STM32_FDCANCLK STM32_PCLK1 + +#else + #error "invalid source selected for FDCAN clock" +#endif + +/** + * @brief 48MHz clock frequency. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) + #define STM32_48CLK STM32_HSI48CLK + +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLQCLK + #define STM32_48CLK STM32_PLL_Q_CLKOUT + +#else + #error "invalid source selected for 48MHz clock" +#endif + +/** + * @brief ADC clock frequency. + */ +#if (STM32_ADC12SEL == STM32_ADC12SEL_NOCLK) || defined(__DOXYGEN__) + #define STM32_ADC12CLK 0 + +#elif STM32_ADC12SEL == STM32_ADC12SEL_PLLPCLK + #define STM32_ADC12CLK STM32_PLL_P_CLKOUT + +#elif STM32_ADC12SEL == STM32_ADC12SEL_SYSCLK + #define STM32_ADC12CLK STM32_SYSCLK + +#else + #error "invalid source selected for ADC clock" +#endif + +/** + * @brief ADC clock frequency. + */ +#if (STM32_ADC345SEL == STM32_ADC345SEL_NOCLK) || defined(__DOXYGEN__) + #define STM32_ADC345CLK 0 + +#elif STM32_ADC345SEL == STM32_ADC345SEL_PLLPCLK + #define STM32_ADC345CLK STM32_PLL_P_CLKOUT + +#elif STM32_ADC345SEL == STM32_ADC345SEL_SYSCLK + #define STM32_ADC345CLK STM32_SYSCLK + +#else + #error "invalid source selected for ADC clock" +#endif + +/** + * @brief TIMP1CLK clock frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) + #define STM32_TIMP1CLK (STM32_PCLK1 * 1) +#else + #define STM32_TIMP1CLK (STM32_PCLK1 * 2) +#endif + +/** + * @brief TIMP2CLK clock frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) + #define STM32_TIMP2CLK (STM32_PCLK2 * 1) +#else + #define STM32_TIMP2CLK (STM32_PCLK2 * 2) +#endif + +/** + * @brief Clock of timers connected to APB1. + */ +#define STM32_TIMCLK1 STM32_TIMP1CLK + +/** + * @brief Clock of timers connected to APB2. + */ +#define STM32_TIMCLK2 STM32_TIMP2CLK + +/** + * @brief RNG clock point. + */ +#define STM32_RNGCLK STM32_48CLK + +/** + * @brief USB clock point. + */ +#define STM32_USBCLK STM32_48CLK + +/** + * @brief Voltage boost settings. + */ +#if STM32_PWR_BOOST || defined(__DOXYGEN__) +#define STM32_CR5BITS PWR_CR5_R1MODE +#else +#define STM32_CR5BITS 0U +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) + #define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD + #define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD + #define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_HCLK <= STM32_3WS_THRESHOLD + #define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS + +#elif STM32_HCLK <= STM32_4WS_THRESHOLD + #define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS + +#else + #define STM32_FLASHBITS FLASH_ACR_LATENCY_5WS +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.c b/os/hal/ports/STM32/STM32H7xx/hal_lld.c index 4f1de78e4f..5199c7daed 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.c @@ -1,439 +1,439 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32H7xx/hal_lld.c - * @brief STM32H7xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f7xx.h. - */ -uint32_t SystemCoreClock = STM32_CORE_CK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting - * of the whole BKP domain. - */ -static inline void init_bkp_domain(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ -} - -/** - * @brief Initializes the PWR unit. - */ -static inline void init_pwr(void) { -#if 0 - PWR_TypeDef *pwr = PWR; /* For inspection.*/ - (void)pwr; -#endif - - /* Lower C3 byte, it must be programmed at very first, then waiting for - power supply to stabilize.*/ - PWR->CR3 = STM32_PWR_CR3 & 0x000000FFU; - while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0) - ; /* CHTODO timeout handling.*/ - - PWR->CR1 = STM32_PWR_CR1 | 0xF0000000U; - PWR->CR2 = STM32_PWR_CR2; - PWR->CR3 = STM32_PWR_CR3; /* Other bits, lower byte is not changed. */ - PWR->CPUCR = STM32_PWR_CPUCR; - PWR->D3CR = STM32_VOS; -#if !defined(STM32_ENFORCE_H7_REV_XY) - SYSCFG->PWRCR = STM32_ODEN; -#endif - while ((PWR->D3CR & PWR_D3CR_VOSRDY) == 0) - ; /* CHTODO timeout handling.*/ -#if STM32_PWR_CR2 & PWR_CR2_BREN -// while ((PWR->CR2 & PWR_CR2_BRRDY) == 0) -// ; -// rccEnableBKPRAM(true); -#endif -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - -#if STM32_NO_INIT == FALSE - /* Reset of all peripherals. AHB3 is not reset entirely because FMC could - have been initialized in the board initialization file (board.c). - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~0); - rccResetAHB2(~0); - rccResetAHB3(~(RCC_AHB3RSTR_FMCRST | - 0x80000000U)); /* Was RCC_AHB3RSTR_CPURST in Rev-V.*/ - rccResetAHB4(~(RCC_APB4RSTR_SYSCFGRST | STM32_GPIO_EN_MASK)); - rccResetAPB1L(~0); - rccResetAPB1H(~0); - rccResetAPB2(~0); - rccResetAPB3(~0); - rccResetAPB4(~0); -#endif /* STM32_NO_INIT == FALSE */ - - /* DMA subsystems initialization.*/ -#if defined(STM32_BDMA_REQUIRED) - bdmaInit(); -#endif -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif -#if defined(STM32_MDMA_REQUIRED) - mdmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* MPU initialization.*/ -#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) || (STM32_NOCACHE_SRAM3 == TRUE) - { - uint32_t base, size; - -#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == TRUE) - base = 0x30000000U; - size = MPU_RASR_SIZE_512K; -#elif (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == FALSE) - base = 0x30000000U; - size = MPU_RASR_SIZE_256K; -#elif (STM32_NOCACHE_SRAM1_SRAM2 == FALSE) && (STM32_NOCACHE_SRAM3 == TRUE) - base = 0x30040000U; - size = MPU_RASR_SIZE_16K; -#else -#error "invalid constants used in mcuconf.h" -#endif - - /* The SRAM2 bank can optionally made a non cache-able area for use by - DMA engines.*/ - mpuConfigureRegion(STM32_NOCACHE_MPU_REGION, - base, - MPU_RASR_ATTR_AP_RW_RW | - MPU_RASR_ATTR_NON_CACHEABLE | - MPU_RASR_ATTR_S | - size | - MPU_RASR_ENABLE); - mpuEnable(MPU_CTRL_PRIVDEFENA); - - /* Invalidating data cache to make sure that the MPU settings are taken - immediately.*/ - SCB_CleanInvalidateDCache(); - } -#endif -} - -/** - * @brief STM32H7xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { -#if STM32_NO_INIT == FALSE - uint32_t cfgr; - -#if 0 - RCC_TypeDef *rcc = RCC; /* For inspection.*/ - (void)rcc; -#endif - -#if defined(STM32_ENFORCE_H7_REV_XY) - /* Fix for errata 2.2.15: Reading from AXI SRAM might lead to data - read corruption. - AXI->TARG7_FN_MOD.*/ - *((volatile uint32_t *)(0x51000000 + 0x1108 + 0x7000)) = 0x00000001U; -#endif - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB4(RCC_APB4ENR_SYSCFGEN, true); - - /* PWR initialization.*/ - init_pwr(); - - /* Backup domain initialization.*/ - init_bkp_domain(); - - /* HSI setup, it enforces the reset situation in order to handle possible - problems with JTAG probes and re-initializations.*/ - RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ - while (!(RCC->CR & RCC_CR_HSIRDY)) - ; /* Wait until HSI is stable. */ - - /* HSI is selected as new source without touching the other fields in - CFGR. This is only required when using a debugger than can cause - restarts.*/ - RCC->CFGR = 0x00000000U; /* Reset SW to HSI. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) - ; /* Wait until HSI is selected. */ - - /* Registers cleared to reset values.*/ - RCC->CR = RCC_CR_HSION; /* CR Reset value. */ - RCC->HSICFGR = 0x40000000U; /* HSICFGR Reset value. */ -#if !defined(STM32_ENFORCE_H7_REV_XY) - RCC->CSICFGR = 0x20000000U; /* CSICFGR Reset value. */ -#endif - RCC->CSR = 0x00000000U; /* CSR reset value. */ - RCC->PLLCFGR = 0x01FF0000U; /* PLLCFGR reset value. */ - - /* Other clock-related settings, done before other things because - recommended in the RM.*/ - cfgr = STM32_MCO2SEL | RCC_CFGR_MCO2PRE_VALUE(STM32_MCO2PRE_VALUE) | - STM32_MCO1SEL | RCC_CFGR_MCO1PRE_VALUE(STM32_MCO1PRE_VALUE) | - RCC_CFGR_RTCPRE_VALUE(STM32_RTCPRE_VALUE) | - STM32_HRTIMSEL | STM32_STOPKERWUCK | STM32_STOPWUCK; -#if STM32_TIMPRE_ENABLE == TRUE - cfgr |= RCC_CFGR_TIMPRE; -#endif - RCC->CFGR = cfgr; - - /* HSE activation with optional bypass.*/ -#if STM32_HSE_ENABLED == TRUE -#if defined(STM32_HSE_BYPASS) - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#else - RCC->CR |= RCC_CR_HSEON; -#endif - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Waits until HSE is stable. */ -#endif /* STM32_HSE_ENABLED == TRUE */ - - /* HSI48 activation.*/ -#if STM32_HSI48_ENABLED == TRUE - RCC->CR |= RCC_CR_HSI48ON; - while ((RCC->CR & RCC_CR_HSI48RDY) == 0) - ; /* Waits until HSI48 is stable. */ - -#endif /* STM32_HSI48_ENABLED == TRUE */ - - /* CSI activation.*/ -#if STM32_CSI_ENABLED == TRUE - RCC->CR |= RCC_CR_CSION; - while ((RCC->CR & RCC_CR_CSIRDY) == 0) - ; /* Waits until CSI is stable. */ -#endif /* STM32_CSI_ENABLED == TRUE */ - - /* LSI activation.*/ -#if STM32_LSI_ENABLED == TRUE - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif /* STM32_LSI_ENABLED == TRUE */ - - /* PLLs activation, it happens in parallel in order to - reduce boot time.*/ -#if (STM32_PLL1_ENABLED == TRUE) || \ - (STM32_PLL2_ENABLED == TRUE) || \ - (STM32_PLL3_ENABLED == TRUE) - { - uint32_t onmask = 0; - uint32_t rdymask = 0; - uint32_t cfgmask = 0; - - RCC->PLLCKSELR = RCC_PLLCKSELR_DIVM3_VALUE(STM32_PLL3_DIVM_VALUE) | - RCC_PLLCKSELR_DIVM2_VALUE(STM32_PLL2_DIVM_VALUE) | - RCC_PLLCKSELR_DIVM1_VALUE(STM32_PLL1_DIVM_VALUE) | - RCC_PLLCKSELR_PLLSRC_VALUE(STM32_PLLSRC); - - cfgmask = STM32_PLLCFGR_PLL3RGE | STM32_PLLCFGR_PLL3VCOSEL | RCC_PLLCFGR_PLL3FRACEN | - STM32_PLLCFGR_PLL2RGE | STM32_PLLCFGR_PLL2VCOSEL | RCC_PLLCFGR_PLL2FRACEN | - STM32_PLLCFGR_PLL1RGE | STM32_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN; - -#if STM32_PLL1_ENABLED == TRUE - RCC->PLL1FRACR = STM32_PLL1_FRACN; - RCC->PLL1DIVR = STM32_PLL1_DIVR | STM32_PLL1_DIVQ | - STM32_PLL1_DIVP | STM32_PLL1_DIVN; - onmask |= RCC_CR_PLL1ON; - rdymask |= RCC_CR_PLL1RDY; -#if STM32_PLL1_P_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVP1EN; -#endif -#if STM32_PLL1_Q_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVQ1EN; -#endif -#if STM32_PLL1_R_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVR1EN; -#endif -#endif /* STM32_PLL1_ENABLED == TRUE */ - -#if STM32_PLL2_ENABLED == TRUE - RCC->PLL2FRACR = STM32_PLL2_FRACN; - RCC->PLL2DIVR = STM32_PLL2_DIVR | STM32_PLL2_DIVQ | - STM32_PLL2_DIVP | STM32_PLL2_DIVN; - onmask |= RCC_CR_PLL2ON; - rdymask |= RCC_CR_PLL2RDY; -#if STM32_PLL2_P_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVP2EN; -#endif -#if STM32_PLL2_Q_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVQ2EN; -#endif -#if STM32_PLL2_R_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVR2EN; -#endif -#endif /* STM32_PLL2_ENABLED == TRUE */ - -#if STM32_PLL3_ENABLED == TRUE - RCC->PLL3FRACR = STM32_PLL3_FRACN; - RCC->PLL3DIVR = STM32_PLL3_DIVR | STM32_PLL3_DIVQ | - STM32_PLL3_DIVP | STM32_PLL3_DIVN; - onmask |= RCC_CR_PLL3ON; - rdymask |= RCC_CR_PLL3RDY; -#if STM32_PLL3_P_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVP3EN; -#endif -#if STM32_PLL3_Q_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVQ3EN; -#endif -#if STM32_PLL3_R_ENABLED == TRUE - cfgmask |= RCC_PLLCFGR_DIVR3EN; -#endif -#endif /* STM32_PLL3_ENABLED == TRUE */ - - /* Activating enabled PLLs and waiting for all of them to become ready.*/ - RCC->PLLCFGR = cfgmask & STM32_PLLCFGR_MASK; - RCC->CR |= onmask; - while ((RCC->CR & rdymask) != rdymask) - ; - } -#endif /* STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */ - - /* AHB and APB dividers.*/ - RCC->D1CFGR = STM32_D1CPRE | STM32_D1PPRE3 | STM32_D1HPRE; - RCC->D2CFGR = STM32_D2PPRE2 | STM32_D2PPRE1; - RCC->D3CFGR = STM32_D3PPRE4; - - /* Peripherals clocks.*/ - RCC->D1CCIPR = STM32_CKPERSEL | STM32_SDMMCSEL | STM32_QSPISEL | - STM32_FMCSEL; - RCC->D2CCIP1R = STM32_SWPSEL | STM32_FDCANSEL | STM32_DFSDM1SEL | - STM32_SPDIFSEL | STM32_SPDIFSEL | STM32_SPI45SEL | - STM32_SPI123SEL | STM32_SAI23SEL | STM32_SAI1SEL; - RCC->D2CCIP2R = STM32_LPTIM1SEL | STM32_CECSEL | STM32_USBSEL | - STM32_I2C123SEL | STM32_RNGSEL | STM32_USART16SEL | - STM32_USART234578SEL; - RCC->D3CCIPR = STM32_SPI6SEL | STM32_SAI4BSEL | STM32_SAI4ASEL | - STM32_ADCSEL | STM32_LPTIM345SEL | STM32_LPTIM2SEL | - STM32_I2C4SEL | STM32_LPUART1SEL; - - /* Flash setup.*/ - FLASH->ACR = FLASH_ACR_WRHIGHFREQ_1 | FLASH_ACR_WRHIGHFREQ_0 | - STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY)) { - } - - /* Switching to the configured clock source if it is different - from HSI.*/ -#if STM32_SW != STM32_SW_HSI_CK - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3U)) - ; -#endif - -#if 0 - /* Peripheral clock sources.*/ - RCC->DCKCFGR2 = STM32_SDMMCSEL | STM32_CK48MSEL | STM32_CECSEL | - STM32_LPTIM1SEL | STM32_I2C4SEL | STM32_I2C3SEL | - STM32_I2C2SEL | STM32_I2C1SEL | STM32_UART8SEL | - STM32_UART7SEL | STM32_USART6SEL | STM32_UART5SEL | - STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | - STM32_USART1SEL; -#endif - - /* RAM1 2 and 3 clocks enabled.*/ - rccEnableSRAM1(true); - rccEnableSRAM2(true); - rccEnableSRAM3(true); -#endif /* STM32_NO_INIT */ -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32H7xx/hal_lld.c + * @brief STM32H7xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f7xx.h. + */ +uint32_t SystemCoreClock = STM32_CORE_CK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing clock source impossible without resetting + * of the whole BKP domain. + */ +static inline void init_bkp_domain(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ +} + +/** + * @brief Initializes the PWR unit. + */ +static inline void init_pwr(void) { +#if 0 + PWR_TypeDef *pwr = PWR; /* For inspection.*/ + (void)pwr; +#endif + + /* Lower C3 byte, it must be programmed at very first, then waiting for + power supply to stabilize.*/ + PWR->CR3 = STM32_PWR_CR3 & 0x000000FFU; + while ((PWR->CSR1 & PWR_CSR1_ACTVOSRDY) == 0) + ; /* CHTODO timeout handling.*/ + + PWR->CR1 = STM32_PWR_CR1 | 0xF0000000U; + PWR->CR2 = STM32_PWR_CR2; + PWR->CR3 = STM32_PWR_CR3; /* Other bits, lower byte is not changed. */ + PWR->CPUCR = STM32_PWR_CPUCR; + PWR->D3CR = STM32_VOS; +#if !defined(STM32_ENFORCE_H7_REV_XY) + SYSCFG->PWRCR = STM32_ODEN; +#endif + while ((PWR->D3CR & PWR_D3CR_VOSRDY) == 0) + ; /* CHTODO timeout handling.*/ +#if STM32_PWR_CR2 & PWR_CR2_BREN +// while ((PWR->CR2 & PWR_CR2_BRRDY) == 0) +// ; +// rccEnableBKPRAM(true); +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + +#if STM32_NO_INIT == FALSE + /* Reset of all peripherals. AHB3 is not reset entirely because FMC could + have been initialized in the board initialization file (board.c). + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~0); + rccResetAHB2(~0); + rccResetAHB3(~(RCC_AHB3RSTR_FMCRST | + 0x80000000U)); /* Was RCC_AHB3RSTR_CPURST in Rev-V.*/ + rccResetAHB4(~(RCC_APB4RSTR_SYSCFGRST | STM32_GPIO_EN_MASK)); + rccResetAPB1L(~0); + rccResetAPB1H(~0); + rccResetAPB2(~0); + rccResetAPB3(~0); + rccResetAPB4(~0); +#endif /* STM32_NO_INIT == FALSE */ + + /* DMA subsystems initialization.*/ +#if defined(STM32_BDMA_REQUIRED) + bdmaInit(); +#endif +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif +#if defined(STM32_MDMA_REQUIRED) + mdmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* MPU initialization.*/ +#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) || (STM32_NOCACHE_SRAM3 == TRUE) + { + uint32_t base, size; + +#if (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == TRUE) + base = 0x30000000U; + size = MPU_RASR_SIZE_512K; +#elif (STM32_NOCACHE_SRAM1_SRAM2 == TRUE) && (STM32_NOCACHE_SRAM3 == FALSE) + base = 0x30000000U; + size = MPU_RASR_SIZE_256K; +#elif (STM32_NOCACHE_SRAM1_SRAM2 == FALSE) && (STM32_NOCACHE_SRAM3 == TRUE) + base = 0x30040000U; + size = MPU_RASR_SIZE_16K; +#else +#error "invalid constants used in mcuconf.h" +#endif + + /* The SRAM2 bank can optionally made a non cache-able area for use by + DMA engines.*/ + mpuConfigureRegion(STM32_NOCACHE_MPU_REGION, + base, + MPU_RASR_ATTR_AP_RW_RW | + MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_ATTR_S | + size | + MPU_RASR_ENABLE); + mpuEnable(MPU_CTRL_PRIVDEFENA); + + /* Invalidating data cache to make sure that the MPU settings are taken + immediately.*/ + SCB_CleanInvalidateDCache(); + } +#endif +} + +/** + * @brief STM32H7xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { +#if STM32_NO_INIT == FALSE + uint32_t cfgr; + +#if 0 + RCC_TypeDef *rcc = RCC; /* For inspection.*/ + (void)rcc; +#endif + +#if defined(STM32_ENFORCE_H7_REV_XY) + /* Fix for errata 2.2.15: Reading from AXI SRAM might lead to data + read corruption. + AXI->TARG7_FN_MOD.*/ + *((volatile uint32_t *)(0x51000000 + 0x1108 + 0x7000)) = 0x00000001U; +#endif + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB4(RCC_APB4ENR_SYSCFGEN, true); + + /* PWR initialization.*/ + init_pwr(); + + /* Backup domain initialization.*/ + init_bkp_domain(); + + /* HSI setup, it enforces the reset situation in order to handle possible + problems with JTAG probes and re-initializations.*/ + RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ + while (!(RCC->CR & RCC_CR_HSIRDY)) + ; /* Wait until HSI is stable. */ + + /* HSI is selected as new source without touching the other fields in + CFGR. This is only required when using a debugger than can cause + restarts.*/ + RCC->CFGR = 0x00000000U; /* Reset SW to HSI. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) + ; /* Wait until HSI is selected. */ + + /* Registers cleared to reset values.*/ + RCC->CR = RCC_CR_HSION; /* CR Reset value. */ + RCC->HSICFGR = 0x40000000U; /* HSICFGR Reset value. */ +#if !defined(STM32_ENFORCE_H7_REV_XY) + RCC->CSICFGR = 0x20000000U; /* CSICFGR Reset value. */ +#endif + RCC->CSR = 0x00000000U; /* CSR reset value. */ + RCC->PLLCFGR = 0x01FF0000U; /* PLLCFGR reset value. */ + + /* Other clock-related settings, done before other things because + recommended in the RM.*/ + cfgr = STM32_MCO2SEL | RCC_CFGR_MCO2PRE_VALUE(STM32_MCO2PRE_VALUE) | + STM32_MCO1SEL | RCC_CFGR_MCO1PRE_VALUE(STM32_MCO1PRE_VALUE) | + RCC_CFGR_RTCPRE_VALUE(STM32_RTCPRE_VALUE) | + STM32_HRTIMSEL | STM32_STOPKERWUCK | STM32_STOPWUCK; +#if STM32_TIMPRE_ENABLE == TRUE + cfgr |= RCC_CFGR_TIMPRE; +#endif + RCC->CFGR = cfgr; + + /* HSE activation with optional bypass.*/ +#if STM32_HSE_ENABLED == TRUE +#if defined(STM32_HSE_BYPASS) + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#else + RCC->CR |= RCC_CR_HSEON; +#endif + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif /* STM32_HSE_ENABLED == TRUE */ + + /* HSI48 activation.*/ +#if STM32_HSI48_ENABLED == TRUE + RCC->CR |= RCC_CR_HSI48ON; + while ((RCC->CR & RCC_CR_HSI48RDY) == 0) + ; /* Waits until HSI48 is stable. */ + +#endif /* STM32_HSI48_ENABLED == TRUE */ + + /* CSI activation.*/ +#if STM32_CSI_ENABLED == TRUE + RCC->CR |= RCC_CR_CSION; + while ((RCC->CR & RCC_CR_CSIRDY) == 0) + ; /* Waits until CSI is stable. */ +#endif /* STM32_CSI_ENABLED == TRUE */ + + /* LSI activation.*/ +#if STM32_LSI_ENABLED == TRUE + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif /* STM32_LSI_ENABLED == TRUE */ + + /* PLLs activation, it happens in parallel in order to + reduce boot time.*/ +#if (STM32_PLL1_ENABLED == TRUE) || \ + (STM32_PLL2_ENABLED == TRUE) || \ + (STM32_PLL3_ENABLED == TRUE) + { + uint32_t onmask = 0; + uint32_t rdymask = 0; + uint32_t cfgmask = 0; + + RCC->PLLCKSELR = RCC_PLLCKSELR_DIVM3_VALUE(STM32_PLL3_DIVM_VALUE) | + RCC_PLLCKSELR_DIVM2_VALUE(STM32_PLL2_DIVM_VALUE) | + RCC_PLLCKSELR_DIVM1_VALUE(STM32_PLL1_DIVM_VALUE) | + RCC_PLLCKSELR_PLLSRC_VALUE(STM32_PLLSRC); + + cfgmask = STM32_PLLCFGR_PLL3RGE | STM32_PLLCFGR_PLL3VCOSEL | RCC_PLLCFGR_PLL3FRACEN | + STM32_PLLCFGR_PLL2RGE | STM32_PLLCFGR_PLL2VCOSEL | RCC_PLLCFGR_PLL2FRACEN | + STM32_PLLCFGR_PLL1RGE | STM32_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN; + +#if STM32_PLL1_ENABLED == TRUE + RCC->PLL1FRACR = STM32_PLL1_FRACN; + RCC->PLL1DIVR = STM32_PLL1_DIVR | STM32_PLL1_DIVQ | + STM32_PLL1_DIVP | STM32_PLL1_DIVN; + onmask |= RCC_CR_PLL1ON; + rdymask |= RCC_CR_PLL1RDY; +#if STM32_PLL1_P_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVP1EN; +#endif +#if STM32_PLL1_Q_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVQ1EN; +#endif +#if STM32_PLL1_R_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVR1EN; +#endif +#endif /* STM32_PLL1_ENABLED == TRUE */ + +#if STM32_PLL2_ENABLED == TRUE + RCC->PLL2FRACR = STM32_PLL2_FRACN; + RCC->PLL2DIVR = STM32_PLL2_DIVR | STM32_PLL2_DIVQ | + STM32_PLL2_DIVP | STM32_PLL2_DIVN; + onmask |= RCC_CR_PLL2ON; + rdymask |= RCC_CR_PLL2RDY; +#if STM32_PLL2_P_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVP2EN; +#endif +#if STM32_PLL2_Q_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVQ2EN; +#endif +#if STM32_PLL2_R_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVR2EN; +#endif +#endif /* STM32_PLL2_ENABLED == TRUE */ + +#if STM32_PLL3_ENABLED == TRUE + RCC->PLL3FRACR = STM32_PLL3_FRACN; + RCC->PLL3DIVR = STM32_PLL3_DIVR | STM32_PLL3_DIVQ | + STM32_PLL3_DIVP | STM32_PLL3_DIVN; + onmask |= RCC_CR_PLL3ON; + rdymask |= RCC_CR_PLL3RDY; +#if STM32_PLL3_P_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVP3EN; +#endif +#if STM32_PLL3_Q_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVQ3EN; +#endif +#if STM32_PLL3_R_ENABLED == TRUE + cfgmask |= RCC_PLLCFGR_DIVR3EN; +#endif +#endif /* STM32_PLL3_ENABLED == TRUE */ + + /* Activating enabled PLLs and waiting for all of them to become ready.*/ + RCC->PLLCFGR = cfgmask & STM32_PLLCFGR_MASK; + RCC->CR |= onmask; + while ((RCC->CR & rdymask) != rdymask) + ; + } +#endif /* STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */ + + /* AHB and APB dividers.*/ + RCC->D1CFGR = STM32_D1CPRE | STM32_D1PPRE3 | STM32_D1HPRE; + RCC->D2CFGR = STM32_D2PPRE2 | STM32_D2PPRE1; + RCC->D3CFGR = STM32_D3PPRE4; + + /* Peripherals clocks.*/ + RCC->D1CCIPR = STM32_CKPERSEL | STM32_SDMMCSEL | STM32_QSPISEL | + STM32_FMCSEL; + RCC->D2CCIP1R = STM32_SWPSEL | STM32_FDCANSEL | STM32_DFSDM1SEL | + STM32_SPDIFSEL | STM32_SPDIFSEL | STM32_SPI45SEL | + STM32_SPI123SEL | STM32_SAI23SEL | STM32_SAI1SEL; + RCC->D2CCIP2R = STM32_LPTIM1SEL | STM32_CECSEL | STM32_USBSEL | + STM32_I2C123SEL | STM32_RNGSEL | STM32_USART16SEL | + STM32_USART234578SEL; + RCC->D3CCIPR = STM32_SPI6SEL | STM32_SAI4BSEL | STM32_SAI4ASEL | + STM32_ADCSEL | STM32_LPTIM345SEL | STM32_LPTIM2SEL | + STM32_I2C4SEL | STM32_LPUART1SEL; + + /* Flash setup.*/ + FLASH->ACR = FLASH_ACR_WRHIGHFREQ_1 | FLASH_ACR_WRHIGHFREQ_0 | + STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY)) { + } + + /* Switching to the configured clock source if it is different + from HSI.*/ +#if STM32_SW != STM32_SW_HSI_CK + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 3U)) + ; +#endif + +#if 0 + /* Peripheral clock sources.*/ + RCC->DCKCFGR2 = STM32_SDMMCSEL | STM32_CK48MSEL | STM32_CECSEL | + STM32_LPTIM1SEL | STM32_I2C4SEL | STM32_I2C3SEL | + STM32_I2C2SEL | STM32_I2C1SEL | STM32_UART8SEL | + STM32_UART7SEL | STM32_USART6SEL | STM32_UART5SEL | + STM32_UART4SEL | STM32_USART3SEL | STM32_USART2SEL | + STM32_USART1SEL; +#endif + + /* RAM1 2 and 3 clocks enabled.*/ + rccEnableSRAM1(true); + rccEnableSRAM2(true); + rccEnableSRAM3(true); +#endif /* STM32_NO_INIT */ +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.h b/os/hal/ports/STM32/STM32H7xx/hal_lld.h index b52766de7f..dacd238882 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.h @@ -1,3072 +1,3072 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32H7xx/hal_lld.h - * @brief STM32H7xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * - STM32_VDD (as hundredths of Volt). - * . - * One of the following macros must also be defined: - * - STM32H743xx, STM32H753xx very high-performance MCUs. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32H742xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32H742 Single Core Very High Performance with DSP and FPU" - -#elif defined(STM32H743xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32H743 Single Core Very High Performance with DSP and FPU" - -#elif defined(STM32H753xx) -#define PLATFORM_NAME "STM32H753 Single Core Very High Performance with DSP and FPU" - -#elif defined(STM32H745xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32H745 Dual Core Very High Performance with DSP and FPU" - -#elif defined(STM32H755xx) -#define PLATFORM_NAME "STM32H755 Dual Core Very High Performance with DSP and FPU" - -#elif defined(STM32H747xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32H747 Dual Core Very High Performance with DSP and FPU" - -#elif defined(STM32H757xx) -#define PLATFORM_NAME "STM32H757 Dual Core Very High Performance with DSP and FPU" - -#elif defined(STM32H750xx) -#define PLATFORM_NAME "STM32H750 Value Line Very High Performance with DSP and FPU" - -#else -#error "STM32H7xx device not specified" -#endif -/** @} */ - -/** - * @name Sub-family identifier - */ -#if !defined(STM32H7XX) || defined(__DOXYGEN__) -#define STM32H7XX -#endif -/** @} */ - -#if !defined(STM32_ENFORCE_H7_REV_XY) -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Absolute maximum system clock. - */ -#define STM32_SYSCLK_MAX 480000000 - -/** - * @brief Maximum SYSCLK clock frequency without voltage boost. - */ -#define STM32_SYSCLK_MAX_NOBOOST 400000000 - -/** - * @brief Absolute maximum HCLK clock. - */ -#define STM32_HCLK_MAX (STM32_SYSCLK_MAX / 2) - -/** - * @brief Maximum HSE clock frequency. - */ -#define STM32_HSECLK_MAX 48000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 50000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_BYP_MIN 4000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSE_CK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSE_CK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSE_CK_MIN 32768 - -/** - * @brief Minimum PLLs input clock frequency.. - */ -#define STM32_PLLIN_MIN 1000000 - -/** - * @brief PLLs input threshold frequency 1. - */ -#define STM32_PLLIN_THRESHOLD1 2000000 - -/** - * @brief PLLs input threshold frequency 2. - */ -#define STM32_PLLIN_THRESHOLD2 4000000 - -/** - * @brief PLLs input threshold frequency 3. - */ -#define STM32_PLLIN_THRESHOLD3 8000000 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 16000000 - -/** - * @brief Minimum PLLs VCO clock frequency. - */ -#define STM32_PLLVCO_MIN 150000000 /* DS says 192, RM says 150. */ - -/** - * @brief Threshold PLLs clock frequency. - */ -#define STM32_PLLVCO_THRESHOLD 420000000 - -/** - * @brief Maximum PLLs VCOH clock frequency. - */ -#define STM32_PLLVCO_MAX 960000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX (STM32_HCLK_MAX / 2) - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX (STM32_HCLK_MAX / 2) - -/** - * @brief Maximum APB3 clock frequency. - */ -#define STM32_PCLK3_MAX (STM32_HCLK_MAX / 2) - -/** - * @brief Maximum APB4 clock frequency. - */ -#define STM32_PCLK4_MAX (STM32_HCLK_MAX / 2) - -/** - * @brief Maximum SPI1, SPI2 and SPI3 clock frequency. - */ -#define STM32_SPI123_MAX 200000000 - -/** - * @brief Maximum SPI4, SPI5 and SPI6 clock frequency. - */ -#define STM32_SPI456_MAX 125000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 50000000 -/** @} */ - -#else /* defined(STM32_ENFORCE_H7_REV_XY) */ - -#define STM32_SYSCLK_MAX 400000000 -#define STM32_SYSCLK_MAX_NOBOOST 400000000 -#define STM32_HCLK_MAX (STM32_SYSCLK_MAX / 2) -#define STM32_HSECLK_MAX 48000000 -#define STM32_HSECLK_BYP_MAX 50000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 4000000 -#define STM32_LSE_CK_MAX 32768 -#define STM32_LSE_CK_BYP_MAX 1000000 -#define STM32_LSE_CK_MIN 32768 -#define STM32_PLLIN_MIN 1000000 -#define STM32_PLLIN_THRESHOLD1 2000000 -#define STM32_PLLIN_THRESHOLD2 4000000 -#define STM32_PLLIN_THRESHOLD3 8000000 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLVCO_MIN 150000000 -#define STM32_PLLVCO_THRESHOLD 420000000 -#define STM32_PLLVCO_MAX 836000000 -#define STM32_PCLK1_MAX (STM32_HCLK_MAX / 2) -#define STM32_PCLK2_MAX (STM32_HCLK_MAX / 2) -#define STM32_PCLK3_MAX (STM32_HCLK_MAX / 2) -#define STM32_PCLK4_MAX (STM32_HCLK_MAX / 2) -#define STM32_SPI123_MAX 133000000 -#define STM32_SPI456_MAX 100000000 -#define STM32_ADCCLK_MAX 36000000 - -#endif /* defined(STM32_ENFORCE_H7_REV_XY) */ - -/** - * @name Internal clock sources frequencies - * @{ - */ -#define STM32_HSI_OSC 64000000 -#define STM32_HSI48_OSC 48000000 -#define STM32_CSI_OSC 4000000 -#define STM32_LSI_OSC 32000 -/** @} */ - -/** - * @name Register helpers not found in ST headers - * @{ - */ -#define RCC_CR_HSIDIV_VALUE(n) ((n) << 3U) - -#define RCC_CFGR_SW_VALUE(n) ((n) << 0U) -#define RCC_CFGR_RTCPRE_VALUE(n) ((n) << 8U) -#define RCC_CFGR_MCO1PRE_VALUE(n) ((n) << 18U) -#define RCC_CFGR_MCO1_VALUE(n) ((n) << 22U) -#define RCC_CFGR_MCO2PRE_VALUE(n) ((n) << 25U) -#define RCC_CFGR_MCO2_VALUE(n) ((n) << 29U) - -#define RCC_D1CFGR_D1HPRE_VALUE(n) ((n) << RCC_D1CFGR_HPRE_Pos) -#define RCC_D1CFGR_D1CPRE_VALUE(n) ((n) << RCC_D1CFGR_D1CPRE_Pos) -#define RCC_D1CFGR_D1PPRE3_VALUE(n) ((n) << RCC_D1CFGR_D1PPRE_Pos) - -#define RCC_D2CFGR_D2PPRE1_VALUE(n) ((n) << RCC_D2CFGR_D2PPRE1_Pos) -#define RCC_D2CFGR_D2PPRE2_VALUE(n) ((n) << RCC_D2CFGR_D2PPRE2_Pos) - -#define RCC_D3CFGR_D3PPRE4_VALUE(n) ((n) << RCC_D3CFGR_D3PPRE_Pos) - -#define RCC_PLLCKSELR_PLLSRC_VALUE(n) ((n) << RCC_PLLCKSELR_PLLSRC_Pos) - -#define RCC_PLLCKSELR_DIVM1_VALUE(n) ((n) << RCC_PLLCKSELR_DIVM1_Pos) -#define RCC_PLLCKSELR_DIVM2_VALUE(n) ((n) << RCC_PLLCKSELR_DIVM2_Pos) -#define RCC_PLLCKSELR_DIVM3_VALUE(n) ((n) << RCC_PLLCKSELR_DIVM3_Pos) - -#define RCC_PLL1DIVR_DIVN1_VALUE(n) ((n) << RCC_PLL1DIVR_N1) -#define RCC_PLL1DIVR_DIVP1_VALUE(n) ((n) << RCC_PLL1DIVR_P1) -#define RCC_PLL1DIVR_DIVQ1_VALUE(n) ((n) << RCC_PLL1DIVR_Q1) -#define RCC_PLL1DIVR_DIVR1_VALUE(n) ((n) << RCC_PLL1DIVR_R1) - -#define RCC_PLL1FRACR_FRACN1_VALUE(n) ((n) << RCC_PLL1FRACR_FRACN1_Pos) - -#define RCC_PLL2DIVR_DIVN2_VALUE(n) ((n) << RCC_PLL2DIVR_N2) -#define RCC_PLL2DIVR_DIVP2_VALUE(n) ((n) << RCC_PLL2DIVR_P2) -#define RCC_PLL2DIVR_DIVQ2_VALUE(n) ((n) << RCC_PLL2DIVR_Q2) -#define RCC_PLL2DIVR_DIVR2_VALUE(n) ((n) << RCC_PLL2DIVR_R2) - -#define RCC_PLL2FRACR_FRACN2_VALUE(n) ((n) << RCC_PLL2FRACR_FRACN2_Pos) - -#define RCC_PLL3DIVR_DIVN3_VALUE(n) ((n) << RCC_PLL3DIVR_N3) -#define RCC_PLL3DIVR_DIVP3_VALUE(n) ((n) << RCC_PLL3DIVR_P3) -#define RCC_PLL3DIVR_DIVQ3_VALUE(n) ((n) << RCC_PLL3DIVR_Q3) -#define RCC_PLL3DIVR_DIVR3_VALUE(n) ((n) << RCC_PLL3DIVR_R3) - -#define RCC_PLL3FRACR_FRACN3_VALUE(n) ((n) << RCC_PLL3FRACR_FRACN3_Pos) - -#define RCC_D1CCIPR_CKPERSEL_VALUE(n) ((n) << RCC_D1CCIPR_CKPERSEL_Pos) -#define RCC_D1CCIPR_SDMMCSEL_VALUE(n) ((n) << RCC_D1CCIPR_SDMMCSEL_Pos) -#define RCC_D1CCIPR_QSPISEL_VALUE(n) ((n) << RCC_D1CCIPR_QSPISEL_Pos) -#define RCC_D1CCIPR_FMCSEL_VALUE(n) ((n) << RCC_D1CCIPR_FMCSEL_Pos) - -#define RCC_D2CCIP1R_SWPSEL_VALUE(n) ((n) << RCC_D2CCIP1R_SWPSEL_Pos) -#define RCC_D2CCIP1R_FDCANSEL_VALUE(n) ((n) << RCC_D2CCIP1R_FDCANSEL_Pos) -#define RCC_D2CCIP1R_DFSDM1SEL_VALUE(n) ((n) << RCC_D2CCIP1R_DFSDM1SEL_Pos) -#define RCC_D2CCIP1R_SPDIFSEL_VALUE(n) ((n) << RCC_D2CCIP1R_SPDIFSEL_Pos) -#define RCC_D2CCIP1R_SPI45SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SPI45SEL_Pos) -#define RCC_D2CCIP1R_SPI123SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SPI123SEL_Pos) -#define RCC_D2CCIP1R_SAI23SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SAI23SEL_Pos) -#define RCC_D2CCIP1R_SAI1SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SAI1SEL_Pos) - -#define RCC_D2CCIP2R_LPTIM1SEL_VALUE(n) ((n) << RCC_D2CCIP2R_LPTIM1SEL_Pos) -#define RCC_D2CCIP2R_CECSEL_VALUE(n) ((n) << RCC_D2CCIP2R_CECSEL_Pos) -#define RCC_D2CCIP2R_USBSEL_VALUE(n) ((n) << RCC_D2CCIP2R_USBSEL_Pos) -#define RCC_D2CCIP2R_I2C123SEL_VALUE(n) ((n) << RCC_D2CCIP2R_I2C123SEL_Pos) -#define RCC_D2CCIP2R_RNGSEL_VALUE(n) ((n) << RCC_D2CCIP2R_RNGSEL_Pos) -#define RCC_D2CCIP2R_USART16SEL_VALUE(n) ((n) << RCC_D2CCIP2R_USART16SEL_Pos) -#define RCC_D2CCIP2R_USART234578SEL_VALUE(n) ((n) << RCC_D2CCIP2R_USART28SEL_Pos) - -#define RCC_D3CCIPR_SPI6SEL_VALUE(n) ((n) << RCC_D3CCIPR_SPI6SEL_Pos) -#define RCC_D3CCIPR_SAI4BSEL_VALUE(n) ((n) << RCC_D3CCIPR_SAI4BSEL_Pos) -#define RCC_D3CCIPR_SAI4ASEL_VALUE(n) ((n) << RCC_D3CCIPR_SAI4ASEL_Pos) -#define RCC_D3CCIPR_ADCSEL_VALUE(n) ((n) << RCC_D3CCIPR_ADCSEL_Pos) -#define RCC_D3CCIPR_LPTIM345SEL_VALUE(n) ((n) << RCC_D3CCIPR_LPTIM345SEL_Pos) -#define RCC_D3CCIPR_LPTIM2SEL_VALUE(n) ((n) << RCC_D3CCIPR_LPTIM2SEL_Pos) -#define RCC_D3CCIPR_I2C4SEL_VALUE(n) ((n) << RCC_D3CCIPR_I2C4SEL_Pos) -#define RCC_D3CCIPR_LPUART1SEL_VALUE(n) ((n) << RCC_D3CCIPR_LPUART1SEL_Pos) - -#define RCC_BDCR_RTCSEL_VALUE(n) ((n) << RCC_BDCR_RTCSEL_Pos) -/** @} */ - -/** - * @name Configuration switches to be used in @p mcuconf.h - * @{ - */ -#define STM32_ODEN_DISABLED 0U -#define STM32_ODEN_ENABLED (SYSCFG_PWRCR_ODEN) - -#define STM32_VOS_SCALE3 (PWR_D3CR_VOS_0) -#define STM32_VOS_SCALE2 (PWR_D3CR_VOS_1) -#define STM32_VOS_SCALE1 (PWR_D3CR_VOS_1 | PWR_D3CR_VOS_0) - -#define STM32_SW_HSI_CK RCC_CFGR_SW_VALUE(0U) -#define STM32_SW_CSI_CK RCC_CFGR_SW_VALUE(1U) -#define STM32_SW_HSE_CK RCC_CFGR_SW_VALUE(2U) -#define STM32_SW_PLL1_P_CK RCC_CFGR_SW_VALUE(3U) - -#define STM32_D1CPRE_DIV1 RCC_D1CFGR_D1CPRE_VALUE(0U) -#define STM32_D1CPRE_DIV2 RCC_D1CFGR_D1CPRE_VALUE(8U) -#define STM32_D1CPRE_DIV4 RCC_D1CFGR_D1CPRE_VALUE(9U) -#define STM32_D1CPRE_DIV8 RCC_D1CFGR_D1CPRE_VALUE(10U) -#define STM32_D1CPRE_DIV16 RCC_D1CFGR_D1CPRE_VALUE(11U) -#define STM32_D1CPRE_DIV64 RCC_D1CFGR_D1CPRE_VALUE(12U) -#define STM32_D1CPRE_DIV128 RCC_D1CFGR_D1CPRE_VALUE(13U) -#define STM32_D1CPRE_DIV256 RCC_D1CFGR_D1CPRE_VALUE(14U) -#define STM32_D1CPRE_DIV512 RCC_D1CFGR_D1CPRE_VALUE(15U) - -#define STM32_D1HPRE_DIV1 RCC_D1CFGR_D1HPRE_VALUE(0U) -#define STM32_D1HPRE_DIV2 RCC_D1CFGR_D1HPRE_VALUE(8U) -#define STM32_D1HPRE_DIV4 RCC_D1CFGR_D1HPRE_VALUE(9U) -#define STM32_D1HPRE_DIV8 RCC_D1CFGR_D1HPRE_VALUE(10U) -#define STM32_D1HPRE_DIV16 RCC_D1CFGR_D1HPRE_VALUE(11U) -#define STM32_D1HPRE_DIV64 RCC_D1CFGR_D1HPRE_VALUE(12U) -#define STM32_D1HPRE_DIV128 RCC_D1CFGR_D1HPRE_VALUE(13U) -#define STM32_D1HPRE_DIV256 RCC_D1CFGR_D1HPRE_VALUE(14U) -#define STM32_D1HPRE_DIV512 RCC_D1CFGR_D1HPRE_VALUE(15U) - -#define STM32_D1PPRE3_DIV1 RCC_D1CFGR_D1PPRE3_VALUE(0U) -#define STM32_D1PPRE3_DIV2 RCC_D1CFGR_D1PPRE3_VALUE(4U) -#define STM32_D1PPRE3_DIV4 RCC_D1CFGR_D1PPRE3_VALUE(5U) -#define STM32_D1PPRE3_DIV8 RCC_D1CFGR_D1PPRE3_VALUE(6U) -#define STM32_D1PPRE3_DIV16 RCC_D1CFGR_D1PPRE3_VALUE(7U) - -#define STM32_D2PPRE1_DIV1 RCC_D2CFGR_D2PPRE1_VALUE(0U) -#define STM32_D2PPRE1_DIV2 RCC_D2CFGR_D2PPRE1_VALUE(4U) -#define STM32_D2PPRE1_DIV4 RCC_D2CFGR_D2PPRE1_VALUE(5U) -#define STM32_D2PPRE1_DIV8 RCC_D2CFGR_D2PPRE1_VALUE(6U) -#define STM32_D2PPRE1_DIV16 RCC_D2CFGR_D2PPRE1_VALUE(7U) - -#define STM32_D2PPRE2_DIV1 RCC_D2CFGR_D2PPRE2_VALUE(0U) -#define STM32_D2PPRE2_DIV2 RCC_D2CFGR_D2PPRE2_VALUE(4U) -#define STM32_D2PPRE2_DIV4 RCC_D2CFGR_D2PPRE2_VALUE(5U) -#define STM32_D2PPRE2_DIV8 RCC_D2CFGR_D2PPRE2_VALUE(6U) -#define STM32_D2PPRE2_DIV16 RCC_D2CFGR_D2PPRE2_VALUE(7U) - -#define STM32_D3PPRE4_DIV1 RCC_D3CFGR_D3PPRE4_VALUE(0U) -#define STM32_D3PPRE4_DIV2 RCC_D3CFGR_D3PPRE4_VALUE(4U) -#define STM32_D3PPRE4_DIV4 RCC_D3CFGR_D3PPRE4_VALUE(5U) -#define STM32_D3PPRE4_DIV8 RCC_D3CFGR_D3PPRE4_VALUE(6U) -#define STM32_D3PPRE4_DIV16 RCC_D3CFGR_D3PPRE4_VALUE(7U) - -#define STM32_HSIDIV_DIV1 RCC_CR_HSIDIV_VALUE(0U) -#define STM32_HSIDIV_DIV2 RCC_CR_HSIDIV_VALUE(1U) -#define STM32_HSIDIV_DIV4 RCC_CR_HSIDIV_VALUE(2U) -#define STM32_HSIDIV_DIV8 RCC_CR_HSIDIV_VALUE(3U) - -#define STM32_MCO1SEL_HSI_CK RCC_CFGR_MCO1_VALUE(0U) -#define STM32_MCO1SEL_LSE_CK RCC_CFGR_MCO1_VALUE(1U) -#define STM32_MCO1SEL_HSE_CK RCC_CFGR_MCO1_VALUE(2U) -#define STM32_MCO1SEL_PLL1_Q_CK RCC_CFGR_MCO1_VALUE(3U) -#define STM32_MCO1SEL_HSI48_CK RCC_CFGR_MCO1_VALUE(4U) - -#define STM32_MCO2SEL_SYS_CK RCC_CFGR_MCO2_VALUE(0U) -#define STM32_MCO2SEL_PLL2_P_CK RCC_CFGR_MCO2_VALUE(1U) -#define STM32_MCO2SEL_HSE_CK RCC_CFGR_MCO2_VALUE(2U) -#define STM32_MCO2SEL_PLL1_P_CK RCC_CFGR_MCO2_VALUE(3U) -#define STM32_MCO2SEL_CSI_CK RCC_CFGR_MCO2_VALUE(4U) -#define STM32_MCO2SEL_LSI_CK RCC_CFGR_MCO2_VALUE(5U) - -#define STM32_RTCSEL_MASK RCC_BDCR_RTCSEL_Msk -#define STM32_RTCSEL_NOCLK RCC_BDCR_RTCSEL_VALUE(0U) -#define STM32_RTCSEL_LSE_CK RCC_BDCR_RTCSEL_VALUE(1U) -#define STM32_RTCSEL_LSI_CK RCC_BDCR_RTCSEL_VALUE(2U) -#define STM32_RTCSEL_HSE_1M_CK RCC_BDCR_RTCSEL_VALUE(3U) - -#define STM32_HRTIMSEL_C_CLK RCC_CFGR_HRTIMSEL - -#define STM32_STOPKERWUCK_ENABLED RCC_CFGR_STOPKERWUCK - -#define STM32_STOPWUCK_ENABLED RCC_CFGR_STOPKERWUCK - -#define STM32_PLLSRC_HSI_CK RCC_PLLCKSELR_PLLSRC_VALUE(0U) -#define STM32_PLLSRC_CSI_CK RCC_PLLCKSELR_PLLSRC_VALUE(1U) -#define STM32_PLLSRC_HSE_CK RCC_PLLCKSELR_PLLSRC_VALUE(2U) -#define STM32_PLLSRC_DISABLE RCC_PLLCKSELR_PLLSRC_VALUE(23U) - -#define STM32_CKPERSEL_HSI_CK RCC_D1CCIPR_CKPERSEL_VALUE(0U) -#define STM32_CKPERSEL_CSI_CK RCC_D1CCIPR_CKPERSEL_VALUE(1U) -#define STM32_CKPERSEL_HSE_CK RCC_D1CCIPR_CKPERSEL_VALUE(2U) - -#define STM32_SDMMCSEL_PLL1_Q_CK RCC_D1CCIPR_SDMMCSEL_VALUE(0U) -#define STM32_SDMMCSEL_PLL2_R_CK RCC_D1CCIPR_SDMMCSEL_VALUE(1U) - -#define STM32_QSPISEL_HCLK RCC_D1CCIPR_QSPISEL_VALUE(0U) -#define STM32_QSPISEL_PLL1_Q_CK RCC_D1CCIPR_QSPISEL_VALUE(1U) -#define STM32_QSPISEL_PLL2_R_CK RCC_D1CCIPR_QSPISEL_VALUE(2U) -#define STM32_QSPISEL_PER_CK RCC_D1CCIPR_QSPISEL_VALUE(3U) - -#define STM32_FMCSEL_HCLK RCC_D1CCIPR_FMCSEL_VALUE(0U) -#define STM32_FMCSEL_PLL1_Q_CK RCC_D1CCIPR_FMCSEL_VALUE(1U) -#define STM32_FMCSEL_PLL2_R_CK RCC_D1CCIPR_FMCSEL_VALUE(2U) -#define STM32_FMCSEL_PER_CK RCC_D1CCIPR_FMCSEL_VALUE(3U) - -#define STM32_SWPSEL_PCLK1 RCC_D2CCIP1R_SWPSEL_VALUE(0U) -#define STM32_SWPSEL_HSI_KER_CK RCC_D2CCIP1R_SWPSEL_VALUE(1U) - -#define STM32_FDCANSEL_HSE_CK RCC_D2CCIP1R_FDCANSEL_VALUE(0U) -#define STM32_FDCANSEL_PLL1_Q_CK RCC_D2CCIP1R_FDCANSEL_VALUE(1U) -#define STM32_FDCANSEL_PLL2_Q_CK RCC_D2CCIP1R_FDCANSEL_VALUE(2U) - -#define STM32_DFSDM1SEL_PCLK2 RCC_D2CCIP1R_DFSDM1SEL_VALUE(0U) -#define STM32_DFSDM1SEL_SYS_CK RCC_D2CCIP1R_DFSDM1SEL_VALUE(1U) - -#define STM32_SPDIFSEL_PLL1_Q_CK RCC_D2CCIP1R_SPDIFSEL_VALUE(0U) -#define STM32_SPDIFSEL_PLL2_R_CK RCC_D2CCIP1R_SPDIFSEL_VALUE(1U) -#define STM32_SPDIFSEL_PLL3_R_CK RCC_D2CCIP1R_SPDIFSEL_VALUE(2U) -#define STM32_SPDIFSEL_HSI_KET_CLK RCC_D2CCIP1R_SPDIFSEL_VALUE(3U) - -#define STM32_SPI45SEL_PCLK2 RCC_D2CCIP1R_SPI45SEL_VALUE(0U) -#define STM32_SPI45SEL_PLL2_Q_CK RCC_D2CCIP1R_SPI45SEL_VALUE(1U) -#define STM32_SPI45SEL_PLL3_Q_CK RCC_D2CCIP1R_SPI45SEL_VALUE(2U) -#define STM32_SPI45SEL_HSI_KER_CK RCC_D2CCIP1R_SPI45SEL_VALUE(3U) -#define STM32_SPI45SEL_CSI_KER_CK RCC_D2CCIP1R_SPI45SEL_VALUE(4U) -#define STM32_SPI45SEL_HSE_CK RCC_D2CCIP1R_SPI45SEL_VALUE(5U) - -#define STM32_SPI123SEL_PLL1_Q_CK RCC_D2CCIP1R_SPI123SEL_VALUE(0U) -#define STM32_SPI123SEL_PLL2_P_CK RCC_D2CCIP1R_SPI123SEL_VALUE(1U) -#define STM32_SPI123SEL_PLL3_P_CK RCC_D2CCIP1R_SPI123SEL_VALUE(2U) -#define STM32_SPI123SEL_I2S_CKIN RCC_D2CCIP1R_SPI123SEL_VALUE(3U) -#define STM32_SPI123SEL_PER_CK RCC_D2CCIP1R_SPI123SEL_VALUE(4U) - -#define STM32_SAI23SEL_PLL1_Q_CK RCC_D2CCIP1R_SAI23SEL_VALUE(0U) -#define STM32_SAI23SEL_PLL2_P_CK RCC_D2CCIP1R_SAI23SEL_VALUE(1U) -#define STM32_SAI23SEL_PLL3_P_CK RCC_D2CCIP1R_SAI23SEL_VALUE(2U) -#define STM32_SAI23SEL_I2S_CKIN RCC_D2CCIP1R_SAI23SEL_VALUE(3U) -#define STM32_SAI23SEL_PER_CK RCC_D2CCIP1R_SAI23SEL_VALUE(4U) - -#define STM32_SAI1SEL_PLL1_Q_CK RCC_D2CCIP1R_SAI1SEL_VALUE(0U) -#define STM32_SAI1SEL_PLL2_P_CK RCC_D2CCIP1R_SAI1SEL_VALUE(1U) -#define STM32_SAI1SEL_PLL3_P_CK RCC_D2CCIP1R_SAI1SEL_VALUE(2U) -#define STM32_SAI1SEL_I2S_CKIN RCC_D2CCIP1R_SAI1SEL_VALUE(3U) -#define STM32_SAI1SEL_PER_CK RCC_D2CCIP1R_SAI1SEL_VALUE(4U) - -#define STM32_LPTIM1SEL_PCLK1 RCC_D2CCIP2R_LPTIM1SEL_VALUE(0U) -#define STM32_LPTIM1SEL_PLL2_P_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(1U) -#define STM32_LPTIM1SEL_PLL3_R_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(2U) -#define STM32_LPTIM1SEL_LSE_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(3U) -#define STM32_LPTIM1SEL_LSI_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(4U) -#define STM32_LPTIM1SEL_PER_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(5U) - -#define STM32_CECSEL_LSE_CK RCC_D2CCIP2R_CECSEL_VALUE(0U) -#define STM32_CECSEL_LSI_CK RCC_D2CCIP2R_CECSEL_VALUE(1U) -#define STM32_CECSEL_CSI_KER_CK RCC_D2CCIP2R_CECSEL_VALUE(2U) -#define STM32_CECSEL_DISABLE RCC_D2CCIP2R_CECSEL_VALUE(3U) - -#define STM32_USBSEL_DISABLE RCC_D2CCIP2R_USBSEL_VALUE(0U) -#define STM32_USBSEL_PLL1_Q_CK RCC_D2CCIP2R_USBSEL_VALUE(1U) -#define STM32_USBSEL_PLL3_Q_CK RCC_D2CCIP2R_USBSEL_VALUE(2U) -#define STM32_USBSEL_HSI48_CK RCC_D2CCIP2R_USBSEL_VALUE(3U) - -#define STM32_I2C123SEL_PCLK1 RCC_D2CCIP2R_I2C123SEL_VALUE(0U) -#define STM32_I2C123SEL_PLL3_R_CK RCC_D2CCIP2R_I2C123SEL_VALUE(1U) -#define STM32_I2C123SEL_HSI_KER_CK RCC_D2CCIP2R_I2C123SEL_VALUE(2U) -#define STM32_I2C123SEL_CSI_KER_CK RCC_D2CCIP2R_I2C123SEL_VALUE(3U) - -#define STM32_RNGSEL_HSI48_CK RCC_D2CCIP2R_RNGSEL_VALUE(0U) -#define STM32_RNGSEL_PLL1_Q_CK RCC_D2CCIP2R_RNGSEL_VALUE(1U) -#define STM32_RNGSEL_LSE_CK RCC_D2CCIP2R_RNGSEL_VALUE(2U) -#define STM32_RNGSEL_LSI_CK RCC_D2CCIP2R_RNGSEL_VALUE(3U) - -#define STM32_USART16SEL_PCLK2 RCC_D2CCIP2R_USART16SEL_VALUE(0U) -#define STM32_USART16SEL_PLL2_Q_CK RCC_D2CCIP2R_USART16SEL_VALUE(1U) -#define STM32_USART16SEL_PLL3_Q_CK RCC_D2CCIP2R_USART16SEL_VALUE(2U) -#define STM32_USART16SEL_HSI_KER_CK RCC_D2CCIP2R_USART16SEL_VALUE(3U) -#define STM32_USART16SEL_CSI_KER_CK RCC_D2CCIP2R_USART16SEL_VALUE(4U) -#define STM32_USART16SEL_LSE_CK RCC_D2CCIP2R_USART16SEL_VALUE(5U) - -#define STM32_USART234578SEL_PCLK1 RCC_D2CCIP2R_USART234578SEL_VALUE(0U) -#define STM32_USART234578SEL_PLL2_Q_CK RCC_D2CCIP2R_USART234578SEL_VALUE(1U) -#define STM32_USART234578SEL_PLL3_Q_CK RCC_D2CCIP2R_USART234578SEL_VALUE(2U) -#define STM32_USART234578SEL_HSI_KER_CK RCC_D2CCIP2R_USART234578SEL_VALUE(3U) -#define STM32_USART234578SEL_CSI_KER_CK RCC_D2CCIP2R_USART234578SEL_VALUE(4U) -#define STM32_USART234578SEL_LSE_CK RCC_D2CCIP2R_USART234578SEL_VALUE(5U) - -#define STM32_SPI6SEL_PCLK4 RCC_D3CCIPR_SPI6SEL_VALUE(0U) -#define STM32_SPI6SEL_PLL2_Q_CK RCC_D3CCIPR_SPI6SEL_VALUE(1U) -#define STM32_SPI6SEL_PLL3_Q_CK RCC_D3CCIPR_SPI6SEL_VALUE(2U) -#define STM32_SPI6SEL_HSI_KER_CK RCC_D3CCIPR_SPI6SEL_VALUE(3U) -#define STM32_SPI6SEL_CSI_KER_CK RCC_D3CCIPR_SPI6SEL_VALUE(4U) -#define STM32_SPI6SEL_HSE_CK RCC_D3CCIPR_SPI6SEL_VALUE(5U) - -#define STM32_SAI4BSEL_PLL1_Q_CK RCC_D3CCIPR_SAI4BSEL_VALUE(0U) -#define STM32_SAI4BSEL_PLL2_P_CK RCC_D3CCIPR_SAI4BSEL_VALUE(1U) -#define STM32_SAI4BSEL_PLL3_P_CK RCC_D3CCIPR_SAI4BSEL_VALUE(2U) -#define STM32_SAI4BSEL_I2S_CKIN RCC_D3CCIPR_SAI4BSEL_VALUE(3U) -#define STM32_SAI4BSEL_PER_CK RCC_D3CCIPR_SAI4BSEL_VALUE(4U) - -#define STM32_SAI4ASEL_PLL1_Q_CK RCC_D3CCIPR_SAI4ASEL_VALUE(0U) -#define STM32_SAI4ASEL_PLL2_P_CK RCC_D3CCIPR_SAI4ASEL_VALUE(1U) -#define STM32_SAI4ASEL_PLL3_P_CK RCC_D3CCIPR_SAI4ASEL_VALUE(2U) -#define STM32_SAI4ASEL_I2S_CKIN RCC_D3CCIPR_SAI4ASEL_VALUE(3U) -#define STM32_SAI4ASEL_PER_CK RCC_D3CCIPR_SAI4ASEL_VALUE(4U) - -#define STM32_ADCSEL_PLL2_P_CK RCC_D3CCIPR_ADCSEL_VALUE(0U) -#define STM32_ADCSEL_PLL3_R_CK RCC_D3CCIPR_ADCSEL_VALUE(1U) -#define STM32_ADCSEL_PER_CK RCC_D3CCIPR_ADCSEL_VALUE(2U) -#define STM32_ADCSEL_DISABLE RCC_D3CCIPR_ADCSEL_VALUE(3U) - -#define STM32_LPTIM345SEL_PCLK4 RCC_D3CCIPR_LPTIM345SEL_VALUE(0U) -#define STM32_LPTIM345SEL_PLL2_P_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(1U) -#define STM32_LPTIM345SEL_PLL3_P_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(2U) -#define STM32_LPTIM345SEL_LSE_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(3U) -#define STM32_LPTIM345SEL_LSI_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(4U) -#define STM32_LPTIM345SEL_PER_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(5U) - -#define STM32_LPTIM2SEL_PCLK4 RCC_D3CCIPR_LPTIM2SEL_VALUE(0U) -#define STM32_LPTIM2SEL_PLL2_P_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(1U) -#define STM32_LPTIM2SEL_PLL3_P_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(2U) -#define STM32_LPTIM2SEL_LSE_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(3U) -#define STM32_LPTIM2SEL_LSI_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(4U) -#define STM32_LPTIM2SEL_PER_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(5U) - -#define STM32_I2C4SEL_PCLK4 RCC_D3CCIPR_I2C4SEL_VALUE(0U) -#define STM32_I2C4SEL_PLL3_R_CK RCC_D3CCIPR_I2C4SEL_VALUE(1U) -#define STM32_I2C4SEL_HSI_KER_CK RCC_D3CCIPR_I2C4SEL_VALUE(2U) -#define STM32_I2C4SEL_CSI_KER_CK RCC_D3CCIPR_I2C4SEL_VALUE(3U) - -#define STM32_LPUART1SEL_PCLK4 RCC_D3CCIPR_LPUART1SEL_VALUE(0U) -#define STM32_LPUART1SEL_PLL2_Q_CK RCC_D3CCIPR_LPUART1SEL_VALUE(1U) -#define STM32_LPUART1SEL_PLL3_Q_CK RCC_D3CCIPR_LPUART1SEL_VALUE(2U) -#define STM32_LPUART1SEL_HSI_KER_CK RCC_D3CCIPR_LPUART1SEL_VALUE(3U) -#define STM32_LPUART1SEL_CSI_KER_CK RCC_D3CCIPR_LPUART1SEL_VALUE(4U) -#define STM32_LPUART1SEL_LSE_CK RCC_D3CCIPR_LPUART1SEL_VALUE(5U) -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - * @note All the clock tree constants are calculated but the initialization - * is not performed. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Target code for this HAL configuration. - * @note Core 1 is the Cortex-M7, core 2 is the Cortex-M4. - */ -#if !defined(STM32_TARGET_CORE) || defined(__DOXYGEN__) -#define STM32_TARGET_CORE 1 -#endif - -/** - * @brief MPU region to be used for no-cache RAM area. - */ -#if !defined(STM32_NOCACHE_MPU_REGION) || defined(__DOXYGEN__) -#define STM32_NOCACHE_MPU_REGION MPU_REGION_6 -#endif - -/** - * @brief Add no-cache attribute to SRAM1 and SRAM2. - * @note MPU region 7 is used if enabled. - */ -#if !defined(STM32_NOCACHE_SRAM1_SRAM2) || defined(__DOXYGEN__) -#define STM32_NOCACHE_SRAM1_SRAM2 FALSE -#endif - -/** - * @brief Add no-cache attribute to SRAM3. - * @note MPU region 7 is used if enabled. - */ -#if !defined(STM32_NOCACHE_SRAM3) || defined(__DOXYGEN__) -#define STM32_NOCACHE_SRAM3 TRUE -#endif - -/** - * @brief PWR CR1 initializer. - */ -#if !defined(STM32_PWR_CR1) || defined(__DOXYGEN__) -#define STM32_PWR_CR1 (PWR_CR1_SVOS_1 | \ - PWR_CR1_SVOS_0) -#endif - -/** - * @brief PWR CR2 initializer. - */ -#if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__) -#define STM32_PWR_CR2 (PWR_CR2_BREN) -#endif - -/** - * @brief PWR CR3 initializer. - */ -#if !defined(STM32_PWR_CR3) || defined(__DOXYGEN__) -#define STM32_PWR_CR3 (PWR_CR3_LDOEN | \ - PWR_CR3_USBREGEN | \ - PWR_CR3_USB33DEN) -#endif - -/** - * @brief PWR CPUCR initializer. - */ -#if !defined(STM32_PWR_CPUCR) || defined(__DOXYGEN__) -#define STM32_PWR_CPUCR 0 -#endif - -/** - * @brief VOS setting. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_SCALE1 -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_CSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_CSI_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSI48 clock source. - */ -#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI48_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED TRUE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief HSI divider. - */ -#if !defined(STM32_HSIDIV) || defined(__DOXYGEN__) -#define STM32_HSIDIV STM32_HSIDIV_DIV1 -#endif - -/** - * @brief Clock source for all PLLs. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSE_CK -#endif - -/** - * @brief Masking of PLLCFGR register. - * @note By default all options in PLLCFGR are enabled, this option - * allows to mask specific bits for power saving reasons. - * Use with caution. - */ -#if !defined(STM32_PLLCFGR_MASK) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_MASK ~0 -#endif - -/** - * @brief Enables or disables the PLL1. - */ -#if !defined(STM32_PLL1_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL1_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL1 P output. - */ -#if !defined(STM32_PLL1_P_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL1_P_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL1 Q output. - */ -#if !defined(STM32_PLL1_Q_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL1_Q_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL1 R output. - */ -#if !defined(STM32_PLL1_R_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL1_R_ENABLED TRUE -#endif - -/** - * @brief PLL1 DIVM divider. - * @note The allowed values are 1..63. - */ -#if !defined(STM32_PLL1_DIVM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL1_DIVM_VALUE 4 -#endif - -/** - * @brief PLL1 DIVN multiplier. - * @note The allowed values are 4..512. - */ -#if !defined(STM32_PLL1_DIVN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL1_DIVN_VALUE 400 -#endif - -/** - * @brief PLL1 FRACN multiplier, zero if no fractional part. - * @note The allowed values are 0..8191. - */ -#if !defined(STM32_PLL1_FRACN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL1_FRACN_VALUE 0 -#endif - -/** - * @brief PLL1 DIVP divider. - * @note The allowed values are 2..128, odd values not allowed. - */ -#if !defined(STM32_PLL1_DIVP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL1_DIVP_VALUE 2 -#endif - -/** - * @brief PLL1 DIVQ divider. - * @note The allowed values are 1..128. - */ -#if !defined(STM32_PLL1_DIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL1_DIVQ_VALUE 8 -#endif - -/** - * @brief PLL1 DIVR divider. - * @note The allowed values are 1..128. - */ -#if !defined(STM32_PLL1_DIVR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL1_DIVR_VALUE 8 -#endif - -/** - * @brief Enables or disables the PLL2. - */ -#if !defined(STM32_PLL2_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL2_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL2 P output. - */ -#if !defined(STM32_PLL2_P_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL1_2_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL2 Q output. - */ -#if !defined(STM32_PLL2_Q_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL2_Q_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL2 R output. - */ -#if !defined(STM32_PLL2_R_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL2_R_ENABLED TRUE -#endif - -/** - * @brief PLL2 DIVM divider. - * @note The allowed values are 1..63. - */ -#if !defined(STM32_PLL2_DIVM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2_DIVM_VALUE 4 -#endif - -/** - * @brief PLL2 DIVN multiplier. - * @note The allowed values are 4..512. - */ -#if !defined(STM32_PLL2_DIVN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2_DIVN_VALUE 400 -#endif - -/** - * @brief PLL2 FRACN multiplier, zero if no fractional part. - * @note The allowed values are 0..8191. - */ -#if !defined(STM32_PLL2_FRACN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2_FRACN_VALUE 0 -#endif - -/** - * @brief PLL2 DIVP divider. - * @note The allowed values are 2..128, odd values not allowed. - */ -#if !defined(STM32_PLL2_DIVP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2_DIVP_VALUE 40 -#endif - -/** - * @brief PLL2 DIVQ divider. - * @note The allowed values are 1..128. - */ -#if !defined(STM32_PLL2_DIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2_DIVQ_VALUE 8 -#endif - -/** - * @brief PLL2 DIVR divider. - * @note The allowed values are 1..128. - */ -#if !defined(STM32_PLL2_DIVR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL2_DIVR_VALUE 8 -#endif - -/** - * @brief Enables or disables the PLL3. - */ -#if !defined(STM32_PLL3_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL3_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL3 P output. - */ -#if !defined(STM32_PLL3_P_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL3_P_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL3 Q output. - */ -#if !defined(STM32_PLL3_Q_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL3_Q_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the PLL3 R output. - */ -#if !defined(STM32_PLL3_R_ENABLED) || defined(__DOXYGEN__) -#define STM32_PLL3_R_ENABLED TRUE -#endif - -/** - * @brief PLL3 DIVM divider. - * @note The allowed values are 1..63. - */ -#if !defined(STM32_PLL3_DIVM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3_DIVM_VALUE 4 -#endif - -/** - * @brief PLL3 DIVN multiplier. - * @note The allowed values are 4..512. - */ -#if !defined(STM32_PLL3_DIVN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3_DIVN_VALUE 400 -#endif - -/** - * @brief PLL3 FRACN multiplier, zero if no fractional part. - * @note The allowed values are 0..8191. - */ -#if !defined(STM32_PLL3_FRACN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3_FRACN_VALUE 0 -#endif - -/** - * @brief PLL3 DIVP divider. - * @note The allowed values are 2..128, odd values not allowed. - */ -#if !defined(STM32_PLL3_DIVP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3_DIVP_VALUE 8 -#endif - -/** - * @brief PLL3 DIVQ divider. - * @note The allowed values are 1..128. - */ -#if !defined(STM32_PLL3_DIVQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3_DIVQ_VALUE 8 -#endif - -/** - * @brief PLL3 DIVR divider. - * @note The allowed values are 1..128. - */ -#if !defined(STM32_PLL3_DIVR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLL3_DIVR_VALUE 8 -#endif - -/** - * @brief Peripherals clock selector. - */ -#if !defined(STM32_CKPERSEL) || defined(__DOXYGEN__) -#define STM32_CKPERSEL STM32_CKPERSEL_HSE_CK -#endif - -/** - * @brief MCO1 clock selector. - */ -#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) -#define STM32_MCO1SEL STM32_MCO1SEL_HSI_CK -#endif - -/** - * @brief MCO1 clock prescaler. - */ -#if !defined(STM32_MCO1PRE_VALUE) || defined(__DOXYGEN__) -#define STM32_MCO1PRE_VALUE 4 -#endif - -/** - * @brief MCO2 clock selector. - */ -#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) -#define STM32_MCO2SEL STM32_MCO2SEL_SYS_CK -#endif - -/** - * @brief MCO2 clock prescaler. - */ -#if !defined(STM32_MCO2PRE_VALUE) || defined(__DOXYGEN__) -#define STM32_MCO2PRE_VALUE 4 -#endif - -/** - * @brief TIM clock prescaler selection. - */ -#if !defined(STM32_TIMPRE_ENABLE) || defined(__DOXYGEN__) -#define STM32_TIMPRE_ENABLE FALSE -#endif - -/** - * @brief HRTIM clock prescaler selection. - */ -#if !defined(STM32_HRTIMSEL) || defined(__DOXYGEN__) -#define STM32_HRTIMSEL 0 -#endif - -/** - * @brief Kernel clock selection after a wake up from system Stop. - */ -#if !defined(STM32_STOPKERWUCK) || defined(__DOXYGEN__) -#define STM32_STOPKERWUCK 0 -#endif - -/** - * @brief System clock selection after a wake up from system Stop. - */ -#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) -#define STM32_STOPWUCK 0 -#endif - -/** - * @brief RTC HSE prescaler value. - * @note The allowed values are 2..63. - */ -#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) -#define STM32_RTCPRE_VALUE 8 -#endif - -/** - * @brief Main clock source selection. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL1_P_CK1_P_CK -#endif - -/** - * @brief RTC clock selector. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSE_CK -#endif - -/** - * @brief Clock domain 1 core bus prescaler. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_D1CPRE) || defined(__DOXYGEN__) -#define STM32_D1CPRE STM32_D1CPRE_DIV1 -#endif - -/** - * @brief Clock domain 1 HPRE prescaler. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_D1HPRE) || defined(__DOXYGEN__) -#define STM32_D1HPRE STM32_D1HPRE_DIV4 -#endif - -/** - * @brief Clock domain 1 peripherals bus prescaler. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_D1PPRE3) || defined(__DOXYGEN__) -#define STM32_D1PPRE3 STM32_D1PPRE3_DIV1 -#endif - -/** - * @brief Clock domain 2 peripherals bus 1 prescaler. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_D2PPRE1) || defined(__DOXYGEN__) -#define STM32_D2PPRE1 STM32_D2PPRE1_DIV1 -#endif - -/** - * @brief Clock domain 2 peripherals bus 2 prescaler. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_D2PPRE2) || defined(__DOXYGEN__) -#define STM32_D2PPRE2 STM32_D2PPRE2_DIV1 -#endif - -/** - * @brief Clock domain 3 peripherals bus prescaler. - * @note This setting can be modified at runtime. - */ -#if !defined(STM32_D3PPRE4) || defined(__DOXYGEN__) -#define STM32_D3PPRE4 STM32_D3PPRE4_DIV1 -#endif - -/** - * @brief SDMMC clock source. - */ -#if !defined(STM32_SDMMCSEL) || defined(__DOXYGEN__) -#define STM32_SDMMCSEL STM32_SDMMCSEL_PLL1_Q_CK -#endif - -/** - * @brief QSPI clock source. - */ -#if !defined(STM32_QSPISEL) || defined(__DOXYGEN__) -#define STM32_QSPISEL STM32_QSPISEL_HCLK -#endif - -/** - * @brief FMC clock source. - */ -#if !defined(STM32_FMCSEL) || defined(__DOXYGEN__) -#define STM32_FMCSEL STM32_QSPISEL_HCLK -#endif - -/** - * @brief SWP clock source. - */ -#if !defined(STM32_SWPSEL) || defined(__DOXYGEN__) -#define STM32_SWPSEL STM32_SWPSEL_PCLK1 -#endif - -/** - * @brief FDCAN clock source. - */ -#if !defined(STM32_FDCANSEL) || defined(__DOXYGEN__) -#define STM32_FDCANSEL STM32_FDCANSEL_HSE_CK -#endif - -/** - * @brief DFSDM1 clock source. - */ -#if !defined(STM32_DFSDM1SEL) || defined(__DOXYGEN__) -#define STM32_DFSDM1SEL STM32_DFSDM1SEL_PCLK2 -#endif - -/** - * @brief SPDIF clock source. - */ -#if !defined(STM32_SPDIFSEL) || defined(__DOXYGEN__) -#define STM32_SPDIFSEL STM32_SPDIFSEL_PLL1_Q_CK -#endif - -/** - * @brief SPI45 clock source. - */ -#if !defined(STM32_SPI45SEL) || defined(__DOXYGEN__) -#define STM32_SPI45SEL STM32_SPI45SEL_PCLK2 -#endif - -/** - * @brief SPI123 clock source. - */ -#if !defined(STM32_SPI123SEL) || defined(__DOXYGEN__) -#define STM32_SPI123SEL STM32_SPI123SEL_PLL1_Q_CK -#endif - -/** - * @brief SAI23 clock source. - */ -#if !defined(STM32_SAI23SEL) || defined(__DOXYGEN__) -#define STM32_SAI23SEL STM32_SAI23SEL_PLL1_Q_CK -#endif - -/** - * @brief SAI1 clock source. - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_PLL1_Q_CK -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1_PCLK1 -#endif - -/** - * @brief CEC clock source. - */ -#if !defined(STM32_CECSEL) || defined(__DOXYGEN__) -#define STM32_CECSEL STM32_CECSEL_LSE_CK -#endif - -/** - * @brief USB clock source. - */ -#if !defined(STM32_USBSEL) || defined(__DOXYGEN__) -#define STM32_USBSEL STM32_USBSEL_PLL3_Q_CK -#endif - -/** - * @brief I2C123 clock source. - */ -#if !defined(STM32_I2C123SEL) || defined(__DOXYGEN__) -#define STM32_I2C123SEL STM32_I2C123SEL_PCLK1 -#endif - -/** - * @brief RNG clock source. - */ -#if !defined(STM32_RNGSEL) || defined(__DOXYGEN__) -#define STM32_RNGSEL STM32_RNGSEL_HSI48_CK -#endif - -/** - * @brief USART16 clock source. - */ -#if !defined(STM32_USART16SEL) || defined(__DOXYGEN__) -#define STM32_USART16SEL STM32_USART16SEL_PCLK2 -#endif - -/** - * @brief USART234578 clock source. - */ -#if !defined(STM32_USART234578SEL) || defined(__DOXYGEN__) -#define STM32_USART234578SEL STM32_USART234578SEL_PCLK1 -#endif - -/** - * @brief SPI6SEL clock source. - */ -#if !defined(STM32_SPI6SEL) || defined(__DOXYGEN__) -#define STM32_SPI6SEL STM32_SPI6SEL_PCLK4 -#endif - -/** - * @brief SAI4BSEL clock source. - */ -#if !defined(STM32_SAI4BSEL) || defined(__DOXYGEN__) -#define STM32_SAI4BSEL STM32_SAI4BSEL_PLL1_Q_CK -#endif - -/** - * @brief SAI4ASEL clock source. - */ -#if !defined(STM32_SAI4ASEL) || defined(__DOXYGEN__) -#define STM32_SAI4ASEL STM32_SAI4ASEL_PLL1_Q_CK -#endif - -/** - * @brief ADCSEL clock source. - */ -#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) -#define STM32_ADCSEL STM32_ADCSEL_PLL2_P_CK -#endif - -/** - * @brief LPTIM345SEL clock source. - */ -#if !defined(STM32_LPTIM345SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM345SEL STM32_LPTIM345SEL_PCLK4 -#endif - -/** - * @brief LPTIM2SEL clock source. - */ -#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK4 -#endif - -/** - * @brief I2C4SEL clock source. - */ -#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) -#define STM32_I2C4SEL STM32_I2C4SEL_PCLK4 -#endif - -/** - * @brief LPUART1SEL clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_PCLK4 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32H7xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H7xx_MCUCONF not defined" -#endif - -#if defined(STM32H750xx)&& !defined(STM32H750_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H750_MCUCONF not defined" -#endif - -#if defined(STM32H742xx)&& !defined(STM32H742_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H742_MCUCONF not defined" -#endif - -#if defined(STM32H743xx)&& !defined(STM32H743_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H743_MCUCONF not defined" -#endif - -#if defined(STM32H753xx)&& !defined(STM32H753_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H753_MCUCONF not defined" -#endif - -#if defined(STM32H745xx)&& !defined(STM32H745_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H745_MCUCONF not defined" -#endif - -#if defined(STM32H755xx)&& !defined(STM32H755_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H755_MCUCONF not defined" -#endif - -#if defined(STM32H747xx)&& !defined(STM32H747_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H747_MCUCONF not defined" -#endif - -#if defined(STM32H757xx)&& !defined(STM32H757_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32H757_MCUCONF not defined" -#endif - -/* - * Board file checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/** - * @name Constants depending on VOS and ODEN setting - * @{ - */ -#if STM32_VOS == STM32_VOS_SCALE1 -#define STM32_0WS_THRESHOLD 70000000U -#define STM32_1WS_THRESHOLD 140000000U -#define STM32_2WS_THRESHOLD 210000000U -#define STM32_3WS_THRESHOLD 225000000U -#define STM32_4WS_THRESHOLD 240000000U -#define STM32_PLLOUT_MAX 480000000U -#define STM32_PLLOUT_MIN 1500000U - -#elif STM32_VOS == STM32_VOS_SCALE2 -#define STM32_0WS_THRESHOLD 55000000U -#define STM32_1WS_THRESHOLD 110000000U -#define STM32_2WS_THRESHOLD 165000000U -#define STM32_3WS_THRESHOLD 225000000U -#define STM32_4WS_THRESHOLD 0U -#define STM32_PLLOUT_MAX 300000000U -#define STM32_PLLOUT_MIN 1500000U - -#elif STM32_VOS == STM32_VOS_SCALE3 -#define STM32_0WS_THRESHOLD 45000000U -#define STM32_1WS_THRESHOLD 90000000U -#define STM32_2WS_THRESHOLD 135000000U -#define STM32_3WS_THRESHOLD 180000000U -#define STM32_4WS_THRESHOLD 225000000U -#define STM32_PLLOUT_MAX 200000000U -#define STM32_PLLOUT_MIN 1500000U - -#else -#error "invalid STM32_VOS setting specified" -#endif -/** @} */ - -/* - * HSI related checks. - */ -#if STM32_HSI_ENABLED -#define STM32_HSICLK STM32_HSI_OSC - -#else /* !STM32_HSI_ENABLED */ -#define STM32_HSICLK 0U - -#if STM32_SW == STM32_SW_HSI_CK -#error "HSI not enabled, required by STM32_SW" -#endif - -#if (STM32_PLLSRC == STM32_PLLSRC_HSI_CK) && \ - (STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED) -#error "HSI not enabled, required by STM32_PLLSRC and STM32_PLLx_ENABLED" -#endif - -#if STM32_CKPERSEL == STM32_CKPERSEL_HSI_CK -#error "HSI not enabled, required by STM32_CKPERSEL" -#endif - -#if STM32_MCO1SEL == STM32_MCO1SEL_HSI_CK -#error "HSI not enabled, required by STM32_MCO1SEL" -#endif - -#endif /* !STM32_HSI_ENABLED */ - -/* - * HSI48 related checks. - */ -#if STM32_HSI48_ENABLED -#define STM32_HSI48_CK STM32_HSI48_OSC - -#else /* !STM32_HSI48_ENABLED */ -#define STM32_HSI48_CK 0U - -#if STM32_MCO1SEL == STM32_MCO1SEL_HSI48_CK -#error "HSI48 not enabled, required by STM32_MCO1SEL" -#endif - -#endif /* !STM32_HSI48_ENABLED */ - -/* - * CSI related checks. - */ -#if STM32_CSI_ENABLED -#define STM32_CSI_CK STM32_CSI_OSC - -#else /* !STM32_CSI_ENABLED */ -#define STM32_CSI_CK 0U - -#if STM32_SW == STM32_SW_CSI_CK -#error "CSI not enabled, required by STM32_SW" -#endif - -#if (STM32_PLLSRC == STM32_PLLSRC_CSI_CK) && \ - (STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED) -#error "CSI not enabled, required by STM32_PLLSRC and STM32_PLLx_ENABLED" -#endif - -#if STM32_CKPERSEL == STM32_CKPERSEL_CSI_CK -#error "CSI not enabled, required by STM32_CKPERSEL" -#endif - -#if STM32_MCO2SEL == STM32_MCO2SEL_CSI_CK -#error "CSI not enabled, required by STM32_MCO2SEL" -#endif - -#endif /* !STM32_CSI_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - -#if !defined(STM32_HSECLK) -#error "HSE frequency not defined" -#endif - -#define STM32_HSE_CK STM32_HSECLK - -#if STM32_HSECLK == 0 -#error "HSE oscllator not available" -#else /* STM32_HSECLK != 0 */ -#if defined(STM32_HSE_BYPASS) -#if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN..STM32_HSECLK_BYP_MAX)" -#endif -#else /* !defined(STM32_HSE_BYPASS) */ -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN..STM32_HSECLK_MAX)" -#endif -#endif /* !defined(STM32_HSE_BYPASS) */ -#endif /* STM32_HSECLK != 0 */ -#else /* !STM32_HSE_ENABLED */ - -#if STM32_SW == STM32_SW_HSE_CK -#error "HSE not enabled, required by STM32_SW" -#endif - -#if (STM32_PLLSRC == STM32_PLLSRC_HSE_CK) && \ - (STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED) -#error "HSE not enabled, required by STM32_PLLSRC and STM32_PLLx_ENABLED" -#endif - -#if STM32_MCO1SEL == STM32_MCO1SEL_HSE_CK -#error "HSE not enabled, required by STM32_MCO1SEL" -#endif - -#if STM32_MCO2SEL == STM32_MCO2SEL_HSE_CK -#error "HSE not enabled, required by STM32_MCO2SEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_HSE_1M_CK -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#define STM32_LSI_CK STM32_LSI_OSC - -#else /* !STM32_LSI_ENABLED */ -#define STM32_LSI_CK 0U - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI_CK) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#if STM32_MCO2SEL == STM32_MCO2SEL_LSI_CK -#error "HSE not enabled, required by STM32_MCO2SEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - -#if !defined(STM32_LSECLK) -#error "LSE frequency not defined" -#endif - -#define STM32_LSE_CK STM32_LSECLK - -#if (STM32_LSE_CK == 0) -#error "LSE oscillator not available" -#endif - -#if defined(STM32_LSE_BYPASS) -#if (STM32_LSE_CK < STM32_LSE_CK_MIN) || (STM32_LSE_CK > STM32_LSE_CK_BYP_MAX) -#error "STM32_LSE_CK outside acceptable range (STM32_LSE_CK_MIN..STM32_LSE_CK_BYP_MAX)" -#endif -#else -#if (STM32_LSE_CK < STM32_LSE_CK_MIN) || (STM32_LSE_CK > STM32_LSE_CK_MAX) -#error "STM32_LSE_CK outside acceptable range (STM32_LSE_CK_MIN..STM32_LSE_CK_MAX)" -#endif -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined" -#endif - -#if (STM32_LSEDRV >> 3) > 3 -#error "STM32_LSEDRV outside acceptable range ((0<<3)..(3<<3))" -#endif - -#else /* !STM32_LSE_ENABLED */ - -#if STM32_RTCSEL == STM32_RTCSEL_LSE_CK -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#if STM32_MCO1SEL == STM32_MCO1SEL_LSE_CK -#error "LSE not enabled, required by STM32_MCO1SEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/** - * @brief HSI divided clock. - */ -#if (STM32_HSIDIV == STM32_HSIDIV_DIV1) || defined(__DOXYGEN__) -#define STM32_HSI_CK (STM32_HSICLK / 1U) -#elif STM32_HSIDIV == STM32_HSIDIV_DIV2 -#define STM32_HSI_CK (STM32_HSICLK / 2U) -#elif STM32_HSIDIV == STM32_HSIDIV_DIV4 -#define STM32_HSI_CK (STM32_HSICLK / 4U) -#elif STM32_HSIDIV == STM32_HSIDIV_DIV8 -#define STM32_HSI_CK (STM32_HSICLK / 8U) -#else -#error "invalid STM32_HSIDIV value specified" -#endif - -/** - * @brief HSE divided clock for RTC. - */ -#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_HSE_1M_CK (STM32_HSE_CK / STM32_RTCPRE_VALUE) -#else -#error "invalid STM32_RTCPRE_VALUE value specified" -#endif - -/** - * @brief PLLs input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE_CK) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN STM32_HSE_CK - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI_CK -#define STM32_PLLCLKIN STM32_HSI_CK - -#elif STM32_PLLSRC == STM32_PLLSRC_CSI_CK -#define STM32_PLLCLKIN STM32_CSI_CK - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/** - * @brief PLL1 DIVM field. - */ -#if ((STM32_PLL1_DIVM_VALUE >= 1) && (STM32_PLL1_DIVM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLL1_DIVM (STM32_PLL1_DIVM_VALUE << 4) -#define STM32_PLL1_REF_CK (STM32_PLLCLKIN / STM32_PLL1_DIVM_VALUE) -#else -#error "invalid STM32_PLL1_DIVM_VALUE value specified" -#endif - -/* - * PLL1 input frequency range check. - */ -#if (STM32_PLL1_REF_CK < STM32_PLLIN_MIN) || (STM32_PLL1_REF_CK > STM32_PLLIN_MAX) -#error "STM32_PLL1_REF_CK outside acceptable range (STM32_PLLIN_MIN..STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL1 input range selector. - */ -#if (STM32_PLL1_REF_CK < STM32_PLLIN_THRESHOLD1) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_0 -#elif STM32_PLL1_REF_CK < STM32_PLLIN_THRESHOLD2 -#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_1 -#elif STM32_PLL1_REF_CK < STM32_PLLIN_THRESHOLD3 -#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_2 -#else -#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_3 -#endif - -/** - * @brief PLL2 DIVM field. - */ -#if ((STM32_PLL2_DIVM_VALUE >= 1) && (STM32_PLL2_DIVM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2_DIVM (STM32_PLL2_DIVM_VALUE << 12) -#define STM32_PLL2_REF_CK (STM32_PLLCLKIN / STM32_PLL2_DIVM_VALUE) -#else -#error "invalid STM32_PLL2_DIVM_VALUE value specified" -#endif - -/* - * PLL2 input frequency range check. - */ -#if (STM32_PLL2_REF_CK < STM32_PLLIN_MIN) || (STM32_PLL2_REF_CK > STM32_PLLIN_MAX) -#error "STM32_PLL2_REF_CK outside acceptable range (STM32_PLLIN_MIN..STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL2 input range selector. - */ -#if (STM32_PLL2_REF_CK < STM32_PLLIN_THRESHOLD1) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_0 -#elif STM32_PLL2_REF_CK < STM32_PLLIN_THRESHOLD2 -#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_1 -#elif STM32_PLL2_REF_CK < STM32_PLLIN_THRESHOLD3 -#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_2 -#else -#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_3 -#endif - -/** - * @brief PLL3 DIVM field. - */ -#if ((STM32_PLL3_DIVM_VALUE >= 1) && (STM32_PLL3_DIVM_VALUE <= 63)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3_DIVM (STM32_PLL3_DIVM_VALUE << 20) -#define STM32_PLL3_REF_CK (STM32_PLLCLKIN / STM32_PLL3_DIVM_VALUE) -#else -#error "invalid STM32_PLL3_DIVM_VALUE value specified" -#endif - -/* - * PLL3 input frequency range check. - */ -#if (STM32_PLL3_REF_CK < STM32_PLLIN_MIN) || (STM32_PLL3_REF_CK > STM32_PLLIN_MAX) -#error "STM32_PLL3_REF_CK outside acceptable range (STM32_PLLIN_MIN..STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL3 input range selector. - */ -#if (STM32_PLL3_REF_CK < STM32_PLLIN_THRESHOLD1) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_0 -#elif STM32_PLL3_REF_CK < STM32_PLLIN_THRESHOLD2 -#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_1 -#elif STM32_PLL3_REF_CK < STM32_PLLIN_THRESHOLD3 -#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_2 -#else -#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_3 -#endif - -/** - * @brief PLL1 DIVN field. - */ -#if ((STM32_PLL1_DIVN_VALUE >= 4) && (STM32_PLL1_DIVN_VALUE <= 512)) || \ - defined(__DOXYGEN__) -#define STM32_PLL1_DIVN ((STM32_PLL1_DIVN_VALUE - 1U) << 0U) -#else -#error "invalid STM32_PLL1_DIVN_VALUE value specified" -#endif - -/** - * @brief PLL2 DIVN field. - */ -#if ((STM32_PLL2_DIVN_VALUE >= 4) && (STM32_PLL2_DIVN_VALUE <= 512)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2_DIVN ((STM32_PLL2_DIVN_VALUE - 1U) << 0U) -#else -#error "invalid STM32_PLL2_DIVN_VALUE value specified" -#endif - -/** - * @brief PLL3 DIVN field. - */ -#if ((STM32_PLL3_DIVN_VALUE >= 4) && (STM32_PLL3_DIVN_VALUE <= 512)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3_DIVN ((STM32_PLL3_DIVN_VALUE - 1U) << 0U) -#else -#error "invalid STM32_PLL3_DIVN_VALUE value specified" -#endif - -/** - * @brief PLL1 FRACN field. - */ -#if ((STM32_PLL1_FRACN_VALUE >= 0) && (STM32_PLL1_FRACN_VALUE <= 8191)) || \ - defined(__DOXYGEN__) -#define STM32_PLL1_FRACN (STM32_PLL1_FRACN_VALUE << 3U) -#else -#error "invalid STM32_PLL1_FRACN_VALUE value specified" -#endif - -/** - * @brief PLL2 FRACN field. - */ -#if ((STM32_PLL2_FRACN_VALUE >= 0) && (STM32_PLL2_FRACN_VALUE <= 8191)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2_FRACN (STM32_PLL2_FRACN_VALUE << 3U) -#else -#error "invalid STM32_PLL2_FRACN_VALUE value specified" -#endif - -/** - * @brief PLL3 FRACN field. - */ -#if ((STM32_PLL3_FRACN_VALUE >= 0) && (STM32_PLL3_FRACN_VALUE <= 8191)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3_FRACN (STM32_PLL3_FRACN_VALUE << 3U) -#else -#error "invalid STM32_PLL3_FRACN_VALUE value specified" -#endif - -/** - * @brief PLL1 DIVP field. - */ -#if ((STM32_PLL1_DIVP_VALUE >= 2) && (STM32_PLL1_DIVP_VALUE <= 128) && \ - ((STM32_PLL1_DIVP_VALUE & 1U) == 0U)) || \ - defined(__DOXYGEN__) -#define STM32_PLL1_DIVP ((STM32_PLL1_DIVP_VALUE - 1U) << 9U) -#else -#error "invalid STM32_PLL1_DIVP_VALUE value specified" -#endif - -/** - * @brief PLL2 DIVP field. - */ -#if ((STM32_PLL2_DIVP_VALUE >= 2) && (STM32_PLL2_DIVP_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2_DIVP ((STM32_PLL2_DIVP_VALUE - 1U) << 9U) -#else -#error "invalid STM32_PLL2_DIVP_VALUE value specified" -#endif - -/** - * @brief PLL3 DIVP field. - */ -#if ((STM32_PLL3_DIVP_VALUE >= 2) && (STM32_PLL3_DIVP_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3_DIVP ((STM32_PLL3_DIVP_VALUE - 1U) << 9U) -#else -#error "invalid STM32_PLL3_DIVP_VALUE value specified" -#endif - -/** - * @brief PLL1 DIVQ field. - */ -#if ((STM32_PLL1_DIVQ_VALUE >= 1) && (STM32_PLL1_DIVQ_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL1_DIVQ ((STM32_PLL1_DIVQ_VALUE - 1U) << 16U) -#else -#error "invalid STM32_PLL1_DIVQ_VALUE value specified" -#endif - -/** - * @brief PLL2 DIVQ field. - */ -#if ((STM32_PLL2_DIVQ_VALUE >= 1) && (STM32_PLL2_DIVQ_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2_DIVQ ((STM32_PLL2_DIVQ_VALUE - 1U) << 16U) -#else -#error "invalid STM32_PLL2_DIVQ_VALUE value specified" -#endif - -/** - * @brief PLL3 DIVQ field. - */ -#if ((STM32_PLL3_DIVQ_VALUE >= 1) && (STM32_PLL3_DIVQ_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3_DIVQ ((STM32_PLL3_DIVQ_VALUE - 1U) << 16U) -#else -#error "invalid STM32_PLL3_DIVQ_VALUE value specified" -#endif - -/** - * @brief PLL1 DIVR field. - */ -#if ((STM32_PLL1_DIVR_VALUE >= 1) && (STM32_PLL1_DIVR_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL1_DIVR ((STM32_PLL1_DIVR_VALUE - 1U) << 24U) -#else -#error "invalid STM32_PLL1_DIVR_VALUE value specified" -#endif - -/** - * @brief PLL2 DIVR field. - */ -#if ((STM32_PLL2_DIVR_VALUE >= 1) && (STM32_PLL2_DIVR_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL2_DIVR ((STM32_PLL2_DIVR_VALUE - 1U) << 24U) -#else -#error "invalid STM32_PLL2_DIVR_VALUE value specified" -#endif - -/** - * @brief PLL3 DIVR field. - */ -#if ((STM32_PLL3_DIVR_VALUE >= 1) && (STM32_PLL3_DIVR_VALUE <= 128)) || \ - defined(__DOXYGEN__) -#define STM32_PLL3_DIVR ((STM32_PLL3_DIVR_VALUE - 1U) << 24U) -#else -#error "invalid STM32_PLL3_DIVR_VALUE value specified" -#endif - -/** - * @brief PLL1 VCO frequency. - */ -#define STM32_PLL1_VCO_CK (STM32_PLL1_REF_CK * STM32_PLL1_DIVN_VALUE) - -/* - * PLL1 VCO frequency range check. - */ -#if (STM32_PLL1_VCO_CK < STM32_PLLVCO_MIN) || (STM32_PLL1_VCO_CK > STM32_PLLVCO_MAX) -#error "STM32_PLL1_VCO_CK outside acceptable range (STM32_PLLVCO_MIN..STM32_PLLVCO_MAX)" -#endif - -/* - * PLL1 VCO mode. - */ -#if (STM32_PLL1_VCO_CK > STM32_PLLVCO_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_PLL1VCOSEL 0U -#else -#define STM32_PLLCFGR_PLL1VCOSEL RCC_PLLCFGR_PLL1VCOSEL -#endif - -/** - * @brief PLL2 VCO frequency. - */ -#define STM32_PLL2_VCO_CK (STM32_PLL2_REF_CK * STM32_PLL2_DIVN_VALUE) - -/* - * PLL2 VCO frequency range check. - */ -#if (STM32_PLL2_VCO_CK < STM32_PLLVCO_MIN) || (STM32_PLL2_VCO_CK > STM32_PLLVCO_MAX) -#error "STM32_PLL2_VCO_CK outside acceptable range (STM32_PLLVCO_MIN..STM32_PLLVCO_MAX)" -#endif - -/* - * PLL2 VCO mode. - */ -#if (STM32_PLL2_VCO_CK > STM32_PLLVCO_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_PLL2VCOSEL 0U -#else -#define STM32_PLLCFGR_PLL2VCOSEL RCC_PLLCFGR_PLL2VCOSEL -#endif - -/** - * @brief PLL3 VCO frequency. - */ -#define STM32_PLL3_VCO_CK (STM32_PLL3_REF_CK * STM32_PLL3_DIVN_VALUE) - -/* - * PLL3 VCO frequency range check. - */ -#if (STM32_PLL3_VCO_CK < STM32_PLLVCO_MIN) || (STM32_PLL3_VCO_CK > STM32_PLLVCO_MAX) -#error "STM32_PLL3_VCO_CK outside acceptable range (STM32_PLLVCO_MIN..STM32_PLLVCO_MAX)" -#endif - -/* - * PLL3 VCO mode. - */ -#if (STM32_PLL3_VCO_CK > STM32_PLLVCO_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_PLLCFGR_PLL3VCOSEL 0U -#else -#define STM32_PLLCFGR_PLL3VCOSEL RCC_PLLCFGR_PLL3VCOSEL -#endif - -#if ((STM32_PLL1_ENABLED == TRUE) && (STM32_PLL1_P_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL1 P output clock frequency. - */ -#define STM32_PLL1_P_CK (STM32_PLL1_VCO_CK / STM32_PLL1_DIVP_VALUE) - -/* - * PLL1 P output frequency range check. - */ -#if (STM32_PLL1_P_CK < STM32_PLLOUT_MIN) || (STM32_PLL1_P_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL1_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL1_P_CK 0U -#endif - -#if ((STM32_PLL2_ENABLED == TRUE) && (STM32_PLL2_P_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL2 P output clock frequency. - */ -#define STM32_PLL2_P_CK (STM32_PLL2_VCO_CK / STM32_PLL2_DIVP_VALUE) - -/* - * PLL2 P output frequency range check. - */ -#if (STM32_PLL2_P_CK < STM32_PLLOUT_MIN) || (STM32_PLL2_P_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL2_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL2_P_CK 0U -#endif - -#if ((STM32_PLL3_ENABLED == TRUE) && (STM32_PLL3_P_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL3 P output clock frequency. - */ -#define STM32_PLL3_P_CK (STM32_PLL3_VCO_CK / STM32_PLL3_DIVP_VALUE) - -/* - * PLL3 P output frequency range check. - */ -#if (STM32_PLL3_P_CK < STM32_PLLOUT_MIN) || (STM32_PLL3_P_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL3_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL3_P_CK 0U -#endif - -#if ((STM32_PLL1_ENABLED == TRUE) && (STM32_PLL1_Q_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL1 Q output clock frequency. - */ -#define STM32_PLL1_Q_CK (STM32_PLL1_VCO_CK / STM32_PLL1_DIVQ_VALUE) - -/* - * PLL1 Q output frequency range check. - */ -#if (STM32_PLL1_Q_CK < STM32_PLLOUT_MIN) || (STM32_PLL1_Q_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL1_Q_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL1_Q_CK 0U -#endif - -#if ((STM32_PLL2_ENABLED == TRUE) && (STM32_PLL2_Q_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL2 Q output clock frequency. - */ -#define STM32_PLL2_Q_CK (STM32_PLL2_VCO_CK / STM32_PLL2_DIVQ_VALUE) - -/* - * PLL2 Q output frequency range check. - */ -#if (STM32_PLL2_Q_CK < STM32_PLLOUT_MIN) || (STM32_PLL2_Q_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL2_Q_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL2_Q_CK 0U -#endif - -#if ((STM32_PLL3_ENABLED == TRUE) && (STM32_PLL3_Q_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL3 Q output clock frequency. - */ -#define STM32_PLL3_Q_CK (STM32_PLL3_VCO_CK / STM32_PLL3_DIVQ_VALUE) - -/* - * PLL3 Q output frequency range check. - */ -#if (STM32_PLL3_Q_CK < STM32_PLLOUT_MIN) || (STM32_PLL3_Q_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL3_Q_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL3_Q_CK 0U -#endif - -#if ((STM32_PLL1_ENABLED == TRUE) && (STM32_PLL1_R_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL1 R output clock frequency. - */ -#define STM32_PLL1_R_CK (STM32_PLL1_VCO_CK / STM32_PLL1_DIVR_VALUE) - -/* - * PLL1 R output frequency range check. - */ -#if (STM32_PLL1_R_CK < STM32_PLLOUT_MIN) || (STM32_PLL1_R_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL1_R_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL1_R_CK 0U -#endif - -#if ((STM32_PLL2_ENABLED == TRUE) && (STM32_PLL2_R_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL2 R output clock frequency. - */ -#define STM32_PLL2_R_CK (STM32_PLL2_VCO_CK / STM32_PLL2_DIVR_VALUE) - -/* - * PLL2 R output frequency range check. - */ -#if (STM32_PLL2_R_CK < STM32_PLLOUT_MIN) || (STM32_PLL2_R_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL2_R_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL2_R_CK 0U -#endif - -#if ((STM32_PLL3_ENABLED == TRUE) && (STM32_PLL3_R_ENABLED == TRUE)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL3 R output clock frequency. - */ -#define STM32_PLL3_R_CK (STM32_PLL3_VCO_CK / STM32_PLL3_DIVR_VALUE) - -/* - * PLL3 R output frequency range check. - */ -#if (STM32_PLL3_R_CK < STM32_PLLOUT_MIN) || (STM32_PLL3_R_CK > STM32_PLLOUT_MAX) -#error "STM32_PLL3_R_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" -#endif -#else -#define STM32_PLL3_R_CK 0U -#endif - -/** - * @brief System clock source. - */ -#if (STM32_SW == STM32_SW_HSI_CK) || defined(__DOXYGEN__) -#define STM32_SYS_CK STM32_HSI_CK - -#elif (STM32_SW == STM32_SW_CSI_CK) -#define STM32_SYS_CK STM32_CSI_CK - -#elif (STM32_SW == STM32_SW_HSE_CK) -#define STM32_SYS_CK STM32_HSE_CK - -#elif (STM32_SW == STM32_SW_PLL1_P_CK) -#define STM32_SYS_CK STM32_PLL1_P_CK - -#else -#error "invalid STM32_SW value specified" -#endif - -/* - * Check on the system clock. - */ -#if STM32_SYS_CK > STM32_SYSCLK_MAX -#error "STM32_SYS_CK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/* - * ODEN setting based on clock frequency. - */ -#if STM32_SYS_CK > STM32_SYSCLK_MAX_NOBOOST -#define STM32_ODEN STM32_ODEN_ENABLED -#else -#define STM32_ODEN STM32_ODEN_DISABLED -#endif - -/** - * @brief Peripherals clock source. - */ -#if (STM32_CKPERSEL == STM32_CKPERSEL_HSI_CK) || defined(__DOXYGEN__) -#define STM32_PER_CK STM32_HSI_CK - -#elif (STM32_CKPERSEL == STM32_CKPERSEL_CSI_CK) -#define STM32_PER_CK STM32_CSI_CK - -#elif (STM32_CKPERSEL == STM32_CKPERSEL_HSE_CK) -#define STM32_PER_CK STM32_HSE_CK - -#else -#error "invalid STM32_CKPERSEL value specified" -#endif - -/* - * Check on the peripherals clock. - */ -#if STM32_PER_CK > STM32_HCLK_MAX -#error "STM32_PER_CK above maximum rated frequency (STM32_HCLK_MAX)" -#endif - -/** - * @brief MCO1 divider clock. - */ -#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI_CK) || defined(__DOXYGEN__) -#define STM32_MCO1DIVCLK STM32_HSI_CK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE_CK -#define STM32_MCO1DIVCLK STM32_LSE_CK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE_CK -#define STM32_MCO1DIVCLK STM32_HSE_CK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL1_Q_CK -#define STM32_MCO1DIVCLK STM32_PLL1_P_CK - -#elif STM32_MCO1SEL == STM32_MCO1SEL_HSI48_CK -#define STM32_MCO1DIVCLK STM32_HSI48_CK - -#else -#error "invalid STM32_MCO1SEL value specified" -#endif - -/** - * @brief MCO1 output pin clock. - */ -#if (STM32_MCO1PRE_VALUE < 1) || (STM32_MCO1PRE_VALUE > 15) -#error "STM32_MCO1PRE_VALUE outside acceptable range (1..15)" -#endif - -/** - * @brief MCO2 divider clock. - */ -#if (STM32_MCO2SEL == STM32_MCO2SEL_SYS_CK) || defined(__DOXYGEN__) -#define STM32_MCO2DIVCLK STM32_SYS_CK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL1_P_CK -#define STM32_MCO2DIVCLK STM32_PLL2_P_CK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_HSE_CK -#define STM32_MCO2DIVCLK STM32_HSE_CK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL2_P_CK -#define STM32_MCO2DIVCLK STM32_PLL2_P_CK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_CSI_CK -#define STM32_MCO2DIVCLK STM32_CSI_CK - -#elif STM32_MCO2SEL == STM32_MCO2SEL_LSI_CK -#define STM32_MCO2DIVCLK STM32_LSI_CK - -#else -#error "invalid STM32_MCO2SEL value specified" -#endif - -/** - * @brief MCO2 output pin clock. - */ -#if (STM32_MCO2PRE_VALUE < 1) || (STM32_MCO2PRE_VALUE > 15) -#error "STM32_MCO2PRE_VALUE outside acceptable range (1..15)" -#endif - -/** - * @brief RTC clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLK) || defined(__DOXYGEN__) -#define STM32_RTC_CK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE_CK -#define STM32_RTC_CK STM32_LSE_CK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI_CK -#define STM32_RTC_CK STM32_LSI_CK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSE_1M_CK -#define STM32_RTC_CK STM32_HSE_1M_CK - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/* - * Check on the RTC clock. - */ -#if STM32_RTC_CK > 1000000 -#error "STM32_RTC_CK above maximum rated frequency (1000000)" -#endif - -/** - * @brief D1CPRE clock. - */ -#if (STM32_D1CPRE == STM32_D1CPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 1U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV2 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 2U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV4 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 4U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV8 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 8U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV16 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 16U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV64 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 64U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV128 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 128U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV256 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 256U) -#elif STM32_D1CPRE == STM32_D1CPRE_DIV512 -#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 512U) -#else -#error "invalid STM32_D1CPRE value specified" -#endif - -/** - * @brief HCLK clock. - */ -#if (STM32_D1HPRE == STM32_D1HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 1U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV2 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 2U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV4 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 4U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV8 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 8U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV16 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 16U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV64 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 64U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV128 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 128U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV256 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 256U) -#elif STM32_D1HPRE == STM32_D1HPRE_DIV512 -#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 512U) -#else -#error "invalid STM32_D1HPRE value specified" -#endif - -/** - * @brief Core clock. - */ -#define STM32_CORE1_CK STM32_SYS_D1CPRE_CK - -/** - * @brief Core clock. - */ -#define STM32_CORE2_CK STM32_HCLK - -#if (STM32_TARGET_CORE == 1) || defined(__DOXYGEN__) - -#if STM32_HAS_M7 != TRUE -#error "Cortex-M7 not present in this device" -#endif -#define STM32_CORE_CK STM32_CORE1_CK - -#elif STM32_TARGET_CORE == 2 - -#if STM32_HAS_M4 != TRUE -#error "Cortex-M4 not present in this device" -#endif -#define STM32_CORE_CK STM32_CORE2_CK - -#else -#error "invalid STM32_TARGET_CORE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_HCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_HCLK_MAX)" -#endif - -/** - * @brief D1 PCLK3 clock. - */ -#if (STM32_D1PPRE3 == STM32_D1PPRE3_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK3 (STM32_HCLK / 1U) -#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV2 -#define STM32_PCLK3 (STM32_HCLK / 2U) -#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV4 -#define STM32_PCLK3 (STM32_HCLK / 4U) -#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV8 -#define STM32_PCLK3 (STM32_HCLK / 8U) -#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV16 -#define STM32_PCLK3 (STM32_HCLK / 16U) -#else -#error "invalid STM32_D1PPRE3 value specified" -#endif - -/* - * D1 PCLK3 frequency check. - */ -#if STM32_PCLK3 > STM32_PCLK3_MAX -#error "STM32_PCLK3 exceeding maximum frequency (STM32_PCLK3_MAX)" -#endif - -/** - * @brief D2 PCLK1 clock. - */ -#if (STM32_D2PPRE1 == STM32_D2PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1U) -#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2U) -#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4U) -#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8U) -#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16U) -#else -#error "invalid STM32_D2PPRE1 value specified" -#endif - -/* - * D2 PCLK1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief D2 PCLK2 clock. - */ -#if (STM32_D2PPRE2 == STM32_D2PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1U) -#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2U) -#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4U) -#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8U) -#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16U) -#else -#error "invalid STM32_D2PPRE2 value specified" -#endif - -/* - * D2 PCLK2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief D3 PCLK4 clock. - */ -#if (STM32_D3PPRE4 == STM32_D3PPRE4_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK4 (STM32_HCLK / 1U) -#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV2 -#define STM32_PCLK4 (STM32_HCLK / 2U) -#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV4 -#define STM32_PCLK4 (STM32_HCLK / 4U) -#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV8 -#define STM32_PCLK4 (STM32_HCLK / 8U) -#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV16 -#define STM32_PCLK4 (STM32_HCLK / 16U) -#else -#error "invalid STM32_D3PPRE4 value specified" -#endif - -/* - * D3 PCLK4 frequency check. - */ -#if STM32_PCLK4 > STM32_PCLK4_MAX -#error "STM32_PCLK4 exceeding maximum frequency (STM32_PCLK4_MAX)" -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0x00000000 - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS 0x00000001 - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS 0x00000002 - -#elif STM32_HCLK <= STM32_3WS_THRESHOLD -#define STM32_FLASHBITS 0x00000003 - -#elif STM32_HCLK <= STM32_4WS_THRESHOLD -#define STM32_FLASHBITS 0x00000004 - -#else -#define STM32_FLASHBITS 0x00000007 -#endif - -#if (STM32_D2PPRE1 == STM32_D2PPRE1_DIV1) || defined(__DOXYGEN__) -/** - * @brief Clock of timers connected to APB1 - */ -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#if (STM32_TIMPRE_ENABLE == FALSE) || (STM32_D2PPRE1 == STM32_D2PPRE1_DIV2) -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 4) -#endif -#endif - -#if (STM32_D2PPRE2 == STM32_D2PPRE2_DIV1) || defined(__DOXYGEN__) -/** - * @brief Clock of timers connected to APB2. - */ -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#if (STM32_TIMPRE_ENABLE == FALSE) || (STM32_D2PPRE2 == STM32_D2PPRE2_DIV2) -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 4) -#endif -#endif - -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) -/** - * @brief LPTIM1 clock. - */ -#define STM32_LPTIM1CLK STM32_PCLK1 - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_PLL2_P_CK -#define STM32_LPTIM1CLK STM32_PLL2_P_CK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_PLL3_R_CK -#define STM32_LPTIM1CLK STM32_PLL3_R_CK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE_CK -#define STM32_LPTIM1CLK STM32_LSE_CK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI_CK -#define STM32_LPTIM1CLK STM32_LSI_CK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_PER_CK -#define STM32_LPTIM1CLK STM32_PER_CK -#else -#error "invalid source selected for STM32_LPTIM1SEL clock" -#endif - -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK4) || defined(__DOXYGEN__) -/** - * @brief LPTIM2 clock. - */ -#define STM32_LPTIM2CLK STM32_PCLK4 - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_PLL2_P_CK -#define STM32_LPTIM2CLK STM32_PLL2_P_CK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_PLL3_P_CK -#define STM32_LPTIM2CLK STM32_PLL3_P_CK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE_CK -#define STM32_LPTIM2CLK STM32_LSE_CK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI_CK -#define STM32_LPTIM2CLK STM32_LSI_CK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_PER_CK -#define STM32_LPTIM2CLK STM32_PER_CK -#else -#error "invalid source selected for STM32_LPTIM2SEL clock" -#endif - -#if (STM32_LPTIM345SEL == STM32_LPTIM345SEL_PCLK4) || defined(__DOXYGEN__) -/** - * @brief LPTIM3 clock. - */ -#define STM32_LPTIM3CLK STM32_PCLK4 - -/** - * @brief LPTIM4 clock. - */ -#define STM32_LPTIM4CLK STM32_PCLK4 - -/** - * @brief LPTIM5 clock. - */ -#define STM32_LPTIM5CLK STM32_PCLK4 - -#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_PLL2_P_CK -#define STM32_LPTIM3CLK STM32_PLL2_P_CK -#define STM32_LPTIM4CLK STM32_PLL2_P_CK -#define STM32_LPTIM5CLK STM32_PLL2_P_CK -#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_PLL3_P_CK -#define STM32_LPTIM3CLK STM32_PLL3_P_CK -#define STM32_LPTIM4CLK STM32_PLL3_P_CK -#define STM32_LPTIM5CLK STM32_PLL3_P_CK -#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_LSE_CK -#define STM32_LPTIM3CLK STM32_LSE_CK -#define STM32_LPTIM4CLK STM32_LSE_CK -#define STM32_LPTIM5CLK STM32_LSE_CK -#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_LSI_CK -#define STM32_LPTIM3CLK STM32_LSI_CK -#define STM32_LPTIM4CLK STM32_LSI_CK -#define STM32_LPTIM5CLK STM32_LSI_CK -#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_PER_CK -#define STM32_LPTIM3CLK STM32_PER_CK -#define STM32_LPTIM4CLK STM32_PER_CK -#define STM32_LPTIM5CLK STM32_PER_CK -#else -#error "invalid source selected for STM32_LPTIM345SEL clock" -#endif - -#if (STM32_USART16SEL == STM32_USART16SEL_PCLK2) || defined(__DOXYGEN__) -/** - * @brief USART1 clock. - */ -#define STM32_USART1CLK STM32_PCLK2 - -/** - * @brief USART6 clock. - */ -#define STM32_USART6CLK STM32_PCLK2 - -#elif STM32_USART16SEL == STM32_USART16SEL_PLL2_Q_CK -#define STM32_USART1CLK STM32_PLL2_Q_CK -#define STM32_USART6CLK STM32_PLL2_Q_CK -#elif STM32_USART16SEL == STM32_USART16SEL_PLL3_Q_CK -#define STM32_USART1CLK STM32_PLL3_Q_CK -#define STM32_USART6CLK STM32_PLL3_Q_CK -#elif STM32_USART16SEL == STM32_USART16SEL_HSI_KER_CK -#define STM32_USART1CLK STM32_HSI_CK -#define STM32_USART6CLK STM32_HSI_CK -#elif STM32_USART16SEL == STM32_USART16SEL_CSI_KER_CK -#define STM32_USART1CLK STM32_CSI_CK -#define STM32_USART6CLK STM32_CSI_CK -#elif STM32_USART16SEL == STM32_USART16SEL_LSE_CK -#define STM32_USART1CLK STM32_LSE_CK -#define STM32_USART6CLK STM32_LSE_CK -#else -#error "invalid source selected for STM32_USART16SEL clock" -#endif - -#if (STM32_USART234578SEL == STM32_USART234578SEL_PCLK1) || defined(__DOXYGEN__) -/** - * @brief USART2 clock. - */ -#define STM32_USART2CLK STM32_PCLK1 - -/** - * @brief USART3 clock. - */ -#define STM32_USART3CLK STM32_PCLK1 - -/** - * @brief USART4 clock. - */ -#define STM32_UART4CLK STM32_PCLK1 - -/** - * @brief USART5 clock. - */ -#define STM32_UART5CLK STM32_PCLK1 - -/** - * @brief USART7 clock. - */ -#define STM32_UART7CLK STM32_PCLK1 - -/** - * @brief USART8 clock. - */ -#define STM32_UART8CLK STM32_PCLK1 - -#elif STM32_USART234578SEL == STM32_USART234578SEL_PLL2_Q_CK -#define STM32_USART2CLK STM32_PLL2_Q_CK -#define STM32_USART3CLK STM32_PLL2_Q_CK -#define STM32_UART4CLK STM32_PLL2_Q_CK -#define STM32_UART5CLK STM32_PLL2_Q_CK -#define STM32_UART7CLK STM32_PLL2_Q_CK -#define STM32_UART8CLK STM32_PLL2_Q_CK -#elif STM32_USART234578SEL == STM32_USART234578SEL_PLL3_Q_CK -#define STM32_USART2CLK STM32_PLL3_Q_CK -#define STM32_USART3CLK STM32_PLL3_Q_CK -#define STM32_UART4CLK STM32_PLL3_Q_CK -#define STM32_UART5CLK STM32_PLL3_Q_CK -#define STM32_UART7CLK STM32_PLL3_Q_CK -#define STM32_UART8CLK STM32_PLL3_Q_CK -#elif STM32_USART234578SEL == STM32_USART234578SEL_HSI_KER_CK -#define STM32_USART2CLK STM32_HSI_CK -#define STM32_USART3CLK STM32_HSI_CK -#define STM32_UART4CLK STM32_HSI_CK -#define STM32_UART5CLK STM32_HSI_CK -#define STM32_UART7CLK STM32_HSI_CK -#define STM32_UART8CLK STM32_HSI_CK -#elif STM32_USART234578SEL == STM32_USART234578SEL_CSI_KER_CK -#define STM32_USART2CLK STM32_CSI_CK -#define STM32_USART3CLK STM32_CSI_CK -#define STM32_UART4CLK STM32_CSI_CK -#define STM32_UART5CLK STM32_CSI_CK -#define STM32_UART7CLK STM32_CSI_CK -#define STM32_UART8CLK STM32_CSI_CK -#elif STM32_USART234578SEL == STM32_USART234578SEL_LSE_CK -#define STM32_USART2CLK STM32_LSE_CK -#define STM32_USART3CLK STM32_LSE_CK -#define STM32_UART4CLK STM32_LSE_CK -#define STM32_UART6CLK STM32_LSE_CK -#define STM32_UART7CLK STM32_LSE_CK -#define STM32_UART8CLK STM32_LSE_CK -#else -#error "invalid source selected for STM32_USART234578SEL clock" -#endif - -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK4) || defined(__DOXYGEN__) -/** - * @brief LPUART1 clock. - */ -#define STM32_LPUART1CLK STM32_PCLK4 - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_PLL2_Q_CK -#define STM32_LPUART1CLK STM32_PLL2_Q_CK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_PLL3_Q_CK -#define STM32_LPUART1CLK STM32_PLL3_Q_CK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI_KER_CK -#define STM32_LPUART1CLK STM32_HSI_CK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_CSI_KER_CK -#define STM32_LPUART1CLK STM32_CSI_CK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE_CK -#define STM32_LPUART1CLK STM32_LSE_CK -#else -#error "invalid source selected for STM32_LPUART1SEL clock" -#endif - -#if (STM32_SPI123SEL == STM32_SPI123SEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SPI1 clock. - */ -#define STM32_SPI1CLK STM32_PLL1_Q_CK - -/** - * @brief SPI2 clock. - */ -#define STM32_SPI2CLK STM32_PLL1_Q_CK - -/** - * @brief SPI3 clock. - */ -#define STM32_SPI3CLK STM32_PLL1_Q_CK -#elif STM32_SPI123SEL == STM32_SPI123SEL_PLL2_P_CK -#define STM32_SPI1CLK STM32_PLL2_P_CK -#define STM32_SPI2CLK STM32_PLL2_P_CK -#define STM32_SPI3CLK STM32_PLL2_P_CK -#elif STM32_SPI123SEL == STM32_SPI123SEL_PLL3_P_CK -#define STM32_SPI1CLK STM32_PLL3_P_CK -#define STM32_SPI2CLK STM32_PLL3_P_CK -#define STM32_SPI3CLK STM32_PLL3_P_CK -#elif STM32_SPI123SEL == STM32_SPI123SEL_I2S_CKIN -#define STM32_SPI1CLK 0 /* Unknown, would require a board value */ -#define STM32_SPI2CLK 0 /* Unknown, would require a board value */ -#define STM32_SPI3CLK 0 /* Unknown, would require a board value */ -#elif STM32_SPI123SEL == STM32_SPI123SEL_PER_CK -#define STM32_SPI1CLK STM32_PER_CK -#define STM32_SPI2CLK STM32_PER_CK -#define STM32_SPI3CLK STM32_PER_CK -#else -#error "invalid source selected for STM32_SPI123SEL clock" -#endif - -#if (STM32_SPI45SEL == STM32_SPI45SEL_PCLK2) || defined(__DOXYGEN__) -/** - * @brief SPI4 clock. - */ -#define STM32_SPI4CLK STM32_PCLK2 - -/** - * @brief SPI5 clock. - */ -#define STM32_SPI5CLK STM32_PCLK2 - -#elif STM32_SPI45SEL == STM32_SPI45SEL_PLL2_Q_CK -#define STM32_SPI4CLK STM32_PLL2_Q_CK -#define STM32_SPI5CLK STM32_PLL2_Q_CK -#elif STM32_SPI45SEL == STM32_SPI45SEL_PLL3_Q_CK -#define STM32_SPI4CLK STM32_PLL3_Q_CK -#define STM32_SPI5CLK STM32_PLL3_Q_CK -#elif STM32_SPI45SEL == STM32_SPI45SEL_HSI_KER_CK -#define STM32_SPI4CLK STM32_HSI_CK -#define STM32_SPI5CLK STM32_HSI_CK -#elif STM32_SPI45SEL == STM32_SPI45SEL_CSI_KER_CK -#define STM32_SPI4CLK STM32_CSI_CK -#define STM32_SPI5CLK STM32_CSI_CK -#elif STM32_SPI45SEL == STM32_SPI45SEL_HSE_CK -#define STM32_SPI4CLK STM32_HSE_CK -#define STM32_SPI5CLK STM32_HSE_CK -#else -#error "invalid source selected for STM32_SPI45SEL clock" -#endif - -#if (STM32_SPI6SEL == STM32_SPI6SEL_PCLK4) || defined(__DOXYGEN__) -/** - * @brief SPI6 clock. - */ -#define STM32_SPI6CLK STM32_PCLK4 - -#elif STM32_SPI6SEL == STM32_SPI6SEL_PLL2_Q_CK -#define STM32_SPI6CLK STM32_PLL2_Q_CK -#elif STM32_SPI6SEL == STM32_SPI6SEL_PLL3_Q_CK -#define STM32_SPI6CLK STM32_PLL3_Q_CK -#elif STM32_SPI6SEL == STM32_SPI6SEL_HSI_KER_CK -#define STM32_SPI6CLK STM32_HSI_CK -#elif STM32_SPI6SEL == STM32_SPI6SEL_CSI_KER_CK -#define STM32_SPI6CLK STM32_CSI_CK -#elif STM32_SPI6SEL == STM32_SPI6SEL_HSE_CK -#define STM32_SPI6CLK STM32_HSE_CK -#else -#error "invalid source selected for STM32_SPI6SEL clock" -#endif - -#if (STM32_I2C123SEL == STM32_I2C123SEL_PCLK1) || defined(__DOXYGEN__) -/** - * @brief I2C1 clock. - */ -#define STM32_I2C1CLK STM32_PCLK1 - -/** - * @brief I2C2 clock. - */ -#define STM32_I2C2CLK STM32_PCLK1 - -/** - * @brief I2C2 clock. - */ -#define STM32_I2C2CLK STM32_PCLK1 - -#elif STM32_I2C123SEL == STM32_I2C123SEL_PLL3_R_CK -#define STM32_I2C1CLK STM32_PLL3_R_CK -#define STM32_I2C2CLK STM32_PLL3_R_CK -#define STM32_I2C2CLK STM32_PLL3_R_CK - -#elif STM32_I2C123SEL == STM32_I2C123SEL_HSI_KER_CK -#define STM32_I2C1CLK STM32_HSI_CK -#define STM32_I2C2CLK STM32_HSI_CK -#define STM32_I2C2CLK STM32_HSI_CK - -#elif STM32_I2C123SEL == STM32_I2C123SEL_CSI_KER_CK -#define STM32_I2C1CLK STM32_CSI_CK -#define STM32_I2C2CLK STM32_CSI_CK -#define STM32_I2C2CLK STM32_CSI_CK -#else -#error "invalid source selected for STM32_I2C123SEL clock" -#endif - -#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK4) || defined(__DOXYGEN__) -/** - * @brief I2C1 clock. - */ -#define STM32_I2C4CLK STM32_PCLK4 - -#elif STM32_I2C4SEL == STM32_I2C4SEL_PLL3_R_CK -#define STM32_I2C4CLK STM32_PLL3_R_CK -#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI_KER_CK -#define STM32_I2C4CLK STM32_HSI_CK -#elif STM32_I2C4SEL == STM32_I2C4SEL_CSI_KER_CK -#define STM32_I2C4CLK STM32_CSI_CK -#else -#error "invalid source selected for STM32_I2C4SEL clock" -#endif - -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SAI1 clock. - */ -#define STM32_SAI1CLK STM32_PLL1_Q_CK - -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL2_P_CK -#define STM32_SAI1CLK STM32_PLL2_P_CK -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL3_P_CK -#define STM32_SAI1CLK STM32_PLL3_P_CK -#elif STM32_SAI1SEL == STM32_SAI1SEL_I2S_CKIN -#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ -#elif STM32_SAI1SEL == STM32_SAI1SEL_PER_CK -#define STM32_SAI1CLK STM32_PER_CK -#else -#error "invalid source selected for STM32_SAI1SEL clock" -#endif - -#if (STM32_SAI23SEL == STM32_SAI23SEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SAI2 clock. - */ -#define STM32_SAI2CLK STM32_PLL1_Q_CK - -/** - * @brief SAI3 clock. - */ -#define STM32_SAI3CLK STM32_PLL1_Q_CK - -#elif STM32_SAI23SEL == STM32_SAI23SEL_PLL2_P_CK -#define STM32_SAI2CLK STM32_PLL2_P_CK -#define STM32_SAI3CLK STM32_PLL2_P_CK -#elif STM32_SAI23SEL == STM32_SAI23SEL_PLL3_P_CK -#define STM32_SAI2CLK STM32_PLL3_P_CK -#define STM32_SAI3CLK STM32_PLL3_P_CK -#elif STM32_SAI23SEL == STM32_SAI23SEL_I2S_CKIN -#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ -#define STM32_SAI3CLK 0 /* Unknown, would require a board value */ -#elif STM32_SAI23SEL == STM32_SAI23SEL_PER_CK -#define STM32_SAI2CLK STM32_PER_CK -#define STM32_SAI3CLK STM32_PER_CK -#else -#error "invalid source selected for STM32_SAI23SEL clock" -#endif - -#if (STM32_SAI4ASEL == STM32_SAI4ASEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SAI4A clock. - */ -#define STM32_SAI4ACLK STM32_PLL1_Q_CK - -#elif STM32_SAI4ASEL == STM32_SAI4ASEL_PLL2_P_CK -#define STM32_SAI4ACLK STM32_PLL2_P_CK -#elif STM32_SAI4ASEL == STM32_SAI4ASEL_PLL3_P_CK -#define STM32_SAI4ACLK STM32_PLL3_P_CK -#elif STM32_SAI4ASEL == STM32_SAI4ASEL_I2S_CKIN -#define STM32_SAI4ACLK 0 /* Unknown, would require a board value */ -#elif STM32_SAI4ASEL == STM32_SAI4ASEL_PER_CK -#define STM32_SAI4ACLK STM32_PER_CK -#else -#error "invalid source selected for STM32_SAI4ASEL clock" -#endif - -#if (STM32_SAI4BSEL == STM32_SAI4BSEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SAI4B clock. - */ -#define STM32_SAI4BCLK STM32_PLL1_Q_CK - -#elif STM32_SAI4BSEL == STM32_SAI4BSEL_PLL2_P_CK -#define STM32_SAI4BCLK STM32_PLL2_P_CK -#elif STM32_SAI4BSEL == STM32_SAI4BSEL_PLL3_P_CK -#define STM32_SAI4BCLK STM32_PLL3_P_CK -#elif STM32_SAI4BSEL == STM32_SAI4BSEL_I2S_CKIN -#define STM32_SAI4BCLK 0 /* Unknown, would require a board value */ -#elif STM32_SAI4BSEL == STM32_SAI4BSEL_PER_CK -#define STM32_SAI4BCLK STM32_PER_CK -#else -#error "invalid source selected for STM32_SAI4BSEL clock" -#endif - -#if (STM32_USBSEL == STM32_USBSEL_DISABLE) || defined(__DOXYGEN__) -/** - * @brief USB clock. - */ -#define STM32_USBCLK 0 - -#elif STM32_USBSEL == STM32_USBSEL_PLL1_Q_CK -#define STM32_USBCLK STM32_PLL1_Q_CK -#elif STM32_USBSEL == STM32_USBSEL_PLL3_Q_CK -#define STM32_USBCLK STM32_PLL3_Q_CK -#elif STM32_USBSEL == STM32_USBSEL_HSI48_CK -#define STM32_USBCLK STM32_HSI48_CK -#else -#error "invalid source selected for STM32_USBSEL clock" -#endif - -#if (STM32_SDMMCSEL == STM32_SDMMCSEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SDMMC1 frequency. - */ -#define STM32_SDMMC1CLK STM32_PLL1_Q_CK - -/** - * @brief SDMMC2 frequency. - */ -#define STM32_SDMMC2CLK STM32_PLL1_Q_CK - -#elif STM32_SDMMCSEL == STM32_SDMMCSEL_PLL2_R_CK -#define STM32_SDMMC1CLK STM32_PLL2_R_CK -#define STM32_SDMMC2CLK STM32_PLL2_R_CK -#else -#error "invalid source selected for STM32_SDMMCxSEL clock" -#endif - -#if (STM32_QSPISEL == STM32_QSPISEL_HCLK) || defined(__DOXYGEN__) -/** - * @brief QSPI frequency. - */ -#define STM32_QSPICLK STM32_HCLK - -#elif STM32_QSPISEL == STM32_QSPISEL_PLL1_Q_CK -#define STM32_QSPICLK STM32_PLL1_Q_CK -#elif STM32_QSPISEL == STM32_QSPISEL_PLL2_R_CK -#define STM32_QSPICLK STM32_PLL2_R_CK -#elif STM32_QSPISEL == STM32_QSPISEL_PER_CK -#define STM32_QSPICLK STM32_PER_CK -#else -#error "invalid source selected for STM32_QSPISEL clock" -#endif - -#if (STM32_FMCSEL == STM32_FMCSEL_HCLK) || defined(__DOXYGEN__) -/** - * @brief FMC frequency. - */ -#define STM32_FMCCLK STM32_HCLK - -#elif STM32_FMCSEL == STM32_FMCSEL_PLL1_Q_CK -#define STM32_FMCCLK STM32_PLL1_Q_CK -#elif STM32_FMCSEL == STM32_FMCSEL_PLL2_R_CK -#define STM32_FMCCLK STM32_PLL2_R_CK -#elif STM32_FMCSEL == STM32_FMCSEL_PER_CK -#define STM32_FMCCLK STM32_PER_CK -#else -#error "invalid source selected for STM32_FMCSEL clock" -#endif - -#if (STM32_SWPSEL == STM32_SWPSEL_PCLK1) || defined(__DOXYGEN__) -/** - * @brief SDMMC frequency. - */ -#define STM32_SWPCLK STM32_PCLK1 - -#elif STM32_SWPSEL == STM32_SWPSEL_HSI_KER_CK -#define STM32_SWPCLK STM32_HSI_CK -#else -#error "invalid source selected for STM32_SWPSEL clock" -#endif - -#if (STM32_FDCANSEL == STM32_FDCANSEL_HSE_CK) || defined(__DOXYGEN__) -/** - * @brief FDCAN frequency. - */ -#define STM32_FDCANCLK STM32_HSE_CK - -#elif STM32_FDCANSEL == STM32_FDCANSEL_PLL1_Q_CK -#define STM32_FDCANCLK STM32_PLL1_Q_CK -#elif STM32_FDCANSEL == STM32_FDCANSEL_PLL2_Q_CK -#define STM32_FDCANCLK STM32_PLL2_Q_CK -#else -#error "invalid source selected for STM32_FDCANSEL clock" -#endif - -#if (STM32_DFSDM1SEL == STM32_DFSDM1SEL_PCLK2) || defined(__DOXYGEN__) -/** - * @brief SDMMC frequency. - */ -#define STM32_DFSDM1CLK STM32_PCLK2 - -#elif STM32_DFSDM1SEL == STM32_DFSDM1SEL_SYS_CK -#define STM32_DFSDM1CLK STM32_SYS_CK -#else -#error "invalid source selected for STM32_DFSDM1SEL clock" -#endif - -#if (STM32_SPDIFSEL == STM32_SPDIFSEL_PLL1_Q_CK) || defined(__DOXYGEN__) -/** - * @brief SPDIF frequency. - */ -#define STM32_SPDIFCLK STM32_PLL1_Q_CK - -#elif STM32_SPDIFSEL == STM32_SPDIFSEL_PLL2_R_CK -#define STM32_SPDIFCLK STM32_PLL2_R_CK -#elif STM32_SPDIFSEL == STM32_SPDIFSEL_PLL3_R_CK -#define STM32_SPDIFCLK STM32_PLL3_R_CK -#elif STM32_SPDIFSEL == STM32_SPDIFSEL_HSI_KET_CLK -#define STM32_SPDIFCLK STM32_HSI_CK -#else -#error "invalid source selected for STM32_SPDIFSEL clock" -#endif - -#if (STM32_CECSEL == STM32_CECSEL_LSE_CK) || defined(__DOXYGEN__) -/** - * @brief CEC frequency. - */ -#define STM32_CECCLK STM32_LSE_CK - -#elif STM32_CECSEL == STM32_CECSEL_LSI_CK -#define STM32_CECCLK STM32_LSI_CK -#elif STM32_CECSEL == STM32_CECSEL_CSI_KER_CK -#define STM32_CECCLK STM32_CSI_CK -#elif STM32_CECSEL == STM32_CECSEL_DISABLE -#define STM32_CECCLK 0 -#else -#error "invalid source selected for STM32_CECSEL clock" -#endif - -#if (STM32_RNGSEL == STM32_RNGSEL_HSI48_CK) || defined(__DOXYGEN__) -/** - * @brief RNG frequency. - */ -#define STM32_RNGCLK STM32_HSI48_CK - -#elif STM32_RNGSEL == STM32_RNGSEL_PLL1_Q_CK -#define STM32_RNGCLK STM32_PLL1_Q_CK -#elif STM32_RNGSEL == STM32_RNGSEL_LSE_CK -#define STM32_RNGCLK STM32_LSE_CK -#elif STM32_RNGSEL == STM32_RNGSEL_LSI_CK -#define STM32_RNGCLK STM32_LSI_CK -#else -#error "invalid source selected for STM32_RNGSEL clock" -#endif - -#if (STM32_ADCSEL == STM32_ADCSEL_PLL2_P_CK) || defined(__DOXYGEN__) -/** - * @brief ADC frequency. - */ -#define STM32_ADCCLK STM32_PLL2_P_CK - -#elif STM32_ADCSEL == STM32_ADCSEL_PLL3_R_CK -#define STM32_ADCCLK STM32_PLL3_R_CK -#elif STM32_ADCSEL == STM32_ADCSEL_PER_CK -#define STM32_ADCCLK STM32_PER_CK -#elif STM32_ADCSEL == STM32_ADCSEL_DISABLE -#define STM32_ADCCLK 0 -#else -#error "invalid source selected for STM32_ADCSEL clock" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_mdma.h" -#include "stm32_dma.h" -#include "stm32_bdma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32H7xx/hal_lld.h + * @brief STM32H7xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * - STM32_VDD (as hundredths of Volt). + * . + * One of the following macros must also be defined: + * - STM32H743xx, STM32H753xx very high-performance MCUs. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32H742xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32H742 Single Core Very High Performance with DSP and FPU" + +#elif defined(STM32H743xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32H743 Single Core Very High Performance with DSP and FPU" + +#elif defined(STM32H753xx) +#define PLATFORM_NAME "STM32H753 Single Core Very High Performance with DSP and FPU" + +#elif defined(STM32H745xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32H745 Dual Core Very High Performance with DSP and FPU" + +#elif defined(STM32H755xx) +#define PLATFORM_NAME "STM32H755 Dual Core Very High Performance with DSP and FPU" + +#elif defined(STM32H747xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32H747 Dual Core Very High Performance with DSP and FPU" + +#elif defined(STM32H757xx) +#define PLATFORM_NAME "STM32H757 Dual Core Very High Performance with DSP and FPU" + +#elif defined(STM32H750xx) +#define PLATFORM_NAME "STM32H750 Value Line Very High Performance with DSP and FPU" + +#else +#error "STM32H7xx device not specified" +#endif +/** @} */ + +/** + * @name Sub-family identifier + */ +#if !defined(STM32H7XX) || defined(__DOXYGEN__) +#define STM32H7XX +#endif +/** @} */ + +#if !defined(STM32_ENFORCE_H7_REV_XY) +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Absolute maximum system clock. + */ +#define STM32_SYSCLK_MAX 480000000 + +/** + * @brief Maximum SYSCLK clock frequency without voltage boost. + */ +#define STM32_SYSCLK_MAX_NOBOOST 400000000 + +/** + * @brief Absolute maximum HCLK clock. + */ +#define STM32_HCLK_MAX (STM32_SYSCLK_MAX / 2) + +/** + * @brief Maximum HSE clock frequency. + */ +#define STM32_HSECLK_MAX 48000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 50000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_BYP_MIN 4000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSE_CK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSE_CK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSE_CK_MIN 32768 + +/** + * @brief Minimum PLLs input clock frequency.. + */ +#define STM32_PLLIN_MIN 1000000 + +/** + * @brief PLLs input threshold frequency 1. + */ +#define STM32_PLLIN_THRESHOLD1 2000000 + +/** + * @brief PLLs input threshold frequency 2. + */ +#define STM32_PLLIN_THRESHOLD2 4000000 + +/** + * @brief PLLs input threshold frequency 3. + */ +#define STM32_PLLIN_THRESHOLD3 8000000 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs VCO clock frequency. + */ +#define STM32_PLLVCO_MIN 150000000 /* DS says 192, RM says 150. */ + +/** + * @brief Threshold PLLs clock frequency. + */ +#define STM32_PLLVCO_THRESHOLD 420000000 + +/** + * @brief Maximum PLLs VCOH clock frequency. + */ +#define STM32_PLLVCO_MAX 960000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX (STM32_HCLK_MAX / 2) + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX (STM32_HCLK_MAX / 2) + +/** + * @brief Maximum APB3 clock frequency. + */ +#define STM32_PCLK3_MAX (STM32_HCLK_MAX / 2) + +/** + * @brief Maximum APB4 clock frequency. + */ +#define STM32_PCLK4_MAX (STM32_HCLK_MAX / 2) + +/** + * @brief Maximum SPI1, SPI2 and SPI3 clock frequency. + */ +#define STM32_SPI123_MAX 200000000 + +/** + * @brief Maximum SPI4, SPI5 and SPI6 clock frequency. + */ +#define STM32_SPI456_MAX 125000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 50000000 +/** @} */ + +#else /* defined(STM32_ENFORCE_H7_REV_XY) */ + +#define STM32_SYSCLK_MAX 400000000 +#define STM32_SYSCLK_MAX_NOBOOST 400000000 +#define STM32_HCLK_MAX (STM32_SYSCLK_MAX / 2) +#define STM32_HSECLK_MAX 48000000 +#define STM32_HSECLK_BYP_MAX 50000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 4000000 +#define STM32_LSE_CK_MAX 32768 +#define STM32_LSE_CK_BYP_MAX 1000000 +#define STM32_LSE_CK_MIN 32768 +#define STM32_PLLIN_MIN 1000000 +#define STM32_PLLIN_THRESHOLD1 2000000 +#define STM32_PLLIN_THRESHOLD2 4000000 +#define STM32_PLLIN_THRESHOLD3 8000000 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLVCO_MIN 150000000 +#define STM32_PLLVCO_THRESHOLD 420000000 +#define STM32_PLLVCO_MAX 836000000 +#define STM32_PCLK1_MAX (STM32_HCLK_MAX / 2) +#define STM32_PCLK2_MAX (STM32_HCLK_MAX / 2) +#define STM32_PCLK3_MAX (STM32_HCLK_MAX / 2) +#define STM32_PCLK4_MAX (STM32_HCLK_MAX / 2) +#define STM32_SPI123_MAX 133000000 +#define STM32_SPI456_MAX 100000000 +#define STM32_ADCCLK_MAX 36000000 + +#endif /* defined(STM32_ENFORCE_H7_REV_XY) */ + +/** + * @name Internal clock sources frequencies + * @{ + */ +#define STM32_HSI_OSC 64000000 +#define STM32_HSI48_OSC 48000000 +#define STM32_CSI_OSC 4000000 +#define STM32_LSI_OSC 32000 +/** @} */ + +/** + * @name Register helpers not found in ST headers + * @{ + */ +#define RCC_CR_HSIDIV_VALUE(n) ((n) << 3U) + +#define RCC_CFGR_SW_VALUE(n) ((n) << 0U) +#define RCC_CFGR_RTCPRE_VALUE(n) ((n) << 8U) +#define RCC_CFGR_MCO1PRE_VALUE(n) ((n) << 18U) +#define RCC_CFGR_MCO1_VALUE(n) ((n) << 22U) +#define RCC_CFGR_MCO2PRE_VALUE(n) ((n) << 25U) +#define RCC_CFGR_MCO2_VALUE(n) ((n) << 29U) + +#define RCC_D1CFGR_D1HPRE_VALUE(n) ((n) << RCC_D1CFGR_HPRE_Pos) +#define RCC_D1CFGR_D1CPRE_VALUE(n) ((n) << RCC_D1CFGR_D1CPRE_Pos) +#define RCC_D1CFGR_D1PPRE3_VALUE(n) ((n) << RCC_D1CFGR_D1PPRE_Pos) + +#define RCC_D2CFGR_D2PPRE1_VALUE(n) ((n) << RCC_D2CFGR_D2PPRE1_Pos) +#define RCC_D2CFGR_D2PPRE2_VALUE(n) ((n) << RCC_D2CFGR_D2PPRE2_Pos) + +#define RCC_D3CFGR_D3PPRE4_VALUE(n) ((n) << RCC_D3CFGR_D3PPRE_Pos) + +#define RCC_PLLCKSELR_PLLSRC_VALUE(n) ((n) << RCC_PLLCKSELR_PLLSRC_Pos) + +#define RCC_PLLCKSELR_DIVM1_VALUE(n) ((n) << RCC_PLLCKSELR_DIVM1_Pos) +#define RCC_PLLCKSELR_DIVM2_VALUE(n) ((n) << RCC_PLLCKSELR_DIVM2_Pos) +#define RCC_PLLCKSELR_DIVM3_VALUE(n) ((n) << RCC_PLLCKSELR_DIVM3_Pos) + +#define RCC_PLL1DIVR_DIVN1_VALUE(n) ((n) << RCC_PLL1DIVR_N1) +#define RCC_PLL1DIVR_DIVP1_VALUE(n) ((n) << RCC_PLL1DIVR_P1) +#define RCC_PLL1DIVR_DIVQ1_VALUE(n) ((n) << RCC_PLL1DIVR_Q1) +#define RCC_PLL1DIVR_DIVR1_VALUE(n) ((n) << RCC_PLL1DIVR_R1) + +#define RCC_PLL1FRACR_FRACN1_VALUE(n) ((n) << RCC_PLL1FRACR_FRACN1_Pos) + +#define RCC_PLL2DIVR_DIVN2_VALUE(n) ((n) << RCC_PLL2DIVR_N2) +#define RCC_PLL2DIVR_DIVP2_VALUE(n) ((n) << RCC_PLL2DIVR_P2) +#define RCC_PLL2DIVR_DIVQ2_VALUE(n) ((n) << RCC_PLL2DIVR_Q2) +#define RCC_PLL2DIVR_DIVR2_VALUE(n) ((n) << RCC_PLL2DIVR_R2) + +#define RCC_PLL2FRACR_FRACN2_VALUE(n) ((n) << RCC_PLL2FRACR_FRACN2_Pos) + +#define RCC_PLL3DIVR_DIVN3_VALUE(n) ((n) << RCC_PLL3DIVR_N3) +#define RCC_PLL3DIVR_DIVP3_VALUE(n) ((n) << RCC_PLL3DIVR_P3) +#define RCC_PLL3DIVR_DIVQ3_VALUE(n) ((n) << RCC_PLL3DIVR_Q3) +#define RCC_PLL3DIVR_DIVR3_VALUE(n) ((n) << RCC_PLL3DIVR_R3) + +#define RCC_PLL3FRACR_FRACN3_VALUE(n) ((n) << RCC_PLL3FRACR_FRACN3_Pos) + +#define RCC_D1CCIPR_CKPERSEL_VALUE(n) ((n) << RCC_D1CCIPR_CKPERSEL_Pos) +#define RCC_D1CCIPR_SDMMCSEL_VALUE(n) ((n) << RCC_D1CCIPR_SDMMCSEL_Pos) +#define RCC_D1CCIPR_QSPISEL_VALUE(n) ((n) << RCC_D1CCIPR_QSPISEL_Pos) +#define RCC_D1CCIPR_FMCSEL_VALUE(n) ((n) << RCC_D1CCIPR_FMCSEL_Pos) + +#define RCC_D2CCIP1R_SWPSEL_VALUE(n) ((n) << RCC_D2CCIP1R_SWPSEL_Pos) +#define RCC_D2CCIP1R_FDCANSEL_VALUE(n) ((n) << RCC_D2CCIP1R_FDCANSEL_Pos) +#define RCC_D2CCIP1R_DFSDM1SEL_VALUE(n) ((n) << RCC_D2CCIP1R_DFSDM1SEL_Pos) +#define RCC_D2CCIP1R_SPDIFSEL_VALUE(n) ((n) << RCC_D2CCIP1R_SPDIFSEL_Pos) +#define RCC_D2CCIP1R_SPI45SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SPI45SEL_Pos) +#define RCC_D2CCIP1R_SPI123SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SPI123SEL_Pos) +#define RCC_D2CCIP1R_SAI23SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SAI23SEL_Pos) +#define RCC_D2CCIP1R_SAI1SEL_VALUE(n) ((n) << RCC_D2CCIP1R_SAI1SEL_Pos) + +#define RCC_D2CCIP2R_LPTIM1SEL_VALUE(n) ((n) << RCC_D2CCIP2R_LPTIM1SEL_Pos) +#define RCC_D2CCIP2R_CECSEL_VALUE(n) ((n) << RCC_D2CCIP2R_CECSEL_Pos) +#define RCC_D2CCIP2R_USBSEL_VALUE(n) ((n) << RCC_D2CCIP2R_USBSEL_Pos) +#define RCC_D2CCIP2R_I2C123SEL_VALUE(n) ((n) << RCC_D2CCIP2R_I2C123SEL_Pos) +#define RCC_D2CCIP2R_RNGSEL_VALUE(n) ((n) << RCC_D2CCIP2R_RNGSEL_Pos) +#define RCC_D2CCIP2R_USART16SEL_VALUE(n) ((n) << RCC_D2CCIP2R_USART16SEL_Pos) +#define RCC_D2CCIP2R_USART234578SEL_VALUE(n) ((n) << RCC_D2CCIP2R_USART28SEL_Pos) + +#define RCC_D3CCIPR_SPI6SEL_VALUE(n) ((n) << RCC_D3CCIPR_SPI6SEL_Pos) +#define RCC_D3CCIPR_SAI4BSEL_VALUE(n) ((n) << RCC_D3CCIPR_SAI4BSEL_Pos) +#define RCC_D3CCIPR_SAI4ASEL_VALUE(n) ((n) << RCC_D3CCIPR_SAI4ASEL_Pos) +#define RCC_D3CCIPR_ADCSEL_VALUE(n) ((n) << RCC_D3CCIPR_ADCSEL_Pos) +#define RCC_D3CCIPR_LPTIM345SEL_VALUE(n) ((n) << RCC_D3CCIPR_LPTIM345SEL_Pos) +#define RCC_D3CCIPR_LPTIM2SEL_VALUE(n) ((n) << RCC_D3CCIPR_LPTIM2SEL_Pos) +#define RCC_D3CCIPR_I2C4SEL_VALUE(n) ((n) << RCC_D3CCIPR_I2C4SEL_Pos) +#define RCC_D3CCIPR_LPUART1SEL_VALUE(n) ((n) << RCC_D3CCIPR_LPUART1SEL_Pos) + +#define RCC_BDCR_RTCSEL_VALUE(n) ((n) << RCC_BDCR_RTCSEL_Pos) +/** @} */ + +/** + * @name Configuration switches to be used in @p mcuconf.h + * @{ + */ +#define STM32_ODEN_DISABLED 0U +#define STM32_ODEN_ENABLED (SYSCFG_PWRCR_ODEN) + +#define STM32_VOS_SCALE3 (PWR_D3CR_VOS_0) +#define STM32_VOS_SCALE2 (PWR_D3CR_VOS_1) +#define STM32_VOS_SCALE1 (PWR_D3CR_VOS_1 | PWR_D3CR_VOS_0) + +#define STM32_SW_HSI_CK RCC_CFGR_SW_VALUE(0U) +#define STM32_SW_CSI_CK RCC_CFGR_SW_VALUE(1U) +#define STM32_SW_HSE_CK RCC_CFGR_SW_VALUE(2U) +#define STM32_SW_PLL1_P_CK RCC_CFGR_SW_VALUE(3U) + +#define STM32_D1CPRE_DIV1 RCC_D1CFGR_D1CPRE_VALUE(0U) +#define STM32_D1CPRE_DIV2 RCC_D1CFGR_D1CPRE_VALUE(8U) +#define STM32_D1CPRE_DIV4 RCC_D1CFGR_D1CPRE_VALUE(9U) +#define STM32_D1CPRE_DIV8 RCC_D1CFGR_D1CPRE_VALUE(10U) +#define STM32_D1CPRE_DIV16 RCC_D1CFGR_D1CPRE_VALUE(11U) +#define STM32_D1CPRE_DIV64 RCC_D1CFGR_D1CPRE_VALUE(12U) +#define STM32_D1CPRE_DIV128 RCC_D1CFGR_D1CPRE_VALUE(13U) +#define STM32_D1CPRE_DIV256 RCC_D1CFGR_D1CPRE_VALUE(14U) +#define STM32_D1CPRE_DIV512 RCC_D1CFGR_D1CPRE_VALUE(15U) + +#define STM32_D1HPRE_DIV1 RCC_D1CFGR_D1HPRE_VALUE(0U) +#define STM32_D1HPRE_DIV2 RCC_D1CFGR_D1HPRE_VALUE(8U) +#define STM32_D1HPRE_DIV4 RCC_D1CFGR_D1HPRE_VALUE(9U) +#define STM32_D1HPRE_DIV8 RCC_D1CFGR_D1HPRE_VALUE(10U) +#define STM32_D1HPRE_DIV16 RCC_D1CFGR_D1HPRE_VALUE(11U) +#define STM32_D1HPRE_DIV64 RCC_D1CFGR_D1HPRE_VALUE(12U) +#define STM32_D1HPRE_DIV128 RCC_D1CFGR_D1HPRE_VALUE(13U) +#define STM32_D1HPRE_DIV256 RCC_D1CFGR_D1HPRE_VALUE(14U) +#define STM32_D1HPRE_DIV512 RCC_D1CFGR_D1HPRE_VALUE(15U) + +#define STM32_D1PPRE3_DIV1 RCC_D1CFGR_D1PPRE3_VALUE(0U) +#define STM32_D1PPRE3_DIV2 RCC_D1CFGR_D1PPRE3_VALUE(4U) +#define STM32_D1PPRE3_DIV4 RCC_D1CFGR_D1PPRE3_VALUE(5U) +#define STM32_D1PPRE3_DIV8 RCC_D1CFGR_D1PPRE3_VALUE(6U) +#define STM32_D1PPRE3_DIV16 RCC_D1CFGR_D1PPRE3_VALUE(7U) + +#define STM32_D2PPRE1_DIV1 RCC_D2CFGR_D2PPRE1_VALUE(0U) +#define STM32_D2PPRE1_DIV2 RCC_D2CFGR_D2PPRE1_VALUE(4U) +#define STM32_D2PPRE1_DIV4 RCC_D2CFGR_D2PPRE1_VALUE(5U) +#define STM32_D2PPRE1_DIV8 RCC_D2CFGR_D2PPRE1_VALUE(6U) +#define STM32_D2PPRE1_DIV16 RCC_D2CFGR_D2PPRE1_VALUE(7U) + +#define STM32_D2PPRE2_DIV1 RCC_D2CFGR_D2PPRE2_VALUE(0U) +#define STM32_D2PPRE2_DIV2 RCC_D2CFGR_D2PPRE2_VALUE(4U) +#define STM32_D2PPRE2_DIV4 RCC_D2CFGR_D2PPRE2_VALUE(5U) +#define STM32_D2PPRE2_DIV8 RCC_D2CFGR_D2PPRE2_VALUE(6U) +#define STM32_D2PPRE2_DIV16 RCC_D2CFGR_D2PPRE2_VALUE(7U) + +#define STM32_D3PPRE4_DIV1 RCC_D3CFGR_D3PPRE4_VALUE(0U) +#define STM32_D3PPRE4_DIV2 RCC_D3CFGR_D3PPRE4_VALUE(4U) +#define STM32_D3PPRE4_DIV4 RCC_D3CFGR_D3PPRE4_VALUE(5U) +#define STM32_D3PPRE4_DIV8 RCC_D3CFGR_D3PPRE4_VALUE(6U) +#define STM32_D3PPRE4_DIV16 RCC_D3CFGR_D3PPRE4_VALUE(7U) + +#define STM32_HSIDIV_DIV1 RCC_CR_HSIDIV_VALUE(0U) +#define STM32_HSIDIV_DIV2 RCC_CR_HSIDIV_VALUE(1U) +#define STM32_HSIDIV_DIV4 RCC_CR_HSIDIV_VALUE(2U) +#define STM32_HSIDIV_DIV8 RCC_CR_HSIDIV_VALUE(3U) + +#define STM32_MCO1SEL_HSI_CK RCC_CFGR_MCO1_VALUE(0U) +#define STM32_MCO1SEL_LSE_CK RCC_CFGR_MCO1_VALUE(1U) +#define STM32_MCO1SEL_HSE_CK RCC_CFGR_MCO1_VALUE(2U) +#define STM32_MCO1SEL_PLL1_Q_CK RCC_CFGR_MCO1_VALUE(3U) +#define STM32_MCO1SEL_HSI48_CK RCC_CFGR_MCO1_VALUE(4U) + +#define STM32_MCO2SEL_SYS_CK RCC_CFGR_MCO2_VALUE(0U) +#define STM32_MCO2SEL_PLL2_P_CK RCC_CFGR_MCO2_VALUE(1U) +#define STM32_MCO2SEL_HSE_CK RCC_CFGR_MCO2_VALUE(2U) +#define STM32_MCO2SEL_PLL1_P_CK RCC_CFGR_MCO2_VALUE(3U) +#define STM32_MCO2SEL_CSI_CK RCC_CFGR_MCO2_VALUE(4U) +#define STM32_MCO2SEL_LSI_CK RCC_CFGR_MCO2_VALUE(5U) + +#define STM32_RTCSEL_MASK RCC_BDCR_RTCSEL_Msk +#define STM32_RTCSEL_NOCLK RCC_BDCR_RTCSEL_VALUE(0U) +#define STM32_RTCSEL_LSE_CK RCC_BDCR_RTCSEL_VALUE(1U) +#define STM32_RTCSEL_LSI_CK RCC_BDCR_RTCSEL_VALUE(2U) +#define STM32_RTCSEL_HSE_1M_CK RCC_BDCR_RTCSEL_VALUE(3U) + +#define STM32_HRTIMSEL_C_CLK RCC_CFGR_HRTIMSEL + +#define STM32_STOPKERWUCK_ENABLED RCC_CFGR_STOPKERWUCK + +#define STM32_STOPWUCK_ENABLED RCC_CFGR_STOPKERWUCK + +#define STM32_PLLSRC_HSI_CK RCC_PLLCKSELR_PLLSRC_VALUE(0U) +#define STM32_PLLSRC_CSI_CK RCC_PLLCKSELR_PLLSRC_VALUE(1U) +#define STM32_PLLSRC_HSE_CK RCC_PLLCKSELR_PLLSRC_VALUE(2U) +#define STM32_PLLSRC_DISABLE RCC_PLLCKSELR_PLLSRC_VALUE(23U) + +#define STM32_CKPERSEL_HSI_CK RCC_D1CCIPR_CKPERSEL_VALUE(0U) +#define STM32_CKPERSEL_CSI_CK RCC_D1CCIPR_CKPERSEL_VALUE(1U) +#define STM32_CKPERSEL_HSE_CK RCC_D1CCIPR_CKPERSEL_VALUE(2U) + +#define STM32_SDMMCSEL_PLL1_Q_CK RCC_D1CCIPR_SDMMCSEL_VALUE(0U) +#define STM32_SDMMCSEL_PLL2_R_CK RCC_D1CCIPR_SDMMCSEL_VALUE(1U) + +#define STM32_QSPISEL_HCLK RCC_D1CCIPR_QSPISEL_VALUE(0U) +#define STM32_QSPISEL_PLL1_Q_CK RCC_D1CCIPR_QSPISEL_VALUE(1U) +#define STM32_QSPISEL_PLL2_R_CK RCC_D1CCIPR_QSPISEL_VALUE(2U) +#define STM32_QSPISEL_PER_CK RCC_D1CCIPR_QSPISEL_VALUE(3U) + +#define STM32_FMCSEL_HCLK RCC_D1CCIPR_FMCSEL_VALUE(0U) +#define STM32_FMCSEL_PLL1_Q_CK RCC_D1CCIPR_FMCSEL_VALUE(1U) +#define STM32_FMCSEL_PLL2_R_CK RCC_D1CCIPR_FMCSEL_VALUE(2U) +#define STM32_FMCSEL_PER_CK RCC_D1CCIPR_FMCSEL_VALUE(3U) + +#define STM32_SWPSEL_PCLK1 RCC_D2CCIP1R_SWPSEL_VALUE(0U) +#define STM32_SWPSEL_HSI_KER_CK RCC_D2CCIP1R_SWPSEL_VALUE(1U) + +#define STM32_FDCANSEL_HSE_CK RCC_D2CCIP1R_FDCANSEL_VALUE(0U) +#define STM32_FDCANSEL_PLL1_Q_CK RCC_D2CCIP1R_FDCANSEL_VALUE(1U) +#define STM32_FDCANSEL_PLL2_Q_CK RCC_D2CCIP1R_FDCANSEL_VALUE(2U) + +#define STM32_DFSDM1SEL_PCLK2 RCC_D2CCIP1R_DFSDM1SEL_VALUE(0U) +#define STM32_DFSDM1SEL_SYS_CK RCC_D2CCIP1R_DFSDM1SEL_VALUE(1U) + +#define STM32_SPDIFSEL_PLL1_Q_CK RCC_D2CCIP1R_SPDIFSEL_VALUE(0U) +#define STM32_SPDIFSEL_PLL2_R_CK RCC_D2CCIP1R_SPDIFSEL_VALUE(1U) +#define STM32_SPDIFSEL_PLL3_R_CK RCC_D2CCIP1R_SPDIFSEL_VALUE(2U) +#define STM32_SPDIFSEL_HSI_KET_CLK RCC_D2CCIP1R_SPDIFSEL_VALUE(3U) + +#define STM32_SPI45SEL_PCLK2 RCC_D2CCIP1R_SPI45SEL_VALUE(0U) +#define STM32_SPI45SEL_PLL2_Q_CK RCC_D2CCIP1R_SPI45SEL_VALUE(1U) +#define STM32_SPI45SEL_PLL3_Q_CK RCC_D2CCIP1R_SPI45SEL_VALUE(2U) +#define STM32_SPI45SEL_HSI_KER_CK RCC_D2CCIP1R_SPI45SEL_VALUE(3U) +#define STM32_SPI45SEL_CSI_KER_CK RCC_D2CCIP1R_SPI45SEL_VALUE(4U) +#define STM32_SPI45SEL_HSE_CK RCC_D2CCIP1R_SPI45SEL_VALUE(5U) + +#define STM32_SPI123SEL_PLL1_Q_CK RCC_D2CCIP1R_SPI123SEL_VALUE(0U) +#define STM32_SPI123SEL_PLL2_P_CK RCC_D2CCIP1R_SPI123SEL_VALUE(1U) +#define STM32_SPI123SEL_PLL3_P_CK RCC_D2CCIP1R_SPI123SEL_VALUE(2U) +#define STM32_SPI123SEL_I2S_CKIN RCC_D2CCIP1R_SPI123SEL_VALUE(3U) +#define STM32_SPI123SEL_PER_CK RCC_D2CCIP1R_SPI123SEL_VALUE(4U) + +#define STM32_SAI23SEL_PLL1_Q_CK RCC_D2CCIP1R_SAI23SEL_VALUE(0U) +#define STM32_SAI23SEL_PLL2_P_CK RCC_D2CCIP1R_SAI23SEL_VALUE(1U) +#define STM32_SAI23SEL_PLL3_P_CK RCC_D2CCIP1R_SAI23SEL_VALUE(2U) +#define STM32_SAI23SEL_I2S_CKIN RCC_D2CCIP1R_SAI23SEL_VALUE(3U) +#define STM32_SAI23SEL_PER_CK RCC_D2CCIP1R_SAI23SEL_VALUE(4U) + +#define STM32_SAI1SEL_PLL1_Q_CK RCC_D2CCIP1R_SAI1SEL_VALUE(0U) +#define STM32_SAI1SEL_PLL2_P_CK RCC_D2CCIP1R_SAI1SEL_VALUE(1U) +#define STM32_SAI1SEL_PLL3_P_CK RCC_D2CCIP1R_SAI1SEL_VALUE(2U) +#define STM32_SAI1SEL_I2S_CKIN RCC_D2CCIP1R_SAI1SEL_VALUE(3U) +#define STM32_SAI1SEL_PER_CK RCC_D2CCIP1R_SAI1SEL_VALUE(4U) + +#define STM32_LPTIM1SEL_PCLK1 RCC_D2CCIP2R_LPTIM1SEL_VALUE(0U) +#define STM32_LPTIM1SEL_PLL2_P_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(1U) +#define STM32_LPTIM1SEL_PLL3_R_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(2U) +#define STM32_LPTIM1SEL_LSE_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(3U) +#define STM32_LPTIM1SEL_LSI_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(4U) +#define STM32_LPTIM1SEL_PER_CK RCC_D2CCIP2R_LPTIM1SEL_VALUE(5U) + +#define STM32_CECSEL_LSE_CK RCC_D2CCIP2R_CECSEL_VALUE(0U) +#define STM32_CECSEL_LSI_CK RCC_D2CCIP2R_CECSEL_VALUE(1U) +#define STM32_CECSEL_CSI_KER_CK RCC_D2CCIP2R_CECSEL_VALUE(2U) +#define STM32_CECSEL_DISABLE RCC_D2CCIP2R_CECSEL_VALUE(3U) + +#define STM32_USBSEL_DISABLE RCC_D2CCIP2R_USBSEL_VALUE(0U) +#define STM32_USBSEL_PLL1_Q_CK RCC_D2CCIP2R_USBSEL_VALUE(1U) +#define STM32_USBSEL_PLL3_Q_CK RCC_D2CCIP2R_USBSEL_VALUE(2U) +#define STM32_USBSEL_HSI48_CK RCC_D2CCIP2R_USBSEL_VALUE(3U) + +#define STM32_I2C123SEL_PCLK1 RCC_D2CCIP2R_I2C123SEL_VALUE(0U) +#define STM32_I2C123SEL_PLL3_R_CK RCC_D2CCIP2R_I2C123SEL_VALUE(1U) +#define STM32_I2C123SEL_HSI_KER_CK RCC_D2CCIP2R_I2C123SEL_VALUE(2U) +#define STM32_I2C123SEL_CSI_KER_CK RCC_D2CCIP2R_I2C123SEL_VALUE(3U) + +#define STM32_RNGSEL_HSI48_CK RCC_D2CCIP2R_RNGSEL_VALUE(0U) +#define STM32_RNGSEL_PLL1_Q_CK RCC_D2CCIP2R_RNGSEL_VALUE(1U) +#define STM32_RNGSEL_LSE_CK RCC_D2CCIP2R_RNGSEL_VALUE(2U) +#define STM32_RNGSEL_LSI_CK RCC_D2CCIP2R_RNGSEL_VALUE(3U) + +#define STM32_USART16SEL_PCLK2 RCC_D2CCIP2R_USART16SEL_VALUE(0U) +#define STM32_USART16SEL_PLL2_Q_CK RCC_D2CCIP2R_USART16SEL_VALUE(1U) +#define STM32_USART16SEL_PLL3_Q_CK RCC_D2CCIP2R_USART16SEL_VALUE(2U) +#define STM32_USART16SEL_HSI_KER_CK RCC_D2CCIP2R_USART16SEL_VALUE(3U) +#define STM32_USART16SEL_CSI_KER_CK RCC_D2CCIP2R_USART16SEL_VALUE(4U) +#define STM32_USART16SEL_LSE_CK RCC_D2CCIP2R_USART16SEL_VALUE(5U) + +#define STM32_USART234578SEL_PCLK1 RCC_D2CCIP2R_USART234578SEL_VALUE(0U) +#define STM32_USART234578SEL_PLL2_Q_CK RCC_D2CCIP2R_USART234578SEL_VALUE(1U) +#define STM32_USART234578SEL_PLL3_Q_CK RCC_D2CCIP2R_USART234578SEL_VALUE(2U) +#define STM32_USART234578SEL_HSI_KER_CK RCC_D2CCIP2R_USART234578SEL_VALUE(3U) +#define STM32_USART234578SEL_CSI_KER_CK RCC_D2CCIP2R_USART234578SEL_VALUE(4U) +#define STM32_USART234578SEL_LSE_CK RCC_D2CCIP2R_USART234578SEL_VALUE(5U) + +#define STM32_SPI6SEL_PCLK4 RCC_D3CCIPR_SPI6SEL_VALUE(0U) +#define STM32_SPI6SEL_PLL2_Q_CK RCC_D3CCIPR_SPI6SEL_VALUE(1U) +#define STM32_SPI6SEL_PLL3_Q_CK RCC_D3CCIPR_SPI6SEL_VALUE(2U) +#define STM32_SPI6SEL_HSI_KER_CK RCC_D3CCIPR_SPI6SEL_VALUE(3U) +#define STM32_SPI6SEL_CSI_KER_CK RCC_D3CCIPR_SPI6SEL_VALUE(4U) +#define STM32_SPI6SEL_HSE_CK RCC_D3CCIPR_SPI6SEL_VALUE(5U) + +#define STM32_SAI4BSEL_PLL1_Q_CK RCC_D3CCIPR_SAI4BSEL_VALUE(0U) +#define STM32_SAI4BSEL_PLL2_P_CK RCC_D3CCIPR_SAI4BSEL_VALUE(1U) +#define STM32_SAI4BSEL_PLL3_P_CK RCC_D3CCIPR_SAI4BSEL_VALUE(2U) +#define STM32_SAI4BSEL_I2S_CKIN RCC_D3CCIPR_SAI4BSEL_VALUE(3U) +#define STM32_SAI4BSEL_PER_CK RCC_D3CCIPR_SAI4BSEL_VALUE(4U) + +#define STM32_SAI4ASEL_PLL1_Q_CK RCC_D3CCIPR_SAI4ASEL_VALUE(0U) +#define STM32_SAI4ASEL_PLL2_P_CK RCC_D3CCIPR_SAI4ASEL_VALUE(1U) +#define STM32_SAI4ASEL_PLL3_P_CK RCC_D3CCIPR_SAI4ASEL_VALUE(2U) +#define STM32_SAI4ASEL_I2S_CKIN RCC_D3CCIPR_SAI4ASEL_VALUE(3U) +#define STM32_SAI4ASEL_PER_CK RCC_D3CCIPR_SAI4ASEL_VALUE(4U) + +#define STM32_ADCSEL_PLL2_P_CK RCC_D3CCIPR_ADCSEL_VALUE(0U) +#define STM32_ADCSEL_PLL3_R_CK RCC_D3CCIPR_ADCSEL_VALUE(1U) +#define STM32_ADCSEL_PER_CK RCC_D3CCIPR_ADCSEL_VALUE(2U) +#define STM32_ADCSEL_DISABLE RCC_D3CCIPR_ADCSEL_VALUE(3U) + +#define STM32_LPTIM345SEL_PCLK4 RCC_D3CCIPR_LPTIM345SEL_VALUE(0U) +#define STM32_LPTIM345SEL_PLL2_P_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(1U) +#define STM32_LPTIM345SEL_PLL3_P_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(2U) +#define STM32_LPTIM345SEL_LSE_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(3U) +#define STM32_LPTIM345SEL_LSI_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(4U) +#define STM32_LPTIM345SEL_PER_CK RCC_D3CCIPR_LPTIM345SEL_VALUE(5U) + +#define STM32_LPTIM2SEL_PCLK4 RCC_D3CCIPR_LPTIM2SEL_VALUE(0U) +#define STM32_LPTIM2SEL_PLL2_P_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(1U) +#define STM32_LPTIM2SEL_PLL3_P_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(2U) +#define STM32_LPTIM2SEL_LSE_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(3U) +#define STM32_LPTIM2SEL_LSI_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(4U) +#define STM32_LPTIM2SEL_PER_CK RCC_D3CCIPR_LPTIM2SEL_VALUE(5U) + +#define STM32_I2C4SEL_PCLK4 RCC_D3CCIPR_I2C4SEL_VALUE(0U) +#define STM32_I2C4SEL_PLL3_R_CK RCC_D3CCIPR_I2C4SEL_VALUE(1U) +#define STM32_I2C4SEL_HSI_KER_CK RCC_D3CCIPR_I2C4SEL_VALUE(2U) +#define STM32_I2C4SEL_CSI_KER_CK RCC_D3CCIPR_I2C4SEL_VALUE(3U) + +#define STM32_LPUART1SEL_PCLK4 RCC_D3CCIPR_LPUART1SEL_VALUE(0U) +#define STM32_LPUART1SEL_PLL2_Q_CK RCC_D3CCIPR_LPUART1SEL_VALUE(1U) +#define STM32_LPUART1SEL_PLL3_Q_CK RCC_D3CCIPR_LPUART1SEL_VALUE(2U) +#define STM32_LPUART1SEL_HSI_KER_CK RCC_D3CCIPR_LPUART1SEL_VALUE(3U) +#define STM32_LPUART1SEL_CSI_KER_CK RCC_D3CCIPR_LPUART1SEL_VALUE(4U) +#define STM32_LPUART1SEL_LSE_CK RCC_D3CCIPR_LPUART1SEL_VALUE(5U) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + * @note All the clock tree constants are calculated but the initialization + * is not performed. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Target code for this HAL configuration. + * @note Core 1 is the Cortex-M7, core 2 is the Cortex-M4. + */ +#if !defined(STM32_TARGET_CORE) || defined(__DOXYGEN__) +#define STM32_TARGET_CORE 1 +#endif + +/** + * @brief MPU region to be used for no-cache RAM area. + */ +#if !defined(STM32_NOCACHE_MPU_REGION) || defined(__DOXYGEN__) +#define STM32_NOCACHE_MPU_REGION MPU_REGION_6 +#endif + +/** + * @brief Add no-cache attribute to SRAM1 and SRAM2. + * @note MPU region 7 is used if enabled. + */ +#if !defined(STM32_NOCACHE_SRAM1_SRAM2) || defined(__DOXYGEN__) +#define STM32_NOCACHE_SRAM1_SRAM2 FALSE +#endif + +/** + * @brief Add no-cache attribute to SRAM3. + * @note MPU region 7 is used if enabled. + */ +#if !defined(STM32_NOCACHE_SRAM3) || defined(__DOXYGEN__) +#define STM32_NOCACHE_SRAM3 TRUE +#endif + +/** + * @brief PWR CR1 initializer. + */ +#if !defined(STM32_PWR_CR1) || defined(__DOXYGEN__) +#define STM32_PWR_CR1 (PWR_CR1_SVOS_1 | \ + PWR_CR1_SVOS_0) +#endif + +/** + * @brief PWR CR2 initializer. + */ +#if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__) +#define STM32_PWR_CR2 (PWR_CR2_BREN) +#endif + +/** + * @brief PWR CR3 initializer. + */ +#if !defined(STM32_PWR_CR3) || defined(__DOXYGEN__) +#define STM32_PWR_CR3 (PWR_CR3_LDOEN | \ + PWR_CR3_USBREGEN | \ + PWR_CR3_USB33DEN) +#endif + +/** + * @brief PWR CPUCR initializer. + */ +#if !defined(STM32_PWR_CPUCR) || defined(__DOXYGEN__) +#define STM32_PWR_CPUCR 0 +#endif + +/** + * @brief VOS setting. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_SCALE1 +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_CSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_CSI_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSI48 clock source. + */ +#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI48_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED TRUE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief HSI divider. + */ +#if !defined(STM32_HSIDIV) || defined(__DOXYGEN__) +#define STM32_HSIDIV STM32_HSIDIV_DIV1 +#endif + +/** + * @brief Clock source for all PLLs. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSE_CK +#endif + +/** + * @brief Masking of PLLCFGR register. + * @note By default all options in PLLCFGR are enabled, this option + * allows to mask specific bits for power saving reasons. + * Use with caution. + */ +#if !defined(STM32_PLLCFGR_MASK) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_MASK ~0 +#endif + +/** + * @brief Enables or disables the PLL1. + */ +#if !defined(STM32_PLL1_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL1_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL1 P output. + */ +#if !defined(STM32_PLL1_P_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL1_P_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL1 Q output. + */ +#if !defined(STM32_PLL1_Q_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL1_Q_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL1 R output. + */ +#if !defined(STM32_PLL1_R_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL1_R_ENABLED TRUE +#endif + +/** + * @brief PLL1 DIVM divider. + * @note The allowed values are 1..63. + */ +#if !defined(STM32_PLL1_DIVM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL1_DIVM_VALUE 4 +#endif + +/** + * @brief PLL1 DIVN multiplier. + * @note The allowed values are 4..512. + */ +#if !defined(STM32_PLL1_DIVN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL1_DIVN_VALUE 400 +#endif + +/** + * @brief PLL1 FRACN multiplier, zero if no fractional part. + * @note The allowed values are 0..8191. + */ +#if !defined(STM32_PLL1_FRACN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL1_FRACN_VALUE 0 +#endif + +/** + * @brief PLL1 DIVP divider. + * @note The allowed values are 2..128, odd values not allowed. + */ +#if !defined(STM32_PLL1_DIVP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL1_DIVP_VALUE 2 +#endif + +/** + * @brief PLL1 DIVQ divider. + * @note The allowed values are 1..128. + */ +#if !defined(STM32_PLL1_DIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL1_DIVQ_VALUE 8 +#endif + +/** + * @brief PLL1 DIVR divider. + * @note The allowed values are 1..128. + */ +#if !defined(STM32_PLL1_DIVR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL1_DIVR_VALUE 8 +#endif + +/** + * @brief Enables or disables the PLL2. + */ +#if !defined(STM32_PLL2_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL2_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL2 P output. + */ +#if !defined(STM32_PLL2_P_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL1_2_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL2 Q output. + */ +#if !defined(STM32_PLL2_Q_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL2_Q_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL2 R output. + */ +#if !defined(STM32_PLL2_R_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL2_R_ENABLED TRUE +#endif + +/** + * @brief PLL2 DIVM divider. + * @note The allowed values are 1..63. + */ +#if !defined(STM32_PLL2_DIVM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2_DIVM_VALUE 4 +#endif + +/** + * @brief PLL2 DIVN multiplier. + * @note The allowed values are 4..512. + */ +#if !defined(STM32_PLL2_DIVN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2_DIVN_VALUE 400 +#endif + +/** + * @brief PLL2 FRACN multiplier, zero if no fractional part. + * @note The allowed values are 0..8191. + */ +#if !defined(STM32_PLL2_FRACN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2_FRACN_VALUE 0 +#endif + +/** + * @brief PLL2 DIVP divider. + * @note The allowed values are 2..128, odd values not allowed. + */ +#if !defined(STM32_PLL2_DIVP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2_DIVP_VALUE 40 +#endif + +/** + * @brief PLL2 DIVQ divider. + * @note The allowed values are 1..128. + */ +#if !defined(STM32_PLL2_DIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2_DIVQ_VALUE 8 +#endif + +/** + * @brief PLL2 DIVR divider. + * @note The allowed values are 1..128. + */ +#if !defined(STM32_PLL2_DIVR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL2_DIVR_VALUE 8 +#endif + +/** + * @brief Enables or disables the PLL3. + */ +#if !defined(STM32_PLL3_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL3_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL3 P output. + */ +#if !defined(STM32_PLL3_P_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL3_P_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL3 Q output. + */ +#if !defined(STM32_PLL3_Q_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL3_Q_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the PLL3 R output. + */ +#if !defined(STM32_PLL3_R_ENABLED) || defined(__DOXYGEN__) +#define STM32_PLL3_R_ENABLED TRUE +#endif + +/** + * @brief PLL3 DIVM divider. + * @note The allowed values are 1..63. + */ +#if !defined(STM32_PLL3_DIVM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3_DIVM_VALUE 4 +#endif + +/** + * @brief PLL3 DIVN multiplier. + * @note The allowed values are 4..512. + */ +#if !defined(STM32_PLL3_DIVN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3_DIVN_VALUE 400 +#endif + +/** + * @brief PLL3 FRACN multiplier, zero if no fractional part. + * @note The allowed values are 0..8191. + */ +#if !defined(STM32_PLL3_FRACN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3_FRACN_VALUE 0 +#endif + +/** + * @brief PLL3 DIVP divider. + * @note The allowed values are 2..128, odd values not allowed. + */ +#if !defined(STM32_PLL3_DIVP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3_DIVP_VALUE 8 +#endif + +/** + * @brief PLL3 DIVQ divider. + * @note The allowed values are 1..128. + */ +#if !defined(STM32_PLL3_DIVQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3_DIVQ_VALUE 8 +#endif + +/** + * @brief PLL3 DIVR divider. + * @note The allowed values are 1..128. + */ +#if !defined(STM32_PLL3_DIVR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3_DIVR_VALUE 8 +#endif + +/** + * @brief Peripherals clock selector. + */ +#if !defined(STM32_CKPERSEL) || defined(__DOXYGEN__) +#define STM32_CKPERSEL STM32_CKPERSEL_HSE_CK +#endif + +/** + * @brief MCO1 clock selector. + */ +#if !defined(STM32_MCO1SEL) || defined(__DOXYGEN__) +#define STM32_MCO1SEL STM32_MCO1SEL_HSI_CK +#endif + +/** + * @brief MCO1 clock prescaler. + */ +#if !defined(STM32_MCO1PRE_VALUE) || defined(__DOXYGEN__) +#define STM32_MCO1PRE_VALUE 4 +#endif + +/** + * @brief MCO2 clock selector. + */ +#if !defined(STM32_MCO2SEL) || defined(__DOXYGEN__) +#define STM32_MCO2SEL STM32_MCO2SEL_SYS_CK +#endif + +/** + * @brief MCO2 clock prescaler. + */ +#if !defined(STM32_MCO2PRE_VALUE) || defined(__DOXYGEN__) +#define STM32_MCO2PRE_VALUE 4 +#endif + +/** + * @brief TIM clock prescaler selection. + */ +#if !defined(STM32_TIMPRE_ENABLE) || defined(__DOXYGEN__) +#define STM32_TIMPRE_ENABLE FALSE +#endif + +/** + * @brief HRTIM clock prescaler selection. + */ +#if !defined(STM32_HRTIMSEL) || defined(__DOXYGEN__) +#define STM32_HRTIMSEL 0 +#endif + +/** + * @brief Kernel clock selection after a wake up from system Stop. + */ +#if !defined(STM32_STOPKERWUCK) || defined(__DOXYGEN__) +#define STM32_STOPKERWUCK 0 +#endif + +/** + * @brief System clock selection after a wake up from system Stop. + */ +#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) +#define STM32_STOPWUCK 0 +#endif + +/** + * @brief RTC HSE prescaler value. + * @note The allowed values are 2..63. + */ +#if !defined(STM32_RTCPRE_VALUE) || defined(__DOXYGEN__) +#define STM32_RTCPRE_VALUE 8 +#endif + +/** + * @brief Main clock source selection. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL1_P_CK1_P_CK +#endif + +/** + * @brief RTC clock selector. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE_CK +#endif + +/** + * @brief Clock domain 1 core bus prescaler. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_D1CPRE) || defined(__DOXYGEN__) +#define STM32_D1CPRE STM32_D1CPRE_DIV1 +#endif + +/** + * @brief Clock domain 1 HPRE prescaler. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_D1HPRE) || defined(__DOXYGEN__) +#define STM32_D1HPRE STM32_D1HPRE_DIV4 +#endif + +/** + * @brief Clock domain 1 peripherals bus prescaler. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_D1PPRE3) || defined(__DOXYGEN__) +#define STM32_D1PPRE3 STM32_D1PPRE3_DIV1 +#endif + +/** + * @brief Clock domain 2 peripherals bus 1 prescaler. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_D2PPRE1) || defined(__DOXYGEN__) +#define STM32_D2PPRE1 STM32_D2PPRE1_DIV1 +#endif + +/** + * @brief Clock domain 2 peripherals bus 2 prescaler. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_D2PPRE2) || defined(__DOXYGEN__) +#define STM32_D2PPRE2 STM32_D2PPRE2_DIV1 +#endif + +/** + * @brief Clock domain 3 peripherals bus prescaler. + * @note This setting can be modified at runtime. + */ +#if !defined(STM32_D3PPRE4) || defined(__DOXYGEN__) +#define STM32_D3PPRE4 STM32_D3PPRE4_DIV1 +#endif + +/** + * @brief SDMMC clock source. + */ +#if !defined(STM32_SDMMCSEL) || defined(__DOXYGEN__) +#define STM32_SDMMCSEL STM32_SDMMCSEL_PLL1_Q_CK +#endif + +/** + * @brief QSPI clock source. + */ +#if !defined(STM32_QSPISEL) || defined(__DOXYGEN__) +#define STM32_QSPISEL STM32_QSPISEL_HCLK +#endif + +/** + * @brief FMC clock source. + */ +#if !defined(STM32_FMCSEL) || defined(__DOXYGEN__) +#define STM32_FMCSEL STM32_QSPISEL_HCLK +#endif + +/** + * @brief SWP clock source. + */ +#if !defined(STM32_SWPSEL) || defined(__DOXYGEN__) +#define STM32_SWPSEL STM32_SWPSEL_PCLK1 +#endif + +/** + * @brief FDCAN clock source. + */ +#if !defined(STM32_FDCANSEL) || defined(__DOXYGEN__) +#define STM32_FDCANSEL STM32_FDCANSEL_HSE_CK +#endif + +/** + * @brief DFSDM1 clock source. + */ +#if !defined(STM32_DFSDM1SEL) || defined(__DOXYGEN__) +#define STM32_DFSDM1SEL STM32_DFSDM1SEL_PCLK2 +#endif + +/** + * @brief SPDIF clock source. + */ +#if !defined(STM32_SPDIFSEL) || defined(__DOXYGEN__) +#define STM32_SPDIFSEL STM32_SPDIFSEL_PLL1_Q_CK +#endif + +/** + * @brief SPI45 clock source. + */ +#if !defined(STM32_SPI45SEL) || defined(__DOXYGEN__) +#define STM32_SPI45SEL STM32_SPI45SEL_PCLK2 +#endif + +/** + * @brief SPI123 clock source. + */ +#if !defined(STM32_SPI123SEL) || defined(__DOXYGEN__) +#define STM32_SPI123SEL STM32_SPI123SEL_PLL1_Q_CK +#endif + +/** + * @brief SAI23 clock source. + */ +#if !defined(STM32_SAI23SEL) || defined(__DOXYGEN__) +#define STM32_SAI23SEL STM32_SAI23SEL_PLL1_Q_CK +#endif + +/** + * @brief SAI1 clock source. + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_PLL1_Q_CK +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1_PCLK1 +#endif + +/** + * @brief CEC clock source. + */ +#if !defined(STM32_CECSEL) || defined(__DOXYGEN__) +#define STM32_CECSEL STM32_CECSEL_LSE_CK +#endif + +/** + * @brief USB clock source. + */ +#if !defined(STM32_USBSEL) || defined(__DOXYGEN__) +#define STM32_USBSEL STM32_USBSEL_PLL3_Q_CK +#endif + +/** + * @brief I2C123 clock source. + */ +#if !defined(STM32_I2C123SEL) || defined(__DOXYGEN__) +#define STM32_I2C123SEL STM32_I2C123SEL_PCLK1 +#endif + +/** + * @brief RNG clock source. + */ +#if !defined(STM32_RNGSEL) || defined(__DOXYGEN__) +#define STM32_RNGSEL STM32_RNGSEL_HSI48_CK +#endif + +/** + * @brief USART16 clock source. + */ +#if !defined(STM32_USART16SEL) || defined(__DOXYGEN__) +#define STM32_USART16SEL STM32_USART16SEL_PCLK2 +#endif + +/** + * @brief USART234578 clock source. + */ +#if !defined(STM32_USART234578SEL) || defined(__DOXYGEN__) +#define STM32_USART234578SEL STM32_USART234578SEL_PCLK1 +#endif + +/** + * @brief SPI6SEL clock source. + */ +#if !defined(STM32_SPI6SEL) || defined(__DOXYGEN__) +#define STM32_SPI6SEL STM32_SPI6SEL_PCLK4 +#endif + +/** + * @brief SAI4BSEL clock source. + */ +#if !defined(STM32_SAI4BSEL) || defined(__DOXYGEN__) +#define STM32_SAI4BSEL STM32_SAI4BSEL_PLL1_Q_CK +#endif + +/** + * @brief SAI4ASEL clock source. + */ +#if !defined(STM32_SAI4ASEL) || defined(__DOXYGEN__) +#define STM32_SAI4ASEL STM32_SAI4ASEL_PLL1_Q_CK +#endif + +/** + * @brief ADCSEL clock source. + */ +#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) +#define STM32_ADCSEL STM32_ADCSEL_PLL2_P_CK +#endif + +/** + * @brief LPTIM345SEL clock source. + */ +#if !defined(STM32_LPTIM345SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM345SEL STM32_LPTIM345SEL_PCLK4 +#endif + +/** + * @brief LPTIM2SEL clock source. + */ +#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK4 +#endif + +/** + * @brief I2C4SEL clock source. + */ +#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) +#define STM32_I2C4SEL STM32_I2C4SEL_PCLK4 +#endif + +/** + * @brief LPUART1SEL clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_PCLK4 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32H7xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H7xx_MCUCONF not defined" +#endif + +#if defined(STM32H750xx)&& !defined(STM32H750_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H750_MCUCONF not defined" +#endif + +#if defined(STM32H742xx)&& !defined(STM32H742_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H742_MCUCONF not defined" +#endif + +#if defined(STM32H743xx)&& !defined(STM32H743_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H743_MCUCONF not defined" +#endif + +#if defined(STM32H753xx)&& !defined(STM32H753_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H753_MCUCONF not defined" +#endif + +#if defined(STM32H745xx)&& !defined(STM32H745_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H745_MCUCONF not defined" +#endif + +#if defined(STM32H755xx)&& !defined(STM32H755_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H755_MCUCONF not defined" +#endif + +#if defined(STM32H747xx)&& !defined(STM32H747_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H747_MCUCONF not defined" +#endif + +#if defined(STM32H757xx)&& !defined(STM32H757_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32H757_MCUCONF not defined" +#endif + +/* + * Board file checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/** + * @name Constants depending on VOS and ODEN setting + * @{ + */ +#if STM32_VOS == STM32_VOS_SCALE1 +#define STM32_0WS_THRESHOLD 70000000U +#define STM32_1WS_THRESHOLD 140000000U +#define STM32_2WS_THRESHOLD 210000000U +#define STM32_3WS_THRESHOLD 225000000U +#define STM32_4WS_THRESHOLD 240000000U +#define STM32_PLLOUT_MAX 480000000U +#define STM32_PLLOUT_MIN 1500000U + +#elif STM32_VOS == STM32_VOS_SCALE2 +#define STM32_0WS_THRESHOLD 55000000U +#define STM32_1WS_THRESHOLD 110000000U +#define STM32_2WS_THRESHOLD 165000000U +#define STM32_3WS_THRESHOLD 225000000U +#define STM32_4WS_THRESHOLD 0U +#define STM32_PLLOUT_MAX 300000000U +#define STM32_PLLOUT_MIN 1500000U + +#elif STM32_VOS == STM32_VOS_SCALE3 +#define STM32_0WS_THRESHOLD 45000000U +#define STM32_1WS_THRESHOLD 90000000U +#define STM32_2WS_THRESHOLD 135000000U +#define STM32_3WS_THRESHOLD 180000000U +#define STM32_4WS_THRESHOLD 225000000U +#define STM32_PLLOUT_MAX 200000000U +#define STM32_PLLOUT_MIN 1500000U + +#else +#error "invalid STM32_VOS setting specified" +#endif +/** @} */ + +/* + * HSI related checks. + */ +#if STM32_HSI_ENABLED +#define STM32_HSICLK STM32_HSI_OSC + +#else /* !STM32_HSI_ENABLED */ +#define STM32_HSICLK 0U + +#if STM32_SW == STM32_SW_HSI_CK +#error "HSI not enabled, required by STM32_SW" +#endif + +#if (STM32_PLLSRC == STM32_PLLSRC_HSI_CK) && \ + (STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED) +#error "HSI not enabled, required by STM32_PLLSRC and STM32_PLLx_ENABLED" +#endif + +#if STM32_CKPERSEL == STM32_CKPERSEL_HSI_CK +#error "HSI not enabled, required by STM32_CKPERSEL" +#endif + +#if STM32_MCO1SEL == STM32_MCO1SEL_HSI_CK +#error "HSI not enabled, required by STM32_MCO1SEL" +#endif + +#endif /* !STM32_HSI_ENABLED */ + +/* + * HSI48 related checks. + */ +#if STM32_HSI48_ENABLED +#define STM32_HSI48_CK STM32_HSI48_OSC + +#else /* !STM32_HSI48_ENABLED */ +#define STM32_HSI48_CK 0U + +#if STM32_MCO1SEL == STM32_MCO1SEL_HSI48_CK +#error "HSI48 not enabled, required by STM32_MCO1SEL" +#endif + +#endif /* !STM32_HSI48_ENABLED */ + +/* + * CSI related checks. + */ +#if STM32_CSI_ENABLED +#define STM32_CSI_CK STM32_CSI_OSC + +#else /* !STM32_CSI_ENABLED */ +#define STM32_CSI_CK 0U + +#if STM32_SW == STM32_SW_CSI_CK +#error "CSI not enabled, required by STM32_SW" +#endif + +#if (STM32_PLLSRC == STM32_PLLSRC_CSI_CK) && \ + (STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED) +#error "CSI not enabled, required by STM32_PLLSRC and STM32_PLLx_ENABLED" +#endif + +#if STM32_CKPERSEL == STM32_CKPERSEL_CSI_CK +#error "CSI not enabled, required by STM32_CKPERSEL" +#endif + +#if STM32_MCO2SEL == STM32_MCO2SEL_CSI_CK +#error "CSI not enabled, required by STM32_MCO2SEL" +#endif + +#endif /* !STM32_CSI_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + +#if !defined(STM32_HSECLK) +#error "HSE frequency not defined" +#endif + +#define STM32_HSE_CK STM32_HSECLK + +#if STM32_HSECLK == 0 +#error "HSE oscllator not available" +#else /* STM32_HSECLK != 0 */ +#if defined(STM32_HSE_BYPASS) +#if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN..STM32_HSECLK_BYP_MAX)" +#endif +#else /* !defined(STM32_HSE_BYPASS) */ +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN..STM32_HSECLK_MAX)" +#endif +#endif /* !defined(STM32_HSE_BYPASS) */ +#endif /* STM32_HSECLK != 0 */ +#else /* !STM32_HSE_ENABLED */ + +#if STM32_SW == STM32_SW_HSE_CK +#error "HSE not enabled, required by STM32_SW" +#endif + +#if (STM32_PLLSRC == STM32_PLLSRC_HSE_CK) && \ + (STM32_PLL1_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED) +#error "HSE not enabled, required by STM32_PLLSRC and STM32_PLLx_ENABLED" +#endif + +#if STM32_MCO1SEL == STM32_MCO1SEL_HSE_CK +#error "HSE not enabled, required by STM32_MCO1SEL" +#endif + +#if STM32_MCO2SEL == STM32_MCO2SEL_HSE_CK +#error "HSE not enabled, required by STM32_MCO2SEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_HSE_1M_CK +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#define STM32_LSI_CK STM32_LSI_OSC + +#else /* !STM32_LSI_ENABLED */ +#define STM32_LSI_CK 0U + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI_CK) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#if STM32_MCO2SEL == STM32_MCO2SEL_LSI_CK +#error "HSE not enabled, required by STM32_MCO2SEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + +#if !defined(STM32_LSECLK) +#error "LSE frequency not defined" +#endif + +#define STM32_LSE_CK STM32_LSECLK + +#if (STM32_LSE_CK == 0) +#error "LSE oscillator not available" +#endif + +#if defined(STM32_LSE_BYPASS) +#if (STM32_LSE_CK < STM32_LSE_CK_MIN) || (STM32_LSE_CK > STM32_LSE_CK_BYP_MAX) +#error "STM32_LSE_CK outside acceptable range (STM32_LSE_CK_MIN..STM32_LSE_CK_BYP_MAX)" +#endif +#else +#if (STM32_LSE_CK < STM32_LSE_CK_MIN) || (STM32_LSE_CK > STM32_LSE_CK_MAX) +#error "STM32_LSE_CK outside acceptable range (STM32_LSE_CK_MIN..STM32_LSE_CK_MAX)" +#endif +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined" +#endif + +#if (STM32_LSEDRV >> 3) > 3 +#error "STM32_LSEDRV outside acceptable range ((0<<3)..(3<<3))" +#endif + +#else /* !STM32_LSE_ENABLED */ + +#if STM32_RTCSEL == STM32_RTCSEL_LSE_CK +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#if STM32_MCO1SEL == STM32_MCO1SEL_LSE_CK +#error "LSE not enabled, required by STM32_MCO1SEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/** + * @brief HSI divided clock. + */ +#if (STM32_HSIDIV == STM32_HSIDIV_DIV1) || defined(__DOXYGEN__) +#define STM32_HSI_CK (STM32_HSICLK / 1U) +#elif STM32_HSIDIV == STM32_HSIDIV_DIV2 +#define STM32_HSI_CK (STM32_HSICLK / 2U) +#elif STM32_HSIDIV == STM32_HSIDIV_DIV4 +#define STM32_HSI_CK (STM32_HSICLK / 4U) +#elif STM32_HSIDIV == STM32_HSIDIV_DIV8 +#define STM32_HSI_CK (STM32_HSICLK / 8U) +#else +#error "invalid STM32_HSIDIV value specified" +#endif + +/** + * @brief HSE divided clock for RTC. + */ +#if ((STM32_RTCPRE_VALUE >= 2) && (STM32_RTCPRE_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_HSE_1M_CK (STM32_HSE_CK / STM32_RTCPRE_VALUE) +#else +#error "invalid STM32_RTCPRE_VALUE value specified" +#endif + +/** + * @brief PLLs input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE_CK) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN STM32_HSE_CK + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI_CK +#define STM32_PLLCLKIN STM32_HSI_CK + +#elif STM32_PLLSRC == STM32_PLLSRC_CSI_CK +#define STM32_PLLCLKIN STM32_CSI_CK + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/** + * @brief PLL1 DIVM field. + */ +#if ((STM32_PLL1_DIVM_VALUE >= 1) && (STM32_PLL1_DIVM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLL1_DIVM (STM32_PLL1_DIVM_VALUE << 4) +#define STM32_PLL1_REF_CK (STM32_PLLCLKIN / STM32_PLL1_DIVM_VALUE) +#else +#error "invalid STM32_PLL1_DIVM_VALUE value specified" +#endif + +/* + * PLL1 input frequency range check. + */ +#if (STM32_PLL1_REF_CK < STM32_PLLIN_MIN) || (STM32_PLL1_REF_CK > STM32_PLLIN_MAX) +#error "STM32_PLL1_REF_CK outside acceptable range (STM32_PLLIN_MIN..STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL1 input range selector. + */ +#if (STM32_PLL1_REF_CK < STM32_PLLIN_THRESHOLD1) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_0 +#elif STM32_PLL1_REF_CK < STM32_PLLIN_THRESHOLD2 +#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_1 +#elif STM32_PLL1_REF_CK < STM32_PLLIN_THRESHOLD3 +#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_2 +#else +#define STM32_PLLCFGR_PLL1RGE RCC_PLLCFGR_PLL1RGE_3 +#endif + +/** + * @brief PLL2 DIVM field. + */ +#if ((STM32_PLL2_DIVM_VALUE >= 1) && (STM32_PLL2_DIVM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2_DIVM (STM32_PLL2_DIVM_VALUE << 12) +#define STM32_PLL2_REF_CK (STM32_PLLCLKIN / STM32_PLL2_DIVM_VALUE) +#else +#error "invalid STM32_PLL2_DIVM_VALUE value specified" +#endif + +/* + * PLL2 input frequency range check. + */ +#if (STM32_PLL2_REF_CK < STM32_PLLIN_MIN) || (STM32_PLL2_REF_CK > STM32_PLLIN_MAX) +#error "STM32_PLL2_REF_CK outside acceptable range (STM32_PLLIN_MIN..STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL2 input range selector. + */ +#if (STM32_PLL2_REF_CK < STM32_PLLIN_THRESHOLD1) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_0 +#elif STM32_PLL2_REF_CK < STM32_PLLIN_THRESHOLD2 +#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_1 +#elif STM32_PLL2_REF_CK < STM32_PLLIN_THRESHOLD3 +#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_2 +#else +#define STM32_PLLCFGR_PLL2RGE RCC_PLLCFGR_PLL2RGE_3 +#endif + +/** + * @brief PLL3 DIVM field. + */ +#if ((STM32_PLL3_DIVM_VALUE >= 1) && (STM32_PLL3_DIVM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3_DIVM (STM32_PLL3_DIVM_VALUE << 20) +#define STM32_PLL3_REF_CK (STM32_PLLCLKIN / STM32_PLL3_DIVM_VALUE) +#else +#error "invalid STM32_PLL3_DIVM_VALUE value specified" +#endif + +/* + * PLL3 input frequency range check. + */ +#if (STM32_PLL3_REF_CK < STM32_PLLIN_MIN) || (STM32_PLL3_REF_CK > STM32_PLLIN_MAX) +#error "STM32_PLL3_REF_CK outside acceptable range (STM32_PLLIN_MIN..STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL3 input range selector. + */ +#if (STM32_PLL3_REF_CK < STM32_PLLIN_THRESHOLD1) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_0 +#elif STM32_PLL3_REF_CK < STM32_PLLIN_THRESHOLD2 +#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_1 +#elif STM32_PLL3_REF_CK < STM32_PLLIN_THRESHOLD3 +#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_2 +#else +#define STM32_PLLCFGR_PLL3RGE RCC_PLLCFGR_PLL3RGE_3 +#endif + +/** + * @brief PLL1 DIVN field. + */ +#if ((STM32_PLL1_DIVN_VALUE >= 4) && (STM32_PLL1_DIVN_VALUE <= 512)) || \ + defined(__DOXYGEN__) +#define STM32_PLL1_DIVN ((STM32_PLL1_DIVN_VALUE - 1U) << 0U) +#else +#error "invalid STM32_PLL1_DIVN_VALUE value specified" +#endif + +/** + * @brief PLL2 DIVN field. + */ +#if ((STM32_PLL2_DIVN_VALUE >= 4) && (STM32_PLL2_DIVN_VALUE <= 512)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2_DIVN ((STM32_PLL2_DIVN_VALUE - 1U) << 0U) +#else +#error "invalid STM32_PLL2_DIVN_VALUE value specified" +#endif + +/** + * @brief PLL3 DIVN field. + */ +#if ((STM32_PLL3_DIVN_VALUE >= 4) && (STM32_PLL3_DIVN_VALUE <= 512)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3_DIVN ((STM32_PLL3_DIVN_VALUE - 1U) << 0U) +#else +#error "invalid STM32_PLL3_DIVN_VALUE value specified" +#endif + +/** + * @brief PLL1 FRACN field. + */ +#if ((STM32_PLL1_FRACN_VALUE >= 0) && (STM32_PLL1_FRACN_VALUE <= 8191)) || \ + defined(__DOXYGEN__) +#define STM32_PLL1_FRACN (STM32_PLL1_FRACN_VALUE << 3U) +#else +#error "invalid STM32_PLL1_FRACN_VALUE value specified" +#endif + +/** + * @brief PLL2 FRACN field. + */ +#if ((STM32_PLL2_FRACN_VALUE >= 0) && (STM32_PLL2_FRACN_VALUE <= 8191)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2_FRACN (STM32_PLL2_FRACN_VALUE << 3U) +#else +#error "invalid STM32_PLL2_FRACN_VALUE value specified" +#endif + +/** + * @brief PLL3 FRACN field. + */ +#if ((STM32_PLL3_FRACN_VALUE >= 0) && (STM32_PLL3_FRACN_VALUE <= 8191)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3_FRACN (STM32_PLL3_FRACN_VALUE << 3U) +#else +#error "invalid STM32_PLL3_FRACN_VALUE value specified" +#endif + +/** + * @brief PLL1 DIVP field. + */ +#if ((STM32_PLL1_DIVP_VALUE >= 2) && (STM32_PLL1_DIVP_VALUE <= 128) && \ + ((STM32_PLL1_DIVP_VALUE & 1U) == 0U)) || \ + defined(__DOXYGEN__) +#define STM32_PLL1_DIVP ((STM32_PLL1_DIVP_VALUE - 1U) << 9U) +#else +#error "invalid STM32_PLL1_DIVP_VALUE value specified" +#endif + +/** + * @brief PLL2 DIVP field. + */ +#if ((STM32_PLL2_DIVP_VALUE >= 2) && (STM32_PLL2_DIVP_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2_DIVP ((STM32_PLL2_DIVP_VALUE - 1U) << 9U) +#else +#error "invalid STM32_PLL2_DIVP_VALUE value specified" +#endif + +/** + * @brief PLL3 DIVP field. + */ +#if ((STM32_PLL3_DIVP_VALUE >= 2) && (STM32_PLL3_DIVP_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3_DIVP ((STM32_PLL3_DIVP_VALUE - 1U) << 9U) +#else +#error "invalid STM32_PLL3_DIVP_VALUE value specified" +#endif + +/** + * @brief PLL1 DIVQ field. + */ +#if ((STM32_PLL1_DIVQ_VALUE >= 1) && (STM32_PLL1_DIVQ_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL1_DIVQ ((STM32_PLL1_DIVQ_VALUE - 1U) << 16U) +#else +#error "invalid STM32_PLL1_DIVQ_VALUE value specified" +#endif + +/** + * @brief PLL2 DIVQ field. + */ +#if ((STM32_PLL2_DIVQ_VALUE >= 1) && (STM32_PLL2_DIVQ_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2_DIVQ ((STM32_PLL2_DIVQ_VALUE - 1U) << 16U) +#else +#error "invalid STM32_PLL2_DIVQ_VALUE value specified" +#endif + +/** + * @brief PLL3 DIVQ field. + */ +#if ((STM32_PLL3_DIVQ_VALUE >= 1) && (STM32_PLL3_DIVQ_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3_DIVQ ((STM32_PLL3_DIVQ_VALUE - 1U) << 16U) +#else +#error "invalid STM32_PLL3_DIVQ_VALUE value specified" +#endif + +/** + * @brief PLL1 DIVR field. + */ +#if ((STM32_PLL1_DIVR_VALUE >= 1) && (STM32_PLL1_DIVR_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL1_DIVR ((STM32_PLL1_DIVR_VALUE - 1U) << 24U) +#else +#error "invalid STM32_PLL1_DIVR_VALUE value specified" +#endif + +/** + * @brief PLL2 DIVR field. + */ +#if ((STM32_PLL2_DIVR_VALUE >= 1) && (STM32_PLL2_DIVR_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL2_DIVR ((STM32_PLL2_DIVR_VALUE - 1U) << 24U) +#else +#error "invalid STM32_PLL2_DIVR_VALUE value specified" +#endif + +/** + * @brief PLL3 DIVR field. + */ +#if ((STM32_PLL3_DIVR_VALUE >= 1) && (STM32_PLL3_DIVR_VALUE <= 128)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3_DIVR ((STM32_PLL3_DIVR_VALUE - 1U) << 24U) +#else +#error "invalid STM32_PLL3_DIVR_VALUE value specified" +#endif + +/** + * @brief PLL1 VCO frequency. + */ +#define STM32_PLL1_VCO_CK (STM32_PLL1_REF_CK * STM32_PLL1_DIVN_VALUE) + +/* + * PLL1 VCO frequency range check. + */ +#if (STM32_PLL1_VCO_CK < STM32_PLLVCO_MIN) || (STM32_PLL1_VCO_CK > STM32_PLLVCO_MAX) +#error "STM32_PLL1_VCO_CK outside acceptable range (STM32_PLLVCO_MIN..STM32_PLLVCO_MAX)" +#endif + +/* + * PLL1 VCO mode. + */ +#if (STM32_PLL1_VCO_CK > STM32_PLLVCO_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_PLL1VCOSEL 0U +#else +#define STM32_PLLCFGR_PLL1VCOSEL RCC_PLLCFGR_PLL1VCOSEL +#endif + +/** + * @brief PLL2 VCO frequency. + */ +#define STM32_PLL2_VCO_CK (STM32_PLL2_REF_CK * STM32_PLL2_DIVN_VALUE) + +/* + * PLL2 VCO frequency range check. + */ +#if (STM32_PLL2_VCO_CK < STM32_PLLVCO_MIN) || (STM32_PLL2_VCO_CK > STM32_PLLVCO_MAX) +#error "STM32_PLL2_VCO_CK outside acceptable range (STM32_PLLVCO_MIN..STM32_PLLVCO_MAX)" +#endif + +/* + * PLL2 VCO mode. + */ +#if (STM32_PLL2_VCO_CK > STM32_PLLVCO_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_PLL2VCOSEL 0U +#else +#define STM32_PLLCFGR_PLL2VCOSEL RCC_PLLCFGR_PLL2VCOSEL +#endif + +/** + * @brief PLL3 VCO frequency. + */ +#define STM32_PLL3_VCO_CK (STM32_PLL3_REF_CK * STM32_PLL3_DIVN_VALUE) + +/* + * PLL3 VCO frequency range check. + */ +#if (STM32_PLL3_VCO_CK < STM32_PLLVCO_MIN) || (STM32_PLL3_VCO_CK > STM32_PLLVCO_MAX) +#error "STM32_PLL3_VCO_CK outside acceptable range (STM32_PLLVCO_MIN..STM32_PLLVCO_MAX)" +#endif + +/* + * PLL3 VCO mode. + */ +#if (STM32_PLL3_VCO_CK > STM32_PLLVCO_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_PLLCFGR_PLL3VCOSEL 0U +#else +#define STM32_PLLCFGR_PLL3VCOSEL RCC_PLLCFGR_PLL3VCOSEL +#endif + +#if ((STM32_PLL1_ENABLED == TRUE) && (STM32_PLL1_P_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL1 P output clock frequency. + */ +#define STM32_PLL1_P_CK (STM32_PLL1_VCO_CK / STM32_PLL1_DIVP_VALUE) + +/* + * PLL1 P output frequency range check. + */ +#if (STM32_PLL1_P_CK < STM32_PLLOUT_MIN) || (STM32_PLL1_P_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL1_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL1_P_CK 0U +#endif + +#if ((STM32_PLL2_ENABLED == TRUE) && (STM32_PLL2_P_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL2 P output clock frequency. + */ +#define STM32_PLL2_P_CK (STM32_PLL2_VCO_CK / STM32_PLL2_DIVP_VALUE) + +/* + * PLL2 P output frequency range check. + */ +#if (STM32_PLL2_P_CK < STM32_PLLOUT_MIN) || (STM32_PLL2_P_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL2_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL2_P_CK 0U +#endif + +#if ((STM32_PLL3_ENABLED == TRUE) && (STM32_PLL3_P_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL3 P output clock frequency. + */ +#define STM32_PLL3_P_CK (STM32_PLL3_VCO_CK / STM32_PLL3_DIVP_VALUE) + +/* + * PLL3 P output frequency range check. + */ +#if (STM32_PLL3_P_CK < STM32_PLLOUT_MIN) || (STM32_PLL3_P_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL3_P_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL3_P_CK 0U +#endif + +#if ((STM32_PLL1_ENABLED == TRUE) && (STM32_PLL1_Q_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL1 Q output clock frequency. + */ +#define STM32_PLL1_Q_CK (STM32_PLL1_VCO_CK / STM32_PLL1_DIVQ_VALUE) + +/* + * PLL1 Q output frequency range check. + */ +#if (STM32_PLL1_Q_CK < STM32_PLLOUT_MIN) || (STM32_PLL1_Q_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL1_Q_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL1_Q_CK 0U +#endif + +#if ((STM32_PLL2_ENABLED == TRUE) && (STM32_PLL2_Q_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL2 Q output clock frequency. + */ +#define STM32_PLL2_Q_CK (STM32_PLL2_VCO_CK / STM32_PLL2_DIVQ_VALUE) + +/* + * PLL2 Q output frequency range check. + */ +#if (STM32_PLL2_Q_CK < STM32_PLLOUT_MIN) || (STM32_PLL2_Q_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL2_Q_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL2_Q_CK 0U +#endif + +#if ((STM32_PLL3_ENABLED == TRUE) && (STM32_PLL3_Q_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL3 Q output clock frequency. + */ +#define STM32_PLL3_Q_CK (STM32_PLL3_VCO_CK / STM32_PLL3_DIVQ_VALUE) + +/* + * PLL3 Q output frequency range check. + */ +#if (STM32_PLL3_Q_CK < STM32_PLLOUT_MIN) || (STM32_PLL3_Q_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL3_Q_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL3_Q_CK 0U +#endif + +#if ((STM32_PLL1_ENABLED == TRUE) && (STM32_PLL1_R_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL1 R output clock frequency. + */ +#define STM32_PLL1_R_CK (STM32_PLL1_VCO_CK / STM32_PLL1_DIVR_VALUE) + +/* + * PLL1 R output frequency range check. + */ +#if (STM32_PLL1_R_CK < STM32_PLLOUT_MIN) || (STM32_PLL1_R_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL1_R_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL1_R_CK 0U +#endif + +#if ((STM32_PLL2_ENABLED == TRUE) && (STM32_PLL2_R_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL2 R output clock frequency. + */ +#define STM32_PLL2_R_CK (STM32_PLL2_VCO_CK / STM32_PLL2_DIVR_VALUE) + +/* + * PLL2 R output frequency range check. + */ +#if (STM32_PLL2_R_CK < STM32_PLLOUT_MIN) || (STM32_PLL2_R_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL2_R_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL2_R_CK 0U +#endif + +#if ((STM32_PLL3_ENABLED == TRUE) && (STM32_PLL3_R_ENABLED == TRUE)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL3 R output clock frequency. + */ +#define STM32_PLL3_R_CK (STM32_PLL3_VCO_CK / STM32_PLL3_DIVR_VALUE) + +/* + * PLL3 R output frequency range check. + */ +#if (STM32_PLL3_R_CK < STM32_PLLOUT_MIN) || (STM32_PLL3_R_CK > STM32_PLLOUT_MAX) +#error "STM32_PLL3_R_CLKOUT outside acceptable range (STM32_PLLOUT_MIN..STM32_PLLOUT_MAX)" +#endif +#else +#define STM32_PLL3_R_CK 0U +#endif + +/** + * @brief System clock source. + */ +#if (STM32_SW == STM32_SW_HSI_CK) || defined(__DOXYGEN__) +#define STM32_SYS_CK STM32_HSI_CK + +#elif (STM32_SW == STM32_SW_CSI_CK) +#define STM32_SYS_CK STM32_CSI_CK + +#elif (STM32_SW == STM32_SW_HSE_CK) +#define STM32_SYS_CK STM32_HSE_CK + +#elif (STM32_SW == STM32_SW_PLL1_P_CK) +#define STM32_SYS_CK STM32_PLL1_P_CK + +#else +#error "invalid STM32_SW value specified" +#endif + +/* + * Check on the system clock. + */ +#if STM32_SYS_CK > STM32_SYSCLK_MAX +#error "STM32_SYS_CK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/* + * ODEN setting based on clock frequency. + */ +#if STM32_SYS_CK > STM32_SYSCLK_MAX_NOBOOST +#define STM32_ODEN STM32_ODEN_ENABLED +#else +#define STM32_ODEN STM32_ODEN_DISABLED +#endif + +/** + * @brief Peripherals clock source. + */ +#if (STM32_CKPERSEL == STM32_CKPERSEL_HSI_CK) || defined(__DOXYGEN__) +#define STM32_PER_CK STM32_HSI_CK + +#elif (STM32_CKPERSEL == STM32_CKPERSEL_CSI_CK) +#define STM32_PER_CK STM32_CSI_CK + +#elif (STM32_CKPERSEL == STM32_CKPERSEL_HSE_CK) +#define STM32_PER_CK STM32_HSE_CK + +#else +#error "invalid STM32_CKPERSEL value specified" +#endif + +/* + * Check on the peripherals clock. + */ +#if STM32_PER_CK > STM32_HCLK_MAX +#error "STM32_PER_CK above maximum rated frequency (STM32_HCLK_MAX)" +#endif + +/** + * @brief MCO1 divider clock. + */ +#if (STM32_MCO1SEL == STM32_MCO1SEL_HSI_CK) || defined(__DOXYGEN__) +#define STM32_MCO1DIVCLK STM32_HSI_CK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_LSE_CK +#define STM32_MCO1DIVCLK STM32_LSE_CK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_HSE_CK +#define STM32_MCO1DIVCLK STM32_HSE_CK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_PLL1_Q_CK +#define STM32_MCO1DIVCLK STM32_PLL1_P_CK + +#elif STM32_MCO1SEL == STM32_MCO1SEL_HSI48_CK +#define STM32_MCO1DIVCLK STM32_HSI48_CK + +#else +#error "invalid STM32_MCO1SEL value specified" +#endif + +/** + * @brief MCO1 output pin clock. + */ +#if (STM32_MCO1PRE_VALUE < 1) || (STM32_MCO1PRE_VALUE > 15) +#error "STM32_MCO1PRE_VALUE outside acceptable range (1..15)" +#endif + +/** + * @brief MCO2 divider clock. + */ +#if (STM32_MCO2SEL == STM32_MCO2SEL_SYS_CK) || defined(__DOXYGEN__) +#define STM32_MCO2DIVCLK STM32_SYS_CK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL1_P_CK +#define STM32_MCO2DIVCLK STM32_PLL2_P_CK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_HSE_CK +#define STM32_MCO2DIVCLK STM32_HSE_CK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_PLL2_P_CK +#define STM32_MCO2DIVCLK STM32_PLL2_P_CK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_CSI_CK +#define STM32_MCO2DIVCLK STM32_CSI_CK + +#elif STM32_MCO2SEL == STM32_MCO2SEL_LSI_CK +#define STM32_MCO2DIVCLK STM32_LSI_CK + +#else +#error "invalid STM32_MCO2SEL value specified" +#endif + +/** + * @brief MCO2 output pin clock. + */ +#if (STM32_MCO2PRE_VALUE < 1) || (STM32_MCO2PRE_VALUE > 15) +#error "STM32_MCO2PRE_VALUE outside acceptable range (1..15)" +#endif + +/** + * @brief RTC clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLK) || defined(__DOXYGEN__) +#define STM32_RTC_CK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE_CK +#define STM32_RTC_CK STM32_LSE_CK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI_CK +#define STM32_RTC_CK STM32_LSI_CK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSE_1M_CK +#define STM32_RTC_CK STM32_HSE_1M_CK + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/* + * Check on the RTC clock. + */ +#if STM32_RTC_CK > 1000000 +#error "STM32_RTC_CK above maximum rated frequency (1000000)" +#endif + +/** + * @brief D1CPRE clock. + */ +#if (STM32_D1CPRE == STM32_D1CPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 1U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV2 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 2U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV4 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 4U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV8 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 8U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV16 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 16U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV64 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 64U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV128 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 128U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV256 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 256U) +#elif STM32_D1CPRE == STM32_D1CPRE_DIV512 +#define STM32_SYS_D1CPRE_CK (STM32_SYS_CK / 512U) +#else +#error "invalid STM32_D1CPRE value specified" +#endif + +/** + * @brief HCLK clock. + */ +#if (STM32_D1HPRE == STM32_D1HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 1U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV2 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 2U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV4 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 4U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV8 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 8U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV16 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 16U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV64 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 64U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV128 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 128U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV256 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 256U) +#elif STM32_D1HPRE == STM32_D1HPRE_DIV512 +#define STM32_HCLK (STM32_SYS_D1CPRE_CK / 512U) +#else +#error "invalid STM32_D1HPRE value specified" +#endif + +/** + * @brief Core clock. + */ +#define STM32_CORE1_CK STM32_SYS_D1CPRE_CK + +/** + * @brief Core clock. + */ +#define STM32_CORE2_CK STM32_HCLK + +#if (STM32_TARGET_CORE == 1) || defined(__DOXYGEN__) + +#if STM32_HAS_M7 != TRUE +#error "Cortex-M7 not present in this device" +#endif +#define STM32_CORE_CK STM32_CORE1_CK + +#elif STM32_TARGET_CORE == 2 + +#if STM32_HAS_M4 != TRUE +#error "Cortex-M4 not present in this device" +#endif +#define STM32_CORE_CK STM32_CORE2_CK + +#else +#error "invalid STM32_TARGET_CORE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_HCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_HCLK_MAX)" +#endif + +/** + * @brief D1 PCLK3 clock. + */ +#if (STM32_D1PPRE3 == STM32_D1PPRE3_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK3 (STM32_HCLK / 1U) +#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV2 +#define STM32_PCLK3 (STM32_HCLK / 2U) +#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV4 +#define STM32_PCLK3 (STM32_HCLK / 4U) +#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV8 +#define STM32_PCLK3 (STM32_HCLK / 8U) +#elif STM32_D1PPRE3 == STM32_D1PPRE3_DIV16 +#define STM32_PCLK3 (STM32_HCLK / 16U) +#else +#error "invalid STM32_D1PPRE3 value specified" +#endif + +/* + * D1 PCLK3 frequency check. + */ +#if STM32_PCLK3 > STM32_PCLK3_MAX +#error "STM32_PCLK3 exceeding maximum frequency (STM32_PCLK3_MAX)" +#endif + +/** + * @brief D2 PCLK1 clock. + */ +#if (STM32_D2PPRE1 == STM32_D2PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1U) +#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2U) +#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4U) +#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8U) +#elif STM32_D2PPRE1 == STM32_D2PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16U) +#else +#error "invalid STM32_D2PPRE1 value specified" +#endif + +/* + * D2 PCLK1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief D2 PCLK2 clock. + */ +#if (STM32_D2PPRE2 == STM32_D2PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1U) +#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2U) +#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4U) +#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8U) +#elif STM32_D2PPRE2 == STM32_D2PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16U) +#else +#error "invalid STM32_D2PPRE2 value specified" +#endif + +/* + * D2 PCLK2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief D3 PCLK4 clock. + */ +#if (STM32_D3PPRE4 == STM32_D3PPRE4_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK4 (STM32_HCLK / 1U) +#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV2 +#define STM32_PCLK4 (STM32_HCLK / 2U) +#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV4 +#define STM32_PCLK4 (STM32_HCLK / 4U) +#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV8 +#define STM32_PCLK4 (STM32_HCLK / 8U) +#elif STM32_D3PPRE4 == STM32_D3PPRE4_DIV16 +#define STM32_PCLK4 (STM32_HCLK / 16U) +#else +#error "invalid STM32_D3PPRE4 value specified" +#endif + +/* + * D3 PCLK4 frequency check. + */ +#if STM32_PCLK4 > STM32_PCLK4_MAX +#error "STM32_PCLK4 exceeding maximum frequency (STM32_PCLK4_MAX)" +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0x00000000 + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS 0x00000001 + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS 0x00000002 + +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS 0x00000003 + +#elif STM32_HCLK <= STM32_4WS_THRESHOLD +#define STM32_FLASHBITS 0x00000004 + +#else +#define STM32_FLASHBITS 0x00000007 +#endif + +#if (STM32_D2PPRE1 == STM32_D2PPRE1_DIV1) || defined(__DOXYGEN__) +/** + * @brief Clock of timers connected to APB1 + */ +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#if (STM32_TIMPRE_ENABLE == FALSE) || (STM32_D2PPRE1 == STM32_D2PPRE1_DIV2) +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 4) +#endif +#endif + +#if (STM32_D2PPRE2 == STM32_D2PPRE2_DIV1) || defined(__DOXYGEN__) +/** + * @brief Clock of timers connected to APB2. + */ +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#if (STM32_TIMPRE_ENABLE == FALSE) || (STM32_D2PPRE2 == STM32_D2PPRE2_DIV2) +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 4) +#endif +#endif + +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) +/** + * @brief LPTIM1 clock. + */ +#define STM32_LPTIM1CLK STM32_PCLK1 + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_PLL2_P_CK +#define STM32_LPTIM1CLK STM32_PLL2_P_CK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_PLL3_R_CK +#define STM32_LPTIM1CLK STM32_PLL3_R_CK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE_CK +#define STM32_LPTIM1CLK STM32_LSE_CK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI_CK +#define STM32_LPTIM1CLK STM32_LSI_CK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_PER_CK +#define STM32_LPTIM1CLK STM32_PER_CK +#else +#error "invalid source selected for STM32_LPTIM1SEL clock" +#endif + +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK4) || defined(__DOXYGEN__) +/** + * @brief LPTIM2 clock. + */ +#define STM32_LPTIM2CLK STM32_PCLK4 + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_PLL2_P_CK +#define STM32_LPTIM2CLK STM32_PLL2_P_CK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_PLL3_P_CK +#define STM32_LPTIM2CLK STM32_PLL3_P_CK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE_CK +#define STM32_LPTIM2CLK STM32_LSE_CK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI_CK +#define STM32_LPTIM2CLK STM32_LSI_CK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_PER_CK +#define STM32_LPTIM2CLK STM32_PER_CK +#else +#error "invalid source selected for STM32_LPTIM2SEL clock" +#endif + +#if (STM32_LPTIM345SEL == STM32_LPTIM345SEL_PCLK4) || defined(__DOXYGEN__) +/** + * @brief LPTIM3 clock. + */ +#define STM32_LPTIM3CLK STM32_PCLK4 + +/** + * @brief LPTIM4 clock. + */ +#define STM32_LPTIM4CLK STM32_PCLK4 + +/** + * @brief LPTIM5 clock. + */ +#define STM32_LPTIM5CLK STM32_PCLK4 + +#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_PLL2_P_CK +#define STM32_LPTIM3CLK STM32_PLL2_P_CK +#define STM32_LPTIM4CLK STM32_PLL2_P_CK +#define STM32_LPTIM5CLK STM32_PLL2_P_CK +#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_PLL3_P_CK +#define STM32_LPTIM3CLK STM32_PLL3_P_CK +#define STM32_LPTIM4CLK STM32_PLL3_P_CK +#define STM32_LPTIM5CLK STM32_PLL3_P_CK +#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_LSE_CK +#define STM32_LPTIM3CLK STM32_LSE_CK +#define STM32_LPTIM4CLK STM32_LSE_CK +#define STM32_LPTIM5CLK STM32_LSE_CK +#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_LSI_CK +#define STM32_LPTIM3CLK STM32_LSI_CK +#define STM32_LPTIM4CLK STM32_LSI_CK +#define STM32_LPTIM5CLK STM32_LSI_CK +#elif STM32_LPTIM345SEL == STM32_LPTIM345SEL_PER_CK +#define STM32_LPTIM3CLK STM32_PER_CK +#define STM32_LPTIM4CLK STM32_PER_CK +#define STM32_LPTIM5CLK STM32_PER_CK +#else +#error "invalid source selected for STM32_LPTIM345SEL clock" +#endif + +#if (STM32_USART16SEL == STM32_USART16SEL_PCLK2) || defined(__DOXYGEN__) +/** + * @brief USART1 clock. + */ +#define STM32_USART1CLK STM32_PCLK2 + +/** + * @brief USART6 clock. + */ +#define STM32_USART6CLK STM32_PCLK2 + +#elif STM32_USART16SEL == STM32_USART16SEL_PLL2_Q_CK +#define STM32_USART1CLK STM32_PLL2_Q_CK +#define STM32_USART6CLK STM32_PLL2_Q_CK +#elif STM32_USART16SEL == STM32_USART16SEL_PLL3_Q_CK +#define STM32_USART1CLK STM32_PLL3_Q_CK +#define STM32_USART6CLK STM32_PLL3_Q_CK +#elif STM32_USART16SEL == STM32_USART16SEL_HSI_KER_CK +#define STM32_USART1CLK STM32_HSI_CK +#define STM32_USART6CLK STM32_HSI_CK +#elif STM32_USART16SEL == STM32_USART16SEL_CSI_KER_CK +#define STM32_USART1CLK STM32_CSI_CK +#define STM32_USART6CLK STM32_CSI_CK +#elif STM32_USART16SEL == STM32_USART16SEL_LSE_CK +#define STM32_USART1CLK STM32_LSE_CK +#define STM32_USART6CLK STM32_LSE_CK +#else +#error "invalid source selected for STM32_USART16SEL clock" +#endif + +#if (STM32_USART234578SEL == STM32_USART234578SEL_PCLK1) || defined(__DOXYGEN__) +/** + * @brief USART2 clock. + */ +#define STM32_USART2CLK STM32_PCLK1 + +/** + * @brief USART3 clock. + */ +#define STM32_USART3CLK STM32_PCLK1 + +/** + * @brief USART4 clock. + */ +#define STM32_UART4CLK STM32_PCLK1 + +/** + * @brief USART5 clock. + */ +#define STM32_UART5CLK STM32_PCLK1 + +/** + * @brief USART7 clock. + */ +#define STM32_UART7CLK STM32_PCLK1 + +/** + * @brief USART8 clock. + */ +#define STM32_UART8CLK STM32_PCLK1 + +#elif STM32_USART234578SEL == STM32_USART234578SEL_PLL2_Q_CK +#define STM32_USART2CLK STM32_PLL2_Q_CK +#define STM32_USART3CLK STM32_PLL2_Q_CK +#define STM32_UART4CLK STM32_PLL2_Q_CK +#define STM32_UART5CLK STM32_PLL2_Q_CK +#define STM32_UART7CLK STM32_PLL2_Q_CK +#define STM32_UART8CLK STM32_PLL2_Q_CK +#elif STM32_USART234578SEL == STM32_USART234578SEL_PLL3_Q_CK +#define STM32_USART2CLK STM32_PLL3_Q_CK +#define STM32_USART3CLK STM32_PLL3_Q_CK +#define STM32_UART4CLK STM32_PLL3_Q_CK +#define STM32_UART5CLK STM32_PLL3_Q_CK +#define STM32_UART7CLK STM32_PLL3_Q_CK +#define STM32_UART8CLK STM32_PLL3_Q_CK +#elif STM32_USART234578SEL == STM32_USART234578SEL_HSI_KER_CK +#define STM32_USART2CLK STM32_HSI_CK +#define STM32_USART3CLK STM32_HSI_CK +#define STM32_UART4CLK STM32_HSI_CK +#define STM32_UART5CLK STM32_HSI_CK +#define STM32_UART7CLK STM32_HSI_CK +#define STM32_UART8CLK STM32_HSI_CK +#elif STM32_USART234578SEL == STM32_USART234578SEL_CSI_KER_CK +#define STM32_USART2CLK STM32_CSI_CK +#define STM32_USART3CLK STM32_CSI_CK +#define STM32_UART4CLK STM32_CSI_CK +#define STM32_UART5CLK STM32_CSI_CK +#define STM32_UART7CLK STM32_CSI_CK +#define STM32_UART8CLK STM32_CSI_CK +#elif STM32_USART234578SEL == STM32_USART234578SEL_LSE_CK +#define STM32_USART2CLK STM32_LSE_CK +#define STM32_USART3CLK STM32_LSE_CK +#define STM32_UART4CLK STM32_LSE_CK +#define STM32_UART6CLK STM32_LSE_CK +#define STM32_UART7CLK STM32_LSE_CK +#define STM32_UART8CLK STM32_LSE_CK +#else +#error "invalid source selected for STM32_USART234578SEL clock" +#endif + +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK4) || defined(__DOXYGEN__) +/** + * @brief LPUART1 clock. + */ +#define STM32_LPUART1CLK STM32_PCLK4 + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_PLL2_Q_CK +#define STM32_LPUART1CLK STM32_PLL2_Q_CK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_PLL3_Q_CK +#define STM32_LPUART1CLK STM32_PLL3_Q_CK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI_KER_CK +#define STM32_LPUART1CLK STM32_HSI_CK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_CSI_KER_CK +#define STM32_LPUART1CLK STM32_CSI_CK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE_CK +#define STM32_LPUART1CLK STM32_LSE_CK +#else +#error "invalid source selected for STM32_LPUART1SEL clock" +#endif + +#if (STM32_SPI123SEL == STM32_SPI123SEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SPI1 clock. + */ +#define STM32_SPI1CLK STM32_PLL1_Q_CK + +/** + * @brief SPI2 clock. + */ +#define STM32_SPI2CLK STM32_PLL1_Q_CK + +/** + * @brief SPI3 clock. + */ +#define STM32_SPI3CLK STM32_PLL1_Q_CK +#elif STM32_SPI123SEL == STM32_SPI123SEL_PLL2_P_CK +#define STM32_SPI1CLK STM32_PLL2_P_CK +#define STM32_SPI2CLK STM32_PLL2_P_CK +#define STM32_SPI3CLK STM32_PLL2_P_CK +#elif STM32_SPI123SEL == STM32_SPI123SEL_PLL3_P_CK +#define STM32_SPI1CLK STM32_PLL3_P_CK +#define STM32_SPI2CLK STM32_PLL3_P_CK +#define STM32_SPI3CLK STM32_PLL3_P_CK +#elif STM32_SPI123SEL == STM32_SPI123SEL_I2S_CKIN +#define STM32_SPI1CLK 0 /* Unknown, would require a board value */ +#define STM32_SPI2CLK 0 /* Unknown, would require a board value */ +#define STM32_SPI3CLK 0 /* Unknown, would require a board value */ +#elif STM32_SPI123SEL == STM32_SPI123SEL_PER_CK +#define STM32_SPI1CLK STM32_PER_CK +#define STM32_SPI2CLK STM32_PER_CK +#define STM32_SPI3CLK STM32_PER_CK +#else +#error "invalid source selected for STM32_SPI123SEL clock" +#endif + +#if (STM32_SPI45SEL == STM32_SPI45SEL_PCLK2) || defined(__DOXYGEN__) +/** + * @brief SPI4 clock. + */ +#define STM32_SPI4CLK STM32_PCLK2 + +/** + * @brief SPI5 clock. + */ +#define STM32_SPI5CLK STM32_PCLK2 + +#elif STM32_SPI45SEL == STM32_SPI45SEL_PLL2_Q_CK +#define STM32_SPI4CLK STM32_PLL2_Q_CK +#define STM32_SPI5CLK STM32_PLL2_Q_CK +#elif STM32_SPI45SEL == STM32_SPI45SEL_PLL3_Q_CK +#define STM32_SPI4CLK STM32_PLL3_Q_CK +#define STM32_SPI5CLK STM32_PLL3_Q_CK +#elif STM32_SPI45SEL == STM32_SPI45SEL_HSI_KER_CK +#define STM32_SPI4CLK STM32_HSI_CK +#define STM32_SPI5CLK STM32_HSI_CK +#elif STM32_SPI45SEL == STM32_SPI45SEL_CSI_KER_CK +#define STM32_SPI4CLK STM32_CSI_CK +#define STM32_SPI5CLK STM32_CSI_CK +#elif STM32_SPI45SEL == STM32_SPI45SEL_HSE_CK +#define STM32_SPI4CLK STM32_HSE_CK +#define STM32_SPI5CLK STM32_HSE_CK +#else +#error "invalid source selected for STM32_SPI45SEL clock" +#endif + +#if (STM32_SPI6SEL == STM32_SPI6SEL_PCLK4) || defined(__DOXYGEN__) +/** + * @brief SPI6 clock. + */ +#define STM32_SPI6CLK STM32_PCLK4 + +#elif STM32_SPI6SEL == STM32_SPI6SEL_PLL2_Q_CK +#define STM32_SPI6CLK STM32_PLL2_Q_CK +#elif STM32_SPI6SEL == STM32_SPI6SEL_PLL3_Q_CK +#define STM32_SPI6CLK STM32_PLL3_Q_CK +#elif STM32_SPI6SEL == STM32_SPI6SEL_HSI_KER_CK +#define STM32_SPI6CLK STM32_HSI_CK +#elif STM32_SPI6SEL == STM32_SPI6SEL_CSI_KER_CK +#define STM32_SPI6CLK STM32_CSI_CK +#elif STM32_SPI6SEL == STM32_SPI6SEL_HSE_CK +#define STM32_SPI6CLK STM32_HSE_CK +#else +#error "invalid source selected for STM32_SPI6SEL clock" +#endif + +#if (STM32_I2C123SEL == STM32_I2C123SEL_PCLK1) || defined(__DOXYGEN__) +/** + * @brief I2C1 clock. + */ +#define STM32_I2C1CLK STM32_PCLK1 + +/** + * @brief I2C2 clock. + */ +#define STM32_I2C2CLK STM32_PCLK1 + +/** + * @brief I2C2 clock. + */ +#define STM32_I2C2CLK STM32_PCLK1 + +#elif STM32_I2C123SEL == STM32_I2C123SEL_PLL3_R_CK +#define STM32_I2C1CLK STM32_PLL3_R_CK +#define STM32_I2C2CLK STM32_PLL3_R_CK +#define STM32_I2C2CLK STM32_PLL3_R_CK + +#elif STM32_I2C123SEL == STM32_I2C123SEL_HSI_KER_CK +#define STM32_I2C1CLK STM32_HSI_CK +#define STM32_I2C2CLK STM32_HSI_CK +#define STM32_I2C2CLK STM32_HSI_CK + +#elif STM32_I2C123SEL == STM32_I2C123SEL_CSI_KER_CK +#define STM32_I2C1CLK STM32_CSI_CK +#define STM32_I2C2CLK STM32_CSI_CK +#define STM32_I2C2CLK STM32_CSI_CK +#else +#error "invalid source selected for STM32_I2C123SEL clock" +#endif + +#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK4) || defined(__DOXYGEN__) +/** + * @brief I2C1 clock. + */ +#define STM32_I2C4CLK STM32_PCLK4 + +#elif STM32_I2C4SEL == STM32_I2C4SEL_PLL3_R_CK +#define STM32_I2C4CLK STM32_PLL3_R_CK +#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI_KER_CK +#define STM32_I2C4CLK STM32_HSI_CK +#elif STM32_I2C4SEL == STM32_I2C4SEL_CSI_KER_CK +#define STM32_I2C4CLK STM32_CSI_CK +#else +#error "invalid source selected for STM32_I2C4SEL clock" +#endif + +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SAI1 clock. + */ +#define STM32_SAI1CLK STM32_PLL1_Q_CK + +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL2_P_CK +#define STM32_SAI1CLK STM32_PLL2_P_CK +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL3_P_CK +#define STM32_SAI1CLK STM32_PLL3_P_CK +#elif STM32_SAI1SEL == STM32_SAI1SEL_I2S_CKIN +#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ +#elif STM32_SAI1SEL == STM32_SAI1SEL_PER_CK +#define STM32_SAI1CLK STM32_PER_CK +#else +#error "invalid source selected for STM32_SAI1SEL clock" +#endif + +#if (STM32_SAI23SEL == STM32_SAI23SEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SAI2 clock. + */ +#define STM32_SAI2CLK STM32_PLL1_Q_CK + +/** + * @brief SAI3 clock. + */ +#define STM32_SAI3CLK STM32_PLL1_Q_CK + +#elif STM32_SAI23SEL == STM32_SAI23SEL_PLL2_P_CK +#define STM32_SAI2CLK STM32_PLL2_P_CK +#define STM32_SAI3CLK STM32_PLL2_P_CK +#elif STM32_SAI23SEL == STM32_SAI23SEL_PLL3_P_CK +#define STM32_SAI2CLK STM32_PLL3_P_CK +#define STM32_SAI3CLK STM32_PLL3_P_CK +#elif STM32_SAI23SEL == STM32_SAI23SEL_I2S_CKIN +#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ +#define STM32_SAI3CLK 0 /* Unknown, would require a board value */ +#elif STM32_SAI23SEL == STM32_SAI23SEL_PER_CK +#define STM32_SAI2CLK STM32_PER_CK +#define STM32_SAI3CLK STM32_PER_CK +#else +#error "invalid source selected for STM32_SAI23SEL clock" +#endif + +#if (STM32_SAI4ASEL == STM32_SAI4ASEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SAI4A clock. + */ +#define STM32_SAI4ACLK STM32_PLL1_Q_CK + +#elif STM32_SAI4ASEL == STM32_SAI4ASEL_PLL2_P_CK +#define STM32_SAI4ACLK STM32_PLL2_P_CK +#elif STM32_SAI4ASEL == STM32_SAI4ASEL_PLL3_P_CK +#define STM32_SAI4ACLK STM32_PLL3_P_CK +#elif STM32_SAI4ASEL == STM32_SAI4ASEL_I2S_CKIN +#define STM32_SAI4ACLK 0 /* Unknown, would require a board value */ +#elif STM32_SAI4ASEL == STM32_SAI4ASEL_PER_CK +#define STM32_SAI4ACLK STM32_PER_CK +#else +#error "invalid source selected for STM32_SAI4ASEL clock" +#endif + +#if (STM32_SAI4BSEL == STM32_SAI4BSEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SAI4B clock. + */ +#define STM32_SAI4BCLK STM32_PLL1_Q_CK + +#elif STM32_SAI4BSEL == STM32_SAI4BSEL_PLL2_P_CK +#define STM32_SAI4BCLK STM32_PLL2_P_CK +#elif STM32_SAI4BSEL == STM32_SAI4BSEL_PLL3_P_CK +#define STM32_SAI4BCLK STM32_PLL3_P_CK +#elif STM32_SAI4BSEL == STM32_SAI4BSEL_I2S_CKIN +#define STM32_SAI4BCLK 0 /* Unknown, would require a board value */ +#elif STM32_SAI4BSEL == STM32_SAI4BSEL_PER_CK +#define STM32_SAI4BCLK STM32_PER_CK +#else +#error "invalid source selected for STM32_SAI4BSEL clock" +#endif + +#if (STM32_USBSEL == STM32_USBSEL_DISABLE) || defined(__DOXYGEN__) +/** + * @brief USB clock. + */ +#define STM32_USBCLK 0 + +#elif STM32_USBSEL == STM32_USBSEL_PLL1_Q_CK +#define STM32_USBCLK STM32_PLL1_Q_CK +#elif STM32_USBSEL == STM32_USBSEL_PLL3_Q_CK +#define STM32_USBCLK STM32_PLL3_Q_CK +#elif STM32_USBSEL == STM32_USBSEL_HSI48_CK +#define STM32_USBCLK STM32_HSI48_CK +#else +#error "invalid source selected for STM32_USBSEL clock" +#endif + +#if (STM32_SDMMCSEL == STM32_SDMMCSEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SDMMC1 frequency. + */ +#define STM32_SDMMC1CLK STM32_PLL1_Q_CK + +/** + * @brief SDMMC2 frequency. + */ +#define STM32_SDMMC2CLK STM32_PLL1_Q_CK + +#elif STM32_SDMMCSEL == STM32_SDMMCSEL_PLL2_R_CK +#define STM32_SDMMC1CLK STM32_PLL2_R_CK +#define STM32_SDMMC2CLK STM32_PLL2_R_CK +#else +#error "invalid source selected for STM32_SDMMCxSEL clock" +#endif + +#if (STM32_QSPISEL == STM32_QSPISEL_HCLK) || defined(__DOXYGEN__) +/** + * @brief QSPI frequency. + */ +#define STM32_QSPICLK STM32_HCLK + +#elif STM32_QSPISEL == STM32_QSPISEL_PLL1_Q_CK +#define STM32_QSPICLK STM32_PLL1_Q_CK +#elif STM32_QSPISEL == STM32_QSPISEL_PLL2_R_CK +#define STM32_QSPICLK STM32_PLL2_R_CK +#elif STM32_QSPISEL == STM32_QSPISEL_PER_CK +#define STM32_QSPICLK STM32_PER_CK +#else +#error "invalid source selected for STM32_QSPISEL clock" +#endif + +#if (STM32_FMCSEL == STM32_FMCSEL_HCLK) || defined(__DOXYGEN__) +/** + * @brief FMC frequency. + */ +#define STM32_FMCCLK STM32_HCLK + +#elif STM32_FMCSEL == STM32_FMCSEL_PLL1_Q_CK +#define STM32_FMCCLK STM32_PLL1_Q_CK +#elif STM32_FMCSEL == STM32_FMCSEL_PLL2_R_CK +#define STM32_FMCCLK STM32_PLL2_R_CK +#elif STM32_FMCSEL == STM32_FMCSEL_PER_CK +#define STM32_FMCCLK STM32_PER_CK +#else +#error "invalid source selected for STM32_FMCSEL clock" +#endif + +#if (STM32_SWPSEL == STM32_SWPSEL_PCLK1) || defined(__DOXYGEN__) +/** + * @brief SDMMC frequency. + */ +#define STM32_SWPCLK STM32_PCLK1 + +#elif STM32_SWPSEL == STM32_SWPSEL_HSI_KER_CK +#define STM32_SWPCLK STM32_HSI_CK +#else +#error "invalid source selected for STM32_SWPSEL clock" +#endif + +#if (STM32_FDCANSEL == STM32_FDCANSEL_HSE_CK) || defined(__DOXYGEN__) +/** + * @brief FDCAN frequency. + */ +#define STM32_FDCANCLK STM32_HSE_CK + +#elif STM32_FDCANSEL == STM32_FDCANSEL_PLL1_Q_CK +#define STM32_FDCANCLK STM32_PLL1_Q_CK +#elif STM32_FDCANSEL == STM32_FDCANSEL_PLL2_Q_CK +#define STM32_FDCANCLK STM32_PLL2_Q_CK +#else +#error "invalid source selected for STM32_FDCANSEL clock" +#endif + +#if (STM32_DFSDM1SEL == STM32_DFSDM1SEL_PCLK2) || defined(__DOXYGEN__) +/** + * @brief SDMMC frequency. + */ +#define STM32_DFSDM1CLK STM32_PCLK2 + +#elif STM32_DFSDM1SEL == STM32_DFSDM1SEL_SYS_CK +#define STM32_DFSDM1CLK STM32_SYS_CK +#else +#error "invalid source selected for STM32_DFSDM1SEL clock" +#endif + +#if (STM32_SPDIFSEL == STM32_SPDIFSEL_PLL1_Q_CK) || defined(__DOXYGEN__) +/** + * @brief SPDIF frequency. + */ +#define STM32_SPDIFCLK STM32_PLL1_Q_CK + +#elif STM32_SPDIFSEL == STM32_SPDIFSEL_PLL2_R_CK +#define STM32_SPDIFCLK STM32_PLL2_R_CK +#elif STM32_SPDIFSEL == STM32_SPDIFSEL_PLL3_R_CK +#define STM32_SPDIFCLK STM32_PLL3_R_CK +#elif STM32_SPDIFSEL == STM32_SPDIFSEL_HSI_KET_CLK +#define STM32_SPDIFCLK STM32_HSI_CK +#else +#error "invalid source selected for STM32_SPDIFSEL clock" +#endif + +#if (STM32_CECSEL == STM32_CECSEL_LSE_CK) || defined(__DOXYGEN__) +/** + * @brief CEC frequency. + */ +#define STM32_CECCLK STM32_LSE_CK + +#elif STM32_CECSEL == STM32_CECSEL_LSI_CK +#define STM32_CECCLK STM32_LSI_CK +#elif STM32_CECSEL == STM32_CECSEL_CSI_KER_CK +#define STM32_CECCLK STM32_CSI_CK +#elif STM32_CECSEL == STM32_CECSEL_DISABLE +#define STM32_CECCLK 0 +#else +#error "invalid source selected for STM32_CECSEL clock" +#endif + +#if (STM32_RNGSEL == STM32_RNGSEL_HSI48_CK) || defined(__DOXYGEN__) +/** + * @brief RNG frequency. + */ +#define STM32_RNGCLK STM32_HSI48_CK + +#elif STM32_RNGSEL == STM32_RNGSEL_PLL1_Q_CK +#define STM32_RNGCLK STM32_PLL1_Q_CK +#elif STM32_RNGSEL == STM32_RNGSEL_LSE_CK +#define STM32_RNGCLK STM32_LSE_CK +#elif STM32_RNGSEL == STM32_RNGSEL_LSI_CK +#define STM32_RNGCLK STM32_LSI_CK +#else +#error "invalid source selected for STM32_RNGSEL clock" +#endif + +#if (STM32_ADCSEL == STM32_ADCSEL_PLL2_P_CK) || defined(__DOXYGEN__) +/** + * @brief ADC frequency. + */ +#define STM32_ADCCLK STM32_PLL2_P_CK + +#elif STM32_ADCSEL == STM32_ADCSEL_PLL3_R_CK +#define STM32_ADCCLK STM32_PLL3_R_CK +#elif STM32_ADCSEL == STM32_ADCSEL_PER_CK +#define STM32_ADCCLK STM32_PER_CK +#elif STM32_ADCSEL == STM32_ADCSEL_DISABLE +#define STM32_ADCCLK 0 +#else +#error "invalid source selected for STM32_ADCSEL clock" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_mdma.h" +#include "stm32_dma.h" +#include "stm32_bdma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.c b/os/hal/ports/STM32/STM32L0xx/hal_lld.c index 43ab11bf96..95b4adafb5 100644 --- a/os/hal/ports/STM32/STM32L0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.c @@ -1,269 +1,269 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L0xx/hal_lld.c - * @brief STM32L0xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32l0xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->CSR |= RCC_CSR_RTCRST; - RCC->CSR &= ~RCC_CSR_RTCRST; - } - - /* If enabled then the LSE is started.*/ -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - RCC->CSR |= RCC_CSR_LSEON; - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->CSR & RCC_CSR_LSERDY) == 0) - ; -#endif - -#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { - /* Selects clock source.*/ - RCC->CSR |= STM32_RTCSEL; -#if STM32_LSE_ENABLED - RCC->CSR |= (RCC->CSR & RCC_CSR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->CSR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->CSR |= RCC_CSR_RTCEN; - } -#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals except those on IOP.*/ - rccResetAHB(~RCC_AHBRSTR_MIFRST); - rccResetAPB1(~RCC_APB1RSTR_PWRRST); - rccResetAPB2(~0); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ -} - -/** - * @brief STM32L0xx voltage, clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -/** - * @brief Clocks and internal voltage initialization. - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enable.*/ - RCC->APB1ENR = RCC_APB1ENR_PWREN; - - /* Core voltage setup.*/ - while ((PWR->CSR & PWR_CSR_VOSF) != 0) - ; /* Waits until regulator is stable. */ - PWR->CR = STM32_VOS; - while ((PWR->CSR & PWR_CSR_VOSF) != 0) - ; /* Waits until regulator is stable. */ - - /* Initial clocks setup and wait for MSI stabilization, the MSI clock is - always enabled because it is the fallback clock when PLL the fails. - Trim fields are not altered from reset values.*/ - RCC->CFGR = 0; - RCC->ICSCR = (RCC->ICSCR & ~STM32_MSIRANGE_MASK) | STM32_MSIRANGE; - RCC->CR = RCC_CR_MSION; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; /* Waits until MSI is stable. */ - -#if STM32_HSI16_ENABLED - /* HSI activation.*/ - RCC->CR |= RCC_CR_HSION; - while ((RCC->CR & RCC_CR_HSIRDY) == 0) - ; /* Waits until HSI16 is stable. */ - -#if STM32_HSI16_DIVIDER_ENABLED - RCC->CR |= RCC_CR_HSIDIVEN; - while ((RCC->CR & RCC_CR_HSIDIVF) == 0) - ; -#endif -#endif - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - -#if STM32_LSE_ENABLED - /* LSE activation, have to unlock the register.*/ - if ((RCC->CSR & RCC_CSR_LSEON) == 0) { - PWR->CR |= PWR_CR_DBP; -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->CSR |= STM32_LSEDRV | RCC_CSR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->CSR |= STM32_LSEDRV; -#endif - RCC->CSR |= RCC_CSR_LSEON; - PWR->CR &= ~PWR_CR_DBP; - } - while ((RCC->CSR & RCC_CSR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CFGR |= STM32_PLLDIV | STM32_PLLMUL | STM32_PLLSRC; - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL is stable. */ -#endif - -#if STM32_ACTIVATE_HSI48 - /* Enabling SYSCFG clock. */ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); - /* Configuring SYSCFG to enable VREFINT and HSI48 VREFINT buffer. */ - SYSCFG->CFGR3 = STM32_VREFINT_EN | SYSCFG_CFGR3_ENREF_HSI48; - - while (!(SYSCFG->CFGR3 & SYSCFG_CFGR3_VREFINT_RDYF)) - ; /* Waits until VREFINT is stable. */ - /* Disabling SYSCFG clock. */ - rccDisableAPB2(RCC_APB2ENR_SYSCFGEN); - - /* Enabling HSI48. */ - RCC->CRRCR |= RCC_CRRCR_HSI48ON; - while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) - ; /* Waits until HSI48 is stable. */ -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CR |= STM32_RTCPRE; - RCC->CFGR |= STM32_MCOPRE | STM32_MCOSEL | - STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; - RCC->CSR |= STM32_RTCSEL; - - /* Flash setup and final clock selection.*/ -#if defined(STM32_FLASHBITS) - FLASH->ACR = STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } -#endif - - /* Switching to the configured clock source if it is different from MSI. */ -#if (STM32_SW != STM32_SW_MSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif - - /* Peripherals clock sources setup.*/ - RCC->CCIPR = STM32_HSI48SEL | STM32_LPTIM1SEL | STM32_I2C1SEL | - STM32_LPUART1SEL | STM32_USART2SEL | STM32_USART1SEL; - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -#endif /* STM32_NO_INIT */ -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L0xx/hal_lld.c + * @brief STM32L0xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32l0xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->CSR |= RCC_CSR_RTCRST; + RCC->CSR &= ~RCC_CSR_RTCRST; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; + RCC->CSR |= RCC_CSR_LSEON; + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->CSR & RCC_CSR_LSERDY) == 0) + ; +#endif + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { + /* Selects clock source.*/ + RCC->CSR |= STM32_RTCSEL; +#if STM32_LSE_ENABLED + RCC->CSR |= (RCC->CSR & RCC_CSR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->CSR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->CSR |= RCC_CSR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals except those on IOP.*/ + rccResetAHB(~RCC_AHBRSTR_MIFRST); + rccResetAPB1(~RCC_APB1RSTR_PWRRST); + rccResetAPB2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32L0xx voltage, clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +/** + * @brief Clocks and internal voltage initialization. + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ + RCC->APB1ENR = RCC_APB1ENR_PWREN; + + /* Core voltage setup.*/ + while ((PWR->CSR & PWR_CSR_VOSF) != 0) + ; /* Waits until regulator is stable. */ + PWR->CR = STM32_VOS; + while ((PWR->CSR & PWR_CSR_VOSF) != 0) + ; /* Waits until regulator is stable. */ + + /* Initial clocks setup and wait for MSI stabilization, the MSI clock is + always enabled because it is the fallback clock when PLL the fails. + Trim fields are not altered from reset values.*/ + RCC->CFGR = 0; + RCC->ICSCR = (RCC->ICSCR & ~STM32_MSIRANGE_MASK) | STM32_MSIRANGE; + RCC->CR = RCC_CR_MSION; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; /* Waits until MSI is stable. */ + +#if STM32_HSI16_ENABLED + /* HSI activation.*/ + RCC->CR |= RCC_CR_HSION; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Waits until HSI16 is stable. */ + +#if STM32_HSI16_DIVIDER_ENABLED + RCC->CR |= RCC_CR_HSIDIVEN; + while ((RCC->CR & RCC_CR_HSIDIVF) == 0) + ; +#endif +#endif + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_LSE_ENABLED + /* LSE activation, have to unlock the register.*/ + if ((RCC->CSR & RCC_CSR_LSEON) == 0) { + PWR->CR |= PWR_CR_DBP; +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->CSR |= STM32_LSEDRV | RCC_CSR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->CSR |= STM32_LSEDRV; +#endif + RCC->CSR |= RCC_CSR_LSEON; + PWR->CR &= ~PWR_CR_DBP; + } + while ((RCC->CSR & RCC_CSR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CFGR |= STM32_PLLDIV | STM32_PLLMUL | STM32_PLLSRC; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + +#if STM32_ACTIVATE_HSI48 + /* Enabling SYSCFG clock. */ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); + /* Configuring SYSCFG to enable VREFINT and HSI48 VREFINT buffer. */ + SYSCFG->CFGR3 = STM32_VREFINT_EN | SYSCFG_CFGR3_ENREF_HSI48; + + while (!(SYSCFG->CFGR3 & SYSCFG_CFGR3_VREFINT_RDYF)) + ; /* Waits until VREFINT is stable. */ + /* Disabling SYSCFG clock. */ + rccDisableAPB2(RCC_APB2ENR_SYSCFGEN); + + /* Enabling HSI48. */ + RCC->CRRCR |= RCC_CRRCR_HSI48ON; + while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) + ; /* Waits until HSI48 is stable. */ +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CR |= STM32_RTCPRE; + RCC->CFGR |= STM32_MCOPRE | STM32_MCOSEL | + STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + RCC->CSR |= STM32_RTCSEL; + + /* Flash setup and final clock selection.*/ +#if defined(STM32_FLASHBITS) + FLASH->ACR = STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } +#endif + + /* Switching to the configured clock source if it is different from MSI. */ +#if (STM32_SW != STM32_SW_MSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif + + /* Peripherals clock sources setup.*/ + RCC->CCIPR = STM32_HSI48SEL | STM32_LPTIM1SEL | STM32_I2C1SEL | + STM32_LPUART1SEL | STM32_USART2SEL | STM32_USART1SEL; + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +#endif /* STM32_NO_INIT */ +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.h b/os/hal/ports/STM32/STM32L0xx/hal_lld.h index 0c89bd0135..e673a73e75 100644 --- a/os/hal/ports/STM32/STM32L0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.h @@ -1,1253 +1,1257 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L0xx/hal_lld.h - * @brief STM32L0xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32L011xx, STM32L031xx, - * STM32L051xx, STM32L052xx, STM32L053xx, - * STM32L061xx, STM32L062xx, STM32L063xx, - * STM32L071xx, STM32L072xx, STM32L073xx for ultra-low-power MCUs. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -/* - * Registry definitions. - */ -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification macros - * @{ - */ -#if defined(STM32L011xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32L011xx ultra-low-power MCU" - -#elif defined(STM32L031xx) -#define PLATFORM_NAME "STM32L031xx ultra-low-power MCU" - -#elif defined(STM32L051xx) -#define PLATFORM_NAME "STM32L051xx ultra-low-power MCU" - -#elif defined(STM32L052xx) -#define PLATFORM_NAME "STM32L052xx ultra-low-power MCU" - -#elif defined(STM32L053xx) -#define PLATFORM_NAME "STM32L053xx ultra-low-power MCU" - -#elif defined(STM32L061xx) -#define PLATFORM_NAME "STM32L061xx ultra-low-power MCU" - -#elif defined(STM32L062xx) -#define PLATFORM_NAME "STM32L062xx ultra-low-power MCU" - -#elif defined(STM32L063xx) -#define PLATFORM_NAME "STM32L063xx ultra-low-power MCU" - -#elif defined(STM32L071xx) -#define PLATFORM_NAME "STM32L071xx ultra-low-power MCU" - -#elif defined(STM32L072xx) -#define PLATFORM_NAME "STM32L073xx ultra-low-power MCU" - -#elif defined(STM32L073xx) -#define PLATFORM_NAME "STM32L073xx ultra-low-power MCU" - -#else -#error "STM32L0xx device not specified" -#endif -/** @} */ - -/** - * @name Sub-family identifier - */ -#if !defined(STM32L0XX) || defined(__DOXYGEN__) -#define STM32L0XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ -#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ -#define STM32_LSICLK 37000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 5) /**< PLS field mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_EXT (7 << 5) /**< PVD level 7. */ - -#define STM32_VOS_MASK (3 << 11) /**< VOS field mask. */ -#define STM32_VOS_1P8 (1 << 11) /**< VOS level 1.8 volts. */ -#define STM32_VOS_1P5 (2 << 11) /**< VOS level 1.5 volts. */ -#define STM32_VOS_1P2 (3 << 11) /**< VOS level 1.2 volts. */ -/** @} */ - -/** - * @name RCC_CR register bits definitions - * @{ - */ -#define STM32_RTCPRE_MASK (3 << 20) /**< RTCPRE mask. */ -#define STM32_RTCPRE_DIV2 (0 << 20) /**< HSE divided by 2. */ -#define STM32_RTCPRE_DIV4 (1 << 20) /**< HSE divided by 4. */ -#define STM32_RTCPRE_DIV8 (2 << 20) /**< HSE divided by 2. */ -#define STM32_RTCPRE_DIV16 (3 << 20) /**< HSE divided by 16. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ -#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ -#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI16 */ -#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 8) /**< PPRE2 field mask. */ -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_STOPWUCK_MASK (1 << 15) /**< PLLDIV field mask. */ -#define STM32_STOPWUCK_MSI (0 << 15) /**< MSI is wakeup clock. */ -#define STM32_STOPWUCK_HSI16 (1 << 15) /**< HSI16 is wakeup clock. */ - -#define STM32_PLLSRC_MASK (1 << 16) /**< PLLSRC field mask. */ -#define STM32_PLLSRC_HSI16 (0 << 16) /**< PLL clock source is HSI16. */ -#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ - -#define STM32_PLLMUL_MASK (15 << 18) /**< PLLMUL field mask. */ -#define STM32_PLLMUL_MUL3 (0 << 18) /**< PLL multiplier is 3. */ -#define STM32_PLLMUL_MUL4 (1 << 18) /**< PLL multiplier is 4. */ -#define STM32_PLLMUL_MUL6 (2 << 18) /**< PLL multiplier is 6. */ -#define STM32_PLLMUL_MUL8 (3 << 18) /**< PLL multiplier is 8. */ -#define STM32_PLLMUL_MUL12 (4 << 18) /**< PLL multiplier is 12. */ -#define STM32_PLLMUL_MUL16 (5 << 18) /**< PLL multiplier is 16. */ -#define STM32_PLLMUL_MUL24 (6 << 18) /**< PLL multiplier is 24. */ -#define STM32_PLLMUL_MUL32 (7 << 18) /**< PLL multiplier is 32. */ -#define STM32_PLLMUL_MUL48 (8 << 18) /**< PLL multiplier is 48. */ - -#define STM32_PLLDIV_MASK (3 << 22) /**< PLLDIV field mask. */ -#define STM32_PLLDIV_DIV2 (1 << 22) /**< PLL divided by 2. */ -#define STM32_PLLDIV_DIV3 (2 << 22) /**< PLL divided by 3. */ -#define STM32_PLLDIV_DIV4 (3 << 22) /**< PLL divided by 4. */ - -#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI16 (2 << 24) /**< HSI16 clock on MCO pin. */ -#define STM32_MCOSEL_MSI (3 << 24) /**< MSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ - -#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ -#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO is divided by 1. */ -#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO is divided by 1. */ -#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO is divided by 1. */ -#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO is divided by 1. */ -#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO is divided by 1. */ -/** @} */ - -/** - * @name RCC_ICSCR register bits definitions - * @{ - */ -#define STM32_MSIRANGE_MASK (7 << 13) /**< MSIRANGE field mask. */ -#define STM32_MSIRANGE_64K (0 << 13) /**< 64kHz nominal. */ -#define STM32_MSIRANGE_128K (1 << 13) /**< 128kHz nominal. */ -#define STM32_MSIRANGE_256K (2 << 13) /**< 256kHz nominal. */ -#define STM32_MSIRANGE_512K (3 << 13) /**< 512kHz nominal. */ -#define STM32_MSIRANGE_1M (4 << 13) /**< 1MHz nominal. */ -#define STM32_MSIRANGE_2M (5 << 13) /**< 2MHz nominal. */ -#define STM32_MSIRANGE_4M (6 << 13) /**< 4MHz nominal */ -/** @} */ - -/** - * @name RCC_CSR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 16) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 16) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 16) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 16) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 16) /**< RTC source is HSE divided. */ -/** @} */ - -/** - * @name RCC_CCIPR register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3 << 0) /**< USART1 clock source mask. */ -#define STM32_USART1SEL_APB (0 << 0) /**< USART1 clock is APB. */ -#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */ -#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 clock is HSI16. */ -#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 clock is LSE. */ - -#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 clock source mask. */ -#define STM32_USART2SEL_APB (0 << 2) /**< USART2 clock is APB. */ -#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 clock is SYSCLK. */ -#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 clock is HSI16. */ -#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 clock is LSE. */ - -#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 clock source mask. */ -#define STM32_LPUART1SEL_APB (0 << 10) /**< LPUART1 clock is APB. */ -#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 clock is SYSCLK. */ -#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 clock is HSI16. */ -#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 clock is LSE. */ - -#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1 clock source mask. */ -#define STM32_I2C1SEL_APB (0 << 12) /**< I2C1 clock is APB. */ -#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 clock is SYSCLK. */ -#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 clock is HSI16. */ - -#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3 clock source mask. */ -#define STM32_I2C3SEL_APB (0 << 16) /**< I2C3 clock is APB. */ -#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 clock is SYSCLK. */ -#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 clock is HSI16. */ - -#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1 clock source mask. */ -#define STM32_LPTIM1SEL_APB (0 << 18) /**< LPTIM1 clock is APB. */ -#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 clock is LSI. */ -#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 clock is HSI16. */ -#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 clock is LSE. */ - -#define STM32_HSI48SEL_MASK (1 << 26) /**< HSI48SEL clock source mask.*/ -#define STM32_HSI48SEL_USBPLL (0 << 26) /**< USB48 clock is PLL/2. */ -#define STM32_HSI48SEL_HSI48 (1 << 26) /**< USB48 clock is HSI48. */ -/** @} */ - -/** - * @name SYSCFG_CFGR3_ register bits definitions - * @{ - */ -#define STM32_VREFINT_EN (1 << 0) /**< VREFINT enable switch. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_1P8 -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI16 clock source. - */ -#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSI16 clock divider. - */ -#if !defined(STM32_HSI16_DIVIDER_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_DIVIDER_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief ADC clock setting. - */ -#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_ADC_CLOCK_ENABLED TRUE -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_ENABLED TRUE -#endif - -/** - * @brief MSI frequency setting. - */ -#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) -#define STM32_MSIRANGE STM32_MSIRANGE_2M -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSI16 -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed values are 3, 4, 6, 8, 12, 16, 32, 48. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 4 -#endif - -/** - * @brief PLL divider value. - * @note The allowed values are 2, 3, 4. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLDIV_VALUE 2 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief RTC/LCD clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif - -/** - * @brief HSE divider toward RTC setting. - */ -#if !defined(STM32_RTCPRE) || defined(__DOXYGEN__) -#define STM32_RTCPRE STM32_RTCPRE_DIV2 -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_APB -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_APB -#endif - -/** - * @brief LPUART1 clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_APB -#endif - -/** - * @brief I2C clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_APB -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_APB -#endif - -/** - * @bief USB/RNG clock source. - */ -#if !defined(STM32_HSI48SEL) || defined(__DOXYGEN__) -#define STM32_HSI48SEL STM32_HSI48SEL_USBPLL -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32L0xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L0xx_MCUCONF not defined" -#endif - -#if defined(STM32L052xx) && !defined(STM32L052_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L052_MCUCONF not defined" - -#elif defined(STM32L053xx) && !defined(STM32L053_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L053_MCUCONF not defined" - -#elif defined(STM32L072xx) && !defined(STM32L072_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L072_MCUCONF not defined" - -#elif defined(STM32L073xx) && !defined(STM32L073_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L073_MCUCONF not defined" - -#endif - -/* - * Board files sanity checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif - -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_1P8) || defined(__DOXYGEN__) -/** - * @name Absolute Maximum Ratings - * @{ - */ -/** - * @brief Maximum SYSCLK clock frequency at current voltage setting. - */ -#define STM32_SYSCLK_MAX 32000000 - -/** - * @brief Maximum HSE clock frequency at current voltage setting. - */ -#define STM32_HSECLK_MAX 32000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 1000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 1000 - -/** - * @brief Maximum PLL input frequency. - */ -#define STM32_PLLIN_MAX 24000000 - -/** - * @brief Maximum PLL input frequency. - */ -#define STM32_PLLIN_MIN 2000000 - -/** - * @brief Maximum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MAX 96000000 - -/** - * @brief Minimum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MIN 6000000 - -/** - * @brief Maximum PLL output frequency. - */ -#define STM32_PLLOUT_MAX 32000000 - -/** - * @brief Maximum PLL output frequency. - */ -#define STM32_PLLOUT_MIN 2000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 32000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 32000000 - -/** - * @brief Maximum frequency not requiring a wait state for flash accesses. - */ -#define STM32_0WS_THRESHOLD 16000000 - -/** - * @brief HSI availability at current voltage settings. - */ -#define STM32_HSI_AVAILABLE TRUE -/** @} */ - -#elif STM32_VOS == STM32_VOS_1P5 -#define STM32_SYSCLK_MAX 16000000 -#define STM32_HSECLK_MAX 16000000 -#define STM32_HSECLK_MIN 1000000 -#define STM32_LSECLK_MAX 1000000 -#define STM32_LSECLK_MIN 1000 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLIN_MIN 2000000 -#define STM32_PLLVCO_MAX 48000000 -#define STM32_PLLVCO_MIN 6000000 -#define STM32_PLLOUT_MAX 16000000 -#define STM32_PLLOUT_MIN 2000000 -#define STM32_PCLK1_MAX 16000000 -#define STM32_PCLK2_MAX 16000000 -#define STM32_0WS_THRESHOLD 8000000 -#define STM32_HSI_AVAILABLE TRUE -#elif STM32_VOS == STM32_VOS_1P2 -#define STM32_SYSCLK_MAX 4000000 -#define STM32_HSECLK_MAX 8000000 -#define STM32_HSECLK_MIN 1000000 -#define STM32_LSECLK_MAX 1000000 -#define STM32_LSECLK_MIN 1000 -#define STM32_PLLIN_MAX 8000000 -#define STM32_PLLIN_MIN 2000000 -#define STM32_PLLVCO_MAX 24000000 -#define STM32_PLLVCO_MIN 6000000 -#define STM32_PLLOUT_MAX 4000000 -#define STM32_PLLOUT_MIN 2000000 -#define STM32_PCLK1_MAX 4000000 -#define STM32_PCLK2_MAX 4000000 -#define STM32_0WS_THRESHOLD 4000000 -#define STM32_HSI_AVAILABLE FALSE -#else -#error "invalid STM32_VOS value specified" -#endif - -/* HSI related checks.*/ -#if STM32_HSI16_ENABLED -#if !STM32_HSI_AVAILABLE - #error "impossible to activate HSI under the current voltage settings" -#endif -#else /* !STM32_HSI16_ENABLED */ - -#if STM32_ADC_CLOCK_ENABLED -#error "HSI16 not enabled, required by STM32_ADC_CLOCK_ENABLED" -#endif - -#if (STM32_SW == STM32_SW_HSI16) -#error "HSI16 not enabled, required by STM32_SW" -#endif - -#if ((STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16)) -#error "HSI16 not enabled, required by STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) -#error "HSI16 not enabled, required by STM32_MCOSEL" -#endif - -#if ((STM32_MCOSEL == STM32_MCOSEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16)) -#error "HSI16 not enabled, required by STM32_PLLSRC" -#endif - -#endif /* !STM32_HSI16_ENABLED */ - -/* - * @brief Divided HSI16 clock. - */ -#if STM32_HSI16_DIVIDER_ENABLED || defined(__DOXYGEN__) -#define STM32_HSI16DIVCLK (STM32_HSI16CLK / 4) -#else -#define STM32_HSI16DIVCLK STM32_HSI16CLK -#endif - -/* HSE related checks.*/ -#if STM32_HSE_ENABLED -#if STM32_HSECLK == 0 -#error "impossible to activate HSE, frequency is zero" -#endif -#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" -#endif -#else /* !STM32_HSE_ENABLED */ - -#if (STM32_SW == STM32_SW_HSE) -#error "HSE not enabled, required by STM32_SW" -#endif - -#if ((STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSE) -#error "HSE not enabled, required by STM32_MCOSEL" -#endif - -#if ((STM32_MCOSEL == STM32_MCOSEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE)) -#error "HSE not enabled, required by STM32_PLLSRC" -#endif - -#if (STM32_RTCSEL == STM32_RTCSEL_HSEDIV) -#error "HSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_HSE_ENABLED */ - -/* LSI related checks.*/ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_LSI -#error "LSI not enabled, required by STM32_MCOSEL" -#endif - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* LSE related checks.*/ -#if STM32_LSE_ENABLED -#if (STM32_LSECLK == 0) -#error "impossible to activate LSE, frequency is zero" -#endif -#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) -#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" -#endif -#else /* !STM32_LSE_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_LSE -#error "LSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL related checks.*/ -#if (STM32_SW == STM32_SW_PLL) || (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - (STM32_USB_CLOCK_ENABLED && (STM32_HSI48SEL == STM32_HSI48SEL_USBPLL)) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/* HSI48 related checks.*/ -#if (STM32_USB_CLOCK_ENABLED && (STM32_HSI48SEL == STM32_HSI48SEL_HSI48)) || \ - defined(__DOXYGEN__) -/** - * @brief HSI48 activation flag. - */ -#define STM32_ACTIVATE_HSI48 TRUE -#else -#define STM32_ACTIVATE_HSI48 FALSE -#endif - -/** - * @brief PLLMUL field. - */ -#if (STM32_PLLMUL_VALUE == 3) || defined(__DOXYGEN__) -#define STM32_PLLMUL STM32_PLLMUL_MUL3 -#elif STM32_PLLMUL_VALUE == 4 -#define STM32_PLLMUL STM32_PLLMUL_MUL4 -#elif STM32_PLLMUL_VALUE == 6 -#define STM32_PLLMUL STM32_PLLMUL_MUL6 -#elif STM32_PLLMUL_VALUE == 8 -#define STM32_PLLMUL STM32_PLLMUL_MUL8 -#elif STM32_PLLMUL_VALUE == 12 -#define STM32_PLLMUL STM32_PLLMUL_MUL12 -#elif STM32_PLLMUL_VALUE == 16 -#define STM32_PLLMUL STM32_PLLMUL_MUL16 -#elif STM32_PLLMUL_VALUE == 24 -#define STM32_PLLMUL STM32_PLLMUL_MUL24 -#elif STM32_PLLMUL_VALUE == 32 -#define STM32_PLLMUL STM32_PLLMUL_MUL32 -#elif STM32_PLLMUL_VALUE == 48 -#define STM32_PLLMUL STM32_PLLMUL_MUL48 -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLLDIV field. - */ -#if (STM32_PLLDIV_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLDIV STM32_PLLDIV_DIV2 -#elif STM32_PLLDIV_VALUE == 3 -#define STM32_PLLDIV STM32_PLLDIV_DIV3 -#elif STM32_PLLDIV_VALUE == 4 -#define STM32_PLLDIV STM32_PLLDIV_DIV4 -#else -#error "invalid STM32_PLLDIV_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN STM32_HSECLK -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 -#define STM32_PLLCLKIN STM32_HSI16DIVCLK -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLDIV_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) -#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" -#endif - -/** - * @brief MSI frequency. - * @note Values are taken from the STM8Lxx datasheet. - */ -#if STM32_MSIRANGE == STM32_MSIRANGE_64K -#define STM32_MSICLK 65500 -#elif STM32_MSIRANGE == STM32_MSIRANGE_128K -#define STM32_MSICLK 131000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_256K -#define STM32_MSICLK 262000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_512K -#define STM32_MSICLK 524000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_1M -#define STM32_MSICLK 1050000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_2M -#define STM32_MSICLK 2100000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_4M -#define STM32_MSICLK 4200000 -#else -#error "invalid STM32_MSIRANGE value specified" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK 2100000 -#elif (STM32_SW == STM32_SW_MSI) -#define STM32_SYSCLK STM32_MSICLK -#elif (STM32_SW == STM32_SW_HSI16) -#define STM32_SYSCLK STM32_HSI16DIVCLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief MCO selector clock. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK -#define STM32_MCODIVCLK STM32_SYSCLK -#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 -#define STM32_MCODIVCLK STM32_HSI16DIVCLK -#elif STM32_MCOSEL == STM32_MCOSEL_MSI -#define STM32_MCODIVCLK STM32_MSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK -#elif STM32_MCOSEL == STM32_MCOSEL_PLL -#define STM32_MCODIVCLK STM32_PLLCLKOUT -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK -#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 -#define STM32_MCODIVCLK STM32_HSI48CLK -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief HSE divider toward RTC clock. - */ -#if (STM32_RTCPRE == STM32_RTCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 2) -#elif (STM32_RTCPRE == STM32_RTCPRE_DIV4) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 4) -#elif (STM32_RTCPRE == STM32_RTCPRE_DIV8) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 8) -#elif (STM32_RTCPRE == STM32_RTCPRE_DIV16) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 16) -#else -#error "invalid STM32_RTCPRE value specified" -#endif - -/** - * @brief RTC/LCD clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK STM32_HSEDIVCLK -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_APB) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK2 -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 -#define STM32_USART1CLK STM32_HSI16DIVCLK -#elif STM32_USART1SEL == STM32_USART1SEL_LSE -#define STM32_USART1CLK STM32_LSECLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 frequency. - */ -#if (STM32_USART2SEL == STM32_USART2SEL_APB) || defined(__DOXYGEN__) -#define STM32_USART2CLK STM32_PCLK1 -#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK -#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 -#define STM32_USART2CLK STM32_HSI16DIVCLK -#elif STM32_USART2SEL == STM32_USART2SEL_LSE -#define STM32_USART2CLK STM32_LSECLK -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART4 frequency. - */ -#define STM32_UART4CLK STM32_PCLK1 - -/** - * @brief USART5 frequency. - */ -#define STM32_UART5CLK STM32_PCLK1 - -/** - * @brief LPUART1 frequency. - */ -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_APB) || defined(__DOXYGEN__) -#define STM32_LPUART1CLK STM32_PCLK1 -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK -#define STM32_LPUART1CLK STM32_SYSCLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 -#define STM32_LPUART1CLK STM32_HSI16DIVCLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE -#define STM32_LPUART1CLK STM32_LSECLK -#else -#error "invalid source selected for LPUART1 clock" -#endif - -/** - * @brief I2C1 frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_APB) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_PCLK1 -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 -#define STM32_I2C1CLK STM32_HSI16DIVCLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief LPTIM1 frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_APB) || defined(__DOXYGEN__) -#define STM32_LPTIM1CLK STM32_PCLK1 -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI -#define STM32_LPTIM1CLK STM32_LSICLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 -#define STM32_LPTIM1CLK STM32_HSI16DIVCLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE -#define STM32_LPTIM1CLK STM32_LSECLK -#else -#error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief USB clock point. - */ -#if (STM32_HSI48SEL == STM32_HSI48SEL_HSI48) || defined(__DOXYGEN__) -#define STM32_USBCLK STM32_HSI48CLK -#elif STM32_HSI48SEL == STM32_HSI48SEL_USBPLL -#define STM32_USBCLK (STM32_PLLVCO / 2) -#else -#error "invalid STM32_HSI48SEL value specified" -#endif - -/** - * @brief RNG clock point. - */ -#define STM32_RNGCLK STM32_USBCLK - -/** - * @brief Timers LPTIM1, TIM2, TIM6 clock. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers TIM21, TIM22 clock. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS 0 -#else -#define STM32_FLASHBITS (FLASH_ACR_PRE_READ | \ - FLASH_ACR_PRFTEN | \ - FLASH_ACR_LATENCY) -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L0xx/hal_lld.h + * @brief STM32L0xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32L011xx, STM32L031xx, + * STM32L051xx, STM32L052xx, STM32L053xx, + * STM32L061xx, STM32L062xx, STM32L063xx, + * STM32L071xx, STM32L072xx, STM32L073xx for ultra-low-power MCUs. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +/* + * Registry definitions. + */ +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification macros + * @{ + */ +#if defined(STM32L011xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32L011xx ultra-low-power MCU" + +#elif defined(STM32L031xx) +#define PLATFORM_NAME "STM32L031xx ultra-low-power MCU" + +#elif defined(STM32L051xx) +#define PLATFORM_NAME "STM32L051xx ultra-low-power MCU" + +#elif defined(STM32L052xx) +#define PLATFORM_NAME "STM32L052xx ultra-low-power MCU" + +#elif defined(STM32L053xx) +#define PLATFORM_NAME "STM32L053xx ultra-low-power MCU" + +#elif defined(STM32L061xx) +#define PLATFORM_NAME "STM32L061xx ultra-low-power MCU" + +#elif defined(STM32L062xx) +#define PLATFORM_NAME "STM32L062xx ultra-low-power MCU" + +#elif defined(STM32L063xx) +#define PLATFORM_NAME "STM32L063xx ultra-low-power MCU" + +#elif defined(STM32L071xx) +#define PLATFORM_NAME "STM32L071xx ultra-low-power MCU" + +#elif defined(STM32L072xx) +#define PLATFORM_NAME "STM32L073xx ultra-low-power MCU" + +#elif defined(STM32L073xx) +#define PLATFORM_NAME "STM32L073xx ultra-low-power MCU" + +#else +#error "STM32L0xx device not specified" +#endif +/** @} */ + +/** + * @name Sub-family identifier + */ +#if !defined(STM32L0XX) || defined(__DOXYGEN__) +#define STM32L0XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ +#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ +#define STM32_LSICLK 37000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 5) /**< PLS field mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_EXT (7 << 5) /**< PVD level 7. */ + +#define STM32_VOS_MASK (3 << 11) /**< VOS field mask. */ +#define STM32_VOS_1P8 (1 << 11) /**< VOS level 1.8 volts. */ +#define STM32_VOS_1P5 (2 << 11) /**< VOS level 1.5 volts. */ +#define STM32_VOS_1P2 (3 << 11) /**< VOS level 1.2 volts. */ +/** @} */ + +/** + * @name RCC_CR register bits definitions + * @{ + */ +#define STM32_RTCPRE_MASK (3 << 20) /**< RTCPRE mask. */ +#define STM32_RTCPRE_DIV2 (0 << 20) /**< HSE divided by 2. */ +#define STM32_RTCPRE_DIV4 (1 << 20) /**< HSE divided by 4. */ +#define STM32_RTCPRE_DIV8 (2 << 20) /**< HSE divided by 2. */ +#define STM32_RTCPRE_DIV16 (3 << 20) /**< HSE divided by 16. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ +#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ +#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI16 */ +#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 8) /**< PPRE2 field mask. */ +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_STOPWUCK_MASK (1 << 15) /**< PLLDIV field mask. */ +#define STM32_STOPWUCK_MSI (0 << 15) /**< MSI is wakeup clock. */ +#define STM32_STOPWUCK_HSI16 (1 << 15) /**< HSI16 is wakeup clock. */ + +#define STM32_PLLSRC_MASK (1 << 16) /**< PLLSRC field mask. */ +#define STM32_PLLSRC_HSI16 (0 << 16) /**< PLL clock source is HSI16. */ +#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ + +#define STM32_PLLMUL_MASK (15 << 18) /**< PLLMUL field mask. */ +#define STM32_PLLMUL_MUL3 (0 << 18) /**< PLL multiplier is 3. */ +#define STM32_PLLMUL_MUL4 (1 << 18) /**< PLL multiplier is 4. */ +#define STM32_PLLMUL_MUL6 (2 << 18) /**< PLL multiplier is 6. */ +#define STM32_PLLMUL_MUL8 (3 << 18) /**< PLL multiplier is 8. */ +#define STM32_PLLMUL_MUL12 (4 << 18) /**< PLL multiplier is 12. */ +#define STM32_PLLMUL_MUL16 (5 << 18) /**< PLL multiplier is 16. */ +#define STM32_PLLMUL_MUL24 (6 << 18) /**< PLL multiplier is 24. */ +#define STM32_PLLMUL_MUL32 (7 << 18) /**< PLL multiplier is 32. */ +#define STM32_PLLMUL_MUL48 (8 << 18) /**< PLL multiplier is 48. */ + +#define STM32_PLLDIV_MASK (3 << 22) /**< PLLDIV field mask. */ +#define STM32_PLLDIV_DIV2 (1 << 22) /**< PLL divided by 2. */ +#define STM32_PLLDIV_DIV3 (2 << 22) /**< PLL divided by 3. */ +#define STM32_PLLDIV_DIV4 (3 << 22) /**< PLL divided by 4. */ + +#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI16 (2 << 24) /**< HSI16 clock on MCO pin. */ +#define STM32_MCOSEL_MSI (3 << 24) /**< MSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ + +#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ +#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO is divided by 1. */ +#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO is divided by 1. */ +#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO is divided by 1. */ +#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO is divided by 1. */ +#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO is divided by 1. */ +/** @} */ + +/** + * @name RCC_ICSCR register bits definitions + * @{ + */ +#define STM32_MSIRANGE_MASK (7 << 13) /**< MSIRANGE field mask. */ +#define STM32_MSIRANGE_64K (0 << 13) /**< 64kHz nominal. */ +#define STM32_MSIRANGE_128K (1 << 13) /**< 128kHz nominal. */ +#define STM32_MSIRANGE_256K (2 << 13) /**< 256kHz nominal. */ +#define STM32_MSIRANGE_512K (3 << 13) /**< 512kHz nominal. */ +#define STM32_MSIRANGE_1M (4 << 13) /**< 1MHz nominal. */ +#define STM32_MSIRANGE_2M (5 << 13) /**< 2MHz nominal. */ +#define STM32_MSIRANGE_4M (6 << 13) /**< 4MHz nominal */ +/** @} */ + +/** + * @name RCC_CSR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 16) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 16) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 16) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 16) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 16) /**< RTC source is HSE divided. */ +/** @} */ + +/** + * @name RCC_CCIPR register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3 << 0) /**< USART1 clock source mask. */ +#define STM32_USART1SEL_APB (0 << 0) /**< USART1 clock is APB. */ +#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 clock is SYSCLK. */ +#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 clock is HSI16. */ +#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 clock is LSE. */ + +#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 clock source mask. */ +#define STM32_USART2SEL_APB (0 << 2) /**< USART2 clock is APB. */ +#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 clock is SYSCLK. */ +#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 clock is HSI16. */ +#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 clock is LSE. */ + +#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 clock source mask. */ +#define STM32_LPUART1SEL_APB (0 << 10) /**< LPUART1 clock is APB. */ +#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 clock is SYSCLK. */ +#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 clock is HSI16. */ +#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 clock is LSE. */ + +#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1 clock source mask. */ +#define STM32_I2C1SEL_APB (0 << 12) /**< I2C1 clock is APB. */ +#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 clock is SYSCLK. */ +#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 clock is HSI16. */ + +#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3 clock source mask. */ +#define STM32_I2C3SEL_APB (0 << 16) /**< I2C3 clock is APB. */ +#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 clock is SYSCLK. */ +#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 clock is HSI16. */ + +#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1 clock source mask. */ +#define STM32_LPTIM1SEL_APB (0 << 18) /**< LPTIM1 clock is APB. */ +#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 clock is LSI. */ +#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 clock is HSI16. */ +#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 clock is LSE. */ + +#define STM32_HSI48SEL_MASK (1 << 26) /**< HSI48SEL clock source mask.*/ +#define STM32_HSI48SEL_USBPLL (0 << 26) /**< USB48 clock is PLL/2. */ +#define STM32_HSI48SEL_HSI48 (1 << 26) /**< USB48 clock is HSI48. */ +/** @} */ + +/** + * @name SYSCFG_CFGR3_ register bits definitions + * @{ + */ +#define STM32_VREFINT_EN (1 << 0) /**< VREFINT enable switch. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_1P8 +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI16 clock source. + */ +#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSI16 clock divider. + */ +#if !defined(STM32_HSI16_DIVIDER_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_DIVIDER_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief ADC clock setting. + */ +#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_ADC_CLOCK_ENABLED TRUE +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_ENABLED TRUE +#endif + +/** + * @brief MSI frequency setting. + */ +#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) +#define STM32_MSIRANGE STM32_MSIRANGE_2M +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSI16 +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed values are 3, 4, 6, 8, 12, 16, 32, 48. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 4 +#endif + +/** + * @brief PLL divider value. + * @note The allowed values are 2, 3, 4. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLDIV_VALUE 2 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief RTC/LCD clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif + +/** + * @brief HSE divider toward RTC setting. + */ +#if !defined(STM32_RTCPRE) || defined(__DOXYGEN__) +#define STM32_RTCPRE STM32_RTCPRE_DIV2 +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_APB +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_APB +#endif + +/** + * @brief LPUART1 clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_APB +#endif + +/** + * @brief I2C clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_APB +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_APB +#endif + +/** + * @bief USB/RNG clock source. + */ +#if !defined(STM32_HSI48SEL) || defined(__DOXYGEN__) +#define STM32_HSI48SEL STM32_HSI48SEL_USBPLL +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32L0xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L0xx_MCUCONF not defined" +#endif + +#if defined(STM32L052xx) && !defined(STM32L052_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L052_MCUCONF not defined" + +#elif defined(STM32L053xx) && !defined(STM32L053_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L053_MCUCONF not defined" + +#elif defined(STM32L072xx) && !defined(STM32L072_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L072_MCUCONF not defined" + +#elif defined(STM32L073xx) && !defined(STM32L073_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L073_MCUCONF not defined" + +#endif + +/* + * Board files sanity checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif + +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_1P8) || defined(__DOXYGEN__) +/** + * @name Absolute Maximum Ratings + * @{ + */ +/** + * @brief Maximum SYSCLK clock frequency at current voltage setting. + */ +#define STM32_SYSCLK_MAX 32000000 + +/** + * @brief Maximum HSE clock frequency at current voltage setting. + */ +#define STM32_HSECLK_MAX 32000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 1000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 1000 + +/** + * @brief Maximum PLL input frequency. + */ +#define STM32_PLLIN_MAX 24000000 + +/** + * @brief Maximum PLL input frequency. + */ +#define STM32_PLLIN_MIN 2000000 + +/** + * @brief Maximum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MAX 96000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 6000000 + +/** + * @brief Maximum PLL output frequency. + */ +#define STM32_PLLOUT_MAX 32000000 + +/** + * @brief Maximum PLL output frequency. + */ +#define STM32_PLLOUT_MIN 2000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 32000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 32000000 + +/** + * @brief Maximum frequency not requiring a wait state for flash accesses. + */ +#define STM32_0WS_THRESHOLD 16000000 + +/** + * @brief HSI availability at current voltage settings. + */ +#define STM32_HSI_AVAILABLE TRUE +/** @} */ + +#elif STM32_VOS == STM32_VOS_1P5 +#define STM32_SYSCLK_MAX 16000000 +#define STM32_HSECLK_MAX 16000000 +#define STM32_HSECLK_MIN 1000000 +#define STM32_LSECLK_MAX 1000000 +#define STM32_LSECLK_MIN 1000 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLIN_MIN 2000000 +#define STM32_PLLVCO_MAX 48000000 +#define STM32_PLLVCO_MIN 6000000 +#define STM32_PLLOUT_MAX 16000000 +#define STM32_PLLOUT_MIN 2000000 +#define STM32_PCLK1_MAX 16000000 +#define STM32_PCLK2_MAX 16000000 +#define STM32_0WS_THRESHOLD 8000000 +#define STM32_HSI_AVAILABLE TRUE +#elif STM32_VOS == STM32_VOS_1P2 +#define STM32_SYSCLK_MAX 4000000 +#define STM32_HSECLK_MAX 8000000 +#define STM32_HSECLK_MIN 1000000 +#define STM32_LSECLK_MAX 1000000 +#define STM32_LSECLK_MIN 1000 +#define STM32_PLLIN_MAX 8000000 +#define STM32_PLLIN_MIN 2000000 +#define STM32_PLLVCO_MAX 24000000 +#define STM32_PLLVCO_MIN 6000000 +#define STM32_PLLOUT_MAX 4000000 +#define STM32_PLLOUT_MIN 2000000 +#define STM32_PCLK1_MAX 4000000 +#define STM32_PCLK2_MAX 4000000 +#define STM32_0WS_THRESHOLD 4000000 +#define STM32_HSI_AVAILABLE FALSE +#else +#error "invalid STM32_VOS value specified" +#endif + +/* HSI related checks.*/ +#if STM32_HSI16_ENABLED +#if !STM32_HSI_AVAILABLE + #error "impossible to activate HSI under the current voltage settings" +#endif +#else /* !STM32_HSI16_ENABLED */ + +#if STM32_ADC_CLOCK_ENABLED +#error "HSI16 not enabled, required by STM32_ADC_CLOCK_ENABLED" +#endif + +#if (STM32_SW == STM32_SW_HSI16) +#error "HSI16 not enabled, required by STM32_SW" +#endif + +#if ((STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16)) +#error "HSI16 not enabled, required by STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) +#error "HSI16 not enabled, required by STM32_MCOSEL" +#endif + +#if ((STM32_MCOSEL == STM32_MCOSEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16)) +#error "HSI16 not enabled, required by STM32_PLLSRC" +#endif + +#endif /* !STM32_HSI16_ENABLED */ + +/* + * @brief Divided HSI16 clock. + */ +#if STM32_HSI16_DIVIDER_ENABLED || defined(__DOXYGEN__) +#define STM32_HSI16DIVCLK (STM32_HSI16CLK / 4) +#else +#define STM32_HSI16DIVCLK STM32_HSI16CLK +#endif + +/* HSE related checks.*/ +#if STM32_HSE_ENABLED +#if STM32_HSECLK == 0 +#error "impossible to activate HSE, frequency is zero" +#endif +#if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" +#endif +#else /* !STM32_HSE_ENABLED */ + +#if (STM32_SW == STM32_SW_HSE) +#error "HSE not enabled, required by STM32_SW" +#endif + +#if ((STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSE) +#error "HSE not enabled, required by STM32_MCOSEL" +#endif + +#if ((STM32_MCOSEL == STM32_MCOSEL_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE)) +#error "HSE not enabled, required by STM32_PLLSRC" +#endif + +#if (STM32_RTCSEL == STM32_RTCSEL_HSEDIV) +#error "HSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_HSE_ENABLED */ + +/* LSI related checks.*/ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_LSI +#error "LSI not enabled, required by STM32_MCOSEL" +#endif + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* LSE related checks.*/ +#if STM32_LSE_ENABLED +#if (STM32_LSECLK == 0) +#error "impossible to activate LSE, frequency is zero" +#endif +#if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) +#error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" +#endif +#else /* !STM32_LSE_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_LSE +#error "LSE not enabled, required by STM32_MCOSEL" +#endif + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL related checks.*/ +#if (STM32_SW == STM32_SW_PLL) || (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + (STM32_USB_CLOCK_ENABLED && (STM32_HSI48SEL == STM32_HSI48SEL_USBPLL)) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/* HSI48 related checks.*/ +#if (STM32_USB_CLOCK_ENABLED && (STM32_HSI48SEL == STM32_HSI48SEL_HSI48)) || \ + defined(__DOXYGEN__) +/** + * @brief HSI48 activation flag. + */ +#define STM32_ACTIVATE_HSI48 TRUE +#else +#define STM32_ACTIVATE_HSI48 FALSE +#endif + +/** + * @brief PLLMUL field. + */ +#if (STM32_PLLMUL_VALUE == 3) || defined(__DOXYGEN__) +#define STM32_PLLMUL STM32_PLLMUL_MUL3 +#elif STM32_PLLMUL_VALUE == 4 +#define STM32_PLLMUL STM32_PLLMUL_MUL4 +#elif STM32_PLLMUL_VALUE == 6 +#define STM32_PLLMUL STM32_PLLMUL_MUL6 +#elif STM32_PLLMUL_VALUE == 8 +#define STM32_PLLMUL STM32_PLLMUL_MUL8 +#elif STM32_PLLMUL_VALUE == 12 +#define STM32_PLLMUL STM32_PLLMUL_MUL12 +#elif STM32_PLLMUL_VALUE == 16 +#define STM32_PLLMUL STM32_PLLMUL_MUL16 +#elif STM32_PLLMUL_VALUE == 24 +#define STM32_PLLMUL STM32_PLLMUL_MUL24 +#elif STM32_PLLMUL_VALUE == 32 +#define STM32_PLLMUL STM32_PLLMUL_MUL32 +#elif STM32_PLLMUL_VALUE == 48 +#define STM32_PLLMUL STM32_PLLMUL_MUL48 +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLLDIV field. + */ +#if (STM32_PLLDIV_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLDIV STM32_PLLDIV_DIV2 +#elif STM32_PLLDIV_VALUE == 3 +#define STM32_PLLDIV STM32_PLLDIV_DIV3 +#elif STM32_PLLDIV_VALUE == 4 +#define STM32_PLLDIV STM32_PLLDIV_DIV4 +#else +#error "invalid STM32_PLLDIV_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN STM32_HSECLK +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 +#define STM32_PLLCLKIN STM32_HSI16DIVCLK +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLDIV_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < STM32_PLLOUT_MIN) || (STM32_PLLCLKOUT > STM32_PLLOUT_MAX) +#error "STM32_PLLCLKOUT outside acceptable range (STM32_PLLOUT_MIN...STM32_PLLOUT_MAX)" +#endif + +/** + * @brief MSI frequency. + * @note Values are taken from the STM8Lxx datasheet. + */ +#if STM32_MSIRANGE == STM32_MSIRANGE_64K +#define STM32_MSICLK 65500 +#elif STM32_MSIRANGE == STM32_MSIRANGE_128K +#define STM32_MSICLK 131000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_256K +#define STM32_MSICLK 262000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_512K +#define STM32_MSICLK 524000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_1M +#define STM32_MSICLK 1050000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_2M +#define STM32_MSICLK 2100000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_4M +#define STM32_MSICLK 4200000 +#else +#error "invalid STM32_MSIRANGE value specified" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK 2100000 +#elif (STM32_SW == STM32_SW_MSI) +#define STM32_SYSCLK STM32_MSICLK +#elif (STM32_SW == STM32_SW_HSI16) +#define STM32_SYSCLK STM32_HSI16DIVCLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief MCO selector clock. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK +#define STM32_MCODIVCLK STM32_SYSCLK +#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 +#define STM32_MCODIVCLK STM32_HSI16DIVCLK +#elif STM32_MCOSEL == STM32_MCOSEL_MSI +#define STM32_MCODIVCLK STM32_MSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK +#elif STM32_MCOSEL == STM32_MCOSEL_PLL +#define STM32_MCODIVCLK STM32_PLLCLKOUT +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK +#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 +#define STM32_MCODIVCLK STM32_HSI48CLK +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief HSE divider toward RTC clock. + */ +#if (STM32_RTCPRE == STM32_RTCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 2) +#elif (STM32_RTCPRE == STM32_RTCPRE_DIV4) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 4) +#elif (STM32_RTCPRE == STM32_RTCPRE_DIV8) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 8) +#elif (STM32_RTCPRE == STM32_RTCPRE_DIV16) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief RTC/LCD clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK STM32_HSEDIVCLK +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_APB) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK2 +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 +#define STM32_USART1CLK STM32_HSI16DIVCLK +#elif STM32_USART1SEL == STM32_USART1SEL_LSE +#define STM32_USART1CLK STM32_LSECLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 frequency. + */ +#if (STM32_USART2SEL == STM32_USART2SEL_APB) || defined(__DOXYGEN__) +#define STM32_USART2CLK STM32_PCLK1 +#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK +#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 +#define STM32_USART2CLK STM32_HSI16DIVCLK +#elif STM32_USART2SEL == STM32_USART2SEL_LSE +#define STM32_USART2CLK STM32_LSECLK +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART4 frequency. + */ +#define STM32_UART4CLK STM32_PCLK1 + +/** + * @brief USART5 frequency. + */ +#define STM32_UART5CLK STM32_PCLK1 + +/** + * @brief LPUART1 frequency. + */ +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_APB) || defined(__DOXYGEN__) +#define STM32_LPUART1CLK STM32_PCLK1 +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK +#define STM32_LPUART1CLK STM32_SYSCLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 +#define STM32_LPUART1CLK STM32_HSI16DIVCLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE +#define STM32_LPUART1CLK STM32_LSECLK +#else +#error "invalid source selected for LPUART1 clock" +#endif + +/** + * @brief I2C1 frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_APB) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_PCLK1 +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 +#define STM32_I2C1CLK STM32_HSI16DIVCLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief LPTIM1 frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_APB) || defined(__DOXYGEN__) +#define STM32_LPTIM1CLK STM32_PCLK1 +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI +#define STM32_LPTIM1CLK STM32_LSICLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 +#define STM32_LPTIM1CLK STM32_HSI16DIVCLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE +#define STM32_LPTIM1CLK STM32_LSECLK +#else +#error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief USB clock point. + */ +#if (STM32_HSI48SEL == STM32_HSI48SEL_HSI48) || defined(__DOXYGEN__) +#define STM32_USBCLK STM32_HSI48CLK +#elif STM32_HSI48SEL == STM32_HSI48SEL_USBPLL +#define STM32_USBCLK (STM32_PLLVCO / 2) +#else +#error "invalid STM32_HSI48SEL value specified" +#endif + +/** + * @brief RNG clock point. + */ +#define STM32_RNGCLK STM32_USBCLK + +/** + * @brief Timers LPTIM1, TIM2, TIM6 clock. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers TIM21, TIM22 clock. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS 0 +#else +#define STM32_FLASHBITS (FLASH_ACR_PRE_READ | \ + FLASH_ACR_PRFTEN | \ + FLASH_ACR_LATENCY) +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L1xx/hal_lld.c b/os/hal/ports/STM32/STM32L1xx/hal_lld.c index 9731411837..5cd284f7e7 100644 --- a/os/hal/ports/STM32/STM32L1xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L1xx/hal_lld.c @@ -1,244 +1,244 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L1xx/hal_lld.c - * @brief STM32L1xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -/* CHTODO: LSEBYP like in F3.*/ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32l1xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Backup domain access enabled and left open.*/ - PWR->CR |= PWR_CR_DBP; - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->CSR |= RCC_CSR_RTCRST; - RCC->CSR &= ~RCC_CSR_RTCRST; - } - - /* If enabled then the LSE is started.*/ -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - /* Waits until LSE is stable or times out. */ - RCC->CSR |= RCC_CSR_LSEON; - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->CSR & RCC_CSR_LSERDY) == 0) - ; -#endif - -#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->CSR |= (RCC->CSR & RCC_CSR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->CSR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->CSR |= RCC_CSR_RTCEN; - } -#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB(~(RCC_AHBRSTR_FLITFRST | STM32_GPIO_EN_MASK)); - rccResetAPB1(~RCC_APB1RSTR_PWRRST); - rccResetAPB2(~0); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); -#endif /* STM32_PVD_ENABLE */ -} - -/** - * @brief STM32L1xx voltage, clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -/** - * @brief Clocks and internal voltage initialization. - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enable.*/ - RCC->APB1ENR = RCC_APB1ENR_PWREN; - - /* Core voltage setup.*/ - while ((PWR->CSR & PWR_CSR_VOSF) != 0) - ; /* Waits until regulator is stable. */ - PWR->CR = STM32_VOS; - while ((PWR->CSR & PWR_CSR_VOSF) != 0) - ; /* Waits until regulator is stable. */ - - /* Initial clocks setup and wait for MSI stabilization, the MSI clock is - always enabled because it is the fallback clock when PLL the fails. - Trim fields are not altered from reset values.*/ - RCC->CFGR = 0; - RCC->ICSCR = (RCC->ICSCR & ~STM32_MSIRANGE_MASK) | STM32_MSIRANGE; - RCC->CR = RCC_CR_MSION; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; /* Waits until MSI is stable. */ - -#if STM32_HSI_ENABLED - /* HSI activation.*/ - RCC->CR |= RCC_CR_HSION; - while ((RCC->CR & RCC_CR_HSIRDY) == 0) - ; /* Waits until HSI is stable. */ -#endif - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Waits until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Waits until LSI is stable. */ -#endif - -#if STM32_LSE_ENABLED - /* LSE activation, have to unlock the register.*/ - if ((RCC->CSR & RCC_CSR_LSEON) == 0) { - PWR->CR |= PWR_CR_DBP; - RCC->CSR |= RCC_CSR_LSEON; - PWR->CR &= ~PWR_CR_DBP; - } - while ((RCC->CSR & RCC_CSR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CFGR |= STM32_PLLDIV | STM32_PLLMUL | STM32_PLLSRC; - RCC->CR |= RCC_CR_PLLON; - while (!(RCC->CR & RCC_CR_PLLRDY)) - ; /* Waits until PLL is stable. */ -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CR |= STM32_RTCPRE; - RCC->CFGR |= STM32_MCOPRE | STM32_MCOSEL | - STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; - RCC->CSR |= STM32_RTCSEL; - - /* Flash setup and final clock selection.*/ -#if defined(STM32_FLASHBITS1) - FLASH->ACR = STM32_FLASHBITS1; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS1 & FLASH_ACR_LATENCY_Msk)) { - } -#endif -#if defined(STM32_FLASHBITS2) - FLASH->ACR = STM32_FLASHBITS2; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS2 & FLASH_ACR_LATENCY_Msk)) { - } -#endif - - /* Switching to the configured clock source if it is different from MSI.*/ -#if (STM32_SW != STM32_SW_MSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L1xx/hal_lld.c + * @brief STM32L1xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +/* CHTODO: LSEBYP like in F3.*/ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32l1xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Backup domain access enabled and left open.*/ + PWR->CR |= PWR_CR_DBP; + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->CSR |= RCC_CSR_RTCRST; + RCC->CSR &= ~RCC_CSR_RTCRST; + } + + /* If enabled then the LSE is started.*/ +#if STM32_LSE_ENABLED + int fomeLseCounter = 0; + /* Waits until LSE is stable or times out. */ + RCC->CSR |= RCC_CSR_LSEON; + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->CSR & RCC_CSR_LSERDY) == 0) + ; +#endif + +#if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->CSR |= (RCC->CSR & RCC_CSR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->CSR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->CSR |= RCC_CSR_RTCEN; + } +#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB(~(RCC_AHBRSTR_FLITFRST | STM32_GPIO_EN_MASK)); + rccResetAPB1(~RCC_APB1RSTR_PWRRST); + rccResetAPB2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); +#endif /* STM32_PVD_ENABLE */ +} + +/** + * @brief STM32L1xx voltage, clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +/** + * @brief Clocks and internal voltage initialization. + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ + RCC->APB1ENR = RCC_APB1ENR_PWREN; + + /* Core voltage setup.*/ + while ((PWR->CSR & PWR_CSR_VOSF) != 0) + ; /* Waits until regulator is stable. */ + PWR->CR = STM32_VOS; + while ((PWR->CSR & PWR_CSR_VOSF) != 0) + ; /* Waits until regulator is stable. */ + + /* Initial clocks setup and wait for MSI stabilization, the MSI clock is + always enabled because it is the fallback clock when PLL the fails. + Trim fields are not altered from reset values.*/ + RCC->CFGR = 0; + RCC->ICSCR = (RCC->ICSCR & ~STM32_MSIRANGE_MASK) | STM32_MSIRANGE; + RCC->CR = RCC_CR_MSION; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; /* Waits until MSI is stable. */ + +#if STM32_HSI_ENABLED + /* HSI activation.*/ + RCC->CR |= RCC_CR_HSION; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Waits until HSI is stable. */ +#endif + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Waits until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Waits until LSI is stable. */ +#endif + +#if STM32_LSE_ENABLED + /* LSE activation, have to unlock the register.*/ + if ((RCC->CSR & RCC_CSR_LSEON) == 0) { + PWR->CR |= PWR_CR_DBP; + RCC->CSR |= RCC_CSR_LSEON; + PWR->CR &= ~PWR_CR_DBP; + } + while ((RCC->CSR & RCC_CSR_LSERDY) == 0) + ; /* Waits until LSE is stable. */ +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CFGR |= STM32_PLLDIV | STM32_PLLMUL | STM32_PLLSRC; + RCC->CR |= RCC_CR_PLLON; + while (!(RCC->CR & RCC_CR_PLLRDY)) + ; /* Waits until PLL is stable. */ +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CR |= STM32_RTCPRE; + RCC->CFGR |= STM32_MCOPRE | STM32_MCOSEL | + STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + RCC->CSR |= STM32_RTCSEL; + + /* Flash setup and final clock selection.*/ +#if defined(STM32_FLASHBITS1) + FLASH->ACR = STM32_FLASHBITS1; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS1 & FLASH_ACR_LATENCY_Msk)) { + } +#endif +#if defined(STM32_FLASHBITS2) + FLASH->ACR = STM32_FLASHBITS2; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS2 & FLASH_ACR_LATENCY_Msk)) { + } +#endif + + /* Switching to the configured clock source if it is different from MSI.*/ +#if (STM32_SW != STM32_SW_MSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L1xx/hal_lld.h b/os/hal/ports/STM32/STM32L1xx/hal_lld.h index 28ed1bf165..f7d6a9ee2b 100644 --- a/os/hal/ports/STM32/STM32L1xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L1xx/hal_lld.h @@ -1,882 +1,886 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L1xx/hal_lld.h - * @brief STM32L1xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32L100xB, STM32L100xBA, STM32L100xC. - * - STM32L151xB, STM32L151xBA, STM32L151xC, STM32L151xCA, - * STM32L151xD, STM32L151xDX, STM32L151xE. - * - STM32L152xB, STM32L152xBA, STM32L152xC, STM32L152xCA, - * STM32L152xD, STM32L152xDX, STM32L152xE. - * - STM32L162xC, STM32L162xCA, STM32L162xD, STM32L162xDX, - * STM32L162xE. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(STM32L100xB) || defined(STM32L151xB) || \ - defined(STM32L152xB) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32L1xx Ultra Low Power Medium Density" - -#elif defined(STM32L100xBA) || defined(STM32L100xC) || \ - defined(STM32L151xBA) || defined(STM32L151xC) || \ - defined(STM32L151xCA) || defined(STM32L152xBA) || \ - defined(STM32L152xC) || defined(STM32L152xCA) || \ - defined(STM32L162xC) || defined(STM32L162xCA) -#define PLATFORM_NAME "STM32L1xx Ultra Low Power Medium Density Plus" - -#elif defined(STM32L151xD) || defined(STM32L151xDX) || \ - defined(STM32L151xE) || defined(STM32L152xD) || \ - defined(STM32L152xDX) || defined(STM32L152xE) || \ - defined(STM32L162xD) || defined(STM32L162xDX) || \ - defined(STM32L162xE) -#define PLATFORM_NAME "STM32L1xx Ultra Low Power High Density" - -#else -#error "STM32L1xx device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32L1XX) || defined(__DOXYGEN__) -#define STM32L1XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSICLK 16000000 /**< High speed internal clock. */ -#define STM32_LSICLK 38000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR register bits definitions - * @{ - */ -#define STM32_VOS_MASK (3 << 11) /**< Core voltage mask. */ -#define STM32_VOS_1P8 (1 << 11) /**< Core voltage 1.8 Volts. */ -#define STM32_VOS_1P5 (2 << 11) /**< Core voltage 1.5 Volts. */ -#define STM32_VOS_1P2 (3 << 11) /**< Core voltage 1.2 Volts. */ - -#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ -#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CR register bits definitions - * @{ - */ -#define STM32_RTCPRE_MASK (3 << 29) /**< RTCPRE mask. */ -#define STM32_RTCPRE_DIV2 (0 << 29) /**< HSE divided by 2. */ -#define STM32_RTCPRE_DIV4 (1 << 29) /**< HSE divided by 4. */ -#define STM32_RTCPRE_DIV8 (2 << 29) /**< HSE divided by 2. */ -#define STM32_RTCPRE_DIV16 (3 << 29) /**< HSE divided by 16. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ -#define STM32_SW_HSI (1 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ -#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ - -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_HSI (2 << 24) /**< HSI clock on MCO pin. */ -#define STM32_MCOSEL_MSI (3 << 24) /**< MSI clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ - -#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ -#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ -#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ -#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ -#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ -/** @} */ - -/** - * @name RCC_ICSCR register bits definitions - * @{ - */ -#define STM32_MSIRANGE_MASK (7 << 13) /**< MSIRANGE field mask. */ -#define STM32_MSIRANGE_64K (0 << 13) /**< 64kHz nominal. */ -#define STM32_MSIRANGE_128K (1 << 13) /**< 128kHz nominal. */ -#define STM32_MSIRANGE_256K (2 << 13) /**< 256kHz nominal. */ -#define STM32_MSIRANGE_512K (3 << 13) /**< 512kHz nominal. */ -#define STM32_MSIRANGE_1M (4 << 13) /**< 1MHz nominal. */ -#define STM32_MSIRANGE_2M (5 << 13) /**< 2MHz nominal. */ -#define STM32_MSIRANGE_4M (6 << 13) /**< 4MHz nominal */ -/** @} */ - -/** - * @name RCC_CSR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 16) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 16) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 16) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 16) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 16) /**< RTC source is HSE divided. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_1P8 -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI clock source. - */ -#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief ADC clock setting. - */ -#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_ADC_CLOCK_ENABLED TRUE -#endif - -/** - * @brief USB clock setting. - */ -#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) -#define STM32_USB_CLOCK_ENABLED TRUE -#endif - -/** - * @brief MSI frequency setting. - */ -#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) -#define STM32_MSIRANGE STM32_MSIRANGE_2M -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_HSI -#endif - -/** - * @brief PLL multiplier value. - * @note The allowed values are 3, 4, 6, 8, 12, 16, 32, 48. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLMUL_VALUE 6 -#endif - -/** - * @brief PLL divider value. - * @note The allowed values are 2, 3, 4. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_PLLDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLDIV_VALUE 3 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 32MHz system clock from - * the internal 16MHz HSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief RTC/LCD clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief HSE divider toward RTC setting. - */ -#if !defined(STM32_RTCPRE) || defined(__DOXYGEN__) -#define STM32_RTCPRE STM32_RTCPRE_DIV2 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32L1xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L1xx_MCUCONF not defined" -#endif - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_1P8) || defined(__DOXYGEN__) -/** - * @brief Maximum HSE clock frequency at current voltage setting. - */ -#define STM32_HSECLK_MAX 32000000 - -/** - * @brief Maximum SYSCLK clock frequency at current voltage setting. - */ -#define STM32_SYSCLK_MAX 32000000 - -/** - * @brief Maximum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MAX 96000000 - -/** - * @brief Minimum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MIN 6000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 32000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 32000000 - -/** - * @brief Maximum frequency not requiring a wait state for flash accesses. - */ -#define STM32_0WS_THRESHOLD 16000000 - -/** - * @brief HSI availability at current voltage settings. - */ -#define STM32_HSI_AVAILABLE TRUE - -#elif STM32_VOS == STM32_VOS_1P5 -#define STM32_HSECLK_MAX 16000000 -#define STM32_SYSCLK_MAX 16000000 -#define STM32_PLLVCO_MAX 48000000 -#define STM32_PLLVCO_MIN 6000000 -#define STM32_PCLK1_MAX 16000000 -#define STM32_PCLK2_MAX 16000000 -#define STM32_0WS_THRESHOLD 8000000 -#define STM32_HSI_AVAILABLE TRUE -#elif STM32_VOS == STM32_VOS_1P2 -#define STM32_HSECLK_MAX 4000000 -#define STM32_SYSCLK_MAX 4000000 -#define STM32_PLLVCO_MAX 24000000 -#define STM32_PLLVCO_MIN 6000000 -#define STM32_PCLK1_MAX 4000000 -#define STM32_PCLK2_MAX 4000000 -#define STM32_0WS_THRESHOLD 2000000 -#define STM32_HSI_AVAILABLE FALSE -#else -#error "invalid STM32_VOS value specified" -#endif - -/* HSI related checks.*/ -#if STM32_HSI_ENABLED -#if !STM32_HSI_AVAILABLE - #error "impossible to activate HSI under the current voltage settings" -#endif -#else /* !STM32_HSI_ENABLED */ -#if STM32_ADC_CLOCK_ENABLED || \ - (STM32_SW == STM32_SW_HSI) || \ - ((STM32_SW == STM32_SW_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) || \ - (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI)) -#error "required HSI clock is not enabled" -#endif -#endif /* !STM32_HSI_ENABLED */ - -/* HSE related checks.*/ -#if STM32_HSE_ENABLED -#if STM32_HSECLK == 0 -#error "impossible to activate HSE" -#endif -#if (STM32_HSECLK < 1000000) || (STM32_HSECLK > STM32_HSECLK_MAX) -#error "STM32_HSECLK outside acceptable range (1MHz...STM32_HSECLK_MAX)" -#endif -#else /* !STM32_HSE_ENABLED */ -#if (STM32_SW == STM32_SW_HSE) || \ - ((STM32_SW == STM32_SW_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ - (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ - (STM32_RTCSEL == STM32_RTCSEL_HSEDIV) -#error "required HSE clock is not enabled" -#endif -#endif /* !STM32_HSE_ENABLED */ - -/* LSI related checks.*/ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_LSI -#error "LSI not enabled, required by STM32_MCOSEL" -#endif - -#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) -#error "LSI not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSI_ENABLED */ - -/* LSE related checks.*/ -#if STM32_LSE_ENABLED -#if (STM32_LSECLK == 0) -#error "impossible to activate LSE" -#endif -#if (STM32_LSECLK < 1000) || (STM32_LSECLK > 1000000) -#error "STM32_LSECLK outside acceptable range (1...1000kHz)" -#endif -#else /* !STM32_LSE_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_LSE -#error "LSE not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_RTCSEL == STM32_RTCSEL_LSE -#error "LSE not enabled, required by STM32_RTCSEL" -#endif - -#endif /* !STM32_LSE_ENABLED */ - -/* PLL related checks.*/ -#if STM32_USB_CLOCK_ENABLED || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - defined(__DOXYGEN__) -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief PLLMUL field. - */ -#if (STM32_PLLMUL_VALUE == 3) || defined(__DOXYGEN__) -#define STM32_PLLMUL (0 << 18) -#elif STM32_PLLMUL_VALUE == 4 -#define STM32_PLLMUL (1 << 18) -#elif STM32_PLLMUL_VALUE == 6 -#define STM32_PLLMUL (2 << 18) -#elif STM32_PLLMUL_VALUE == 8 -#define STM32_PLLMUL (3 << 18) -#elif STM32_PLLMUL_VALUE == 12 -#define STM32_PLLMUL (4 << 18) -#elif STM32_PLLMUL_VALUE == 16 -#define STM32_PLLMUL (5 << 18) -#elif STM32_PLLMUL_VALUE == 24 -#define STM32_PLLMUL (6 << 18) -#elif STM32_PLLMUL_VALUE == 32 -#define STM32_PLLMUL (7 << 18) -#elif STM32_PLLMUL_VALUE == 48 -#define STM32_PLLMUL (8 << 18) -#else -#error "invalid STM32_PLLMUL_VALUE value specified" -#endif - -/** - * @brief PLLDIV field. - */ -#if (STM32_PLLDIV_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLDIV (1 << 22) -#elif STM32_PLLDIV_VALUE == 3 -#define STM32_PLLDIV (2 << 22) -#elif STM32_PLLDIV_VALUE == 4 -#define STM32_PLLDIV (3 << 22) -#else -#error "invalid STM32_PLLDIV_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN STM32_HSECLK -#elif STM32_PLLSRC == STM32_PLLSRC_HSI -#define STM32_PLLCLKIN STM32_HSICLK -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* PLL input frequency range check.*/ -#if (STM32_PLLCLKIN < 2000000) || (STM32_PLLCLKIN > 24000000) -#error "STM32_PLLCLKIN outside acceptable range (2...24MHz)" -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL output clock frequency. - */ -#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLDIV_VALUE) - -/* PLL output frequency range check.*/ -#if (STM32_PLLCLKOUT < 2000000) || (STM32_PLLCLKOUT > 32000000) -#error "STM32_PLLCLKOUT outside acceptable range (2...32MHz)" -#endif - -/** - * @brief MSI frequency. - */ -#if STM32_MSIRANGE == STM32_MSIRANGE_64K -#define STM32_MSICLK 65500 -#elif STM32_MSIRANGE == STM32_MSIRANGE_128K -#define STM32_MSICLK 131000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_256K -#define STM32_MSICLK 262000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_512K -#define STM32_MSICLK 524000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_1M -#define STM32_MSICLK 1050000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_2M -#define STM32_MSICLK 2100000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_4M -#define STM32_MSICLK 4200000 -#else -#error "invalid STM32_MSIRANGE value specified" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK 2100000 -#elif (STM32_SW == STM32_SW_MSI) -#define STM32_SYSCLK STM32_MSICLK -#elif (STM32_SW == STM32_SW_HSI) -#define STM32_SYSCLK STM32_HSICLK -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLLCLKOUT -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* AHB frequency check.*/ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* APB1 frequency check.*/ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* APB2 frequency check.*/ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief MCO clock before divider. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 -#elif STM32_MCOSEL == STM32_MCOSEL_HSI -#define STM32_MCODIVCLK STM32_HSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_MSI -#define STM32_MCODIVCLK STM32_MSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK -#elif STM32_MCOSEL == STM32_MCOSEL_PLL -#define STM32_MCODIVCLK STM32_PLLCLKOUT -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief HSE divider toward RTC clock. - */ -#if (STM32_RTCPRE == STM32_RTCPRE_DIV2) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 2) -#elif (STM32_RTCPRE == STM32_RTCPRE_DIV4) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 4) -#elif (STM32_RTCPRE == STM32_RTCPRE_DIV8) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 8) -#elif (STM32_RTCPRE == STM32_RTCPRE_DIV16) || defined(__DOXYGEN__) -#define STM32_HSEDIVCLK (STM32_HSECLK / 16) -#else -#error "invalid STM32_RTCPRE value specified" -#endif - -/** - * @brief RTC/LCD clock. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK STM32_HSEDIVCLK -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USB frequency. - */ -#define STM32_USBCLK (STM32_PLLVCO / 2) - -/** - * @brief Timers 2, 3, 4, 6, 7 clock. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Timers 9, 10, 11 clock. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS1 0x00000000 -#else -#define STM32_FLASHBITS1 0x00000004 -#define STM32_FLASHBITS2 0x00000007 -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L1xx/hal_lld.h + * @brief STM32L1xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32L100xB, STM32L100xBA, STM32L100xC. + * - STM32L151xB, STM32L151xBA, STM32L151xC, STM32L151xCA, + * STM32L151xD, STM32L151xDX, STM32L151xE. + * - STM32L152xB, STM32L152xBA, STM32L152xC, STM32L152xCA, + * STM32L152xD, STM32L152xDX, STM32L152xE. + * - STM32L162xC, STM32L162xCA, STM32L162xD, STM32L162xDX, + * STM32L162xE. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(STM32L100xB) || defined(STM32L151xB) || \ + defined(STM32L152xB) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32L1xx Ultra Low Power Medium Density" + +#elif defined(STM32L100xBA) || defined(STM32L100xC) || \ + defined(STM32L151xBA) || defined(STM32L151xC) || \ + defined(STM32L151xCA) || defined(STM32L152xBA) || \ + defined(STM32L152xC) || defined(STM32L152xCA) || \ + defined(STM32L162xC) || defined(STM32L162xCA) +#define PLATFORM_NAME "STM32L1xx Ultra Low Power Medium Density Plus" + +#elif defined(STM32L151xD) || defined(STM32L151xDX) || \ + defined(STM32L151xE) || defined(STM32L152xD) || \ + defined(STM32L152xDX) || defined(STM32L152xE) || \ + defined(STM32L162xD) || defined(STM32L162xDX) || \ + defined(STM32L162xE) +#define PLATFORM_NAME "STM32L1xx Ultra Low Power High Density" + +#else +#error "STM32L1xx device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32L1XX) || defined(__DOXYGEN__) +#define STM32L1XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSICLK 16000000 /**< High speed internal clock. */ +#define STM32_LSICLK 38000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR register bits definitions + * @{ + */ +#define STM32_VOS_MASK (3 << 11) /**< Core voltage mask. */ +#define STM32_VOS_1P8 (1 << 11) /**< Core voltage 1.8 Volts. */ +#define STM32_VOS_1P5 (2 << 11) /**< Core voltage 1.5 Volts. */ +#define STM32_VOS_1P2 (3 << 11) /**< Core voltage 1.2 Volts. */ + +#define STM32_PLS_MASK (7 << 5) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 5) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 5) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 5) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 5) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 5) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 5) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 5) /**< PVD level 6. */ +#define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CR register bits definitions + * @{ + */ +#define STM32_RTCPRE_MASK (3 << 29) /**< RTCPRE mask. */ +#define STM32_RTCPRE_DIV2 (0 << 29) /**< HSE divided by 2. */ +#define STM32_RTCPRE_DIV4 (1 << 29) /**< HSE divided by 4. */ +#define STM32_RTCPRE_DIV8 (2 << 29) /**< HSE divided by 2. */ +#define STM32_RTCPRE_DIV16 (3 << 29) /**< HSE divided by 16. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ +#define STM32_SW_HSI (1 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_PLLSRC_HSI (0 << 16) /**< PLL clock source is HSI. */ +#define STM32_PLLSRC_HSE (1 << 16) /**< PLL clock source is HSE. */ + +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_HSI (2 << 24) /**< HSI clock on MCO pin. */ +#define STM32_MCOSEL_MSI (3 << 24) /**< MSI clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ + +#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ +#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ +#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ +#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ +#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ +/** @} */ + +/** + * @name RCC_ICSCR register bits definitions + * @{ + */ +#define STM32_MSIRANGE_MASK (7 << 13) /**< MSIRANGE field mask. */ +#define STM32_MSIRANGE_64K (0 << 13) /**< 64kHz nominal. */ +#define STM32_MSIRANGE_128K (1 << 13) /**< 128kHz nominal. */ +#define STM32_MSIRANGE_256K (2 << 13) /**< 256kHz nominal. */ +#define STM32_MSIRANGE_512K (3 << 13) /**< 512kHz nominal. */ +#define STM32_MSIRANGE_1M (4 << 13) /**< 1MHz nominal. */ +#define STM32_MSIRANGE_2M (5 << 13) /**< 2MHz nominal. */ +#define STM32_MSIRANGE_4M (6 << 13) /**< 4MHz nominal */ +/** @} */ + +/** + * @name RCC_CSR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 16) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 16) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 16) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 16) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 16) /**< RTC source is HSE divided. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_1P8 +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI clock source. + */ +#if !defined(STM32_HSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief ADC clock setting. + */ +#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_ADC_CLOCK_ENABLED TRUE +#endif + +/** + * @brief USB clock setting. + */ +#if !defined(STM32_USB_CLOCK_ENABLED) || defined(__DOXYGEN__) +#define STM32_USB_CLOCK_ENABLED TRUE +#endif + +/** + * @brief MSI frequency setting. + */ +#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) +#define STM32_MSIRANGE STM32_MSIRANGE_2M +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_HSI +#endif + +/** + * @brief PLL multiplier value. + * @note The allowed values are 3, 4, 6, 8, 12, 16, 32, 48. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLMUL_VALUE 6 +#endif + +/** + * @brief PLL divider value. + * @note The allowed values are 2, 3, 4. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_PLLDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLDIV_VALUE 3 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 32MHz system clock from + * the internal 16MHz HSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief RTC/LCD clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief HSE divider toward RTC setting. + */ +#if !defined(STM32_RTCPRE) || defined(__DOXYGEN__) +#define STM32_RTCPRE STM32_RTCPRE_DIV2 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32L1xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L1xx_MCUCONF not defined" +#endif + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_1P8) || defined(__DOXYGEN__) +/** + * @brief Maximum HSE clock frequency at current voltage setting. + */ +#define STM32_HSECLK_MAX 32000000 + +/** + * @brief Maximum SYSCLK clock frequency at current voltage setting. + */ +#define STM32_SYSCLK_MAX 32000000 + +/** + * @brief Maximum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MAX 96000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 6000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 32000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 32000000 + +/** + * @brief Maximum frequency not requiring a wait state for flash accesses. + */ +#define STM32_0WS_THRESHOLD 16000000 + +/** + * @brief HSI availability at current voltage settings. + */ +#define STM32_HSI_AVAILABLE TRUE + +#elif STM32_VOS == STM32_VOS_1P5 +#define STM32_HSECLK_MAX 16000000 +#define STM32_SYSCLK_MAX 16000000 +#define STM32_PLLVCO_MAX 48000000 +#define STM32_PLLVCO_MIN 6000000 +#define STM32_PCLK1_MAX 16000000 +#define STM32_PCLK2_MAX 16000000 +#define STM32_0WS_THRESHOLD 8000000 +#define STM32_HSI_AVAILABLE TRUE +#elif STM32_VOS == STM32_VOS_1P2 +#define STM32_HSECLK_MAX 4000000 +#define STM32_SYSCLK_MAX 4000000 +#define STM32_PLLVCO_MAX 24000000 +#define STM32_PLLVCO_MIN 6000000 +#define STM32_PCLK1_MAX 4000000 +#define STM32_PCLK2_MAX 4000000 +#define STM32_0WS_THRESHOLD 2000000 +#define STM32_HSI_AVAILABLE FALSE +#else +#error "invalid STM32_VOS value specified" +#endif + +/* HSI related checks.*/ +#if STM32_HSI_ENABLED +#if !STM32_HSI_AVAILABLE + #error "impossible to activate HSI under the current voltage settings" +#endif +#else /* !STM32_HSI_ENABLED */ +#if STM32_ADC_CLOCK_ENABLED || \ + (STM32_SW == STM32_SW_HSI) || \ + ((STM32_SW == STM32_SW_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) || \ + (STM32_MCOSEL == STM32_MCOSEL_HSI) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI)) +#error "required HSI clock is not enabled" +#endif +#endif /* !STM32_HSI_ENABLED */ + +/* HSE related checks.*/ +#if STM32_HSE_ENABLED +#if STM32_HSECLK == 0 +#error "impossible to activate HSE" +#endif +#if (STM32_HSECLK < 1000000) || (STM32_HSECLK > STM32_HSECLK_MAX) +#error "STM32_HSECLK outside acceptable range (1MHz...STM32_HSECLK_MAX)" +#endif +#else /* !STM32_HSE_ENABLED */ +#if (STM32_SW == STM32_SW_HSE) || \ + ((STM32_SW == STM32_SW_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ + (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) || \ + (STM32_RTCSEL == STM32_RTCSEL_HSEDIV) +#error "required HSE clock is not enabled" +#endif +#endif /* !STM32_HSE_ENABLED */ + +/* LSI related checks.*/ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_LSI +#error "LSI not enabled, required by STM32_MCOSEL" +#endif + +#if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) +#error "LSI not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSI_ENABLED */ + +/* LSE related checks.*/ +#if STM32_LSE_ENABLED +#if (STM32_LSECLK == 0) +#error "impossible to activate LSE" +#endif +#if (STM32_LSECLK < 1000) || (STM32_LSECLK > 1000000) +#error "STM32_LSECLK outside acceptable range (1...1000kHz)" +#endif +#else /* !STM32_LSE_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_LSE +#error "LSE not enabled, required by STM32_MCOSEL" +#endif + +#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL_LSE) +#error "LSE not enabled, required by FOME_STM32_LSE_WAIT_MAX_RTCSEL" +#endif + +#if STM32_RTCSEL == STM32_RTCSEL_LSE +#error "LSE not enabled, required by STM32_RTCSEL" +#endif + +#endif /* !STM32_LSE_ENABLED */ + +/* PLL related checks.*/ +#if STM32_USB_CLOCK_ENABLED || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + defined(__DOXYGEN__) +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief PLLMUL field. + */ +#if (STM32_PLLMUL_VALUE == 3) || defined(__DOXYGEN__) +#define STM32_PLLMUL (0 << 18) +#elif STM32_PLLMUL_VALUE == 4 +#define STM32_PLLMUL (1 << 18) +#elif STM32_PLLMUL_VALUE == 6 +#define STM32_PLLMUL (2 << 18) +#elif STM32_PLLMUL_VALUE == 8 +#define STM32_PLLMUL (3 << 18) +#elif STM32_PLLMUL_VALUE == 12 +#define STM32_PLLMUL (4 << 18) +#elif STM32_PLLMUL_VALUE == 16 +#define STM32_PLLMUL (5 << 18) +#elif STM32_PLLMUL_VALUE == 24 +#define STM32_PLLMUL (6 << 18) +#elif STM32_PLLMUL_VALUE == 32 +#define STM32_PLLMUL (7 << 18) +#elif STM32_PLLMUL_VALUE == 48 +#define STM32_PLLMUL (8 << 18) +#else +#error "invalid STM32_PLLMUL_VALUE value specified" +#endif + +/** + * @brief PLLDIV field. + */ +#if (STM32_PLLDIV_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLDIV (1 << 22) +#elif STM32_PLLDIV_VALUE == 3 +#define STM32_PLLDIV (2 << 22) +#elif STM32_PLLDIV_VALUE == 4 +#define STM32_PLLDIV (3 << 22) +#else +#error "invalid STM32_PLLDIV_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN STM32_HSECLK +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLCLKIN STM32_HSICLK +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* PLL input frequency range check.*/ +#if (STM32_PLLCLKIN < 2000000) || (STM32_PLLCLKIN > 24000000) +#error "STM32_PLLCLKIN outside acceptable range (2...24MHz)" +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLMUL_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL output clock frequency. + */ +#define STM32_PLLCLKOUT (STM32_PLLVCO / STM32_PLLDIV_VALUE) + +/* PLL output frequency range check.*/ +#if (STM32_PLLCLKOUT < 2000000) || (STM32_PLLCLKOUT > 32000000) +#error "STM32_PLLCLKOUT outside acceptable range (2...32MHz)" +#endif + +/** + * @brief MSI frequency. + */ +#if STM32_MSIRANGE == STM32_MSIRANGE_64K +#define STM32_MSICLK 65500 +#elif STM32_MSIRANGE == STM32_MSIRANGE_128K +#define STM32_MSICLK 131000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_256K +#define STM32_MSICLK 262000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_512K +#define STM32_MSICLK 524000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_1M +#define STM32_MSICLK 1050000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_2M +#define STM32_MSICLK 2100000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_4M +#define STM32_MSICLK 4200000 +#else +#error "invalid STM32_MSIRANGE value specified" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK 2100000 +#elif (STM32_SW == STM32_SW_MSI) +#define STM32_SYSCLK STM32_MSICLK +#elif (STM32_SW == STM32_SW_HSI) +#define STM32_SYSCLK STM32_HSICLK +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLLCLKOUT +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* AHB frequency check.*/ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* APB1 frequency check.*/ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* APB2 frequency check.*/ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief MCO clock before divider. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 +#elif STM32_MCOSEL == STM32_MCOSEL_HSI +#define STM32_MCODIVCLK STM32_HSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_MSI +#define STM32_MCODIVCLK STM32_MSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK +#elif STM32_MCOSEL == STM32_MCOSEL_PLL +#define STM32_MCODIVCLK STM32_PLLCLKOUT +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief HSE divider toward RTC clock. + */ +#if (STM32_RTCPRE == STM32_RTCPRE_DIV2) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 2) +#elif (STM32_RTCPRE == STM32_RTCPRE_DIV4) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 4) +#elif (STM32_RTCPRE == STM32_RTCPRE_DIV8) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 8) +#elif (STM32_RTCPRE == STM32_RTCPRE_DIV16) || defined(__DOXYGEN__) +#define STM32_HSEDIVCLK (STM32_HSECLK / 16) +#else +#error "invalid STM32_RTCPRE value specified" +#endif + +/** + * @brief RTC/LCD clock. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK STM32_HSEDIVCLK +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USB frequency. + */ +#define STM32_USBCLK (STM32_PLLVCO / 2) + +/** + * @brief Timers 2, 3, 4, 6, 7 clock. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Timers 9, 10, 11 clock. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS1 0x00000000 +#else +#define STM32_FLASHBITS1 0x00000004 +#define STM32_FLASHBITS2 0x00000007 +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L4xx+/hal_lld.c b/os/hal/ports/STM32/STM32L4xx+/hal_lld.c index 6a6d6de997..23ec8d3a00 100644 --- a/os/hal/ports/STM32/STM32L4xx+/hal_lld.c +++ b/os/hal/ports/STM32/STM32L4xx+/hal_lld.c @@ -1,381 +1,381 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L4xx+/hal_lld.c - * @brief STM32L4xx+ HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32l4xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing RTC clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if STM32_MSIPLL_ENABLED - /* MSI PLL activation depends on LSE. Reactivating and checking for - MSI stability.*/ - RCC->CR |= RCC_CR_MSIPLLEN; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; /* Wait until MSI is stable. */ -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ - - /* Low speed output mode.*/ - RCC->BDCR |= STM32_LSCOSEL; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~0); - rccResetAHB2(~STM32_GPIO_EN_MASK); - rccResetAHB3(~0); - rccResetAPB1R1(~RCC_APB1RSTR1_PWRRST); - rccResetAPB1R2(~0); - rccResetAPB2(~0); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR2 = PWR_CR2_PVDE | (STM32_PLS & STM32_PLS_MASK); -#else - PWR->CR2 = 0; -#endif /* STM32_PVD_ENABLE */ - - /* Enabling independent VDDUSB.*/ -#if HAL_USE_USB - PWR->CR2 |= PWR_CR2_USV; -#endif /* HAL_USE_USB */ - - /* Enabling independent VDDIO2 required by GPIOG.*/ -#if STM32_HAS_GPIOG - PWR->CR2 |= PWR_CR2_IOSV; -#endif /* STM32_HAS_GPIOG */ -} - -/** - * @brief STM32L4xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enable.*/ -#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR1_RTCAPBEN) - RCC->APB1ENR1 = RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN; -#else - RCC->APB1ENR1 = RCC_APB1ENR1_PWREN; -#endif - - /* Initial clocks setup and wait for MSI stabilization, the MSI clock is - always enabled because it is the fall back clock when PLL the fails. - Trim fields are not altered from reset values.*/ - - /* MSIRANGE can be set only when MSI is OFF or READY.*/ - RCC->CR = RCC_CR_MSION; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; /* Wait until MSI is stable. */ - - /* Clocking from MSI, in case MSI was not the default source.*/ - RCC->CFGR = 0; - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) - ; /* Wait until MSI is selected. */ - - /* Core voltage setup.*/ - PWR->CR1 = STM32_VOS; - while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ - ; /* stable. */ - - /* Boost mode setting.*/ - PWR->CR5 = STM32_R1MODE; - -#if STM32_HSI16_ENABLED - /* HSI activation.*/ - RCC->CR |= RCC_CR_HSION; - while ((RCC->CR & RCC_CR_HSIRDY) == 0) - ; /* Wait until HSI16 is stable. */ -#endif - -#if STM32_HSI48_ENABLED - /* HSI activation.*/ - RCC->CRRCR |= RCC_CRRCR_HSI48ON; - while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0) - ; /* Wait until HSI48 is stable. */ -#endif - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Wait until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Wait until LSI is stable. */ -#endif - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - -#if STM32_LSE_ENABLED - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Wait until LSE is stable. */ -#endif - - /* Flash setup for selected MSI speed setting.*/ - FLASH->ACR = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | - STM32_MSI_FLASHBITS; - - /* Changing MSIRANGE to configured value.*/ - RCC->CR |= STM32_MSIRANGE; - - /* Switching from MSISRANGE to MSIRANGE.*/ - RCC->CR |= RCC_CR_MSIRGSEL; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; - - /* MSI is configured SYSCLK source so wait for it to be stable as well.*/ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) - ; - -#if STM32_MSIPLL_ENABLED - /* MSI PLL (to LSE) activation */ - RCC->CR |= RCC_CR_MSIPLLEN; -#endif - - /* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high. - This range is used exiting the Standby mode until MSIRGSEL is set.*/ - RCC->CSR |= STM32_MSISRANGE; - -#if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2 - /* PLLM and PLLSRC are common to all PLLs.*/ - RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR | - STM32_PLLREN | STM32_PLLQ | - STM32_PLLQEN | STM32_PLLP | - STM32_PLLPEN | STM32_PLLN | - STM32_PLLM | STM32_PLLSRC; -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLRDY) == 0) - ; -#endif - -#if STM32_ACTIVATE_PLLSAI1 - /* PLLSAI1 activation.*/ - RCC->PLLSAI1CFGR = STM32_PLLSAI1PDIV | STM32_PLLSAI1R | - STM32_PLLSAI1REN | STM32_PLLSAI1Q | - STM32_PLLSAI1QEN | STM32_PLLSAI1P | - STM32_PLLSAI1PEN | STM32_PLLSAI1N | - STM32_PLLSAI1M; - RCC->CR |= RCC_CR_PLLSAI1ON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLSAI1RDY) == 0) - ; -#endif - -#if STM32_ACTIVATE_PLLSAI2 - /* PLLSAI2 activation.*/ - RCC->PLLSAI2CFGR = STM32_PLLSAI2PDIV | STM32_PLLSAI2R | - STM32_PLLSAI2REN | STM32_PLLSAI2P | - STM32_PLLSAI2PEN | STM32_PLLSAI2N | - STM32_PLLSAI2M; - RCC->CR |= RCC_CR_PLLSAI2ON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLSAI2RDY) == 0) - ; -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_STOPWUCK | - STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; - - /* CCIPR register initialization.*/ - { - uint32_t ccipr = STM32_ADCSEL | - STM32_CLK48SEL | STM32_LPTIM2SEL | STM32_LPTIM1SEL | - STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | - STM32_LPUART1SEL | STM32_UART5SEL | STM32_UART4SEL | - STM32_USART3SEL | STM32_USART2SEL | STM32_USART1SEL; - RCC->CCIPR = ccipr; - } - - /* CCIPR2 register initialization, note, must take care of the _OFF - pseudo settings.*/ - { - uint32_t ccipr = STM32_OSPISEL | STM32_PLLSAI2DIVR | - STM32_SDMMCSEL | STM32_DSISEL | STM32_ADFSDMSEL | - STM32_DFSDMSEL | STM32_I2C4SEL; -#if STM32_SAI2SEL != STM32_SAI2SEL_OFF - ccipr |= STM32_SAI2SEL; -#endif -#if STM32_SAI1SEL != STM32_SAI1SEL_OFF - ccipr |= STM32_SAI1SEL; -#endif - RCC->CCIPR2 = ccipr; - } - - /* Set flash WS's for SYSCLK source */ - if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) { - FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - } - - /* Switching to the configured SYSCLK source if it is different from MSI.*/ -#if (STM32_SW != STM32_SW_MSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - /* Wait until SYSCLK is stable.*/ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif - - /* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */ - if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) { - FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - } - -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L4xx+/hal_lld.c + * @brief STM32L4xx+ HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32l4xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing RTC clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int rusefiLseCounter = 0; + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if STM32_MSIPLL_ENABLED + /* MSI PLL activation depends on LSE. Reactivating and checking for + MSI stability.*/ + RCC->CR |= RCC_CR_MSIPLLEN; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; /* Wait until MSI is stable. */ +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + + /* Low speed output mode.*/ + RCC->BDCR |= STM32_LSCOSEL; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~0); + rccResetAHB2(~STM32_GPIO_EN_MASK); + rccResetAHB3(~0); + rccResetAPB1R1(~RCC_APB1RSTR1_PWRRST); + rccResetAPB1R2(~0); + rccResetAPB2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR2 = PWR_CR2_PVDE | (STM32_PLS & STM32_PLS_MASK); +#else + PWR->CR2 = 0; +#endif /* STM32_PVD_ENABLE */ + + /* Enabling independent VDDUSB.*/ +#if HAL_USE_USB + PWR->CR2 |= PWR_CR2_USV; +#endif /* HAL_USE_USB */ + + /* Enabling independent VDDIO2 required by GPIOG.*/ +#if STM32_HAS_GPIOG + PWR->CR2 |= PWR_CR2_IOSV; +#endif /* STM32_HAS_GPIOG */ +} + +/** + * @brief STM32L4xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ +#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR1_RTCAPBEN) + RCC->APB1ENR1 = RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN; +#else + RCC->APB1ENR1 = RCC_APB1ENR1_PWREN; +#endif + + /* Initial clocks setup and wait for MSI stabilization, the MSI clock is + always enabled because it is the fall back clock when PLL the fails. + Trim fields are not altered from reset values.*/ + + /* MSIRANGE can be set only when MSI is OFF or READY.*/ + RCC->CR = RCC_CR_MSION; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; /* Wait until MSI is stable. */ + + /* Clocking from MSI, in case MSI was not the default source.*/ + RCC->CFGR = 0; + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + ; /* Wait until MSI is selected. */ + + /* Core voltage setup.*/ + PWR->CR1 = STM32_VOS; + while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ + ; /* stable. */ + + /* Boost mode setting.*/ + PWR->CR5 = STM32_R1MODE; + +#if STM32_HSI16_ENABLED + /* HSI activation.*/ + RCC->CR |= RCC_CR_HSION; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Wait until HSI16 is stable. */ +#endif + +#if STM32_HSI48_ENABLED + /* HSI activation.*/ + RCC->CRRCR |= RCC_CRRCR_HSI48ON; + while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0) + ; /* Wait until HSI48 is stable. */ +#endif + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Wait until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Wait until LSI is stable. */ +#endif + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + +#if STM32_LSE_ENABLED + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Wait until LSE is stable. */ +#endif + + /* Flash setup for selected MSI speed setting.*/ + FLASH->ACR = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | + STM32_MSI_FLASHBITS; + + /* Changing MSIRANGE to configured value.*/ + RCC->CR |= STM32_MSIRANGE; + + /* Switching from MSISRANGE to MSIRANGE.*/ + RCC->CR |= RCC_CR_MSIRGSEL; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; + + /* MSI is configured SYSCLK source so wait for it to be stable as well.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + ; + +#if STM32_MSIPLL_ENABLED + /* MSI PLL (to LSE) activation */ + RCC->CR |= RCC_CR_MSIPLLEN; +#endif + + /* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high. + This range is used exiting the Standby mode until MSIRGSEL is set.*/ + RCC->CSR |= STM32_MSISRANGE; + +#if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2 + /* PLLM and PLLSRC are common to all PLLs.*/ + RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR | + STM32_PLLREN | STM32_PLLQ | + STM32_PLLQEN | STM32_PLLP | + STM32_PLLPEN | STM32_PLLN | + STM32_PLLM | STM32_PLLSRC; +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLRDY) == 0) + ; +#endif + +#if STM32_ACTIVATE_PLLSAI1 + /* PLLSAI1 activation.*/ + RCC->PLLSAI1CFGR = STM32_PLLSAI1PDIV | STM32_PLLSAI1R | + STM32_PLLSAI1REN | STM32_PLLSAI1Q | + STM32_PLLSAI1QEN | STM32_PLLSAI1P | + STM32_PLLSAI1PEN | STM32_PLLSAI1N | + STM32_PLLSAI1M; + RCC->CR |= RCC_CR_PLLSAI1ON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLSAI1RDY) == 0) + ; +#endif + +#if STM32_ACTIVATE_PLLSAI2 + /* PLLSAI2 activation.*/ + RCC->PLLSAI2CFGR = STM32_PLLSAI2PDIV | STM32_PLLSAI2R | + STM32_PLLSAI2REN | STM32_PLLSAI2P | + STM32_PLLSAI2PEN | STM32_PLLSAI2N | + STM32_PLLSAI2M; + RCC->CR |= RCC_CR_PLLSAI2ON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLSAI2RDY) == 0) + ; +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_STOPWUCK | + STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + + /* CCIPR register initialization.*/ + { + uint32_t ccipr = STM32_ADCSEL | + STM32_CLK48SEL | STM32_LPTIM2SEL | STM32_LPTIM1SEL | + STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | + STM32_LPUART1SEL | STM32_UART5SEL | STM32_UART4SEL | + STM32_USART3SEL | STM32_USART2SEL | STM32_USART1SEL; + RCC->CCIPR = ccipr; + } + + /* CCIPR2 register initialization, note, must take care of the _OFF + pseudo settings.*/ + { + uint32_t ccipr = STM32_OSPISEL | STM32_PLLSAI2DIVR | + STM32_SDMMCSEL | STM32_DSISEL | STM32_ADFSDMSEL | + STM32_DFSDMSEL | STM32_I2C4SEL; +#if STM32_SAI2SEL != STM32_SAI2SEL_OFF + ccipr |= STM32_SAI2SEL; +#endif +#if STM32_SAI1SEL != STM32_SAI1SEL_OFF + ccipr |= STM32_SAI1SEL; +#endif + RCC->CCIPR2 = ccipr; + } + + /* Set flash WS's for SYSCLK source */ + if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) { + FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + } + + /* Switching to the configured SYSCLK source if it is different from MSI.*/ +#if (STM32_SW != STM32_SW_MSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + /* Wait until SYSCLK is stable.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif + + /* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */ + if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) { + FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + } + +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L4xx+/hal_lld.h b/os/hal/ports/STM32/STM32L4xx+/hal_lld.h index 1b16e26561..ee76374198 100644 --- a/os/hal/ports/STM32/STM32L4xx+/hal_lld.h +++ b/os/hal/ports/STM32/STM32L4xx+/hal_lld.h @@ -1,2614 +1,2614 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L4xx+/hal_lld.h - * @brief STM32L4xx+ HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32L4R5xx, STM32L4R7xx, STM32L4R9xx. - * - STM32L4S5xx, STM32L4S7xx, STM32L4S9xx. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || \ - defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32L4+ Ultra Low Power" - -#elif defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) -#define PLATFORM_NAME "STM32L4+ Ultra Low Power with Crypto" - -#else -#error "STM32L4+ device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32L4XXP) || defined(__DOXYGEN__) -#define STM32L4XXP -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ -#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ -#define STM32_LSICLK 32000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR1 register bits definitions - * @{ - */ -#define STM32_VOS_MASK (3 << 9) /**< Core voltage mask. */ -#define STM32_VOS_RANGE1 (1 << 9) /**< Core voltage 1.2 Volts. */ -#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ -/** @} */ - -/** - * @name PWR_CR2 register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */ -#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CR register bits definitions - * @{ - */ -#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */ -#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */ -#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */ -#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */ -#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */ -#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */ -#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */ -#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */ -#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */ -#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */ -#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */ -#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */ -#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ -#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ -#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 8) /**< PPRE1 field mask. */ -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_STOPWUCK_MASK (1 << 15) /**< STOPWUCK field mask. */ -#define STM32_STOPWUCK_MSI (0 << 15) /**< Wakeup clock is MSI. */ -#define STM32_STOPWUCK_HSI16 (1 << 15) /**< Wakeup clock is HSI16. */ - -#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ -#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ - -#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ -#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ -#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ -#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ -#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ -#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSRC_MSI (1 << 0) /**< PLL clock source is MSI. */ -#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CCIPR register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ -#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ -#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ -#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 source is HSI16. */ -#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ - -#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ -#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ -#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ -#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 source is HSI16. */ -#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ - -#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ -#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ -#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ -#define STM32_USART3SEL_HSI16 (2 << 4) /**< USART3 source is HSI16. */ -#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ - -#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ -#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ -#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ -#define STM32_UART4SEL_HSI16 (2 << 6) /**< UART4 source is HSI16. */ -#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ - -#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ -#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ -#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ -#define STM32_UART5SEL_HSI16 (2 << 8) /**< UART5 source is HSI16. */ -#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ - -#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 mask. */ -#define STM32_LPUART1SEL_PCLK1 (0 << 10) /**< LPUART1 source is PCLK1. */ -#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 source is SYSCLK. */ -#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 source is HSI16. */ -#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 source is LSE. */ - -#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK1 (0 << 12) /**< I2C1 source is PCLK1. */ -#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 source is HSI16. */ - -#define STM32_I2C2SEL_MASK (3 << 14) /**< I2C2SEL mask. */ -#define STM32_I2C2SEL_PCLK1 (0 << 14) /**< I2C2 source is PCLK1. */ -#define STM32_I2C2SEL_SYSCLK (1 << 14) /**< I2C2 source is SYSCLK. */ -#define STM32_I2C2SEL_HSI16 (2 << 14) /**< I2C2 source is HSI16. */ - -#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3SEL mask. */ -#define STM32_I2C3SEL_PCLK1 (0 << 16) /**< I2C3 source is PCLK1. */ -#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 source is SYSCLK. */ -#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 source is HSI16. */ - -#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1SEL mask. */ -#define STM32_LPTIM1SEL_PCLK1 (0 << 18) /**< LPTIM1 source is PCLK1. */ -#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 source is HSI16. */ -#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 source is LSE. */ - -#define STM32_LPTIM2SEL_MASK (3 << 20) /**< LPTIM2SEL mask. */ -#define STM32_LPTIM2SEL_PCLK1 (0 << 20) /**< LPTIM2 source is PCLK1. */ -#define STM32_LPTIM2SEL_LSI (1 << 20) /**< LPTIM2 source is LSI. */ -#define STM32_LPTIM2SEL_HSI16 (2 << 20) /**< LPTIM2 source is HSI16. */ -#define STM32_LPTIM2SEL_LSE (3 << 20) /**< LPTIM2 source is LSE. */ - -#define STM32_CLK48SEL_MASK (3 << 26) /**< CLK48SEL mask. */ -#define STM32_CLK48SEL_HSI48 (0 << 26) /**< CLK48 source is HSI48. */ -#define STM32_CLK48SEL_PLLSAI1 (1 << 26) /**< CLK48 source is PLLSAI1-Q. */ -#define STM32_CLK48SEL_PLL (2 << 26) /**< CLK48 source is PLL-Q. */ -#define STM32_CLK48SEL_MSI (3 << 26) /**< CLK48 source is MSI. */ - -#define STM32_ADCSEL_MASK (3 << 28) /**< ADCSEL mask. */ -#define STM32_ADCSEL_NOCLK (0 << 28) /**< ADC clock disabled. */ -#define STM32_ADCSEL_PLLSAI1 (1 << 28) /**< ADC source is PLLSAI1-R. */ -#define STM32_ADCSEL_SYSCLK (3 << 28) /**< ADC source is SYSCLK. */ -/** @} */ - -/** - * @name RCC_CCIPR2 register bits definitions - * @{ - */ -#define STM32_I2C4SEL_MASK (3 << 0) /**< I2C1SEL mask. */ -#define STM32_I2C4SEL_PCLK1 (0 << 0) /**< I2C1 source is PCLK1. */ -#define STM32_I2C4SEL_SYSCLK (1 << 0) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C4SEL_HSI16 (2 << 0) /**< I2C1 source is HSI16. */ - -#define STM32_DFSDMSEL_MASK (1 << 2) /**< DFSDMSEL mask. */ -#define STM32_DFSDMSEL_PCLK2 (0 << 2) /**< DFSDMSEL source is PCLK2. */ -#define STM32_DFSDMSEL_SYSCLK (1 << 2) /**< DFSDMSEL source is SYSCLK. */ - -#define STM32_ADFSDMSEL_MASK (3 << 3) /**< ADFSDMSEL mask. */ -#define STM32_ADFSDMSEL_SAI1CLK (0 << 3) /**< ADFSDMSEL source is - SAI1CLK. */ -#define STM32_ADFSDMSEL_HSI16 (1 << 3) /**< ADFSDMSEL source is HSI16. */ -#define STM32_ADFSDMSEL_MSI (2 << 3) /**< ADFSDMSEL source is MSI. */ - -#define STM32_SAI1SEL_MASK (7 << 5) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_PLLSAI1 (0 << 5) /**< SAI1 source is PLLSAI1CLK. */ -#define STM32_SAI1SEL_PLLSAI2 (1 << 5) /**< SAI1 source is PLLSAI2CLK. */ -#define STM32_SAI1SEL_PLL (2 << 5) /**< SAI1 source is PLLSAI3CLK */ -#define STM32_SAI1SEL_EXTCLK (3 << 5) /**< SAI1 source is external. */ -#define STM32_SAI1SEL_HSI16 (4 << 5) /**< SAI1 source is HSI16. */ -#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ - -#define STM32_SAI2SEL_MASK (7 << 8) /**< SAI2SEL mask. */ -#define STM32_SAI2SEL_PLLSAI1 (0 << 8) /**< SAI2 source is PLLSAI1CLK. */ -#define STM32_SAI2SEL_PLLSAI2 (1 << 8) /**< SAI2 source is PLLSAI2CLK. */ -#define STM32_SAI2SEL_PLL (2 << 8) /**< SAI2 source is PLLSAI3CLK */ -#define STM32_SAI2SEL_EXTCLK (3 << 8) /**< SAI2 source is external. */ -#define STM32_SAI2SEL_HSI16 (4 << 8) /**< SAI2 source is HSI16. */ -#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ - -#define STM32_DSISEL_MASK (1 << 12) /**< DSISE mask. */ -#define STM32_DSISEL_DSIPHY (0 << 12) /**< DSISE source is DSIPHY. */ -#define STM32_DSISEL_PLLDSICLK (1 << 12) /**< DSISE source is PLLDSICLK. */ - -#define STM32_SDMMCSEL_MASK (1 << 14) /**< SDMMCSEL mask. */ -#define STM32_SDMMCSEL_48CLK (0 << 14) /**< SDMMCSEL source is 48CLK. */ -#define STM32_SDMMCSEL_PLLSAI3CLK (1 << 14) /**< SDMMCSEL source is - PLLSAI3CLK. */ - -#define STM32_PLLSAI2DIVR_MASK (3 << 16) /**< PLLSAI2DIVR mask. */ -#define STM32_PLLSAI2DIVR_DIV2 (0 << 16) /**< PLLSAI2_R divided by 2. */ -#define STM32_PLLSAI2DIVR_DIV4 (1 << 16) /**< PLLSAI2_R divided by 4. */ -#define STM32_PLLSAI2DIVR_DIV8 (2 << 16) /**< PLLSAI2_R divided by 8. */ -#define STM32_PLLSAI2DIVR_DIV16 (3 << 16) /**< PLLSAI2_R divided by 16. */ - -#define STM32_OSPISEL_MASK (3 << 20) /**< OSPISEL mask. */ -#define STM32_OSPISEL_SYSCLK (0 << 20) /**< OSPI source is SYSCLK. */ -#define STM32_OSPISEL_MSI (1 << 20) /**< OSPI source is MSI. */ -#define STM32_OSPISEL_48CLK (2 << 20) /**< OSPI source is 48CLK. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ - -#define STM32_LSCOSEL_MASK (3 << 24) /**< LSCO pin clock source. */ -#define STM32_LSCOSEL_NOCLOCK (0 << 24) /**< No clock on LSCO pin. */ -#define STM32_LSCOSEL_LSI (1 << 24) /**< LSI on LSCO pin. */ -#define STM32_LSCOSEL_LSE (3 << 24) /**< LSE on LSCO pin. */ -/** @} */ - -/** - * @name RCC_CSR register bits definitions - * @{ - */ -#define STM32_MSISRANGE_MASK (15 << 8) /**< MSISRANGE field mask. */ -#define STM32_MSISRANGE_1M (4 << 8) /**< 1MHz nominal. */ -#define STM32_MSISRANGE_2M (5 << 8) /**< 2MHz nominal. */ -#define STM32_MSISRANGE_4M (6 << 8) /**< 4MHz nominal. */ -#define STM32_MSISRANGE_8M (7 << 8) /**< 8MHz nominal. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_RANGE1 -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI16 clock source. - */ -#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSI48 clock source. - */ -#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI48_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Enables or disables the MSI PLL on LSE clock source. - */ -#if !defined(STM32_MSIPLL_ENABLED) || defined(__DOXYGEN__) -#define STM32_MSIPLL_ENABLED FALSE -#endif - -/** - * @brief MSI frequency setting. - */ -#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) -#define STM32_MSIRANGE STM32_MSIRANGE_4M -#endif - -/** - * @brief MSI frequency setting after standby. - */ -#if !defined(STM32_MSISRANGE) || defined(__DOXYGEN__) -#define STM32_MSISRANGE STM32_MSISRANGE_4M -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_MSI -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 1 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 8..127. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 60 -#endif - -/** - * @brief PLLPDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLPDIV_VALUE 0 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 7 -#endif - -/** - * @brief PLLQ divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 4 -#endif - -/** - * @brief PLLR divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLR_VALUE 2 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief STOPWUCK clock setting. - */ -#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) -#define STM32_STOPWUCK STM32_STOPWUCK_MSI -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief LSCO clock source. - */ -#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) -#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK -#endif - -/** - * @brief PLLSAI1M divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSAI1M_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1M_VALUE 1 -#endif - -/** - * @brief PLLSAI1N multiplier value. - * @note The allowed values are 8..127. - */ -#if !defined(STM32_PLLSAI1N_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1N_VALUE 72 -#endif - -/** - * @brief PLLSAI1PDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLSAI1PDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1PDIV_VALUE 6 -#endif - -/** - * @brief PLLSAI1P divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLSAI1P_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1P_VALUE 7 -#endif - -/** - * @brief PLLSAI1Q divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI1Q_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1Q_VALUE 6 -#endif - -/** - * @brief PLLSAI1R divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI1R_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1R_VALUE 6 -#endif - -/** - * @brief PLLSAI2M divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSAI2M_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2M_VALUE 1 -#endif - -/** - * @brief PLLSAI2N multiplier value. - * @note The allowed values are 8..127. - */ -#if !defined(STM32_PLLSAI2N_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2N_VALUE 72 -#endif - -/** - * @brief PLLSAI2PDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLSAI2PDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2PDIV_VALUE 6 -#endif - -/** - * @brief PLLSAI2P divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLSAI2P_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2P_VALUE 7 -#endif - -/** - * @brief PLLSAI2Q divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI2Q_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2Q_VALUE 6 -#endif - -/** - * @brief PLLSAI2R divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI2R_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2R_VALUE 6 -#endif - -/** - * @brief PLLSAI2DIVR value. - */ -#if !defined(STM32_PLLSAI2DIVR) || defined(__DOXYGEN__) -#define STM32_PLLSAI2DIVR STM32_PLLSAI2DIVR_DIV16 -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_SYSCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_SYSCLK -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) -#define STM32_USART3SEL STM32_USART3SEL_SYSCLK -#endif - -/** - * @brief UART4 clock source. - */ -#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) -#define STM32_UART4SEL STM32_UART4SEL_SYSCLK -#endif - -/** - * @brief UART5 clock source. - */ -#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) -#define STM32_UART5SEL STM32_UART5SEL_SYSCLK -#endif - -/** - * @brief LPUART1 clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) -#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK -#endif - -/** - * @brief I2C3 clock source. - */ -#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) -#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK -#endif - -/** - * @brief I2C4 clock source. - */ -#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) -#define STM32_I2C4SEL STM32_I2C4SEL_SYSCLK -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 -#endif - -/** - * @brief LPTIM2 clock source. - */ -#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 -#endif - -/** - * @brief CLK48SEL value (48MHz clock source). - */ -#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) -#define STM32_CLK48SEL STM32_CLK48SEL_PLL -#endif - -/** - * @brief ADCSEL value (ADCs clock source). - */ -#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) -#define STM32_ADCSEL STM32_ADCSEL_SYSCLK -#endif - -/** - * @brief DFSDMSEL value (DFSDM clock source). - */ -#if !defined(STM32_DFSDMSEL) || defined(__DOXYGEN__) -#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 -#endif - -/** - * @brief ADFSDMSEL value (DFSDM clock source). - */ -#if !defined(STM32_ADFSDMSEL) || defined(__DOXYGEN__) -#define STM32_ADFSDMSEL STM32_ADFSDMSEL_SAI1CLK -#endif - -/** - * @brief SAI1SEL value (SAI1 clock source). - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#endif - -/** - * @brief SAI2SEL value (SAI2 clock source). - */ -#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) -#define STM32_SAI2SEL STM32_SAI2SEL_OFF -#endif - -/** - * @brief DSISEL value (DSI clock source). - */ -#if !defined(STM32_DSISEL) || defined(__DOXYGEN__) -#define STM32_DSISEL STM32_DSISEL_DSIPHY -#endif - -/** - * @brief SDMMC value (SDMMC clock source). - */ -#if !defined(STM32_SDMMCSEL) || defined(__DOXYGEN__) -#define STM32_SDMMCSEL STM32_SDMMCSEL_48CLK -#endif - -/** - * @brief OSPISEL value (OSPISEL clock source). - */ -#if !defined(STM32_OSPISEL) || defined(__DOXYGEN__) -#define STM32_OSPISEL STM32_OSPISEL_SYSCLK -#endif - -/** - * @brief RTC/LCD clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32L4xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4xx_MCUCONF not defined" -#endif - -#if defined(STM32L4R5xx) && !defined(STM32L4R5_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4R5_MCUCONF not defined" - -#elif defined(STM32L4S5xx) && !defined(STM32L4S5_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4S5_MCUCONF not defined" - -#elif defined(STM32L4R7xx) && !defined(STM32L4R7_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4R7_MCUCONF not defined" - -#elif defined(STM32L4S7xx) && !defined(STM32L4S7_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4S7_MCUCONF not defined" - -#elif defined(STM32L4R9xx) && !defined(STM32L4R9_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4R9_MCUCONF not defined" - -#elif defined(STM32L4S9xx) && !defined(STM32L4S9_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4S9_MCUCONF not defined" - -#endif - -/* - * Board files sanity checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif - -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) -/** - * @name System Limits - * @{ - */ -/** - * @brief Maximum SYSCLK clock frequency in boost mode. - */ -#define STM32_SYSCLK_MAX 120000000 - -/** - * @brief Maximum SYSCLK clock frequency in normal mode. - */ -#define STM32_SYSCLK_NOBOOST_MAX 80000000 - -/** - * @brief Maximum HSE clock frequency at current voltage setting. - */ -#define STM32_HSECLK_MAX 48000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 48000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 8000000 - -/** - * @brief Minimum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MIN 8000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 16000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 2660000 - -/** - * @brief Maximum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MAX 344000000 - -/** - * @brief Minimum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MIN 64000000 - -/** - * @brief Maximum PLL-P output clock frequency. - */ -#define STM32_PLLP_MAX 120000000 - -/** - * @brief Minimum PLL-P output clock frequency. - */ -#define STM32_PLLP_MIN 2064500 - -/** - * @brief Maximum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MAX 120000000 - -/** - * @brief Minimum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MIN 8000000 - -/** - * @brief Maximum PLL-R output clock frequency. - */ -#define STM32_PLLR_MAX 120000000 - -/** - * @brief Minimum PLL-R output clock frequency. - */ -#define STM32_PLLR_MIN 8000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 120000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 120000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 80000000 -/** @} */ - -/** - * @name Flash Wait states - * @{ - */ -#define STM32_0WS_THRESHOLD 20000000 -#define STM32_1WS_THRESHOLD 40000000 -#define STM32_2WS_THRESHOLD 60000000 -#define STM32_3WS_THRESHOLD 80000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 120000000 -/** @} */ - -#elif STM32_VOS == STM32_VOS_RANGE2 -#define STM32_SYSCLK_MAX 26000000 -#define STM32_SYSCLK_NOBOOST_MAX 26000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 26000000 -#define STM32_HSECLK_MIN 8000000 -#define STM32_HSECLK_BYP_MIN 8000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_LSECLK_BYP_MIN 32768 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLIN_MIN 2660000 -#define STM32_PLLVCO_MAX 128000000 -#define STM32_PLLVCO_MIN 64000000 -#define STM32_PLLP_MAX 26000000 -#define STM32_PLLP_MIN 2064500 -#define STM32_PLLQ_MAX 26000000 -#define STM32_PLLQ_MIN 8000000 -#define STM32_PLLR_MAX 26000000 -#define STM32_PLLR_MIN 8000000 -#define STM32_PCLK1_MAX 26000000 -#define STM32_PCLK2_MAX 26000000 -#define STM32_ADCCLK_MAX 26000000 - -#define STM32_0WS_THRESHOLD 8000000 -#define STM32_1WS_THRESHOLD 16000000 -#define STM32_2WS_THRESHOLD 26000000 -#define STM32_3WS_THRESHOLD 0 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 - -#else -#error "invalid STM32_VOS value specified" -#endif - -/** - * @brief MSI frequency. - */ -#if STM32_MSIRANGE == STM32_MSIRANGE_100K -#define STM32_MSICLK 100000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_200K -#define STM32_MSICLK 200000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_400K -#define STM32_MSICLK 400000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_800K -#define STM32_MSICLK 800000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_1M -#define STM32_MSICLK 1000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_2M -#define STM32_MSICLK 2000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_4M -#define STM32_MSICLK 4000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_8M -#define STM32_MSICLK 8000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_16M -#define STM32_MSICLK 16000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_24M -#define STM32_MSICLK 24000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_32M -#define STM32_MSICLK 32000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_48M -#define STM32_MSICLK 48000000 -#else -#error "invalid STM32_MSIRANGE value specified" -#endif - -/** - * @brief MSIS frequency. - */ -#if STM32_MSISRANGE == STM32_MSISRANGE_1M -#define STM32_MSISCLK 1000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_2M -#define STM32_MSISCLK 2000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_4M -#define STM32_MSISCLK 4000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_8M -#define STM32_MSISCLK 8000000 -#else -#error "invalid STM32_MSISRANGE value specified" -#endif - -/* - * HSI16 related checks. - */ -#if STM32_HSI16_ENABLED -#else /* !STM32_HSI16_ENABLED */ - -#if STM32_SW == STM32_SW_HSI16 -#error "HSI16 not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -/* NOTE: Missing checks on the HSI16 pre-muxes, it is also required for newer - L4 devices.*/ - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16)) -#error "HSI16 not enabled, required by STM32_MCOSEL" -#endif - -#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SAI1SEL" -#endif - -#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SAI2SEL" -#endif - -#if (STM32_USART1SEL == STM32_USART1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART1SEL" -#endif -#if (STM32_USART2SEL == STM32_USART2SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART2SEL" -#endif -#if (STM32_USART3SEL == STM32_USART3SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART3SEL" -#endif -#if (STM32_UART4SEL == STM32_UART4SEL_HSI16) -#error "HSI16 not enabled, required by STM32_UART4SEL" -#endif -#if (STM32_UART5SEL == STM32_UART5SEL_HSI16) -#error "HSI16 not enabled, required by STM32_UART5SEL" -#endif -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_LPUART1SEL" -#endif - -#if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) -#error "HSI16 not enabled, required by I2C1SEL" -#endif -#if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) -#error "HSI16 not enabled, required by I2C2SEL" -#endif -#if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) -#error "HSI16 not enabled, required by I2C3SEL" -#endif -#if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) -#error "HSI16 not enabled, required by I2C4SEL" -#endif - -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) -#error "HSI16 not enabled, required by LPTIM1SEL" -#endif -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) -#error "HSI16 not enabled, required by LPTIM2SEL" -#endif - -#if (STM32_STOPWUCK == STM32_STOPWUCK_HSI16) -#error "HSI16 not enabled, required by STM32_STOPWUCK" -#endif - -#endif /* !STM32_HSI16_ENABLED */ - -#if STM32_HSI48_ENABLED -#else /* !STM32_HSI48_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_HSI48 -#error "HSI48 not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 -#error "HSI48 not enabled, required by STM32_CLK48SEL" -#endif -#endif /* !STM32_HSI48_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - - #if STM32_HSECLK == 0 - #error "HSE frequency not defined" - #else /* STM32_HSECLK != 0 */ - #if defined(STM32_HSE_BYPASS) - #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" - #endif - #else /* !defined(STM32_HSE_BYPASS) */ - #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" - #endif - #endif /* !defined(STM32_HSE_BYPASS) */ - #endif /* STM32_HSECLK != 0 */ - - #else /* !STM32_HSE_ENABLED */ - - #if STM32_SW == STM32_SW_HSE - #error "HSE not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) - #error "HSE not enabled, required by STM32_MCOSEL" - #endif - - #if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) | \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SAI1SEL" - #endif - - #if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) | \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SAI2SEL" - #endif - - #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV - #error "HSE not enabled, required by STM32_RTCSEL" - #endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - - #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) - #error "LSI not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSI - #error "LSI not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSI - #error "LSI not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - - #if (STM32_LSECLK == 0) - #error "LSE frequency not defined" - #endif - - #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) - #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" - #endif - -#else /* !STM32_LSE_ENABLED */ - - #if STM32_RTCSEL == STM32_RTCSEL_LSE - #error "LSE not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSE - #error "LSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSE - #error "LSE not enabled, required by STM32_LSCOSEL" - #endif - - #if STM32_MSIPLL_ENABLED == TRUE - #error "LSE not enabled, required by STM32_MSIPLL_ENABLED" - #endif - -#endif /* !STM32_LSE_ENABLED */ - -/* - * MSI related checks. - */ -#if (STM32_MSIRANGE == STM32_MSIRANGE_48M) && !STM32_MSIPLL_ENABLED -#warning "STM32_MSIRANGE_48M should be used with STM32_MSIPLL_ENABLED" -#endif - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_MSI -#define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 -#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK -#define STM32_PLLCLKIN 0 - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLL input frequency range check. - */ -#if (STM32_PLLCLKIN != 0) && \ - ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_HSI48_ENABLED && (STM32_CLK48SEL == STM32_CLK48SEL_PLL)) || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ - defined(__DOXYGEN__) - -#if STM32_PLLCLKIN == 0 -#error "PLL activation required but no PLL clock selected" -#endif - -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 8) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLP (0 << 17) - -#elif STM32_PLLP_VALUE == 17 -#define STM32_PLLP (1 << 17) - -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLQ (0 << 21) - -#elif STM32_PLLQ_VALUE == 4 -#define STM32_PLLQ (1 << 21) - -#elif STM32_PLLQ_VALUE == 6 -#define STM32_PLLQ (2 << 21) - -#elif STM32_PLLQ_VALUE == 8 -#define STM32_PLLQ (3 << 21) - -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLR field. - */ -#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLR (0 << 25) - -#elif STM32_PLLR_VALUE == 4 -#define STM32_PLLR (1 << 25) - -#elif STM32_PLLR_VALUE == 6 -#define STM32_PLLR (2 << 25) - -#elif STM32_PLLR_VALUE == 8 -#define STM32_PLLR (3 << 25) - -#else -#error "invalid STM32_PLLR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLPDIV field. - */ -#if (STM32_PLLPDIV_VALUE == 0) || \ - ((STM32_PLLPDIV_VALUE != 1) && (STM32_PLLPDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) -#else -#error "invalid STM32_PLLPDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLPEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ - defined(__DOXYGEN__) -#define STM32_PLLPEN (1 << 16) -#else -#define STM32_PLLPEN (0 << 16) -#endif - -/** - * @brief STM32_PLLQEN field. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__) -#define STM32_PLLQEN (1 << 20) -#else -#define STM32_PLLQEN (0 << 20) -#endif - -/** - * @brief STM32_PLLREN field. - */ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - defined(__DOXYGEN__) -#define STM32_PLLREN (1 << 24) -#else -#define STM32_PLLREN (0 << 24) -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL P output clock frequency. - */ -#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) -#else -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) -#endif - -/** - * @brief PLL Q output clock frequency. - */ -#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) - -/** - * @brief PLL R output clock frequency. - */ -#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) - -/* - * PLL-P output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLL-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLL-R output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_MSICLK - -#elif (STM32_SW == STM32_SW_MSI) -#define STM32_SYSCLK STM32_MSICLK - -#elif (STM32_SW == STM32_SW_HSI16) -#define STM32_SYSCLK STM32_HSI16CLK - -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK - -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLL_R_CLKOUT - -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) - -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) - -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) - -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) - -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) - -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) - -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) - -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) - -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) - -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief STM32_PLLSAI1M field. - */ -#if ((STM32_PLLSAI1M_VALUE >= 1) && (STM32_PLLSAI1M_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1M ((STM32_PLLSAI1M_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLSAI1M_VALUE value specified" -#endif - -/** - * @brief PLLSAI1 input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1CLKIN (STM32_HSECLK / STM32_PLLSAI1M_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_MSI -#define STM32_PLLSAI1CLKIN (STM32_MSICLK / STM32_PLLSAI1M_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 -#define STM32_PLLSAI1CLKIN (STM32_HSI16CLK / STM32_PLLSAI1M_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK -#define STM32_PLLSAI1CLKIN 0 - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLLSAI1 input frequency range check. - */ -#if (STM32_PLLSAI1CLKIN != 0) && \ - ((STM32_PLLSAI1CLKIN < STM32_PLLIN_MIN) || \ - (STM32_PLLSAI1CLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLSAI1CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLLSAI1 enable check. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ - (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ - defined(__DOXYGEN__) - -#if STM32_PLLSAI1CLKIN == 0 -#error "PLLSAI1 activation required but no PLL clock selected" -#endif - -/** - * @brief PLLSAI1 activation flag. - */ -#define STM32_ACTIVATE_PLLSAI1 TRUE -#else -#define STM32_ACTIVATE_PLLSAI1 FALSE -#endif - -/** - * @brief STM32_PLLSAI1N field. - */ -#if ((STM32_PLLSAI1N_VALUE >= 8) && (STM32_PLLSAI1N_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1N (STM32_PLLSAI1N_VALUE << 8) -#else -#error "invalid STM32_PLLSAI1N_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1P field. - */ -#if (STM32_PLLSAI1P_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLSAI1P (0 << 17) - -#elif STM32_PLLSAI1P_VALUE == 17 -#define STM32_PLLSAI1P (1 << 17) - -#else -#error "invalid STM32_PLLSAI1P_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1Q field. - */ -#if (STM32_PLLSAI1Q_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI1Q (0 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 4 -#define STM32_PLLSAI1Q (1 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 6 -#define STM32_PLLSAI1Q (2 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 8 -#define STM32_PLLSAI1Q (3 << 21) - -#else -#error "invalid STM32_PLLSAI1Q_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1R field. - */ -#if (STM32_PLLSAI1R_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI1R (0 << 25) - -#elif STM32_PLLSAI1R_VALUE == 4 -#define STM32_PLLSAI1R (1 << 25) - -#elif STM32_PLLSAI1R_VALUE == 6 -#define STM32_PLLSAI1R (2 << 25) - -#elif STM32_PLLSAI1R_VALUE == 8 -#define STM32_PLLSAI1R (3 << 25) - -#else -#error "invalid STM32_PLLSAI1R_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1PDIV field. - */ -#if ((STM32_PLLSAI1PDIV_VALUE != 1) && (STM32_PLLSAI1PDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1PDIV (STM32_PLLSAI1PDIV_VALUE << 27) -#else -#error "invalid STM32_PLLSAI1PDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1PEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1PEN (1 << 16) -#else -#define STM32_PLLSAI1PEN (0 << 16) -#endif - -/** - * @brief STM32_PLLSAI1QEN field. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_PLLSAI1QEN (1 << 20) -#else -#define STM32_PLLSAI1QEN (0 << 20) -#endif - -/** - * @brief STM32_PLLSAI1REN field. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_PLLSAI1REN (1 << 24) -#else -#define STM32_PLLSAI1REN (0 << 24) -#endif - -/** - * @brief PLLSAI1 VCO frequency. - */ -#define STM32_PLLSAI1VCO (STM32_PLLSAI1CLKIN * STM32_PLLSAI1N_VALUE) - -/* - * PLLSAI1 VCO frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI1-P output clock frequency. - */ -#if (STM32_PLLSAI1PDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE) -#else -#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1PDIV_VALUE) -#endif - -/** - * @brief PLLSAI1-Q output clock frequency. - */ -#define STM32_PLLSAI1_Q_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) - -/** - * @brief PLLSAI1-R output clock frequency. - */ -#define STM32_PLLSAI1_R_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1R_VALUE) - -/* - * PLLSAI1-P output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLLSAI1-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLLSAI1-R output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief STM32_PLLSAI2M field. - */ -#if ((STM32_PLLSAI2M_VALUE >= 1) && (STM32_PLLSAI2M_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2M ((STM32_PLLSAI2M_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLSAI2M_VALUE value specified" -#endif - -/** - * @brief PLLSAI2 input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2CLKIN (STM32_HSECLK / STM32_PLLSAI2M_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_MSI -#define STM32_PLLSAI2CLKIN (STM32_MSICLK / STM32_PLLSAI2M_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 -#define STM32_PLLSAI2CLKIN (STM32_HSI16CLK / STM32_PLLSAI2M_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK -#define STM32_PLLSAI2CLKIN 0 - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLLSAI2 input frequency range check. - */ -#if (STM32_PLLSAI2CLKIN != 0) && \ - ((STM32_PLLSAI2CLKIN < STM32_PLLIN_MIN) || \ - (STM32_PLLSAI2CLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLSAI2CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLLSAI2 enable check. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ - defined(__DOXYGEN__) - -#if STM32_PLLSAI2CLKIN == 0 -#error "PLLSAI2 activation required but no PLL clock selected" -#endif - -/** - * @brief PLLSAI2 activation flag. - */ -#define STM32_ACTIVATE_PLLSAI2 TRUE -#else -#define STM32_ACTIVATE_PLLSAI2 FALSE -#endif - -/** - * @brief STM32_PLLSAI2N field. - */ -#if ((STM32_PLLSAI2N_VALUE >= 8) && (STM32_PLLSAI2N_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2N (STM32_PLLSAI2N_VALUE << 8) -#else -#error "invalid STM32_PLLSAI2N_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2P field. - */ -#if (STM32_PLLSAI2P_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLSAI2P (0 << 17) - -#elif STM32_PLLSAI2P_VALUE == 17 -#define STM32_PLLSAI2P (1 << 17) - -#else -#error "invalid STM32_PLLSAI2P_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2R field. - */ -#if (STM32_PLLSAI2R_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI2R (0 << 25) - -#elif STM32_PLLSAI2R_VALUE == 4 -#define STM32_PLLSAI2R (1 << 25) - -#elif STM32_PLLSAI2R_VALUE == 6 -#define STM32_PLLSAI2R (2 << 25) - -#elif STM32_PLLSAI2R_VALUE == 8 -#define STM32_PLLSAI2R (3 << 25) - -#else -#error "invalid STM32_PLLSAI2R_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2PDIV field. - */ -#if ((STM32_PLLSAI2PDIV_VALUE != 1) && (STM32_PLLSAI2PDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2PDIV (STM32_PLLSAI2PDIV_VALUE << 27) -#else -#error "invalid STM32_PLLSAI2PDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2PEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2PEN (1 << 16) -#else -#define STM32_PLLSAI2PEN (0 << 16) -#endif - -/** - * @brief STM32_PLLSAI2REN field. - * @note Always enabled. - * @note It should depend on some condition. - */ -#define STM32_PLLSAI2REN (1 << 24) - -/** - * @brief PLLSAI2 VCO frequency. - */ -#define STM32_PLLSAI2VCO (STM32_PLLSAI2CLKIN * STM32_PLLSAI2N_VALUE) - -/* - * PLLSAI2 VCO frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI2-P output clock frequency. - */ -#if (STM32_PLLSAI2PDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE) -#else -#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2PDIV_VALUE) -#endif - -/** - * @brief PLLSAI2-R output clock frequency. - */ -#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE) - -/* - * PLLSAI2-P output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLLSAI2-R output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief MCO divider clock frequency. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 - -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK -#define STM32_MCODIVCLK STM32_SYSCLK - -#elif STM32_MCOSEL == STM32_MCOSEL_MSI -#define STM32_MCODIVCLK STM32_MSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 -#define STM32_MCODIVCLK STM32_HSI16CLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_PLL -#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT - -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 -#define STM32_MCODIVCLK STM32_HSI48CLK - -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock frequency. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) - -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief RTC clock frequency. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 clock frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK2 - -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK - -#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 -#define STM32_USART1CLK STM32_HSI16CLK - -#elif STM32_USART1SEL == STM32_USART1SEL_LSE -#define STM32_USART1CLK STM32_LSECLK - -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 clock frequency. - */ -#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART2CLK STM32_PCLK1 - -#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK - -#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 -#define STM32_USART2CLK STM32_HSI16CLK - -#elif STM32_USART2SEL == STM32_USART2SEL_LSE -#define STM32_USART2CLK STM32_LSECLK - -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 clock frequency. - */ -#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART3CLK STM32_PCLK1 - -#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK -#define STM32_USART3CLK STM32_SYSCLK - -#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 -#define STM32_USART3CLK STM32_HSI16CLK - -#elif STM32_USART3SEL == STM32_USART3SEL_LSE -#define STM32_USART3CLK STM32_LSECLK - -#else -#error "invalid source selected for USART3 clock" -#endif - -/** - * @brief UART4 clock frequency. - */ -#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART4CLK STM32_PCLK1 - -#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK -#define STM32_UART4CLK STM32_SYSCLK - -#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 -#define STM32_UART4CLK STM32_HSI16CLK - -#elif STM32_UART4SEL == STM32_UART4SEL_LSE -#define STM32_UART4CLK STM32_LSECLK - -#else -#error "invalid source selected for UART4 clock" -#endif - -/** - * @brief UART5 clock frequency. - */ -#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART5CLK STM32_PCLK1 - -#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK -#define STM32_UART5CLK STM32_SYSCLK - -#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 -#define STM32_UART5CLK STM32_HSI16CLK - -#elif STM32_UART5SEL == STM32_UART5SEL_LSE -#define STM32_UART5CLK STM32_LSECLK - -#else -#error "invalid source selected for UART5 clock" -#endif - -/** - * @brief LPUART1 clock frequency. - */ -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPUART1CLK STM32_PCLK1 - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK -#define STM32_LPUART1CLK STM32_SYSCLK - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 -#define STM32_LPUART1CLK STM32_HSI16CLK - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE -#define STM32_LPUART1CLK STM32_LSECLK - -#else -#error "invalid source selected for LPUART1 clock" -#endif - -/** - * @brief I2C1 clock frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_PCLK1 - -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK - -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 -#define STM32_I2C1CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 clock frequency. - */ -#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C2CLK STM32_PCLK1 - -#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK -#define STM32_I2C2CLK STM32_SYSCLK - -#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 -#define STM32_I2C2CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C2 clock" -#endif - -/** - * @brief I2C3 clock frequency. - */ -#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C3CLK STM32_PCLK1 - -#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK -#define STM32_I2C3CLK STM32_SYSCLK - -#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 -#define STM32_I2C3CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C3 clock" -#endif - -/** - * @brief I2C4 clock frequency. - */ -#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C4CLK STM32_PCLK1 - -#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK -#define STM32_I2C4CLK STM32_SYSCLK - -#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 -#define STM32_I2C4CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C4 clock" -#endif - -/** - * @brief LPTIM1 clock frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM1CLK STM32_PCLK1 - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI -#define STM32_LPTIM1CLK STM32_LSICLK - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 -#define STM32_LPTIM1CLK STM32_HSI16CLK - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE -#define STM32_LPTIM1CLK STM32_LSECLK - -#else -#error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief LPTIM2 clock frequency. - */ -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM2CLK STM32_PCLK1 - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI -#define STM32_LPTIM2CLK STM32_LSICLK - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 -#define STM32_LPTIM2CLK STM32_HSI16CLK - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE -#define STM32_LPTIM2CLK STM32_LSECLK - -#else -#error "invalid source selected for LPTIM2 clock" -#endif - -/** - * @brief 48MHz clock frequency. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) -#define STM32_48CLK STM32_HSI48CLK - -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 -#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) - -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL -#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) - -#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI -#define STM32_48CLK STM32_MSICLK - -#else -#error "invalid source selected for 48CLK clock" -#endif - -/** - * @brief SAI1 clock frequency. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_SAI1CLK STM32_PLLSAI1_P_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2 -#define STM32_SAI1CLK STM32_PLLSAI2_P_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL -#define STM32_SAI1CLK STM32_PLL_P_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_EXTCLK -#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ - -#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16 -#define STM32_SAI1CLK STM32_HSI16CLK - -#elif STM32_SAI1SEL == STM32_SAI1SEL_OFF -#define STM32_SAI1CLK 0 - -#else -#error "invalid source selected for SAI1 clock" -#endif - -/** - * @brief SAI2 clock frequency. - */ -#if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_SAI2CLK STM32_PLLSAI1_P_CLKOUT - -#elif STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2 -#define STM32_SAI2CLK STM32_PLLSAI2_P_CLKOUT - -#elif STM32_SAI2SEL == STM32_SAI2SEL_PLL -#define STM32_SAI2CLK STM32_PLL_P_CLKOUT - -#elif STM32_SAI2SEL == STM32_SAI2SEL_EXTCLK -#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ - -#elif STM32_SAI2SEL == STM32_SAI2SEL_HSI16 -#define STM32_SAI2CLK STM32_HSI16CLK - -#elif STM32_SAI2SEL == STM32_SAI2SEL_OFF -#define STM32_SAI2CLK 0 - -#else -#error "invalid source selected for SAI2 clock" -#endif - -/** - * @brief DSI clock frequency. - */ -#if (STM32_DSISEL == STM32_DSISEL_DSIPHY) || defined(__DOXYGEN__) -#define STM32_DSICLK 0 - -#elif STM32_DSISEL == STM32_DSISEL_PLLDSICLK -#define STM32_DSICLK STM32_PLLSAI2_Q_CLKOUT - -#else -#error "invalid source selected for DSI clock" -#endif - -/** - * @brief SDMMC clock frequency. - */ -#if (STM32_SDMMCSEL == STM32_SDMMCSEL_48CLK) || defined(__DOXYGEN__) -#define STM32_SDMMCCLK STM32_48CLK - -#elif STM32_SDMMCSEL == STM32_SDMMCSEL_PLLSAI3CLK -#define STM32_SDMMCCLK STM32_PLL_P_CLKOUT - -#else -#error "invalid source selected for SDMMC clock" -#endif - -/** - * @brief USB clock point. - */ -#define STM32_USBCLK STM32_48CLK - -/** - * @brief RNG clock point. - */ -#define STM32_RNGCLK STM32_48CLK - -/** - * @brief ADC clock frequency. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_NOCLK) || defined(__DOXYGEN__) -#define STM32_ADCCLK 0 - -#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI1 -#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT - -#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK -#define STM32_ADCCLK STM32_SYSCLK - -#else -#error "invalid source selected for ADC clock" -#endif - -/** - * @brief DFSDM clock frequency. - */ -#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_DFSDMCLK STM32_PCLK2 - -#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK -#define STM32_DFSDMCLK STM32_SYSCLK - -#else -#error "invalid source selected for DFSDM clock" -#endif - -/** - * @brief SDMMC frequency. - */ -#define STM32_SDMMC1CLK STM32_48CLK - -/** - * @brief LTDC frequency. - */ -#if (STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV2) || defined(__DOXYGEN__) -#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 2) - -#elif STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV4 -#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 4) - -#elif STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV8 -#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 8) - -#elif STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV16 -#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 16) - -#else -#error "invalid STM32_PLLSAI2DIVR value specified" -#endif - -/** - * @brief OSPI clock frequency. - */ -#if (STM32_OSPISEL == STM32_OSPISEL_SYSCLK) || defined(__DOXYGEN__) -#define STM32_OSPICLK STM32_SYSCLK - -#elif STM32_OSPISEL == STM32_OSPISEL_MSI -#define STM32_OSPICLK STM32_MSICLK - -#elif STM32_OSPISEL == STM32_OSPISEL_48CLK -#define STM32_OSPICLK STM32_PLLSAI1_Q_CLKOUT - -#else -#error "invalid source selected for OSPI clock" -#endif - -/** - * @brief Clock of timers connected to APB1 - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Clock of timers connected to APB2. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Voltage boost settings. - */ -#if (STM32_SYSCLK <= STM32_SYSCLK_NOBOOST_MAX) || defined(__DOXYGEN__) -#define STM32_R1MODE PWR_CR5_R1MODE -#else -#define STM32_R1MODE 0 -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_HCLK <= STM32_3WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS - -#else -#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS -#endif - -/** - * @brief Flash settings for MSI. - */ -#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_MSICLK <= STM32_1WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_MSICLK <= STM32_2WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_MSICLK <= STM32_3WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS - -#else -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L4xx+/hal_lld.h + * @brief STM32L4xx+ HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32L4R5xx, STM32L4R7xx, STM32L4R9xx. + * - STM32L4S5xx, STM32L4S7xx, STM32L4S9xx. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || \ + defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32L4+ Ultra Low Power" + +#elif defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) +#define PLATFORM_NAME "STM32L4+ Ultra Low Power with Crypto" + +#else +#error "STM32L4+ device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32L4XXP) || defined(__DOXYGEN__) +#define STM32L4XXP +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ +#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR1 register bits definitions + * @{ + */ +#define STM32_VOS_MASK (3 << 9) /**< Core voltage mask. */ +#define STM32_VOS_RANGE1 (1 << 9) /**< Core voltage 1.2 Volts. */ +#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ +/** @} */ + +/** + * @name PWR_CR2 register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */ +#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CR register bits definitions + * @{ + */ +#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */ +#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */ +#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */ +#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */ +#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */ +#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */ +#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */ +#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */ +#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */ +#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */ +#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */ +#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */ +#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ +#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ +#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 8) /**< PPRE1 field mask. */ +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_STOPWUCK_MASK (1 << 15) /**< STOPWUCK field mask. */ +#define STM32_STOPWUCK_MSI (0 << 15) /**< Wakeup clock is MSI. */ +#define STM32_STOPWUCK_HSI16 (1 << 15) /**< Wakeup clock is HSI16. */ + +#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ +#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ + +#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ +#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ +#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ +#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ +#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ +#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSRC_MSI (1 << 0) /**< PLL clock source is MSI. */ +#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CCIPR register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ +#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ +#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ +#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 source is HSI16. */ +#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ + +#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ +#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ +#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ +#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 source is HSI16. */ +#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ + +#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ +#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ +#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ +#define STM32_USART3SEL_HSI16 (2 << 4) /**< USART3 source is HSI16. */ +#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ + +#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ +#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ +#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ +#define STM32_UART4SEL_HSI16 (2 << 6) /**< UART4 source is HSI16. */ +#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ + +#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ +#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ +#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ +#define STM32_UART5SEL_HSI16 (2 << 8) /**< UART5 source is HSI16. */ +#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ + +#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 mask. */ +#define STM32_LPUART1SEL_PCLK1 (0 << 10) /**< LPUART1 source is PCLK1. */ +#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 source is SYSCLK. */ +#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 source is HSI16. */ +#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 source is LSE. */ + +#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK1 (0 << 12) /**< I2C1 source is PCLK1. */ +#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 source is HSI16. */ + +#define STM32_I2C2SEL_MASK (3 << 14) /**< I2C2SEL mask. */ +#define STM32_I2C2SEL_PCLK1 (0 << 14) /**< I2C2 source is PCLK1. */ +#define STM32_I2C2SEL_SYSCLK (1 << 14) /**< I2C2 source is SYSCLK. */ +#define STM32_I2C2SEL_HSI16 (2 << 14) /**< I2C2 source is HSI16. */ + +#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3SEL mask. */ +#define STM32_I2C3SEL_PCLK1 (0 << 16) /**< I2C3 source is PCLK1. */ +#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 source is SYSCLK. */ +#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 source is HSI16. */ + +#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1SEL mask. */ +#define STM32_LPTIM1SEL_PCLK1 (0 << 18) /**< LPTIM1 source is PCLK1. */ +#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 source is HSI16. */ +#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 source is LSE. */ + +#define STM32_LPTIM2SEL_MASK (3 << 20) /**< LPTIM2SEL mask. */ +#define STM32_LPTIM2SEL_PCLK1 (0 << 20) /**< LPTIM2 source is PCLK1. */ +#define STM32_LPTIM2SEL_LSI (1 << 20) /**< LPTIM2 source is LSI. */ +#define STM32_LPTIM2SEL_HSI16 (2 << 20) /**< LPTIM2 source is HSI16. */ +#define STM32_LPTIM2SEL_LSE (3 << 20) /**< LPTIM2 source is LSE. */ + +#define STM32_CLK48SEL_MASK (3 << 26) /**< CLK48SEL mask. */ +#define STM32_CLK48SEL_HSI48 (0 << 26) /**< CLK48 source is HSI48. */ +#define STM32_CLK48SEL_PLLSAI1 (1 << 26) /**< CLK48 source is PLLSAI1-Q. */ +#define STM32_CLK48SEL_PLL (2 << 26) /**< CLK48 source is PLL-Q. */ +#define STM32_CLK48SEL_MSI (3 << 26) /**< CLK48 source is MSI. */ + +#define STM32_ADCSEL_MASK (3 << 28) /**< ADCSEL mask. */ +#define STM32_ADCSEL_NOCLK (0 << 28) /**< ADC clock disabled. */ +#define STM32_ADCSEL_PLLSAI1 (1 << 28) /**< ADC source is PLLSAI1-R. */ +#define STM32_ADCSEL_SYSCLK (3 << 28) /**< ADC source is SYSCLK. */ +/** @} */ + +/** + * @name RCC_CCIPR2 register bits definitions + * @{ + */ +#define STM32_I2C4SEL_MASK (3 << 0) /**< I2C1SEL mask. */ +#define STM32_I2C4SEL_PCLK1 (0 << 0) /**< I2C1 source is PCLK1. */ +#define STM32_I2C4SEL_SYSCLK (1 << 0) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C4SEL_HSI16 (2 << 0) /**< I2C1 source is HSI16. */ + +#define STM32_DFSDMSEL_MASK (1 << 2) /**< DFSDMSEL mask. */ +#define STM32_DFSDMSEL_PCLK2 (0 << 2) /**< DFSDMSEL source is PCLK2. */ +#define STM32_DFSDMSEL_SYSCLK (1 << 2) /**< DFSDMSEL source is SYSCLK. */ + +#define STM32_ADFSDMSEL_MASK (3 << 3) /**< ADFSDMSEL mask. */ +#define STM32_ADFSDMSEL_SAI1CLK (0 << 3) /**< ADFSDMSEL source is + SAI1CLK. */ +#define STM32_ADFSDMSEL_HSI16 (1 << 3) /**< ADFSDMSEL source is HSI16. */ +#define STM32_ADFSDMSEL_MSI (2 << 3) /**< ADFSDMSEL source is MSI. */ + +#define STM32_SAI1SEL_MASK (7 << 5) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_PLLSAI1 (0 << 5) /**< SAI1 source is PLLSAI1CLK. */ +#define STM32_SAI1SEL_PLLSAI2 (1 << 5) /**< SAI1 source is PLLSAI2CLK. */ +#define STM32_SAI1SEL_PLL (2 << 5) /**< SAI1 source is PLLSAI3CLK */ +#define STM32_SAI1SEL_EXTCLK (3 << 5) /**< SAI1 source is external. */ +#define STM32_SAI1SEL_HSI16 (4 << 5) /**< SAI1 source is HSI16. */ +#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ + +#define STM32_SAI2SEL_MASK (7 << 8) /**< SAI2SEL mask. */ +#define STM32_SAI2SEL_PLLSAI1 (0 << 8) /**< SAI2 source is PLLSAI1CLK. */ +#define STM32_SAI2SEL_PLLSAI2 (1 << 8) /**< SAI2 source is PLLSAI2CLK. */ +#define STM32_SAI2SEL_PLL (2 << 8) /**< SAI2 source is PLLSAI3CLK */ +#define STM32_SAI2SEL_EXTCLK (3 << 8) /**< SAI2 source is external. */ +#define STM32_SAI2SEL_HSI16 (4 << 8) /**< SAI2 source is HSI16. */ +#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ + +#define STM32_DSISEL_MASK (1 << 12) /**< DSISE mask. */ +#define STM32_DSISEL_DSIPHY (0 << 12) /**< DSISE source is DSIPHY. */ +#define STM32_DSISEL_PLLDSICLK (1 << 12) /**< DSISE source is PLLDSICLK. */ + +#define STM32_SDMMCSEL_MASK (1 << 14) /**< SDMMCSEL mask. */ +#define STM32_SDMMCSEL_48CLK (0 << 14) /**< SDMMCSEL source is 48CLK. */ +#define STM32_SDMMCSEL_PLLSAI3CLK (1 << 14) /**< SDMMCSEL source is + PLLSAI3CLK. */ + +#define STM32_PLLSAI2DIVR_MASK (3 << 16) /**< PLLSAI2DIVR mask. */ +#define STM32_PLLSAI2DIVR_DIV2 (0 << 16) /**< PLLSAI2_R divided by 2. */ +#define STM32_PLLSAI2DIVR_DIV4 (1 << 16) /**< PLLSAI2_R divided by 4. */ +#define STM32_PLLSAI2DIVR_DIV8 (2 << 16) /**< PLLSAI2_R divided by 8. */ +#define STM32_PLLSAI2DIVR_DIV16 (3 << 16) /**< PLLSAI2_R divided by 16. */ + +#define STM32_OSPISEL_MASK (3 << 20) /**< OSPISEL mask. */ +#define STM32_OSPISEL_SYSCLK (0 << 20) /**< OSPI source is SYSCLK. */ +#define STM32_OSPISEL_MSI (1 << 20) /**< OSPI source is MSI. */ +#define STM32_OSPISEL_48CLK (2 << 20) /**< OSPI source is 48CLK. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ + +#define STM32_LSCOSEL_MASK (3 << 24) /**< LSCO pin clock source. */ +#define STM32_LSCOSEL_NOCLOCK (0 << 24) /**< No clock on LSCO pin. */ +#define STM32_LSCOSEL_LSI (1 << 24) /**< LSI on LSCO pin. */ +#define STM32_LSCOSEL_LSE (3 << 24) /**< LSE on LSCO pin. */ +/** @} */ + +/** + * @name RCC_CSR register bits definitions + * @{ + */ +#define STM32_MSISRANGE_MASK (15 << 8) /**< MSISRANGE field mask. */ +#define STM32_MSISRANGE_1M (4 << 8) /**< 1MHz nominal. */ +#define STM32_MSISRANGE_2M (5 << 8) /**< 2MHz nominal. */ +#define STM32_MSISRANGE_4M (6 << 8) /**< 4MHz nominal. */ +#define STM32_MSISRANGE_8M (7 << 8) /**< 8MHz nominal. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_RANGE1 +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI16 clock source. + */ +#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSI48 clock source. + */ +#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI48_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Enables or disables the MSI PLL on LSE clock source. + */ +#if !defined(STM32_MSIPLL_ENABLED) || defined(__DOXYGEN__) +#define STM32_MSIPLL_ENABLED FALSE +#endif + +/** + * @brief MSI frequency setting. + */ +#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#endif + +/** + * @brief MSI frequency setting after standby. + */ +#if !defined(STM32_MSISRANGE) || defined(__DOXYGEN__) +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_MSI +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 1 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 8..127. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 60 +#endif + +/** + * @brief PLLPDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLPDIV_VALUE 0 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 7 +#endif + +/** + * @brief PLLQ divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 4 +#endif + +/** + * @brief PLLR divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLR_VALUE 2 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief STOPWUCK clock setting. + */ +#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief LSCO clock source. + */ +#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#endif + +/** + * @brief PLLSAI1M divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSAI1M_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1M_VALUE 1 +#endif + +/** + * @brief PLLSAI1N multiplier value. + * @note The allowed values are 8..127. + */ +#if !defined(STM32_PLLSAI1N_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1N_VALUE 72 +#endif + +/** + * @brief PLLSAI1PDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLSAI1PDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1PDIV_VALUE 6 +#endif + +/** + * @brief PLLSAI1P divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLSAI1P_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1P_VALUE 7 +#endif + +/** + * @brief PLLSAI1Q divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI1Q_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1Q_VALUE 6 +#endif + +/** + * @brief PLLSAI1R divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI1R_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1R_VALUE 6 +#endif + +/** + * @brief PLLSAI2M divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSAI2M_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2M_VALUE 1 +#endif + +/** + * @brief PLLSAI2N multiplier value. + * @note The allowed values are 8..127. + */ +#if !defined(STM32_PLLSAI2N_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2N_VALUE 72 +#endif + +/** + * @brief PLLSAI2PDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLSAI2PDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2PDIV_VALUE 6 +#endif + +/** + * @brief PLLSAI2P divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLSAI2P_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2P_VALUE 7 +#endif + +/** + * @brief PLLSAI2Q divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI2Q_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2Q_VALUE 6 +#endif + +/** + * @brief PLLSAI2R divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI2R_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2R_VALUE 6 +#endif + +/** + * @brief PLLSAI2DIVR value. + */ +#if !defined(STM32_PLLSAI2DIVR) || defined(__DOXYGEN__) +#define STM32_PLLSAI2DIVR STM32_PLLSAI2DIVR_DIV16 +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) +#define STM32_USART3SEL STM32_USART3SEL_SYSCLK +#endif + +/** + * @brief UART4 clock source. + */ +#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) +#define STM32_UART4SEL STM32_UART4SEL_SYSCLK +#endif + +/** + * @brief UART5 clock source. + */ +#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) +#define STM32_UART5SEL STM32_UART5SEL_SYSCLK +#endif + +/** + * @brief LPUART1 clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) +#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK +#endif + +/** + * @brief I2C3 clock source. + */ +#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#endif + +/** + * @brief I2C4 clock source. + */ +#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) +#define STM32_I2C4SEL STM32_I2C4SEL_SYSCLK +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#endif + +/** + * @brief LPTIM2 clock source. + */ +#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#endif + +/** + * @brief CLK48SEL value (48MHz clock source). + */ +#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) +#define STM32_CLK48SEL STM32_CLK48SEL_PLL +#endif + +/** + * @brief ADCSEL value (ADCs clock source). + */ +#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#endif + +/** + * @brief DFSDMSEL value (DFSDM clock source). + */ +#if !defined(STM32_DFSDMSEL) || defined(__DOXYGEN__) +#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 +#endif + +/** + * @brief ADFSDMSEL value (DFSDM clock source). + */ +#if !defined(STM32_ADFSDMSEL) || defined(__DOXYGEN__) +#define STM32_ADFSDMSEL STM32_ADFSDMSEL_SAI1CLK +#endif + +/** + * @brief SAI1SEL value (SAI1 clock source). + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#endif + +/** + * @brief SAI2SEL value (SAI2 clock source). + */ +#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#endif + +/** + * @brief DSISEL value (DSI clock source). + */ +#if !defined(STM32_DSISEL) || defined(__DOXYGEN__) +#define STM32_DSISEL STM32_DSISEL_DSIPHY +#endif + +/** + * @brief SDMMC value (SDMMC clock source). + */ +#if !defined(STM32_SDMMCSEL) || defined(__DOXYGEN__) +#define STM32_SDMMCSEL STM32_SDMMCSEL_48CLK +#endif + +/** + * @brief OSPISEL value (OSPISEL clock source). + */ +#if !defined(STM32_OSPISEL) || defined(__DOXYGEN__) +#define STM32_OSPISEL STM32_OSPISEL_SYSCLK +#endif + +/** + * @brief RTC/LCD clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32L4xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4xx_MCUCONF not defined" +#endif + +#if defined(STM32L4R5xx) && !defined(STM32L4R5_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4R5_MCUCONF not defined" + +#elif defined(STM32L4S5xx) && !defined(STM32L4S5_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4S5_MCUCONF not defined" + +#elif defined(STM32L4R7xx) && !defined(STM32L4R7_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4R7_MCUCONF not defined" + +#elif defined(STM32L4S7xx) && !defined(STM32L4S7_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4S7_MCUCONF not defined" + +#elif defined(STM32L4R9xx) && !defined(STM32L4R9_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4R9_MCUCONF not defined" + +#elif defined(STM32L4S9xx) && !defined(STM32L4S9_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4S9_MCUCONF not defined" + +#endif + +/* + * Board files sanity checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif + +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) +/** + * @name System Limits + * @{ + */ +/** + * @brief Maximum SYSCLK clock frequency in boost mode. + */ +#define STM32_SYSCLK_MAX 120000000 + +/** + * @brief Maximum SYSCLK clock frequency in normal mode. + */ +#define STM32_SYSCLK_NOBOOST_MAX 80000000 + +/** + * @brief Maximum HSE clock frequency at current voltage setting. + */ +#define STM32_HSECLK_MAX 48000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 48000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 8000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 8000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 2660000 + +/** + * @brief Maximum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MAX 344000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 64000000 + +/** + * @brief Maximum PLL-P output clock frequency. + */ +#define STM32_PLLP_MAX 120000000 + +/** + * @brief Minimum PLL-P output clock frequency. + */ +#define STM32_PLLP_MIN 2064500 + +/** + * @brief Maximum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MAX 120000000 + +/** + * @brief Minimum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MIN 8000000 + +/** + * @brief Maximum PLL-R output clock frequency. + */ +#define STM32_PLLR_MAX 120000000 + +/** + * @brief Minimum PLL-R output clock frequency. + */ +#define STM32_PLLR_MIN 8000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 120000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 120000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 80000000 +/** @} */ + +/** + * @name Flash Wait states + * @{ + */ +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 120000000 +/** @} */ + +#elif STM32_VOS == STM32_VOS_RANGE2 +#define STM32_SYSCLK_MAX 26000000 +#define STM32_SYSCLK_NOBOOST_MAX 26000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 26000000 +#define STM32_HSECLK_MIN 8000000 +#define STM32_HSECLK_BYP_MIN 8000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_LSECLK_BYP_MIN 32768 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLIN_MIN 2660000 +#define STM32_PLLVCO_MAX 128000000 +#define STM32_PLLVCO_MIN 64000000 +#define STM32_PLLP_MAX 26000000 +#define STM32_PLLP_MIN 2064500 +#define STM32_PLLQ_MAX 26000000 +#define STM32_PLLQ_MIN 8000000 +#define STM32_PLLR_MAX 26000000 +#define STM32_PLLR_MIN 8000000 +#define STM32_PCLK1_MAX 26000000 +#define STM32_PCLK2_MAX 26000000 +#define STM32_ADCCLK_MAX 26000000 + +#define STM32_0WS_THRESHOLD 8000000 +#define STM32_1WS_THRESHOLD 16000000 +#define STM32_2WS_THRESHOLD 26000000 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 + +#else +#error "invalid STM32_VOS value specified" +#endif + +/** + * @brief MSI frequency. + */ +#if STM32_MSIRANGE == STM32_MSIRANGE_100K +#define STM32_MSICLK 100000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_200K +#define STM32_MSICLK 200000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_400K +#define STM32_MSICLK 400000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_800K +#define STM32_MSICLK 800000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_1M +#define STM32_MSICLK 1000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_2M +#define STM32_MSICLK 2000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_4M +#define STM32_MSICLK 4000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_8M +#define STM32_MSICLK 8000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_16M +#define STM32_MSICLK 16000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_24M +#define STM32_MSICLK 24000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_32M +#define STM32_MSICLK 32000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_48M +#define STM32_MSICLK 48000000 +#else +#error "invalid STM32_MSIRANGE value specified" +#endif + +/** + * @brief MSIS frequency. + */ +#if STM32_MSISRANGE == STM32_MSISRANGE_1M +#define STM32_MSISCLK 1000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_2M +#define STM32_MSISCLK 2000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_4M +#define STM32_MSISCLK 4000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_8M +#define STM32_MSISCLK 8000000 +#else +#error "invalid STM32_MSISRANGE value specified" +#endif + +/* + * HSI16 related checks. + */ +#if STM32_HSI16_ENABLED +#else /* !STM32_HSI16_ENABLED */ + +#if STM32_SW == STM32_SW_HSI16 +#error "HSI16 not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +/* NOTE: Missing checks on the HSI16 pre-muxes, it is also required for newer + L4 devices.*/ + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16)) +#error "HSI16 not enabled, required by STM32_MCOSEL" +#endif + +#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SAI1SEL" +#endif + +#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SAI2SEL" +#endif + +#if (STM32_USART1SEL == STM32_USART1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART1SEL" +#endif +#if (STM32_USART2SEL == STM32_USART2SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART2SEL" +#endif +#if (STM32_USART3SEL == STM32_USART3SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART3SEL" +#endif +#if (STM32_UART4SEL == STM32_UART4SEL_HSI16) +#error "HSI16 not enabled, required by STM32_UART4SEL" +#endif +#if (STM32_UART5SEL == STM32_UART5SEL_HSI16) +#error "HSI16 not enabled, required by STM32_UART5SEL" +#endif +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_LPUART1SEL" +#endif + +#if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) +#error "HSI16 not enabled, required by I2C1SEL" +#endif +#if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) +#error "HSI16 not enabled, required by I2C2SEL" +#endif +#if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) +#error "HSI16 not enabled, required by I2C3SEL" +#endif +#if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) +#error "HSI16 not enabled, required by I2C4SEL" +#endif + +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) +#error "HSI16 not enabled, required by LPTIM1SEL" +#endif +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) +#error "HSI16 not enabled, required by LPTIM2SEL" +#endif + +#if (STM32_STOPWUCK == STM32_STOPWUCK_HSI16) +#error "HSI16 not enabled, required by STM32_STOPWUCK" +#endif + +#endif /* !STM32_HSI16_ENABLED */ + +#if STM32_HSI48_ENABLED +#else /* !STM32_HSI48_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_HSI48 +#error "HSI48 not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 +#error "HSI48 not enabled, required by STM32_CLK48SEL" +#endif +#endif /* !STM32_HSI48_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + + #if STM32_HSECLK == 0 + #error "HSE frequency not defined" + #else /* STM32_HSECLK != 0 */ + #if defined(STM32_HSE_BYPASS) + #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" + #endif + #else /* !defined(STM32_HSE_BYPASS) */ + #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" + #endif + #endif /* !defined(STM32_HSE_BYPASS) */ + #endif /* STM32_HSECLK != 0 */ + + #else /* !STM32_HSE_ENABLED */ + + #if STM32_SW == STM32_SW_HSE + #error "HSE not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) + #error "HSE not enabled, required by STM32_MCOSEL" + #endif + + #if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) | \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SAI1SEL" + #endif + + #if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) | \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SAI2SEL" + #endif + + #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV + #error "HSE not enabled, required by STM32_RTCSEL" + #endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + + #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) + #error "LSI not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSI + #error "LSI not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSI + #error "LSI not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + + #if (STM32_LSECLK == 0) + #error "LSE frequency not defined" + #endif + + #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) + #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" + #endif + +#else /* !STM32_LSE_ENABLED */ + + #if STM32_RTCSEL == STM32_RTCSEL_LSE + #error "LSE not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSE + #error "LSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSE + #error "LSE not enabled, required by STM32_LSCOSEL" + #endif + + #if STM32_MSIPLL_ENABLED == TRUE + #error "LSE not enabled, required by STM32_MSIPLL_ENABLED" + #endif + +#endif /* !STM32_LSE_ENABLED */ + +/* + * MSI related checks. + */ +#if (STM32_MSIRANGE == STM32_MSIRANGE_48M) && !STM32_MSIPLL_ENABLED +#warning "STM32_MSIRANGE_48M should be used with STM32_MSIPLL_ENABLED" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_MSI +#define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 +#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK +#define STM32_PLLCLKIN 0 + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLL input frequency range check. + */ +#if (STM32_PLLCLKIN != 0) && \ + ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_HSI48_ENABLED && (STM32_CLK48SEL == STM32_CLK48SEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ + defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLL activation required but no PLL clock selected" +#endif + +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 127)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 8) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLP (0 << 17) + +#elif STM32_PLLP_VALUE == 17 +#define STM32_PLLP (1 << 17) + +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLQ (0 << 21) + +#elif STM32_PLLQ_VALUE == 4 +#define STM32_PLLQ (1 << 21) + +#elif STM32_PLLQ_VALUE == 6 +#define STM32_PLLQ (2 << 21) + +#elif STM32_PLLQ_VALUE == 8 +#define STM32_PLLQ (3 << 21) + +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLR field. + */ +#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLR (0 << 25) + +#elif STM32_PLLR_VALUE == 4 +#define STM32_PLLR (1 << 25) + +#elif STM32_PLLR_VALUE == 6 +#define STM32_PLLR (2 << 25) + +#elif STM32_PLLR_VALUE == 8 +#define STM32_PLLR (3 << 25) + +#else +#error "invalid STM32_PLLR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLPDIV field. + */ +#if (STM32_PLLPDIV_VALUE == 0) || \ + ((STM32_PLLPDIV_VALUE != 1) && (STM32_PLLPDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) +#else +#error "invalid STM32_PLLPDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLPEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ + defined(__DOXYGEN__) +#define STM32_PLLPEN (1 << 16) +#else +#define STM32_PLLPEN (0 << 16) +#endif + +/** + * @brief STM32_PLLQEN field. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__) +#define STM32_PLLQEN (1 << 20) +#else +#define STM32_PLLQEN (0 << 20) +#endif + +/** + * @brief STM32_PLLREN field. + */ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + defined(__DOXYGEN__) +#define STM32_PLLREN (1 << 24) +#else +#define STM32_PLLREN (0 << 24) +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL P output clock frequency. + */ +#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) +#else +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) +#endif + +/** + * @brief PLL Q output clock frequency. + */ +#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) + +/** + * @brief PLL R output clock frequency. + */ +#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) + +/* + * PLL-P output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLL-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLL-R output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_MSICLK + +#elif (STM32_SW == STM32_SW_MSI) +#define STM32_SYSCLK STM32_MSICLK + +#elif (STM32_SW == STM32_SW_HSI16) +#define STM32_SYSCLK STM32_HSI16CLK + +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK + +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLL_R_CLKOUT + +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) + +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) + +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) + +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) + +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) + +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) + +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) + +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) + +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) + +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief STM32_PLLSAI1M field. + */ +#if ((STM32_PLLSAI1M_VALUE >= 1) && (STM32_PLLSAI1M_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1M ((STM32_PLLSAI1M_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLSAI1M_VALUE value specified" +#endif + +/** + * @brief PLLSAI1 input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1CLKIN (STM32_HSECLK / STM32_PLLSAI1M_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_MSI +#define STM32_PLLSAI1CLKIN (STM32_MSICLK / STM32_PLLSAI1M_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 +#define STM32_PLLSAI1CLKIN (STM32_HSI16CLK / STM32_PLLSAI1M_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK +#define STM32_PLLSAI1CLKIN 0 + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLLSAI1 input frequency range check. + */ +#if (STM32_PLLSAI1CLKIN != 0) && \ + ((STM32_PLLSAI1CLKIN < STM32_PLLIN_MIN) || \ + (STM32_PLLSAI1CLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLSAI1CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLLSAI1 enable check. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ + (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ + defined(__DOXYGEN__) + +#if STM32_PLLSAI1CLKIN == 0 +#error "PLLSAI1 activation required but no PLL clock selected" +#endif + +/** + * @brief PLLSAI1 activation flag. + */ +#define STM32_ACTIVATE_PLLSAI1 TRUE +#else +#define STM32_ACTIVATE_PLLSAI1 FALSE +#endif + +/** + * @brief STM32_PLLSAI1N field. + */ +#if ((STM32_PLLSAI1N_VALUE >= 8) && (STM32_PLLSAI1N_VALUE <= 127)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1N (STM32_PLLSAI1N_VALUE << 8) +#else +#error "invalid STM32_PLLSAI1N_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1P field. + */ +#if (STM32_PLLSAI1P_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLSAI1P (0 << 17) + +#elif STM32_PLLSAI1P_VALUE == 17 +#define STM32_PLLSAI1P (1 << 17) + +#else +#error "invalid STM32_PLLSAI1P_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1Q field. + */ +#if (STM32_PLLSAI1Q_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI1Q (0 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 4 +#define STM32_PLLSAI1Q (1 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 6 +#define STM32_PLLSAI1Q (2 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 8 +#define STM32_PLLSAI1Q (3 << 21) + +#else +#error "invalid STM32_PLLSAI1Q_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1R field. + */ +#if (STM32_PLLSAI1R_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI1R (0 << 25) + +#elif STM32_PLLSAI1R_VALUE == 4 +#define STM32_PLLSAI1R (1 << 25) + +#elif STM32_PLLSAI1R_VALUE == 6 +#define STM32_PLLSAI1R (2 << 25) + +#elif STM32_PLLSAI1R_VALUE == 8 +#define STM32_PLLSAI1R (3 << 25) + +#else +#error "invalid STM32_PLLSAI1R_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1PDIV field. + */ +#if ((STM32_PLLSAI1PDIV_VALUE != 1) && (STM32_PLLSAI1PDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1PDIV (STM32_PLLSAI1PDIV_VALUE << 27) +#else +#error "invalid STM32_PLLSAI1PDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1PEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1PEN (1 << 16) +#else +#define STM32_PLLSAI1PEN (0 << 16) +#endif + +/** + * @brief STM32_PLLSAI1QEN field. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_PLLSAI1QEN (1 << 20) +#else +#define STM32_PLLSAI1QEN (0 << 20) +#endif + +/** + * @brief STM32_PLLSAI1REN field. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_PLLSAI1REN (1 << 24) +#else +#define STM32_PLLSAI1REN (0 << 24) +#endif + +/** + * @brief PLLSAI1 VCO frequency. + */ +#define STM32_PLLSAI1VCO (STM32_PLLSAI1CLKIN * STM32_PLLSAI1N_VALUE) + +/* + * PLLSAI1 VCO frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI1-P output clock frequency. + */ +#if (STM32_PLLSAI1PDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE) +#else +#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1PDIV_VALUE) +#endif + +/** + * @brief PLLSAI1-Q output clock frequency. + */ +#define STM32_PLLSAI1_Q_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) + +/** + * @brief PLLSAI1-R output clock frequency. + */ +#define STM32_PLLSAI1_R_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1R_VALUE) + +/* + * PLLSAI1-P output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLLSAI1-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLLSAI1-R output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief STM32_PLLSAI2M field. + */ +#if ((STM32_PLLSAI2M_VALUE >= 1) && (STM32_PLLSAI2M_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2M ((STM32_PLLSAI2M_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLSAI2M_VALUE value specified" +#endif + +/** + * @brief PLLSAI2 input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2CLKIN (STM32_HSECLK / STM32_PLLSAI2M_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_MSI +#define STM32_PLLSAI2CLKIN (STM32_MSICLK / STM32_PLLSAI2M_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 +#define STM32_PLLSAI2CLKIN (STM32_HSI16CLK / STM32_PLLSAI2M_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK +#define STM32_PLLSAI2CLKIN 0 + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLLSAI2 input frequency range check. + */ +#if (STM32_PLLSAI2CLKIN != 0) && \ + ((STM32_PLLSAI2CLKIN < STM32_PLLIN_MIN) || \ + (STM32_PLLSAI2CLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLSAI2CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLLSAI2 enable check. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ + defined(__DOXYGEN__) + +#if STM32_PLLSAI2CLKIN == 0 +#error "PLLSAI2 activation required but no PLL clock selected" +#endif + +/** + * @brief PLLSAI2 activation flag. + */ +#define STM32_ACTIVATE_PLLSAI2 TRUE +#else +#define STM32_ACTIVATE_PLLSAI2 FALSE +#endif + +/** + * @brief STM32_PLLSAI2N field. + */ +#if ((STM32_PLLSAI2N_VALUE >= 8) && (STM32_PLLSAI2N_VALUE <= 127)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2N (STM32_PLLSAI2N_VALUE << 8) +#else +#error "invalid STM32_PLLSAI2N_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2P field. + */ +#if (STM32_PLLSAI2P_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLSAI2P (0 << 17) + +#elif STM32_PLLSAI2P_VALUE == 17 +#define STM32_PLLSAI2P (1 << 17) + +#else +#error "invalid STM32_PLLSAI2P_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2R field. + */ +#if (STM32_PLLSAI2R_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI2R (0 << 25) + +#elif STM32_PLLSAI2R_VALUE == 4 +#define STM32_PLLSAI2R (1 << 25) + +#elif STM32_PLLSAI2R_VALUE == 6 +#define STM32_PLLSAI2R (2 << 25) + +#elif STM32_PLLSAI2R_VALUE == 8 +#define STM32_PLLSAI2R (3 << 25) + +#else +#error "invalid STM32_PLLSAI2R_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2PDIV field. + */ +#if ((STM32_PLLSAI2PDIV_VALUE != 1) && (STM32_PLLSAI2PDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2PDIV (STM32_PLLSAI2PDIV_VALUE << 27) +#else +#error "invalid STM32_PLLSAI2PDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2PEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2PEN (1 << 16) +#else +#define STM32_PLLSAI2PEN (0 << 16) +#endif + +/** + * @brief STM32_PLLSAI2REN field. + * @note Always enabled. + * @note It should depend on some condition. + */ +#define STM32_PLLSAI2REN (1 << 24) + +/** + * @brief PLLSAI2 VCO frequency. + */ +#define STM32_PLLSAI2VCO (STM32_PLLSAI2CLKIN * STM32_PLLSAI2N_VALUE) + +/* + * PLLSAI2 VCO frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI2-P output clock frequency. + */ +#if (STM32_PLLSAI2PDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE) +#else +#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2PDIV_VALUE) +#endif + +/** + * @brief PLLSAI2-R output clock frequency. + */ +#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE) + +/* + * PLLSAI2-P output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLLSAI2-R output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief MCO divider clock frequency. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 + +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK +#define STM32_MCODIVCLK STM32_SYSCLK + +#elif STM32_MCOSEL == STM32_MCOSEL_MSI +#define STM32_MCODIVCLK STM32_MSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 +#define STM32_MCODIVCLK STM32_HSI16CLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_PLL +#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT + +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 +#define STM32_MCODIVCLK STM32_HSI48CLK + +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock frequency. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) + +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief RTC clock frequency. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 clock frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK2 + +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK + +#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 +#define STM32_USART1CLK STM32_HSI16CLK + +#elif STM32_USART1SEL == STM32_USART1SEL_LSE +#define STM32_USART1CLK STM32_LSECLK + +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 clock frequency. + */ +#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART2CLK STM32_PCLK1 + +#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK + +#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 +#define STM32_USART2CLK STM32_HSI16CLK + +#elif STM32_USART2SEL == STM32_USART2SEL_LSE +#define STM32_USART2CLK STM32_LSECLK + +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 clock frequency. + */ +#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART3CLK STM32_PCLK1 + +#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK +#define STM32_USART3CLK STM32_SYSCLK + +#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 +#define STM32_USART3CLK STM32_HSI16CLK + +#elif STM32_USART3SEL == STM32_USART3SEL_LSE +#define STM32_USART3CLK STM32_LSECLK + +#else +#error "invalid source selected for USART3 clock" +#endif + +/** + * @brief UART4 clock frequency. + */ +#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART4CLK STM32_PCLK1 + +#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK +#define STM32_UART4CLK STM32_SYSCLK + +#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 +#define STM32_UART4CLK STM32_HSI16CLK + +#elif STM32_UART4SEL == STM32_UART4SEL_LSE +#define STM32_UART4CLK STM32_LSECLK + +#else +#error "invalid source selected for UART4 clock" +#endif + +/** + * @brief UART5 clock frequency. + */ +#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART5CLK STM32_PCLK1 + +#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK +#define STM32_UART5CLK STM32_SYSCLK + +#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 +#define STM32_UART5CLK STM32_HSI16CLK + +#elif STM32_UART5SEL == STM32_UART5SEL_LSE +#define STM32_UART5CLK STM32_LSECLK + +#else +#error "invalid source selected for UART5 clock" +#endif + +/** + * @brief LPUART1 clock frequency. + */ +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPUART1CLK STM32_PCLK1 + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK +#define STM32_LPUART1CLK STM32_SYSCLK + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 +#define STM32_LPUART1CLK STM32_HSI16CLK + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE +#define STM32_LPUART1CLK STM32_LSECLK + +#else +#error "invalid source selected for LPUART1 clock" +#endif + +/** + * @brief I2C1 clock frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_PCLK1 + +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK + +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 +#define STM32_I2C1CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 clock frequency. + */ +#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C2CLK STM32_PCLK1 + +#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK +#define STM32_I2C2CLK STM32_SYSCLK + +#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 +#define STM32_I2C2CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C2 clock" +#endif + +/** + * @brief I2C3 clock frequency. + */ +#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C3CLK STM32_PCLK1 + +#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK +#define STM32_I2C3CLK STM32_SYSCLK + +#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 +#define STM32_I2C3CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C3 clock" +#endif + +/** + * @brief I2C4 clock frequency. + */ +#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C4CLK STM32_PCLK1 + +#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK +#define STM32_I2C4CLK STM32_SYSCLK + +#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 +#define STM32_I2C4CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C4 clock" +#endif + +/** + * @brief LPTIM1 clock frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM1CLK STM32_PCLK1 + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI +#define STM32_LPTIM1CLK STM32_LSICLK + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 +#define STM32_LPTIM1CLK STM32_HSI16CLK + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE +#define STM32_LPTIM1CLK STM32_LSECLK + +#else +#error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief LPTIM2 clock frequency. + */ +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM2CLK STM32_PCLK1 + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI +#define STM32_LPTIM2CLK STM32_LSICLK + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 +#define STM32_LPTIM2CLK STM32_HSI16CLK + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE +#define STM32_LPTIM2CLK STM32_LSECLK + +#else +#error "invalid source selected for LPTIM2 clock" +#endif + +/** + * @brief 48MHz clock frequency. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) +#define STM32_48CLK STM32_HSI48CLK + +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 +#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) + +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL +#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) + +#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI +#define STM32_48CLK STM32_MSICLK + +#else +#error "invalid source selected for 48CLK clock" +#endif + +/** + * @brief SAI1 clock frequency. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_SAI1CLK STM32_PLLSAI1_P_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2 +#define STM32_SAI1CLK STM32_PLLSAI2_P_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL +#define STM32_SAI1CLK STM32_PLL_P_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_EXTCLK +#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ + +#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16 +#define STM32_SAI1CLK STM32_HSI16CLK + +#elif STM32_SAI1SEL == STM32_SAI1SEL_OFF +#define STM32_SAI1CLK 0 + +#else +#error "invalid source selected for SAI1 clock" +#endif + +/** + * @brief SAI2 clock frequency. + */ +#if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_SAI2CLK STM32_PLLSAI1_P_CLKOUT + +#elif STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2 +#define STM32_SAI2CLK STM32_PLLSAI2_P_CLKOUT + +#elif STM32_SAI2SEL == STM32_SAI2SEL_PLL +#define STM32_SAI2CLK STM32_PLL_P_CLKOUT + +#elif STM32_SAI2SEL == STM32_SAI2SEL_EXTCLK +#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ + +#elif STM32_SAI2SEL == STM32_SAI2SEL_HSI16 +#define STM32_SAI2CLK STM32_HSI16CLK + +#elif STM32_SAI2SEL == STM32_SAI2SEL_OFF +#define STM32_SAI2CLK 0 + +#else +#error "invalid source selected for SAI2 clock" +#endif + +/** + * @brief DSI clock frequency. + */ +#if (STM32_DSISEL == STM32_DSISEL_DSIPHY) || defined(__DOXYGEN__) +#define STM32_DSICLK 0 + +#elif STM32_DSISEL == STM32_DSISEL_PLLDSICLK +#define STM32_DSICLK STM32_PLLSAI2_Q_CLKOUT + +#else +#error "invalid source selected for DSI clock" +#endif + +/** + * @brief SDMMC clock frequency. + */ +#if (STM32_SDMMCSEL == STM32_SDMMCSEL_48CLK) || defined(__DOXYGEN__) +#define STM32_SDMMCCLK STM32_48CLK + +#elif STM32_SDMMCSEL == STM32_SDMMCSEL_PLLSAI3CLK +#define STM32_SDMMCCLK STM32_PLL_P_CLKOUT + +#else +#error "invalid source selected for SDMMC clock" +#endif + +/** + * @brief USB clock point. + */ +#define STM32_USBCLK STM32_48CLK + +/** + * @brief RNG clock point. + */ +#define STM32_RNGCLK STM32_48CLK + +/** + * @brief ADC clock frequency. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_NOCLK) || defined(__DOXYGEN__) +#define STM32_ADCCLK 0 + +#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI1 +#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT + +#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK +#define STM32_ADCCLK STM32_SYSCLK + +#else +#error "invalid source selected for ADC clock" +#endif + +/** + * @brief DFSDM clock frequency. + */ +#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_DFSDMCLK STM32_PCLK2 + +#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK +#define STM32_DFSDMCLK STM32_SYSCLK + +#else +#error "invalid source selected for DFSDM clock" +#endif + +/** + * @brief SDMMC frequency. + */ +#define STM32_SDMMC1CLK STM32_48CLK + +/** + * @brief LTDC frequency. + */ +#if (STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV2) || defined(__DOXYGEN__) +#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 2) + +#elif STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV4 +#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 4) + +#elif STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV8 +#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 8) + +#elif STM32_PLLSAI2DIVR == STM32_PLLSAI2DIVR_DIV16 +#define STM32_LTDCCLK (STM32_PLLSAI2_R_CLKOUT / 16) + +#else +#error "invalid STM32_PLLSAI2DIVR value specified" +#endif + +/** + * @brief OSPI clock frequency. + */ +#if (STM32_OSPISEL == STM32_OSPISEL_SYSCLK) || defined(__DOXYGEN__) +#define STM32_OSPICLK STM32_SYSCLK + +#elif STM32_OSPISEL == STM32_OSPISEL_MSI +#define STM32_OSPICLK STM32_MSICLK + +#elif STM32_OSPISEL == STM32_OSPISEL_48CLK +#define STM32_OSPICLK STM32_PLLSAI1_Q_CLKOUT + +#else +#error "invalid source selected for OSPI clock" +#endif + +/** + * @brief Clock of timers connected to APB1 + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Clock of timers connected to APB2. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Voltage boost settings. + */ +#if (STM32_SYSCLK <= STM32_SYSCLK_NOBOOST_MAX) || defined(__DOXYGEN__) +#define STM32_R1MODE PWR_CR5_R1MODE +#else +#define STM32_R1MODE 0 +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + +/** + * @brief Flash settings for MSI. + */ +#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_MSICLK <= STM32_1WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_MSICLK <= STM32_2WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_MSICLK <= STM32_3WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.c b/os/hal/ports/STM32/STM32L4xx/hal_lld.c index 4e3fc566b2..b00a45c010 100644 --- a/os/hal/ports/STM32/STM32L4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.c @@ -1,399 +1,399 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L4xx/hal_lld.c - * @brief STM32L4xx HAL subsystem low level driver source. - * - * @addtogroup HAL - * @{ - */ - -#include "hal.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief CMSIS system core clock variable. - * @note It is declared in system_stm32f7xx.h. - */ -uint32_t SystemCoreClock = STM32_HCLK; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Initializes the backup domain. - * @note WARNING! Changing RTC clock source impossible without resetting - * of the whole BKP domain. - */ -static void hal_lld_backup_domain_init(void) { - - /* Reset BKP domain if different clock source selected.*/ - if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { - /* Backup domain reset.*/ - RCC->BDCR = RCC_BDCR_BDRST; - RCC->BDCR = 0; - } - -#if STM32_LSE_ENABLED - int rusefiLseCounter = 0; - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - /* Waits until LSE is stable or times out. */ - while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) - && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; -#endif - -#if STM32_MSIPLL_ENABLED - /* MSI PLL activation depends on LSE. Reactivating and checking for - MSI stability.*/ - RCC->CR |= RCC_CR_MSIPLLEN; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; /* Wait until MSI is stable. */ -#endif - -#if HAL_USE_RTC - /* If the backup domain hasn't been initialized yet then proceed with - initialization.*/ - if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { - /* Selects clock source.*/ -#if STM32_LSE_ENABLED - RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; -#else - RCC->BDCR |= STM32_RTCSEL; -#endif - - /* RTC clock enabled.*/ - RCC->BDCR |= RCC_BDCR_RTCEN; - } -#endif /* HAL_USE_RTC */ - - /* Low speed output mode.*/ - RCC->BDCR |= STM32_LSCOSEL; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level HAL driver initialization. - * - * @notapi - */ -void hal_lld_init(void) { - - /* Reset of all peripherals. - Note, GPIOs are not reset because initialized before this point in - board files.*/ - rccResetAHB1(~0); - rccResetAHB2(~STM32_GPIO_EN_MASK); - rccResetAHB3(~0); - rccResetAPB1R1(~RCC_APB1RSTR1_PWRRST); - rccResetAPB1R2(~0); - rccResetAPB2(~0); - - /* PWR clock enabled.*/ - rccEnablePWRInterface(true); - - /* Initializes the backup domain.*/ - hal_lld_backup_domain_init(); - - /* DMA subsystems initialization.*/ -#if defined(STM32_DMA_REQUIRED) - dmaInit(); -#endif - - /* IRQ subsystem initialization.*/ - irqInit(); - - /* Programmable voltage detector enable.*/ -#if STM32_PVD_ENABLE - PWR->CR2 = PWR_CR2_PVDE | (STM32_PLS & STM32_PLS_MASK); -#else - PWR->CR2 = 0; -#endif /* STM32_PVD_ENABLE */ - - /* Enabling independent VDDUSB.*/ -#if HAL_USE_USB - PWR->CR2 |= PWR_CR2_USV; -#endif /* HAL_USE_USB */ - - /* Enabling independent VDDIO2 required by GPIOG.*/ -#if STM32_HAS_GPIOG - PWR->CR2 |= PWR_CR2_IOSV; -#endif /* STM32_HAS_GPIOG */ -} - -/** - * @brief STM32L4xx clocks and PLL initialization. - * @note All the involved constants come from the file @p board.h. - * @note This function should be invoked just after the system reset. - * - * @special - */ -void stm32_clock_init(void) { - -#if !STM32_NO_INIT - /* PWR clock enable.*/ -#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR1_RTCAPBEN) - RCC->APB1ENR1 = RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN; -#else - RCC->APB1ENR1 = RCC_APB1ENR1_PWREN; -#endif - - /* Initial clocks setup and wait for MSI stabilization, the MSI clock is - always enabled because it is the fall back clock when PLL the fails. - Trim fields are not altered from reset values.*/ - - /* MSIRANGE can be set only when MSI is OFF or READY.*/ - RCC->CR = RCC_CR_MSION; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; /* Wait until MSI is stable. */ - - /* Clocking from MSI, in case MSI was not the default source.*/ - RCC->CFGR = 0; - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) - ; /* Wait until MSI is selected. */ - - /* Core voltage setup.*/ - PWR->CR1 = STM32_VOS; - while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ - ; /* stable. */ - -#if STM32_HSI16_ENABLED - /* HSI activation.*/ - RCC->CR |= RCC_CR_HSION; - while ((RCC->CR & RCC_CR_HSIRDY) == 0) - ; /* Wait until HSI16 is stable. */ -#endif - -#if STM32_CLOCK_HAS_HSI48 -#if STM32_HSI48_ENABLED - /* HSI activation.*/ - RCC->CRRCR |= RCC_CRRCR_HSI48ON; - while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0) - ; /* Wait until HSI48 is stable. */ -#endif -#endif - -#if STM32_HSE_ENABLED -#if defined(STM32_HSE_BYPASS) - /* HSE Bypass.*/ - RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; -#endif - /* HSE activation.*/ - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0) - ; /* Wait until HSE is stable. */ -#endif - -#if STM32_LSI_ENABLED - /* LSI activation.*/ - RCC->CSR |= RCC_CSR_LSION; - while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) - ; /* Wait until LSI is stable. */ -#endif - - /* Backup domain access enabled and left open.*/ - PWR->CR1 |= PWR_CR1_DBP; - -#if STM32_LSE_ENABLED - /* LSE activation.*/ -#if defined(STM32_LSE_BYPASS) - /* LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; -#else - /* No LSE Bypass.*/ - RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; -#endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Wait until LSE is stable. */ -#endif - - /* Flash setup for selected MSI speed setting.*/ - FLASH->ACR = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | - STM32_MSI_FLASHBITS; - - /* Changing MSIRANGE to configured value.*/ - RCC->CR |= STM32_MSIRANGE; - - /* Switching from MSISRANGE to MSIRANGE.*/ - RCC->CR |= RCC_CR_MSIRGSEL; - while ((RCC->CR & RCC_CR_MSIRDY) == 0) - ; - - /* MSI is configured SYSCLK source so wait for it to be stable as well.*/ - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) - ; - -#if STM32_MSIPLL_ENABLED - /* MSI PLL (to LSE) activation */ - RCC->CR |= RCC_CR_MSIPLLEN; -#endif - - /* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high. - This range is used exiting the Standby mode until MSIRGSEL is set.*/ - RCC->CSR |= STM32_MSISRANGE; - -#if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2 - /* PLLM and PLLSRC are common to all PLLs.*/ -#if defined(STM32L496xx) || defined(STM32L4A6xx) - RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR | - STM32_PLLREN | STM32_PLLQ | - STM32_PLLQEN | STM32_PLLP | - STM32_PLLPEN | STM32_PLLN | - STM32_PLLM | STM32_PLLSRC; -#else - RCC->PLLCFGR = STM32_PLLR | STM32_PLLREN | - STM32_PLLQ | STM32_PLLQEN | - STM32_PLLP | STM32_PLLPEN | - STM32_PLLN | STM32_PLLM | - STM32_PLLSRC; -#endif -#endif - -#if STM32_ACTIVATE_PLL - /* PLL activation.*/ - RCC->CR |= RCC_CR_PLLON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLRDY) == 0) - ; -#endif - -#if STM32_ACTIVATE_PLLSAI1 - /* PLLSAI1 activation.*/ -#if defined(STM32L496xx) || defined(STM32L4A6xx) - RCC->PLLSAI1CFGR = STM32_PLLSAI1PDIV | STM32_PLLSAI1R | - STM32_PLLSAI1REN | STM32_PLLSAI1Q | - STM32_PLLSAI1QEN | STM32_PLLSAI1P | - STM32_PLLSAI1PEN | STM32_PLLSAI1N; -#else - RCC->PLLSAI1CFGR = STM32_PLLSAI1R | STM32_PLLSAI1REN | - STM32_PLLSAI1Q | STM32_PLLSAI1QEN | - STM32_PLLSAI1P | STM32_PLLSAI1PEN | - STM32_PLLSAI1N; -#endif - RCC->CR |= RCC_CR_PLLSAI1ON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLSAI1RDY) == 0) - ; -#endif - -#if STM32_ACTIVATE_PLLSAI2 - /* PLLSAI2 activation.*/ -#if defined(STM32L496xx) || defined(STM32L4A6xx) - RCC->PLLSAI2CFGR = STM32_PLLSAI2PDIV | STM32_PLLSAI2R | - STM32_PLLSAI2REN | STM32_PLLSAI2P | - STM32_PLLSAI2PEN | STM32_PLLSAI2N; -#else - RCC->PLLSAI2CFGR = STM32_PLLSAI2R | STM32_PLLSAI2REN | - STM32_PLLSAI2P | STM32_PLLSAI2PEN | - STM32_PLLSAI2N; -#endif - RCC->CR |= RCC_CR_PLLSAI2ON; - - /* Waiting for PLL lock.*/ - while ((RCC->CR & RCC_CR_PLLSAI2RDY) == 0) - ; -#endif - - /* Other clock-related settings (dividers, MCO etc).*/ - RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_STOPWUCK | - STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; - - /* CCIPR register initialization, note, must take care of the _OFF - pseudo settings.*/ - { - uint32_t ccipr = STM32_DFSDMSEL | STM32_SWPMI1SEL | STM32_ADCSEL | - STM32_CLK48SEL | STM32_LPTIM2SEL | STM32_LPTIM1SEL | - STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | - STM32_UART5SEL | STM32_UART4SEL | STM32_USART3SEL | - STM32_USART2SEL | STM32_USART1SEL | STM32_LPUART1SEL; -#if STM32_SAI2SEL != STM32_SAI2SEL_OFF - ccipr |= STM32_SAI2SEL; -#endif -#if STM32_SAI1SEL != STM32_SAI1SEL_OFF - ccipr |= STM32_SAI1SEL; -#endif - RCC->CCIPR = ccipr; - } - -#if STM32_HAS_I2C4 - /* CCIPR2 register initialization.*/ - { - uint32_t ccipr2 = STM32_I2C4SEL; - RCC->CCIPR2 = ccipr2; - } -#endif - - /* Set flash WS's for SYSCLK source */ - if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) { - FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - } - - /* Switching to the configured SYSCLK source if it is different from MSI.*/ -#if (STM32_SW != STM32_SW_MSI) - RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ - /* Wait until SYSCLK is stable.*/ - while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) - ; -#endif - - /* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */ - if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) { - FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != - (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { - } - } - -#endif /* STM32_NO_INIT */ - - /* SYSCFG clock enabled here because it is a multi-functional unit shared - among multiple drivers.*/ - rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); -} - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L4xx/hal_lld.c + * @brief STM32L4xx HAL subsystem low level driver source. + * + * @addtogroup HAL + * @{ + */ + +#include "hal.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief CMSIS system core clock variable. + * @note It is declared in system_stm32f7xx.h. + */ +uint32_t SystemCoreClock = STM32_HCLK; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the backup domain. + * @note WARNING! Changing RTC clock source impossible without resetting + * of the whole BKP domain. + */ +static void hal_lld_backup_domain_init(void) { + + /* Reset BKP domain if different clock source selected.*/ + if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { + /* Backup domain reset.*/ + RCC->BDCR = RCC_BDCR_BDRST; + RCC->BDCR = 0; + } + +#if STM32_LSE_ENABLED + int rusefiLseCounter = 0; + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + /* Waits until LSE is stable or times out. */ + while ((!RUSEFI_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < RUSEFI_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; +#endif + +#if STM32_MSIPLL_ENABLED + /* MSI PLL activation depends on LSE. Reactivating and checking for + MSI stability.*/ + RCC->CR |= RCC_CR_MSIPLLEN; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; /* Wait until MSI is stable. */ +#endif + +#if HAL_USE_RTC + /* If the backup domain hasn't been initialized yet then proceed with + initialization.*/ + if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { + /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->BDCR |= STM32_RTCSEL; +#endif + + /* RTC clock enabled.*/ + RCC->BDCR |= RCC_BDCR_RTCEN; + } +#endif /* HAL_USE_RTC */ + + /* Low speed output mode.*/ + RCC->BDCR |= STM32_LSCOSEL; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level HAL driver initialization. + * + * @notapi + */ +void hal_lld_init(void) { + + /* Reset of all peripherals. + Note, GPIOs are not reset because initialized before this point in + board files.*/ + rccResetAHB1(~0); + rccResetAHB2(~STM32_GPIO_EN_MASK); + rccResetAHB3(~0); + rccResetAPB1R1(~RCC_APB1RSTR1_PWRRST); + rccResetAPB1R2(~0); + rccResetAPB2(~0); + + /* PWR clock enabled.*/ + rccEnablePWRInterface(true); + + /* Initializes the backup domain.*/ + hal_lld_backup_domain_init(); + + /* DMA subsystems initialization.*/ +#if defined(STM32_DMA_REQUIRED) + dmaInit(); +#endif + + /* IRQ subsystem initialization.*/ + irqInit(); + + /* Programmable voltage detector enable.*/ +#if STM32_PVD_ENABLE + PWR->CR2 = PWR_CR2_PVDE | (STM32_PLS & STM32_PLS_MASK); +#else + PWR->CR2 = 0; +#endif /* STM32_PVD_ENABLE */ + + /* Enabling independent VDDUSB.*/ +#if HAL_USE_USB + PWR->CR2 |= PWR_CR2_USV; +#endif /* HAL_USE_USB */ + + /* Enabling independent VDDIO2 required by GPIOG.*/ +#if STM32_HAS_GPIOG + PWR->CR2 |= PWR_CR2_IOSV; +#endif /* STM32_HAS_GPIOG */ +} + +/** + * @brief STM32L4xx clocks and PLL initialization. + * @note All the involved constants come from the file @p board.h. + * @note This function should be invoked just after the system reset. + * + * @special + */ +void stm32_clock_init(void) { + +#if !STM32_NO_INIT + /* PWR clock enable.*/ +#if defined(HAL_USE_RTC) && defined(RCC_APB1ENR1_RTCAPBEN) + RCC->APB1ENR1 = RCC_APB1ENR1_PWREN | RCC_APB1ENR1_RTCAPBEN; +#else + RCC->APB1ENR1 = RCC_APB1ENR1_PWREN; +#endif + + /* Initial clocks setup and wait for MSI stabilization, the MSI clock is + always enabled because it is the fall back clock when PLL the fails. + Trim fields are not altered from reset values.*/ + + /* MSIRANGE can be set only when MSI is OFF or READY.*/ + RCC->CR = RCC_CR_MSION; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; /* Wait until MSI is stable. */ + + /* Clocking from MSI, in case MSI was not the default source.*/ + RCC->CFGR = 0; + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + ; /* Wait until MSI is selected. */ + + /* Core voltage setup.*/ + PWR->CR1 = STM32_VOS; + while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ + ; /* stable. */ + +#if STM32_HSI16_ENABLED + /* HSI activation.*/ + RCC->CR |= RCC_CR_HSION; + while ((RCC->CR & RCC_CR_HSIRDY) == 0) + ; /* Wait until HSI16 is stable. */ +#endif + +#if STM32_CLOCK_HAS_HSI48 +#if STM32_HSI48_ENABLED + /* HSI activation.*/ + RCC->CRRCR |= RCC_CRRCR_HSI48ON; + while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0) + ; /* Wait until HSI48 is stable. */ +#endif +#endif + +#if STM32_HSE_ENABLED +#if defined(STM32_HSE_BYPASS) + /* HSE Bypass.*/ + RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; +#endif + /* HSE activation.*/ + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0) + ; /* Wait until HSE is stable. */ +#endif + +#if STM32_LSI_ENABLED + /* LSI activation.*/ + RCC->CSR |= RCC_CSR_LSION; + while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) + ; /* Wait until LSI is stable. */ +#endif + + /* Backup domain access enabled and left open.*/ + PWR->CR1 |= PWR_CR1_DBP; + +#if STM32_LSE_ENABLED + /* LSE activation.*/ +#if defined(STM32_LSE_BYPASS) + /* LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; +#else + /* No LSE Bypass.*/ + RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; +#endif + while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; /* Wait until LSE is stable. */ +#endif + + /* Flash setup for selected MSI speed setting.*/ + FLASH->ACR = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | + STM32_MSI_FLASHBITS; + + /* Changing MSIRANGE to configured value.*/ + RCC->CR |= STM32_MSIRANGE; + + /* Switching from MSISRANGE to MSIRANGE.*/ + RCC->CR |= RCC_CR_MSIRGSEL; + while ((RCC->CR & RCC_CR_MSIRDY) == 0) + ; + + /* MSI is configured SYSCLK source so wait for it to be stable as well.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + ; + +#if STM32_MSIPLL_ENABLED + /* MSI PLL (to LSE) activation */ + RCC->CR |= RCC_CR_MSIPLLEN; +#endif + + /* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high. + This range is used exiting the Standby mode until MSIRGSEL is set.*/ + RCC->CSR |= STM32_MSISRANGE; + +#if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2 + /* PLLM and PLLSRC are common to all PLLs.*/ +#if defined(STM32L496xx) || defined(STM32L4A6xx) + RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR | + STM32_PLLREN | STM32_PLLQ | + STM32_PLLQEN | STM32_PLLP | + STM32_PLLPEN | STM32_PLLN | + STM32_PLLM | STM32_PLLSRC; +#else + RCC->PLLCFGR = STM32_PLLR | STM32_PLLREN | + STM32_PLLQ | STM32_PLLQEN | + STM32_PLLP | STM32_PLLPEN | + STM32_PLLN | STM32_PLLM | + STM32_PLLSRC; +#endif +#endif + +#if STM32_ACTIVATE_PLL + /* PLL activation.*/ + RCC->CR |= RCC_CR_PLLON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLRDY) == 0) + ; +#endif + +#if STM32_ACTIVATE_PLLSAI1 + /* PLLSAI1 activation.*/ +#if defined(STM32L496xx) || defined(STM32L4A6xx) + RCC->PLLSAI1CFGR = STM32_PLLSAI1PDIV | STM32_PLLSAI1R | + STM32_PLLSAI1REN | STM32_PLLSAI1Q | + STM32_PLLSAI1QEN | STM32_PLLSAI1P | + STM32_PLLSAI1PEN | STM32_PLLSAI1N; +#else + RCC->PLLSAI1CFGR = STM32_PLLSAI1R | STM32_PLLSAI1REN | + STM32_PLLSAI1Q | STM32_PLLSAI1QEN | + STM32_PLLSAI1P | STM32_PLLSAI1PEN | + STM32_PLLSAI1N; +#endif + RCC->CR |= RCC_CR_PLLSAI1ON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLSAI1RDY) == 0) + ; +#endif + +#if STM32_ACTIVATE_PLLSAI2 + /* PLLSAI2 activation.*/ +#if defined(STM32L496xx) || defined(STM32L4A6xx) + RCC->PLLSAI2CFGR = STM32_PLLSAI2PDIV | STM32_PLLSAI2R | + STM32_PLLSAI2REN | STM32_PLLSAI2P | + STM32_PLLSAI2PEN | STM32_PLLSAI2N; +#else + RCC->PLLSAI2CFGR = STM32_PLLSAI2R | STM32_PLLSAI2REN | + STM32_PLLSAI2P | STM32_PLLSAI2PEN | + STM32_PLLSAI2N; +#endif + RCC->CR |= RCC_CR_PLLSAI2ON; + + /* Waiting for PLL lock.*/ + while ((RCC->CR & RCC_CR_PLLSAI2RDY) == 0) + ; +#endif + + /* Other clock-related settings (dividers, MCO etc).*/ + RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_STOPWUCK | + STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; + + /* CCIPR register initialization, note, must take care of the _OFF + pseudo settings.*/ + { + uint32_t ccipr = STM32_DFSDMSEL | STM32_SWPMI1SEL | STM32_ADCSEL | + STM32_CLK48SEL | STM32_LPTIM2SEL | STM32_LPTIM1SEL | + STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL | + STM32_UART5SEL | STM32_UART4SEL | STM32_USART3SEL | + STM32_USART2SEL | STM32_USART1SEL | STM32_LPUART1SEL; +#if STM32_SAI2SEL != STM32_SAI2SEL_OFF + ccipr |= STM32_SAI2SEL; +#endif +#if STM32_SAI1SEL != STM32_SAI1SEL_OFF + ccipr |= STM32_SAI1SEL; +#endif + RCC->CCIPR = ccipr; + } + +#if STM32_HAS_I2C4 + /* CCIPR2 register initialization.*/ + { + uint32_t ccipr2 = STM32_I2C4SEL; + RCC->CCIPR2 = ccipr2; + } +#endif + + /* Set flash WS's for SYSCLK source */ + if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) { + FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + } + + /* Switching to the configured SYSCLK source if it is different from MSI.*/ +#if (STM32_SW != STM32_SW_MSI) + RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + /* Wait until SYSCLK is stable.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) + ; +#endif + + /* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */ + if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) { + FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS; + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != + (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { + } + } + +#endif /* STM32_NO_INIT */ + + /* SYSCFG clock enabled here because it is a multi-functional unit shared + among multiple drivers.*/ + rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); +} + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.h b/os/hal/ports/STM32/STM32L4xx/hal_lld.h index 0aae22a844..4dd8a06fe0 100644 --- a/os/hal/ports/STM32/STM32L4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.h @@ -1,2368 +1,2368 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L4xx/hal_lld.h - * @brief STM32L4xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32L432xx, STM32L433xx, STM32L443xx. - * - STM32L471xx, STM32L475xx, STM32L476xx, STM32L496xx. - * - STM32L485xx, STM32L486xx, STM32L4A6xx. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L443xx) || \ - defined(STM32L452xx) || defined(STM32L471xx) || defined(STM32L475xx) || \ - defined(STM32L476xx) || defined(STM32L496xx) || defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32L4xx Ultra Low Power" - -#elif defined(STM32L485xx) || defined(STM32L486xx) || defined(STM32L4A6xx) -#define PLATFORM_NAME "STM32L4xx Ultra Low Power with Crypto" - -#else -#error "STM32L4xx device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32L4XX) || defined(__DOXYGEN__) -#define STM32L4XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ -#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ -#define STM32_LSICLK 32000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR1 register bits definitions - * @{ - */ -#define STM32_VOS_MASK (3 << 9) /**< Core voltage mask. */ -#define STM32_VOS_RANGE1 (1 << 9) /**< Core voltage 1.2 Volts. */ -#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ -/** @} */ - -/** - * @name PWR_CR2 register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */ -#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CR register bits definitions - * @{ - */ -#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */ -#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */ -#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */ -#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */ -#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */ -#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */ -#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */ -#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */ -#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */ -#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */ -#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */ -#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */ -#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ -#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ -#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 8) /**< PPRE1 field mask. */ -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_STOPWUCK_MASK (1 << 15) /**< STOPWUCK field mask. */ -#define STM32_STOPWUCK_MSI (0 << 15) /**< Wakeup clock is MSI. */ -#define STM32_STOPWUCK_HSI16 (1 << 15) /**< Wakeup clock is HSI16. */ - -#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ -#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ - -#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ -#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ -#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ -#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ -#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ -#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSRC_MSI (1 << 0) /**< PLL clock source is MSI. */ -#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CCIPR register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ -#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ -#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ -#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 source is HSI16. */ -#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ - -#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ -#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ -#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ -#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 source is HSI16. */ -#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ - -#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ -#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ -#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ -#define STM32_USART3SEL_HSI16 (2 << 4) /**< USART3 source is HSI16. */ -#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ - -#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ -#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ -#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ -#define STM32_UART4SEL_HSI16 (2 << 6) /**< UART4 source is HSI16. */ -#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ - -#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ -#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ -#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ -#define STM32_UART5SEL_HSI16 (2 << 8) /**< UART5 source is HSI16. */ -#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ - -#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 mask. */ -#define STM32_LPUART1SEL_PCLK1 (0 << 10) /**< LPUART1 source is PCLK1. */ -#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 source is SYSCLK. */ -#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 source is HSI16. */ -#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 source is LSE. */ - -#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK1 (0 << 12) /**< I2C1 source is PCLK1. */ -#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 source is HSI16. */ - -#define STM32_I2C2SEL_MASK (3 << 14) /**< I2C2SEL mask. */ -#define STM32_I2C2SEL_PCLK1 (0 << 14) /**< I2C2 source is PCLK1. */ -#define STM32_I2C2SEL_SYSCLK (1 << 14) /**< I2C2 source is SYSCLK. */ -#define STM32_I2C2SEL_HSI16 (2 << 14) /**< I2C2 source is HSI16. */ - -#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3SEL mask. */ -#define STM32_I2C3SEL_PCLK1 (0 << 16) /**< I2C3 source is PCLK1. */ -#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 source is SYSCLK. */ -#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 source is HSI16. */ - -#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1SEL mask. */ -#define STM32_LPTIM1SEL_PCLK1 (0 << 18) /**< LPTIM1 source is PCLK1. */ -#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 source is HSI16. */ -#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 source is LSE. */ - -#define STM32_LPTIM2SEL_MASK (3 << 20) /**< LPTIM2SEL mask. */ -#define STM32_LPTIM2SEL_PCLK1 (0 << 20) /**< LPTIM2 source is PCLK1. */ -#define STM32_LPTIM2SEL_LSI (1 << 20) /**< LPTIM2 source is LSI. */ -#define STM32_LPTIM2SEL_HSI16 (2 << 20) /**< LPTIM2 source is HSI16. */ -#define STM32_LPTIM2SEL_LSE (3 << 20) /**< LPTIM2 source is LSE. */ - -#define STM32_SAI1SEL_MASK (3 << 22) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_PLLSAI1 (0 << 22) /**< SAI1 source is PLLSAI1-P. */ -#define STM32_SAI1SEL_PLLSAI2 (1 << 22) /**< SAI1 source is PLLSAI2-P. */ -#define STM32_SAI1SEL_PLL (2 << 22) /**< SAI1 source is PLL-P. */ -#define STM32_SAI1SEL_EXTCLK (3 << 22) /**< SAI1 source is external. */ -#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ - -#define STM32_SAI2SEL_MASK (3 << 24) /**< SAI2SEL mask. */ -#define STM32_SAI2SEL_PLLSAI1 (0 << 24) /**< SAI2 source is PLLSAI1-P. */ -#define STM32_SAI2SEL_PLLSAI2 (1 << 24) /**< SAI2 source is PLLSAI2-P. */ -#define STM32_SAI2SEL_PLL (2 << 24) /**< SAI2 source is PLL-P. */ -#define STM32_SAI2SEL_EXTCLK (3 << 24) /**< SAI2 source is external. */ -#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ - -#define STM32_CLK48SEL_MASK (3 << 26) /**< CLK48SEL mask. */ -#if !STM32_CLOCK_HAS_HSI48 -#define STM32_CLK48SEL_NOCLK (0 << 26) /**< CLK48 disabled. */ -#else -#define STM32_CLK48SEL_HSI48 (0 << 26) /**< CLK48 source is HSI48. */ -#endif -#define STM32_CLK48SEL_PLLSAI1 (1 << 26) /**< CLK48 source is PLLSAI1-Q. */ -#define STM32_CLK48SEL_PLL (2 << 26) /**< CLK48 source is PLL-Q. */ -#define STM32_CLK48SEL_MSI (3 << 26) /**< CLK48 source is MSI. */ - -#define STM32_ADCSEL_MASK (3 << 28) /**< ADCSEL mask. */ -#define STM32_ADCSEL_NOCLK (0 << 28) /**< ADC clock disabled. */ -#define STM32_ADCSEL_PLLSAI1 (1 << 28) /**< ADC source is PLLSAI1-R. */ -#define STM32_ADCSEL_PLLSAI2 (2 << 28) /**< ADC source is PLLSAI2-R. */ -#define STM32_ADCSEL_SYSCLK (3 << 28) /**< ADC source is SYSCLK. */ - -#define STM32_SWPMI1SEL_MASK (1 << 30) /**< SWPMI1SEL mask. */ -#define STM32_SWPMI1SEL_PCLK1 (0 << 30) /**< SWPMI1 source is PCLK1. */ -#define STM32_SWPMI1SEL_HSI16 (1 << 30) /**< SWPMI1 source is HSI16. */ - -#define STM32_DFSDMSEL_MASK (1 << 31) /**< DFSDMSEL mask. */ -#define STM32_DFSDMSEL_PCLK2 (0 << 31) /**< DFSDM source is PCLK2. */ -#define STM32_DFSDMSEL_SYSCLK (1 << 31) /**< DFSDM source is SYSCLK. */ -/** @} */ - -/** - * @name RCC_CCIPR2 register bits definitions - * @{ - */ -#define STM32_I2C4SEL_MASK (3 << 0) /**< I2C1SEL mask. */ -#define STM32_I2C4SEL_PCLK1 (0 << 0) /**< I2C1 source is PCLK1. */ -#define STM32_I2C4SEL_SYSCLK (1 << 0) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C4SEL_HSI16 (2 << 0) /**< I2C1 source is HSI16. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ - -#define STM32_LSCOSEL_MASK (3 << 24) /**< LSCO pin clock source. */ -#define STM32_LSCOSEL_NOCLOCK (0 << 24) /**< No clock on LSCO pin. */ -#define STM32_LSCOSEL_LSI (1 << 24) /**< LSI on LSCO pin. */ -#define STM32_LSCOSEL_LSE (3 << 24) /**< LSE on LSCO pin. */ -/** @} */ - -/** - * @name RCC_CSR register bits definitions - * @{ - */ -#define STM32_MSISRANGE_MASK (15 << 8) /**< MSISRANGE field mask. */ -#define STM32_MSISRANGE_1M (4 << 8) /**< 1MHz nominal. */ -#define STM32_MSISRANGE_2M (5 << 8) /**< 2MHz nominal. */ -#define STM32_MSISRANGE_4M (6 << 8) /**< 4MHz nominal. */ -#define STM32_MSISRANGE_8M (7 << 8) /**< 8MHz nominal. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_RANGE1 -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI16 clock source. - */ -#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSI48 clock source. - */ -#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI48_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Enables or disables the MSI PLL on LSE clock source. - */ -#if !defined(STM32_MSIPLL_ENABLED) || defined(__DOXYGEN__) -#define STM32_MSIPLL_ENABLED FALSE -#endif - -/** - * @brief MSI frequency setting. - */ -#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) -#define STM32_MSIRANGE STM32_MSIRANGE_4M -#endif - -/** - * @brief MSI frequency setting after standby. - */ -#if !defined(STM32_MSISRANGE) || defined(__DOXYGEN__) -#define STM32_MSISRANGE STM32_MSISRANGE_4M -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_MSI -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 1..8. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 1 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 8..86. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 80 -#endif - -/** - * @brief PLLPDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLPDIV_VALUE 0 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 7, 17. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 7 -#endif - -/** - * @brief PLLQ divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 6 -#endif - -/** - * @brief PLLR divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLR_VALUE 4 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 80MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief STOPWUCK clock setting. - */ -#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) -#define STM32_STOPWUCK STM32_STOPWUCK_MSI -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief LSCO clock source. - */ -#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) -#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK -#endif - -/** - * @brief PLLSAI1N multiplier value. - * @note The allowed values are 8..86. - */ -#if !defined(STM32_PLLSAI1N_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1N_VALUE 80 -#endif - -/** - * @brief PLLSAI1PDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLSAI1PDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1PDIV_VALUE 0 -#endif - -/** - * @brief PLLSAI1P divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLSAI1P_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1P_VALUE 7 -#endif - -/** - * @brief PLLSAI1Q divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI1Q_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1Q_VALUE 6 -#endif - -/** - * @brief PLLSAI1R divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI1R_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1R_VALUE 4 -#endif - -/** - * @brief PLLSAI2N multiplier value. - * @note The allowed values are 8..86. - */ -#if !defined(STM32_PLLSAI2N_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2N_VALUE 80 -#endif - -/** - * @brief PLLSAI2PDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLSAI2PDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2PDIV_VALUE 0 -#endif - -/** - * @brief PLLSAI2P divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLSAI2P_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2P_VALUE 7 -#endif - -/** - * @brief PLLSAI2R divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI2R_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2R_VALUE 4 -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_SYSCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_SYSCLK -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) -#define STM32_USART3SEL STM32_USART3SEL_SYSCLK -#endif - -/** - * @brief UART4 clock source. - */ -#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) -#define STM32_UART4SEL STM32_UART4SEL_SYSCLK -#endif - -/** - * @brief UART5 clock source. - */ -#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) -#define STM32_UART5SEL STM32_UART5SEL_SYSCLK -#endif - -/** - * @brief LPUART1 clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) -#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK -#endif - -/** - * @brief I2C3 clock source. - */ -#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) -#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK -#endif - -/** - * @brief I2C4 clock source. - */ -#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) -#define STM32_I2C4SEL STM32_I2C4SEL_SYSCLK -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 -#endif - -/** - * @brief LPTIM2 clock source. - */ -#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 -#endif - -/** - * @brief SAI1SEL value (SAI1 clock source). - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#endif - -/** - * @brief SAI2SEL value (SAI2 clock source). - */ -#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) -#define STM32_SAI2SEL STM32_SAI2SEL_OFF -#endif - -/** - * @brief CLK48SEL value (48MHz clock source). - */ -#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) -#define STM32_CLK48SEL STM32_CLK48SEL_PLL -#endif - -/** - * @brief ADCSEL value (ADCs clock source). - */ -#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) -#define STM32_ADCSEL STM32_ADCSEL_SYSCLK -#endif - -/** - * @brief SWPMI1SEL value (SWPMI clock source). - */ -#if !defined(STM32_SWPMI1SEL) || defined(__DOXYGEN__) -#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 -#endif - -/** - * @brief DFSDMSEL value (DFSDM clock source). - */ -#if !defined(STM32_DFSDMSEL) || defined(__DOXYGEN__) -#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 -#endif - -/** - * @brief RTC/LCD clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32L4xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4xx_MCUCONF not defined" -#endif - -/* Only some devices have strongly checked mcuconf.h files. Others will be - added gradually.*/ -#if defined(STM32L432xx) && !defined(STM32L432_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L432_MCUCONF not defined" -#endif - -#if defined(STM32L433xx) && !defined(STM32L433_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L433_MCUCONF not defined" -#endif - -#if defined(STM32L476xx) && !defined(STM32L476_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L476_MCUCONF not defined" -#endif - -#if defined(STM32L486xx) && !defined(STM32L486_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L486_MCUCONF not defined" -#endif - -#if defined(STM32L496xx) && !defined(STM32L496_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L496_MCUCONF not defined" -#endif - -#if defined(STM32L4A6xx) && !defined(STM32L4A6_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L4A6_MCUCONF not defined" -#endif - -/* - * Board files sanity checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif - -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) -/** - * @name System Limits - * @{ - */ -/** - * @brief Maximum SYSCLK clock frequency at current voltage setting. - */ -#define STM32_SYSCLK_MAX 80000000 - -/** - * @brief Maximum HSE clock frequency at current voltage setting. - */ -#define STM32_HSECLK_MAX 48000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 48000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MIN 8000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 16000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 4000000 - -/** - * @brief Maximum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MAX 344000000 - -/** - * @brief Minimum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MIN 64000000 - -/** - * @brief Maximum PLL-P output clock frequency. - */ -#define STM32_PLLP_MAX 80000000 - -/** - * @brief Minimum PLL-P output clock frequency. - */ -#define STM32_PLLP_MIN 2064500 - -/** - * @brief Maximum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MAX 80000000 - -/** - * @brief Minimum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MIN 8000000 - -/** - * @brief Maximum PLL-R output clock frequency. - */ -#define STM32_PLLR_MAX 80000000 - -/** - * @brief Minimum PLL-R output clock frequency. - */ -#define STM32_PLLR_MIN 8000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 80000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 80000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 80000000 -/** @} */ - -/** - * @name Flash Wait states - * @{ - */ -#define STM32_0WS_THRESHOLD 16000000 -#define STM32_1WS_THRESHOLD 32000000 -#define STM32_2WS_THRESHOLD 48000000 -#define STM32_3WS_THRESHOLD 64000000 -/** @} */ - -#elif STM32_VOS == STM32_VOS_RANGE2 -#define STM32_SYSCLK_MAX 26000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 26000000 -#define STM32_HSECLK_MIN 8000000 -#define STM32_HSECLK_BYP_MIN 8000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_LSECLK_BYP_MIN 32768 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLIN_MIN 4000000 -#define STM32_PLLVCO_MAX 128000000 -#define STM32_PLLVCO_MIN 64000000 -#define STM32_PLLP_MAX 26000000 -#define STM32_PLLP_MIN 2064500 -#define STM32_PLLQ_MAX 26000000 -#define STM32_PLLQ_MIN 8000000 -#define STM32_PLLR_MAX 26000000 -#define STM32_PLLR_MIN 8000000 -#define STM32_PCLK1_MAX 26000000 -#define STM32_PCLK2_MAX 26000000 -#define STM32_ADCCLK_MAX 26000000 - -#define STM32_0WS_THRESHOLD 6000000 -#define STM32_1WS_THRESHOLD 12000000 -#define STM32_2WS_THRESHOLD 18000000 -#define STM32_3WS_THRESHOLD 26000000 - -#else -#error "invalid STM32_VOS value specified" -#endif - -/** - * @brief MSI frequency. - */ -#if STM32_MSIRANGE == STM32_MSIRANGE_100K -#define STM32_MSICLK 100000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_200K -#define STM32_MSICLK 200000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_400K -#define STM32_MSICLK 400000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_800K -#define STM32_MSICLK 800000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_1M -#define STM32_MSICLK 1000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_2M -#define STM32_MSICLK 2000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_4M -#define STM32_MSICLK 4000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_8M -#define STM32_MSICLK 8000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_16M -#define STM32_MSICLK 16000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_24M -#define STM32_MSICLK 24000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_32M -#define STM32_MSICLK 32000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_48M -#define STM32_MSICLK 48000000 -#else -#error "invalid STM32_MSIRANGE value specified" -#endif - -/** - * @brief MSIS frequency. - */ -#if STM32_MSISRANGE == STM32_MSISRANGE_1M -#define STM32_MSISCLK 1000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_2M -#define STM32_MSISCLK 2000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_4M -#define STM32_MSISCLK 4000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_8M -#define STM32_MSISCLK 8000000 -#else -#error "invalid STM32_MSISRANGE value specified" -#endif - -/* - * HSI16 related checks. - */ -#if STM32_HSI16_ENABLED -#else /* !STM32_HSI16_ENABLED */ - -#if STM32_SW == STM32_SW_HSI16 -#error "HSI16 not enabled, required by STM32_SW" -#endif - -#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" -#endif - -#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16)) -#error "HSI16 not enabled, required by STM32_MCOSEL" -#endif - -#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SAI1SEL" -#endif - -#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16) -#error "HSI16 not enabled, required by STM32_SAI2SEL" -#endif - -#if (STM32_USART1SEL == STM32_USART1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART1SEL" -#endif -#if (STM32_USART2SEL == STM32_USART2SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART2SEL" -#endif -#if (STM32_USART3SEL == STM32_USART3SEL_HSI16) -#error "HSI16 not enabled, required by STM32_USART3SEL" -#endif -#if (STM32_UART4SEL == STM32_UART4SEL_HSI16) -#error "HSI16 not enabled, required by STM32_UART4SEL" -#endif -#if (STM32_UART5SEL == STM32_UART5SEL_HSI16) -#error "HSI16 not enabled, required by STM32_UART5SEL" -#endif -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) -#error "HSI16 not enabled, required by STM32_LPUART1SEL" -#endif - -#if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) -#error "HSI16 not enabled, required by I2C1SEL" -#endif -#if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) -#error "HSI16 not enabled, required by I2C2SEL" -#endif -#if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) -#error "HSI16 not enabled, required by I2C3SEL" -#endif -#if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) -#error "HSI16 not enabled, required by I2C4SEL" -#endif - -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) -#error "HSI16 not enabled, required by LPTIM1SEL" -#endif -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) -#error "HSI16 not enabled, required by LPTIM2SEL" -#endif - -#if (STM32_SWPMI1SEL == STM32_SWPMI1SEL_HSI16) -#error "HSI16 not enabled, required by SWPMI1SEL" -#endif -#if (STM32_STOPWUCK == STM32_STOPWUCK_HSI16) -#error "HSI16 not enabled, required by STM32_STOPWUCK" -#endif - -#endif /* !STM32_HSI16_ENABLED */ - -#if STM32_CLOCK_HAS_HSI48 -#if STM32_HSI48_ENABLED -#else /* !STM32_HSI48_ENABLED */ - -#if STM32_MCOSEL == STM32_MCOSEL_HSI48 -#error "HSI48 not enabled, required by STM32_MCOSEL" -#endif - -#if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 -#error "HSI48 not enabled, required by STM32_CLK48SEL" -#endif -#endif /* !STM32_HSI48_ENABLED */ -#endif /* STM32_CLOCK_HAS_HSI48 */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - - #if STM32_HSECLK == 0 - #error "HSE frequency not defined" - #else /* STM32_HSECLK != 0 */ - #if defined(STM32_HSE_BYPASS) - #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" - #endif - #else /* !defined(STM32_HSE_BYPASS) */ - #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" - #endif - #endif /* !defined(STM32_HSE_BYPASS) */ - #endif /* STM32_HSECLK != 0 */ - - #else /* !STM32_HSE_ENABLED */ - - #if STM32_SW == STM32_SW_HSE - #error "HSE not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) - #error "HSE not enabled, required by STM32_MCOSEL" - #endif - - #if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) | \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SAI1SEL" - #endif - - #if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) | \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SAI2SEL" - #endif - - #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV - #error "HSE not enabled, required by STM32_RTCSEL" - #endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - - #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) - #error "LSI not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSI - #error "LSI not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSI - #error "LSI not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - - #if (STM32_LSECLK == 0) - #error "LSE frequency not defined" - #endif - - #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) - #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" - #endif - -#else /* !STM32_LSE_ENABLED */ - - #if STM32_RTCSEL == STM32_RTCSEL_LSE - #error "LSE not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSE - #error "LSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSE - #error "LSE not enabled, required by STM32_LSCOSEL" - #endif - - #if STM32_MSIPLL_ENABLED == TRUE - #error "LSE not enabled, required by STM32_MSIPLL_ENABLED" - #endif - -#endif /* !STM32_LSE_ENABLED */ - -/* - * MSI related checks. - */ -#if (STM32_MSIRANGE == STM32_MSIRANGE_48M) && !STM32_MSIPLL_ENABLED -#warning "STM32_MSIRANGE_48M should be used with STM32_MSIPLL_ENABLED" -#endif - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 8)) || \ - defined(__DOXYGEN__) -#define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLLs input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_MSI -#define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 -#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK -#define STM32_PLLCLKIN 0 - -#else -#error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLLs input frequency range check. - */ -#if (STM32_PLLCLKIN != 0) && \ - ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_HSI48_ENABLED && (STM32_CLK48SEL == STM32_CLK48SEL_PLL)) || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ - defined(__DOXYGEN__) - -#if STM32_PLLCLKIN == 0 -#error "PLL activation required but no PLL clock selected" -#endif - -/** - * @brief PLL activation flag. - */ -#define STM32_ACTIVATE_PLL TRUE -#else -#define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 86)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 8) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLP (0 << 17) - -#elif STM32_PLLP_VALUE == 17 -#define STM32_PLLP (1 << 17) - -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLQ (0 << 21) - -#elif STM32_PLLQ_VALUE == 4 -#define STM32_PLLQ (1 << 21) - -#elif STM32_PLLQ_VALUE == 6 -#define STM32_PLLQ (2 << 21) - -#elif STM32_PLLQ_VALUE == 8 -#define STM32_PLLQ (3 << 21) - -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLR field. - */ -#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLR (0 << 25) - -#elif STM32_PLLR_VALUE == 4 -#define STM32_PLLR (1 << 25) - -#elif STM32_PLLR_VALUE == 6 -#define STM32_PLLR (2 << 25) - -#elif STM32_PLLR_VALUE == 8 -#define STM32_PLLR (3 << 25) - -#else -#error "invalid STM32_PLLR_VALUE value specified" -#endif - -#if defined(STM32L496xx) || defined(STM32L4A6xx) -/** - * @brief STM32_PLLPDIV field. (Only for STM32L496xx/4A6xx) - */ -#if (STM32_PLLPDIV_VALUE == 0) || \ - ((STM32_PLLPDIV_VALUE >= 2) && (STM32_PLLPDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) -#else -#error "invalid STM32_PLLPDIV_VALUE value specified" -#endif -#endif - -/** - * @brief STM32_PLLPEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ - defined(__DOXYGEN__) -#define STM32_PLLPEN (1 << 16) -#else -#define STM32_PLLPEN (0 << 16) -#endif - -/** - * @brief STM32_PLLQEN field. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__) -#define STM32_PLLQEN (1 << 20) -#else -#define STM32_PLLQEN (0 << 20) -#endif - -/** - * @brief STM32_PLLREN field. - */ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - defined(__DOXYGEN__) -#define STM32_PLLREN (1 << 24) -#else -#define STM32_PLLREN (0 << 24) -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL P output clock frequency. - */ -#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) -#else -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) -#endif - -/** - * @brief PLL Q output clock frequency. - */ -#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) - -/** - * @brief PLL R output clock frequency. - */ -#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) - -/* - * PLL-P output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLL-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLL-R output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_MSICLK - -#elif (STM32_SW == STM32_SW_MSI) -#define STM32_SYSCLK STM32_MSICLK - -#elif (STM32_SW == STM32_SW_HSI16) -#define STM32_SYSCLK STM32_HSI16CLK - -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK - -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLL_R_CLKOUT - -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) - -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) - -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) - -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) - -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) - -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) - -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) - -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) - -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) - -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/* - * PLLSAI1 enable check. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ - (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ - defined(__DOXYGEN__) - -#if STM32_PLLCLKIN == 0 -#error "PLLSAI1 activation required but no PLL clock selected" -#endif - -/** - * @brief PLLSAI1 activation flag. - */ -#define STM32_ACTIVATE_PLLSAI1 TRUE -#else -#define STM32_ACTIVATE_PLLSAI1 FALSE -#endif - -/** - * @brief STM32_PLLSAI1N field. - */ -#if ((STM32_PLLSAI1N_VALUE >= 8) && (STM32_PLLSAI1N_VALUE <= 86)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1N (STM32_PLLSAI1N_VALUE << 8) -#else -#error "invalid STM32_PLLSAI1N_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1P field. - */ -#if (STM32_PLLSAI1P_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLSAI1P (0 << 17) - -#elif STM32_PLLSAI1P_VALUE == 17 -#define STM32_PLLSAI1P (1 << 17) - -#else -#error "invalid STM32_PLLSAI1P_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1Q field. - */ -#if (STM32_PLLSAI1Q_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI1Q (0 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 4 -#define STM32_PLLSAI1Q (1 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 6 -#define STM32_PLLSAI1Q (2 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 8 -#define STM32_PLLSAI1Q (3 << 21) - -#else -#error "invalid STM32_PLLSAI1Q_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1R field. - */ -#if (STM32_PLLSAI1R_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI1R (0 << 25) - -#elif STM32_PLLSAI1R_VALUE == 4 -#define STM32_PLLSAI1R (1 << 25) - -#elif STM32_PLLSAI1R_VALUE == 6 -#define STM32_PLLSAI1R (2 << 25) - -#elif STM32_PLLSAI1R_VALUE == 8 -#define STM32_PLLSAI1R (3 << 25) - -#else -#error "invalid STM32_PLLSAI1R_VALUE value specified" -#endif - -#if defined(STM32L496xx) || defined(STM32L4A6xx) -/** - * @brief STM32_PLLSAI1PDIV field. (Only for STM32L496xx/4A6xx) - */ -#if ((STM32_PLLSAI1PDIV_VALUE != 1) && (STM32_PLLSAI1PDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1PDIV (STM32_PLLSAI1PDIV_VALUE << 27) -#else -#error "invalid STM32_PLLSAI1PDIV_VALUE value specified" -#endif -#endif - -/** - * @brief STM32_PLLSAI1PEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1PEN (1 << 16) -#else -#define STM32_PLLSAI1PEN (0 << 16) -#endif - -/** - * @brief STM32_PLLSAI1QEN field. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_PLLSAI1QEN (1 << 20) -#else -#define STM32_PLLSAI1QEN (0 << 20) -#endif - -/** - * @brief STM32_PLLSAI1REN field. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_PLLSAI1REN (1 << 24) -#else -#define STM32_PLLSAI1REN (0 << 24) -#endif - -/** - * @brief PLLSAI1 VCO frequency. - */ -#define STM32_PLLSAI1VCO (STM32_PLLCLKIN * STM32_PLLSAI1N_VALUE) - -/* - * PLLSAI1 VCO frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI1-P output clock frequency. - */ -#if (STM32_PLLSAI1PDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE) -#else -#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1PDIV_VALUE) -#endif - -/** - * @brief PLLSAI1-Q output clock frequency. - */ -#define STM32_PLLSAI1_Q_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) - -/** - * @brief PLLSAI1-R output clock frequency. - */ -#define STM32_PLLSAI1_R_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1R_VALUE) - -/* - * PLLSAI1-P output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLLSAI1-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLLSAI1-R output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/* - * PLLSAI2 enable check. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ - (STM32_ADCSEL == STM32_ADCSEL_PLLSAI2) || \ - defined(__DOXYGEN__) - -#if STM32_PLLCLKIN == 0 -#error "PLLSAI2 activation required but no PLL clock selected" -#endif - -/** - * @brief PLLSAI2 activation flag. - */ -#define STM32_ACTIVATE_PLLSAI2 TRUE -#else -#define STM32_ACTIVATE_PLLSAI2 FALSE -#endif - -/** - * @brief STM32_PLLSAI2N field. - */ -#if ((STM32_PLLSAI2N_VALUE >= 8) && (STM32_PLLSAI2N_VALUE <= 86)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2N (STM32_PLLSAI2N_VALUE << 8) -#else -#error "invalid STM32_PLLSAI2N_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2P field. - */ -#if (STM32_PLLSAI2P_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLSAI2P (0 << 17) - -#elif STM32_PLLSAI2P_VALUE == 17 -#define STM32_PLLSAI2P (1 << 17) - -#else -#error "invalid STM32_PLLSAI2P_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2R field. - */ -#if (STM32_PLLSAI2R_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI2R (0 << 25) - -#elif STM32_PLLSAI2R_VALUE == 4 -#define STM32_PLLSAI2R (1 << 25) - -#elif STM32_PLLSAI2R_VALUE == 6 -#define STM32_PLLSAI2R (2 << 25) - -#elif STM32_PLLSAI2R_VALUE == 8 -#define STM32_PLLSAI2R (3 << 25) - -#else -#error "invalid STM32_PLLSAI2R_VALUE value specified" -#endif - -#if defined(STM32L496xx) || defined(STM32L4A6xx) -/** - * @brief STM32_PLLSAI2PDIV field. (Only for STM32L496xx/4A6xx) - */ -#if ((STM32_PLLSAI2PDIV_VALUE != 1) && (STM32_PLLSAI2PDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2PDIV (STM32_PLLSAI2PDIV_VALUE << 27) -#else -#error "invalid STM32_PLLSAI2PDIV_VALUE value specified" -#endif -#endif - -/** - * @brief STM32_PLLSAI2PEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2PEN (1 << 16) -#else -#define STM32_PLLSAI2PEN (0 << 16) -#endif - -/** - * @brief STM32_PLLSAI2REN field. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI2) || defined(__DOXYGEN__) -#define STM32_PLLSAI2REN (1 << 24) -#else -#define STM32_PLLSAI2REN (0 << 24) -#endif - -/** - * @brief PLLSAI2 VCO frequency. - */ -#define STM32_PLLSAI2VCO (STM32_PLLCLKIN * STM32_PLLSAI2N_VALUE) - -/* - * PLLSAI2 VCO frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI2-P output clock frequency. - */ -#if (STM32_PLLSAI2PDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE) -#else -#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2PDIV_VALUE) -#endif - -/** - * @brief PLLSAI2-R output clock frequency. - */ -#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE) - -/* - * PLLSAI2-P output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLLSAI2-R output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief MCO divider clock frequency. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 - -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK -#define STM32_MCODIVCLK STM32_SYSCLK - -#elif STM32_MCOSEL == STM32_MCOSEL_MSI -#define STM32_MCODIVCLK STM32_MSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 -#define STM32_MCODIVCLK STM32_HSI16CLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_PLL -#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT - -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 -#define STM32_MCODIVCLK STM32_HSI48CLK - -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock frequency. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) - -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief RTC clock frequency. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 clock frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK2 -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK -#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 -#define STM32_USART1CLK STM32_HSI16CLK -#elif STM32_USART1SEL == STM32_USART1SEL_LSE -#define STM32_USART1CLK STM32_LSECLK -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 clock frequency. - */ -#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART2CLK STM32_PCLK1 -#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK -#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 -#define STM32_USART2CLK STM32_HSI16CLK -#elif STM32_USART2SEL == STM32_USART2SEL_LSE -#define STM32_USART2CLK STM32_LSECLK -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 clock frequency. - */ -#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART3CLK STM32_PCLK1 -#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK -#define STM32_USART3CLK STM32_SYSCLK -#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 -#define STM32_USART3CLK STM32_HSI16CLK -#elif STM32_USART3SEL == STM32_USART3SEL_LSE -#define STM32_USART3CLK STM32_LSECLK -#else -#error "invalid source selected for USART3 clock" -#endif - -/** - * @brief UART4 clock frequency. - */ -#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART4CLK STM32_PCLK1 -#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK -#define STM32_UART4CLK STM32_SYSCLK -#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 -#define STM32_UART4CLK STM32_HSI16CLK -#elif STM32_UART4SEL == STM32_UART4SEL_LSE -#define STM32_UART4CLK STM32_LSECLK -#else -#error "invalid source selected for UART4 clock" -#endif - -/** - * @brief UART5 clock frequency. - */ -#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART5CLK STM32_PCLK1 -#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK -#define STM32_UART5CLK STM32_SYSCLK -#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 -#define STM32_UART5CLK STM32_HSI16CLK -#elif STM32_UART5SEL == STM32_UART5SEL_LSE -#define STM32_UART5CLK STM32_LSECLK -#else -#error "invalid source selected for UART5 clock" -#endif - -/** - * @brief LPUART1 clock frequency. - */ -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPUART1CLK STM32_PCLK1 -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK -#define STM32_LPUART1CLK STM32_SYSCLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 -#define STM32_LPUART1CLK STM32_HSI16CLK -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE -#define STM32_LPUART1CLK STM32_LSECLK -#else -#error "invalid source selected for LPUART1 clock" -#endif - -/** - * @brief I2C1 clock frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_PCLK1 -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 -#define STM32_I2C1CLK STM32_HSI16CLK -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 clock frequency. - */ -#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C2CLK STM32_PCLK1 -#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK -#define STM32_I2C2CLK STM32_SYSCLK -#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 -#define STM32_I2C2CLK STM32_HSI16CLK -#else -#error "invalid source selected for I2C2 clock" -#endif - -/** - * @brief I2C3 clock frequency. - */ -#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C3CLK STM32_PCLK1 -#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK -#define STM32_I2C3CLK STM32_SYSCLK -#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 -#define STM32_I2C3CLK STM32_HSI16CLK -#else -#error "invalid source selected for I2C3 clock" -#endif - -/** - * @brief I2C4 clock frequency. - */ -#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C4CLK STM32_PCLK1 -#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK -#define STM32_I2C4CLK STM32_SYSCLK -#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 -#define STM32_I2C4CLK STM32_HSI16CLK -#else -#error "invalid source selected for I2C4 clock" -#endif - -/** - * @brief LPTIM1 clock frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM1CLK STM32_PCLK1 -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI -#define STM32_LPTIM1CLK STM32_LSICLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 -#define STM32_LPTIM1CLK STM32_HSI16CLK -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE -#define STM32_LPTIM1CLK STM32_LSECLK -#else -#error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief LPTIM2 clock frequency. - */ -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM2CLK STM32_PCLK1 -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI -#define STM32_LPTIM2CLK STM32_LSICLK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 -#define STM32_LPTIM2CLK STM32_HSI16CLK -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE -#define STM32_LPTIM2CLK STM32_LSECLK -#else -#error "invalid source selected for LPTIM2 clock" -#endif - -/** - * @brief 48MHz clock frequency. - */ -#if !STM32_CLOCK_HAS_HSI48 || defined(__DOXYGEN__) - -#if (STM32_CLK48SEL == STM32_CLK48SEL_NOCLK) || defined(__DOXYGEN__) -#define STM32_48CLK 0 -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 -#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL -#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) -#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI -#define STM32_48CLK STM32_MSICLK -#else -#error "invalid source selected for 48CLK clock" -#endif - -#else /* STM32_CLOCK_HAS_HSI48 */ - -#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) -#define STM32_48CLK STM32_HSI48CLK -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 -#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL -#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) -#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI -#define STM32_48CLK STM32_MSICLK -#else -#error "invalid source selected for 48CLK clock" -#endif - -#endif /* STM32_CLOCK_HAS_HSI48 */ - -/** - * @brief SAI1 clock frequency. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_SAI1CLK STM32_PLLSAI1_P_CLKOUT -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2 -#define STM32_SAI1CLK STM32_PLLSAI2_P_CLKOUT -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL -#define STM32_SAI1CLK STM32_PLL_P_CLKOUT -#elif STM32_SAI1SEL == STM32_SAI1SEL_EXTCLK -#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ -#elif STM32_SAI1SEL == STM32_SAI1SEL_OFF -#define STM32_SAI1CLK 0 -#else -#error "invalid source selected for SAI1 clock" -#endif - -/** - * @brief SAI2 clock frequency. - */ -#if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_SAI2CLK STM32_PLLSAI1_P_CLKOUT -#elif STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2 -#define STM32_SAI2CLK STM32_PLLSAI2_P_CLKOUT -#elif STM32_SAI2SEL == STM32_SAI2SEL_PLL -#define STM32_SAI2CLK STM32_PLL_P_CLKOUT -#elif STM32_SAI2SEL == STM32_SAI2SEL_EXTCLK -#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ -#elif STM32_SAI2SEL == STM32_SAI2SEL_OFF -#define STM32_SAI2CLK 0 -#else -#error "invalid source selected for SAI2 clock" -#endif - -/** - * @brief USB clock point. - */ -#define STM32_USBCLK STM32_48CLK - -/** - * @brief RNG clock point. - */ -#define STM32_RNGCLK STM32_48CLK - -/** - * @brief ADC clock frequency. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_NOCLK) || defined(__DOXYGEN__) -#define STM32_ADCCLK 0 -#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI1 -#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT -#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI2 -#define STM32_ADCCLK STM32_PLLSAI2_R_CLKOUT -#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK -#define STM32_ADCCLK STM32_SYSCLK -#else -#error "invalid source selected for ADC clock" -#endif - -/** - * @brief SWPMI1 clock frequency. - */ -#if (STM32_SWPMI1SEL == STM32_SWPMI1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_SWPMI1CLK STM32_PCLK1 -#elif STM32_SWPMI1SEL == STM32_SWPMI1SEL_HSI16 -#define STM32_SWPMI1CLK STM32_HSI16CLK -#else -#error "invalid source selected for SWPMI1 clock" -#endif - -/** - * @brief DFSDM clock frequency. - */ -#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_DFSDMCLK STM32_PCLK2 -#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK -#define STM32_DFSDMCLK STM32_SYSCLK -#else -#error "invalid source selected for DFSDM clock" -#endif - -/** - * @brief SDMMC frequency. - */ -#define STM32_SDMMC1CLK STM32_48CLK - -/** - * @brief Clock of timers connected to APB1 - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Clock of timers connected to APB2. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_HCLK <= STM32_3WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS - -#else -#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS -#endif - -/** - * @brief Flash settings for MSI. - */ -#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_MSICLK <= STM32_1WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_MSICLK <= STM32_2WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_MSICLK <= STM32_3WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS - -#else -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L4xx/hal_lld.h + * @brief STM32L4xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32L432xx, STM32L433xx, STM32L443xx. + * - STM32L471xx, STM32L475xx, STM32L476xx, STM32L496xx. + * - STM32L485xx, STM32L486xx, STM32L4A6xx. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(STM32L432xx) || defined(STM32L433xx) || defined(STM32L443xx) || \ + defined(STM32L452xx) || defined(STM32L471xx) || defined(STM32L475xx) || \ + defined(STM32L476xx) || defined(STM32L496xx) || defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32L4xx Ultra Low Power" + +#elif defined(STM32L485xx) || defined(STM32L486xx) || defined(STM32L4A6xx) +#define PLATFORM_NAME "STM32L4xx Ultra Low Power with Crypto" + +#else +#error "STM32L4xx device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32L4XX) || defined(__DOXYGEN__) +#define STM32L4XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ +#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR1 register bits definitions + * @{ + */ +#define STM32_VOS_MASK (3 << 9) /**< Core voltage mask. */ +#define STM32_VOS_RANGE1 (1 << 9) /**< Core voltage 1.2 Volts. */ +#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ +/** @} */ + +/** + * @name PWR_CR2 register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */ +#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CR register bits definitions + * @{ + */ +#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */ +#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */ +#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */ +#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */ +#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */ +#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */ +#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */ +#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */ +#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */ +#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */ +#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */ +#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */ +#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ +#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ +#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 8) /**< PPRE1 field mask. */ +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_STOPWUCK_MASK (1 << 15) /**< STOPWUCK field mask. */ +#define STM32_STOPWUCK_MSI (0 << 15) /**< Wakeup clock is MSI. */ +#define STM32_STOPWUCK_HSI16 (1 << 15) /**< Wakeup clock is HSI16. */ + +#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ +#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ + +#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ +#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ +#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ +#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ +#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ +#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSRC_MSI (1 << 0) /**< PLL clock source is MSI. */ +#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CCIPR register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ +#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ +#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ +#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 source is HSI16. */ +#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ + +#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ +#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ +#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ +#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 source is HSI16. */ +#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ + +#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ +#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ +#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ +#define STM32_USART3SEL_HSI16 (2 << 4) /**< USART3 source is HSI16. */ +#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ + +#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ +#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ +#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ +#define STM32_UART4SEL_HSI16 (2 << 6) /**< UART4 source is HSI16. */ +#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ + +#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ +#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ +#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ +#define STM32_UART5SEL_HSI16 (2 << 8) /**< UART5 source is HSI16. */ +#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ + +#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 mask. */ +#define STM32_LPUART1SEL_PCLK1 (0 << 10) /**< LPUART1 source is PCLK1. */ +#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 source is SYSCLK. */ +#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 source is HSI16. */ +#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 source is LSE. */ + +#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK1 (0 << 12) /**< I2C1 source is PCLK1. */ +#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 source is HSI16. */ + +#define STM32_I2C2SEL_MASK (3 << 14) /**< I2C2SEL mask. */ +#define STM32_I2C2SEL_PCLK1 (0 << 14) /**< I2C2 source is PCLK1. */ +#define STM32_I2C2SEL_SYSCLK (1 << 14) /**< I2C2 source is SYSCLK. */ +#define STM32_I2C2SEL_HSI16 (2 << 14) /**< I2C2 source is HSI16. */ + +#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3SEL mask. */ +#define STM32_I2C3SEL_PCLK1 (0 << 16) /**< I2C3 source is PCLK1. */ +#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 source is SYSCLK. */ +#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 source is HSI16. */ + +#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1SEL mask. */ +#define STM32_LPTIM1SEL_PCLK1 (0 << 18) /**< LPTIM1 source is PCLK1. */ +#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 source is HSI16. */ +#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 source is LSE. */ + +#define STM32_LPTIM2SEL_MASK (3 << 20) /**< LPTIM2SEL mask. */ +#define STM32_LPTIM2SEL_PCLK1 (0 << 20) /**< LPTIM2 source is PCLK1. */ +#define STM32_LPTIM2SEL_LSI (1 << 20) /**< LPTIM2 source is LSI. */ +#define STM32_LPTIM2SEL_HSI16 (2 << 20) /**< LPTIM2 source is HSI16. */ +#define STM32_LPTIM2SEL_LSE (3 << 20) /**< LPTIM2 source is LSE. */ + +#define STM32_SAI1SEL_MASK (3 << 22) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_PLLSAI1 (0 << 22) /**< SAI1 source is PLLSAI1-P. */ +#define STM32_SAI1SEL_PLLSAI2 (1 << 22) /**< SAI1 source is PLLSAI2-P. */ +#define STM32_SAI1SEL_PLL (2 << 22) /**< SAI1 source is PLL-P. */ +#define STM32_SAI1SEL_EXTCLK (3 << 22) /**< SAI1 source is external. */ +#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ + +#define STM32_SAI2SEL_MASK (3 << 24) /**< SAI2SEL mask. */ +#define STM32_SAI2SEL_PLLSAI1 (0 << 24) /**< SAI2 source is PLLSAI1-P. */ +#define STM32_SAI2SEL_PLLSAI2 (1 << 24) /**< SAI2 source is PLLSAI2-P. */ +#define STM32_SAI2SEL_PLL (2 << 24) /**< SAI2 source is PLL-P. */ +#define STM32_SAI2SEL_EXTCLK (3 << 24) /**< SAI2 source is external. */ +#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ + +#define STM32_CLK48SEL_MASK (3 << 26) /**< CLK48SEL mask. */ +#if !STM32_CLOCK_HAS_HSI48 +#define STM32_CLK48SEL_NOCLK (0 << 26) /**< CLK48 disabled. */ +#else +#define STM32_CLK48SEL_HSI48 (0 << 26) /**< CLK48 source is HSI48. */ +#endif +#define STM32_CLK48SEL_PLLSAI1 (1 << 26) /**< CLK48 source is PLLSAI1-Q. */ +#define STM32_CLK48SEL_PLL (2 << 26) /**< CLK48 source is PLL-Q. */ +#define STM32_CLK48SEL_MSI (3 << 26) /**< CLK48 source is MSI. */ + +#define STM32_ADCSEL_MASK (3 << 28) /**< ADCSEL mask. */ +#define STM32_ADCSEL_NOCLK (0 << 28) /**< ADC clock disabled. */ +#define STM32_ADCSEL_PLLSAI1 (1 << 28) /**< ADC source is PLLSAI1-R. */ +#define STM32_ADCSEL_PLLSAI2 (2 << 28) /**< ADC source is PLLSAI2-R. */ +#define STM32_ADCSEL_SYSCLK (3 << 28) /**< ADC source is SYSCLK. */ + +#define STM32_SWPMI1SEL_MASK (1 << 30) /**< SWPMI1SEL mask. */ +#define STM32_SWPMI1SEL_PCLK1 (0 << 30) /**< SWPMI1 source is PCLK1. */ +#define STM32_SWPMI1SEL_HSI16 (1 << 30) /**< SWPMI1 source is HSI16. */ + +#define STM32_DFSDMSEL_MASK (1 << 31) /**< DFSDMSEL mask. */ +#define STM32_DFSDMSEL_PCLK2 (0 << 31) /**< DFSDM source is PCLK2. */ +#define STM32_DFSDMSEL_SYSCLK (1 << 31) /**< DFSDM source is SYSCLK. */ +/** @} */ + +/** + * @name RCC_CCIPR2 register bits definitions + * @{ + */ +#define STM32_I2C4SEL_MASK (3 << 0) /**< I2C1SEL mask. */ +#define STM32_I2C4SEL_PCLK1 (0 << 0) /**< I2C1 source is PCLK1. */ +#define STM32_I2C4SEL_SYSCLK (1 << 0) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C4SEL_HSI16 (2 << 0) /**< I2C1 source is HSI16. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ + +#define STM32_LSCOSEL_MASK (3 << 24) /**< LSCO pin clock source. */ +#define STM32_LSCOSEL_NOCLOCK (0 << 24) /**< No clock on LSCO pin. */ +#define STM32_LSCOSEL_LSI (1 << 24) /**< LSI on LSCO pin. */ +#define STM32_LSCOSEL_LSE (3 << 24) /**< LSE on LSCO pin. */ +/** @} */ + +/** + * @name RCC_CSR register bits definitions + * @{ + */ +#define STM32_MSISRANGE_MASK (15 << 8) /**< MSISRANGE field mask. */ +#define STM32_MSISRANGE_1M (4 << 8) /**< 1MHz nominal. */ +#define STM32_MSISRANGE_2M (5 << 8) /**< 2MHz nominal. */ +#define STM32_MSISRANGE_4M (6 << 8) /**< 4MHz nominal. */ +#define STM32_MSISRANGE_8M (7 << 8) /**< 8MHz nominal. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_RANGE1 +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI16 clock source. + */ +#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSI48 clock source. + */ +#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI48_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Enables or disables the MSI PLL on LSE clock source. + */ +#if !defined(STM32_MSIPLL_ENABLED) || defined(__DOXYGEN__) +#define STM32_MSIPLL_ENABLED FALSE +#endif + +/** + * @brief MSI frequency setting. + */ +#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#endif + +/** + * @brief MSI frequency setting after standby. + */ +#if !defined(STM32_MSISRANGE) || defined(__DOXYGEN__) +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_MSI +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 1..8. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 1 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 8..86. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 80 +#endif + +/** + * @brief PLLPDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLPDIV_VALUE 0 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 7, 17. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 7 +#endif + +/** + * @brief PLLQ divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 6 +#endif + +/** + * @brief PLLR divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLR_VALUE 4 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 80MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief STOPWUCK clock setting. + */ +#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief LSCO clock source. + */ +#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#endif + +/** + * @brief PLLSAI1N multiplier value. + * @note The allowed values are 8..86. + */ +#if !defined(STM32_PLLSAI1N_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1N_VALUE 80 +#endif + +/** + * @brief PLLSAI1PDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLSAI1PDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1PDIV_VALUE 0 +#endif + +/** + * @brief PLLSAI1P divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLSAI1P_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1P_VALUE 7 +#endif + +/** + * @brief PLLSAI1Q divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI1Q_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1Q_VALUE 6 +#endif + +/** + * @brief PLLSAI1R divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI1R_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1R_VALUE 4 +#endif + +/** + * @brief PLLSAI2N multiplier value. + * @note The allowed values are 8..86. + */ +#if !defined(STM32_PLLSAI2N_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2N_VALUE 80 +#endif + +/** + * @brief PLLSAI2PDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLSAI2PDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2PDIV_VALUE 0 +#endif + +/** + * @brief PLLSAI2P divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLSAI2P_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2P_VALUE 7 +#endif + +/** + * @brief PLLSAI2R divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI2R_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2R_VALUE 4 +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) +#define STM32_USART3SEL STM32_USART3SEL_SYSCLK +#endif + +/** + * @brief UART4 clock source. + */ +#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) +#define STM32_UART4SEL STM32_UART4SEL_SYSCLK +#endif + +/** + * @brief UART5 clock source. + */ +#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) +#define STM32_UART5SEL STM32_UART5SEL_SYSCLK +#endif + +/** + * @brief LPUART1 clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) +#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK +#endif + +/** + * @brief I2C3 clock source. + */ +#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#endif + +/** + * @brief I2C4 clock source. + */ +#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) +#define STM32_I2C4SEL STM32_I2C4SEL_SYSCLK +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#endif + +/** + * @brief LPTIM2 clock source. + */ +#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#endif + +/** + * @brief SAI1SEL value (SAI1 clock source). + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#endif + +/** + * @brief SAI2SEL value (SAI2 clock source). + */ +#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#endif + +/** + * @brief CLK48SEL value (48MHz clock source). + */ +#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) +#define STM32_CLK48SEL STM32_CLK48SEL_PLL +#endif + +/** + * @brief ADCSEL value (ADCs clock source). + */ +#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#endif + +/** + * @brief SWPMI1SEL value (SWPMI clock source). + */ +#if !defined(STM32_SWPMI1SEL) || defined(__DOXYGEN__) +#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 +#endif + +/** + * @brief DFSDMSEL value (DFSDM clock source). + */ +#if !defined(STM32_DFSDMSEL) || defined(__DOXYGEN__) +#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 +#endif + +/** + * @brief RTC/LCD clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32L4xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4xx_MCUCONF not defined" +#endif + +/* Only some devices have strongly checked mcuconf.h files. Others will be + added gradually.*/ +#if defined(STM32L432xx) && !defined(STM32L432_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L432_MCUCONF not defined" +#endif + +#if defined(STM32L433xx) && !defined(STM32L433_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L433_MCUCONF not defined" +#endif + +#if defined(STM32L476xx) && !defined(STM32L476_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L476_MCUCONF not defined" +#endif + +#if defined(STM32L486xx) && !defined(STM32L486_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L486_MCUCONF not defined" +#endif + +#if defined(STM32L496xx) && !defined(STM32L496_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L496_MCUCONF not defined" +#endif + +#if defined(STM32L4A6xx) && !defined(STM32L4A6_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L4A6_MCUCONF not defined" +#endif + +/* + * Board files sanity checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif + +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) +/** + * @name System Limits + * @{ + */ +/** + * @brief Maximum SYSCLK clock frequency at current voltage setting. + */ +#define STM32_SYSCLK_MAX 80000000 + +/** + * @brief Maximum HSE clock frequency at current voltage setting. + */ +#define STM32_HSECLK_MAX 48000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 48000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 8000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 4000000 + +/** + * @brief Maximum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MAX 344000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 64000000 + +/** + * @brief Maximum PLL-P output clock frequency. + */ +#define STM32_PLLP_MAX 80000000 + +/** + * @brief Minimum PLL-P output clock frequency. + */ +#define STM32_PLLP_MIN 2064500 + +/** + * @brief Maximum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MAX 80000000 + +/** + * @brief Minimum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MIN 8000000 + +/** + * @brief Maximum PLL-R output clock frequency. + */ +#define STM32_PLLR_MAX 80000000 + +/** + * @brief Minimum PLL-R output clock frequency. + */ +#define STM32_PLLR_MIN 8000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 80000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 80000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 80000000 +/** @} */ + +/** + * @name Flash Wait states + * @{ + */ +#define STM32_0WS_THRESHOLD 16000000 +#define STM32_1WS_THRESHOLD 32000000 +#define STM32_2WS_THRESHOLD 48000000 +#define STM32_3WS_THRESHOLD 64000000 +/** @} */ + +#elif STM32_VOS == STM32_VOS_RANGE2 +#define STM32_SYSCLK_MAX 26000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 26000000 +#define STM32_HSECLK_MIN 8000000 +#define STM32_HSECLK_BYP_MIN 8000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_LSECLK_BYP_MIN 32768 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLIN_MIN 4000000 +#define STM32_PLLVCO_MAX 128000000 +#define STM32_PLLVCO_MIN 64000000 +#define STM32_PLLP_MAX 26000000 +#define STM32_PLLP_MIN 2064500 +#define STM32_PLLQ_MAX 26000000 +#define STM32_PLLQ_MIN 8000000 +#define STM32_PLLR_MAX 26000000 +#define STM32_PLLR_MIN 8000000 +#define STM32_PCLK1_MAX 26000000 +#define STM32_PCLK2_MAX 26000000 +#define STM32_ADCCLK_MAX 26000000 + +#define STM32_0WS_THRESHOLD 6000000 +#define STM32_1WS_THRESHOLD 12000000 +#define STM32_2WS_THRESHOLD 18000000 +#define STM32_3WS_THRESHOLD 26000000 + +#else +#error "invalid STM32_VOS value specified" +#endif + +/** + * @brief MSI frequency. + */ +#if STM32_MSIRANGE == STM32_MSIRANGE_100K +#define STM32_MSICLK 100000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_200K +#define STM32_MSICLK 200000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_400K +#define STM32_MSICLK 400000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_800K +#define STM32_MSICLK 800000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_1M +#define STM32_MSICLK 1000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_2M +#define STM32_MSICLK 2000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_4M +#define STM32_MSICLK 4000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_8M +#define STM32_MSICLK 8000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_16M +#define STM32_MSICLK 16000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_24M +#define STM32_MSICLK 24000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_32M +#define STM32_MSICLK 32000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_48M +#define STM32_MSICLK 48000000 +#else +#error "invalid STM32_MSIRANGE value specified" +#endif + +/** + * @brief MSIS frequency. + */ +#if STM32_MSISRANGE == STM32_MSISRANGE_1M +#define STM32_MSISCLK 1000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_2M +#define STM32_MSISCLK 2000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_4M +#define STM32_MSISCLK 4000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_8M +#define STM32_MSISCLK 8000000 +#else +#error "invalid STM32_MSISRANGE value specified" +#endif + +/* + * HSI16 related checks. + */ +#if STM32_HSI16_ENABLED +#else /* !STM32_HSI16_ENABLED */ + +#if STM32_SW == STM32_SW_HSI16 +#error "HSI16 not enabled, required by STM32_SW" +#endif + +#if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" +#endif + +#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16)) +#error "HSI16 not enabled, required by STM32_MCOSEL" +#endif + +#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SAI1SEL" +#endif + +#if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16) +#error "HSI16 not enabled, required by STM32_SAI2SEL" +#endif + +#if (STM32_USART1SEL == STM32_USART1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART1SEL" +#endif +#if (STM32_USART2SEL == STM32_USART2SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART2SEL" +#endif +#if (STM32_USART3SEL == STM32_USART3SEL_HSI16) +#error "HSI16 not enabled, required by STM32_USART3SEL" +#endif +#if (STM32_UART4SEL == STM32_UART4SEL_HSI16) +#error "HSI16 not enabled, required by STM32_UART4SEL" +#endif +#if (STM32_UART5SEL == STM32_UART5SEL_HSI16) +#error "HSI16 not enabled, required by STM32_UART5SEL" +#endif +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) +#error "HSI16 not enabled, required by STM32_LPUART1SEL" +#endif + +#if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) +#error "HSI16 not enabled, required by I2C1SEL" +#endif +#if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) +#error "HSI16 not enabled, required by I2C2SEL" +#endif +#if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) +#error "HSI16 not enabled, required by I2C3SEL" +#endif +#if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) +#error "HSI16 not enabled, required by I2C4SEL" +#endif + +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) +#error "HSI16 not enabled, required by LPTIM1SEL" +#endif +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) +#error "HSI16 not enabled, required by LPTIM2SEL" +#endif + +#if (STM32_SWPMI1SEL == STM32_SWPMI1SEL_HSI16) +#error "HSI16 not enabled, required by SWPMI1SEL" +#endif +#if (STM32_STOPWUCK == STM32_STOPWUCK_HSI16) +#error "HSI16 not enabled, required by STM32_STOPWUCK" +#endif + +#endif /* !STM32_HSI16_ENABLED */ + +#if STM32_CLOCK_HAS_HSI48 +#if STM32_HSI48_ENABLED +#else /* !STM32_HSI48_ENABLED */ + +#if STM32_MCOSEL == STM32_MCOSEL_HSI48 +#error "HSI48 not enabled, required by STM32_MCOSEL" +#endif + +#if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 +#error "HSI48 not enabled, required by STM32_CLK48SEL" +#endif +#endif /* !STM32_HSI48_ENABLED */ +#endif /* STM32_CLOCK_HAS_HSI48 */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + + #if STM32_HSECLK == 0 + #error "HSE frequency not defined" + #else /* STM32_HSECLK != 0 */ + #if defined(STM32_HSE_BYPASS) + #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" + #endif + #else /* !defined(STM32_HSE_BYPASS) */ + #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" + #endif + #endif /* !defined(STM32_HSE_BYPASS) */ + #endif /* STM32_HSECLK != 0 */ + + #else /* !STM32_HSE_ENABLED */ + + #if STM32_SW == STM32_SW_HSE + #error "HSE not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) + #error "HSE not enabled, required by STM32_MCOSEL" + #endif + + #if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) | \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SAI1SEL" + #endif + + #if ((STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) | \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2)) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SAI2SEL" + #endif + + #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV + #error "HSE not enabled, required by STM32_RTCSEL" + #endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + + #if HAL_USE_RTC && (STM32_RTCSEL == STM32_RTCSEL_LSI) + #error "LSI not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSI + #error "LSI not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSI + #error "LSI not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + + #if (STM32_LSECLK == 0) + #error "LSE frequency not defined" + #endif + + #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) + #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" + #endif + +#else /* !STM32_LSE_ENABLED */ + + #if STM32_RTCSEL == STM32_RTCSEL_LSE + #error "LSE not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSE + #error "LSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSE + #error "LSE not enabled, required by STM32_LSCOSEL" + #endif + + #if STM32_MSIPLL_ENABLED == TRUE + #error "LSE not enabled, required by STM32_MSIPLL_ENABLED" + #endif + +#endif /* !STM32_LSE_ENABLED */ + +/* + * MSI related checks. + */ +#if (STM32_MSIRANGE == STM32_MSIRANGE_48M) && !STM32_MSIPLL_ENABLED +#warning "STM32_MSIRANGE_48M should be used with STM32_MSIPLL_ENABLED" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 8)) || \ + defined(__DOXYGEN__) +#define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLLs input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_MSI +#define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 +#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK +#define STM32_PLLCLKIN 0 + +#else +#error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLLs input frequency range check. + */ +#if (STM32_PLLCLKIN != 0) && \ + ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_HSI48_ENABLED && (STM32_CLK48SEL == STM32_CLK48SEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ + defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLL activation required but no PLL clock selected" +#endif + +/** + * @brief PLL activation flag. + */ +#define STM32_ACTIVATE_PLL TRUE +#else +#define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 86)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 8) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLP (0 << 17) + +#elif STM32_PLLP_VALUE == 17 +#define STM32_PLLP (1 << 17) + +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLQ (0 << 21) + +#elif STM32_PLLQ_VALUE == 4 +#define STM32_PLLQ (1 << 21) + +#elif STM32_PLLQ_VALUE == 6 +#define STM32_PLLQ (2 << 21) + +#elif STM32_PLLQ_VALUE == 8 +#define STM32_PLLQ (3 << 21) + +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLR field. + */ +#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLR (0 << 25) + +#elif STM32_PLLR_VALUE == 4 +#define STM32_PLLR (1 << 25) + +#elif STM32_PLLR_VALUE == 6 +#define STM32_PLLR (2 << 25) + +#elif STM32_PLLR_VALUE == 8 +#define STM32_PLLR (3 << 25) + +#else +#error "invalid STM32_PLLR_VALUE value specified" +#endif + +#if defined(STM32L496xx) || defined(STM32L4A6xx) +/** + * @brief STM32_PLLPDIV field. (Only for STM32L496xx/4A6xx) + */ +#if (STM32_PLLPDIV_VALUE == 0) || \ + ((STM32_PLLPDIV_VALUE >= 2) && (STM32_PLLPDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) +#else +#error "invalid STM32_PLLPDIV_VALUE value specified" +#endif +#endif + +/** + * @brief STM32_PLLPEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ + defined(__DOXYGEN__) +#define STM32_PLLPEN (1 << 16) +#else +#define STM32_PLLPEN (0 << 16) +#endif + +/** + * @brief STM32_PLLQEN field. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__) +#define STM32_PLLQEN (1 << 20) +#else +#define STM32_PLLQEN (0 << 20) +#endif + +/** + * @brief STM32_PLLREN field. + */ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + defined(__DOXYGEN__) +#define STM32_PLLREN (1 << 24) +#else +#define STM32_PLLREN (0 << 24) +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL P output clock frequency. + */ +#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) +#else +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) +#endif + +/** + * @brief PLL Q output clock frequency. + */ +#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) + +/** + * @brief PLL R output clock frequency. + */ +#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) + +/* + * PLL-P output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLL-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLL-R output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_MSICLK + +#elif (STM32_SW == STM32_SW_MSI) +#define STM32_SYSCLK STM32_MSICLK + +#elif (STM32_SW == STM32_SW_HSI16) +#define STM32_SYSCLK STM32_HSI16CLK + +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK + +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLL_R_CLKOUT + +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) + +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) + +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) + +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) + +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) + +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) + +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) + +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) + +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) + +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/* + * PLLSAI1 enable check. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ + (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ + defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLLSAI1 activation required but no PLL clock selected" +#endif + +/** + * @brief PLLSAI1 activation flag. + */ +#define STM32_ACTIVATE_PLLSAI1 TRUE +#else +#define STM32_ACTIVATE_PLLSAI1 FALSE +#endif + +/** + * @brief STM32_PLLSAI1N field. + */ +#if ((STM32_PLLSAI1N_VALUE >= 8) && (STM32_PLLSAI1N_VALUE <= 86)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1N (STM32_PLLSAI1N_VALUE << 8) +#else +#error "invalid STM32_PLLSAI1N_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1P field. + */ +#if (STM32_PLLSAI1P_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLSAI1P (0 << 17) + +#elif STM32_PLLSAI1P_VALUE == 17 +#define STM32_PLLSAI1P (1 << 17) + +#else +#error "invalid STM32_PLLSAI1P_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1Q field. + */ +#if (STM32_PLLSAI1Q_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI1Q (0 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 4 +#define STM32_PLLSAI1Q (1 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 6 +#define STM32_PLLSAI1Q (2 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 8 +#define STM32_PLLSAI1Q (3 << 21) + +#else +#error "invalid STM32_PLLSAI1Q_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1R field. + */ +#if (STM32_PLLSAI1R_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI1R (0 << 25) + +#elif STM32_PLLSAI1R_VALUE == 4 +#define STM32_PLLSAI1R (1 << 25) + +#elif STM32_PLLSAI1R_VALUE == 6 +#define STM32_PLLSAI1R (2 << 25) + +#elif STM32_PLLSAI1R_VALUE == 8 +#define STM32_PLLSAI1R (3 << 25) + +#else +#error "invalid STM32_PLLSAI1R_VALUE value specified" +#endif + +#if defined(STM32L496xx) || defined(STM32L4A6xx) +/** + * @brief STM32_PLLSAI1PDIV field. (Only for STM32L496xx/4A6xx) + */ +#if ((STM32_PLLSAI1PDIV_VALUE != 1) && (STM32_PLLSAI1PDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1PDIV (STM32_PLLSAI1PDIV_VALUE << 27) +#else +#error "invalid STM32_PLLSAI1PDIV_VALUE value specified" +#endif +#endif + +/** + * @brief STM32_PLLSAI1PEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1PEN (1 << 16) +#else +#define STM32_PLLSAI1PEN (0 << 16) +#endif + +/** + * @brief STM32_PLLSAI1QEN field. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_PLLSAI1QEN (1 << 20) +#else +#define STM32_PLLSAI1QEN (0 << 20) +#endif + +/** + * @brief STM32_PLLSAI1REN field. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_PLLSAI1REN (1 << 24) +#else +#define STM32_PLLSAI1REN (0 << 24) +#endif + +/** + * @brief PLLSAI1 VCO frequency. + */ +#define STM32_PLLSAI1VCO (STM32_PLLCLKIN * STM32_PLLSAI1N_VALUE) + +/* + * PLLSAI1 VCO frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI1-P output clock frequency. + */ +#if (STM32_PLLSAI1PDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE) +#else +#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1PDIV_VALUE) +#endif + +/** + * @brief PLLSAI1-Q output clock frequency. + */ +#define STM32_PLLSAI1_Q_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) + +/** + * @brief PLLSAI1-R output clock frequency. + */ +#define STM32_PLLSAI1_R_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1R_VALUE) + +/* + * PLLSAI1-P output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLLSAI1-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLLSAI1-R output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/* + * PLLSAI2 enable check. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ + (STM32_ADCSEL == STM32_ADCSEL_PLLSAI2) || \ + defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLLSAI2 activation required but no PLL clock selected" +#endif + +/** + * @brief PLLSAI2 activation flag. + */ +#define STM32_ACTIVATE_PLLSAI2 TRUE +#else +#define STM32_ACTIVATE_PLLSAI2 FALSE +#endif + +/** + * @brief STM32_PLLSAI2N field. + */ +#if ((STM32_PLLSAI2N_VALUE >= 8) && (STM32_PLLSAI2N_VALUE <= 86)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2N (STM32_PLLSAI2N_VALUE << 8) +#else +#error "invalid STM32_PLLSAI2N_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2P field. + */ +#if (STM32_PLLSAI2P_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLSAI2P (0 << 17) + +#elif STM32_PLLSAI2P_VALUE == 17 +#define STM32_PLLSAI2P (1 << 17) + +#else +#error "invalid STM32_PLLSAI2P_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2R field. + */ +#if (STM32_PLLSAI2R_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI2R (0 << 25) + +#elif STM32_PLLSAI2R_VALUE == 4 +#define STM32_PLLSAI2R (1 << 25) + +#elif STM32_PLLSAI2R_VALUE == 6 +#define STM32_PLLSAI2R (2 << 25) + +#elif STM32_PLLSAI2R_VALUE == 8 +#define STM32_PLLSAI2R (3 << 25) + +#else +#error "invalid STM32_PLLSAI2R_VALUE value specified" +#endif + +#if defined(STM32L496xx) || defined(STM32L4A6xx) +/** + * @brief STM32_PLLSAI2PDIV field. (Only for STM32L496xx/4A6xx) + */ +#if ((STM32_PLLSAI2PDIV_VALUE != 1) && (STM32_PLLSAI2PDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2PDIV (STM32_PLLSAI2PDIV_VALUE << 27) +#else +#error "invalid STM32_PLLSAI2PDIV_VALUE value specified" +#endif +#endif + +/** + * @brief STM32_PLLSAI2PEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2PEN (1 << 16) +#else +#define STM32_PLLSAI2PEN (0 << 16) +#endif + +/** + * @brief STM32_PLLSAI2REN field. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI2) || defined(__DOXYGEN__) +#define STM32_PLLSAI2REN (1 << 24) +#else +#define STM32_PLLSAI2REN (0 << 24) +#endif + +/** + * @brief PLLSAI2 VCO frequency. + */ +#define STM32_PLLSAI2VCO (STM32_PLLCLKIN * STM32_PLLSAI2N_VALUE) + +/* + * PLLSAI2 VCO frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI2-P output clock frequency. + */ +#if (STM32_PLLSAI2PDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE) +#else +#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2PDIV_VALUE) +#endif + +/** + * @brief PLLSAI2-R output clock frequency. + */ +#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE) + +/* + * PLLSAI2-P output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLLSAI2-R output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief MCO divider clock frequency. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 + +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK +#define STM32_MCODIVCLK STM32_SYSCLK + +#elif STM32_MCOSEL == STM32_MCOSEL_MSI +#define STM32_MCODIVCLK STM32_MSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 +#define STM32_MCODIVCLK STM32_HSI16CLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_PLL +#define STM32_MCODIVCLK STM32_PLL_R_CLKOUT + +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 +#define STM32_MCODIVCLK STM32_HSI48CLK + +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock frequency. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) + +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief RTC clock frequency. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 clock frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK2 +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK +#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 +#define STM32_USART1CLK STM32_HSI16CLK +#elif STM32_USART1SEL == STM32_USART1SEL_LSE +#define STM32_USART1CLK STM32_LSECLK +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 clock frequency. + */ +#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART2CLK STM32_PCLK1 +#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK +#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 +#define STM32_USART2CLK STM32_HSI16CLK +#elif STM32_USART2SEL == STM32_USART2SEL_LSE +#define STM32_USART2CLK STM32_LSECLK +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 clock frequency. + */ +#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART3CLK STM32_PCLK1 +#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK +#define STM32_USART3CLK STM32_SYSCLK +#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 +#define STM32_USART3CLK STM32_HSI16CLK +#elif STM32_USART3SEL == STM32_USART3SEL_LSE +#define STM32_USART3CLK STM32_LSECLK +#else +#error "invalid source selected for USART3 clock" +#endif + +/** + * @brief UART4 clock frequency. + */ +#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART4CLK STM32_PCLK1 +#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK +#define STM32_UART4CLK STM32_SYSCLK +#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 +#define STM32_UART4CLK STM32_HSI16CLK +#elif STM32_UART4SEL == STM32_UART4SEL_LSE +#define STM32_UART4CLK STM32_LSECLK +#else +#error "invalid source selected for UART4 clock" +#endif + +/** + * @brief UART5 clock frequency. + */ +#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART5CLK STM32_PCLK1 +#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK +#define STM32_UART5CLK STM32_SYSCLK +#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 +#define STM32_UART5CLK STM32_HSI16CLK +#elif STM32_UART5SEL == STM32_UART5SEL_LSE +#define STM32_UART5CLK STM32_LSECLK +#else +#error "invalid source selected for UART5 clock" +#endif + +/** + * @brief LPUART1 clock frequency. + */ +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPUART1CLK STM32_PCLK1 +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK +#define STM32_LPUART1CLK STM32_SYSCLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 +#define STM32_LPUART1CLK STM32_HSI16CLK +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE +#define STM32_LPUART1CLK STM32_LSECLK +#else +#error "invalid source selected for LPUART1 clock" +#endif + +/** + * @brief I2C1 clock frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_PCLK1 +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 +#define STM32_I2C1CLK STM32_HSI16CLK +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 clock frequency. + */ +#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C2CLK STM32_PCLK1 +#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK +#define STM32_I2C2CLK STM32_SYSCLK +#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 +#define STM32_I2C2CLK STM32_HSI16CLK +#else +#error "invalid source selected for I2C2 clock" +#endif + +/** + * @brief I2C3 clock frequency. + */ +#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C3CLK STM32_PCLK1 +#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK +#define STM32_I2C3CLK STM32_SYSCLK +#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 +#define STM32_I2C3CLK STM32_HSI16CLK +#else +#error "invalid source selected for I2C3 clock" +#endif + +/** + * @brief I2C4 clock frequency. + */ +#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C4CLK STM32_PCLK1 +#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK +#define STM32_I2C4CLK STM32_SYSCLK +#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 +#define STM32_I2C4CLK STM32_HSI16CLK +#else +#error "invalid source selected for I2C4 clock" +#endif + +/** + * @brief LPTIM1 clock frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM1CLK STM32_PCLK1 +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI +#define STM32_LPTIM1CLK STM32_LSICLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 +#define STM32_LPTIM1CLK STM32_HSI16CLK +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE +#define STM32_LPTIM1CLK STM32_LSECLK +#else +#error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief LPTIM2 clock frequency. + */ +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM2CLK STM32_PCLK1 +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI +#define STM32_LPTIM2CLK STM32_LSICLK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 +#define STM32_LPTIM2CLK STM32_HSI16CLK +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE +#define STM32_LPTIM2CLK STM32_LSECLK +#else +#error "invalid source selected for LPTIM2 clock" +#endif + +/** + * @brief 48MHz clock frequency. + */ +#if !STM32_CLOCK_HAS_HSI48 || defined(__DOXYGEN__) + +#if (STM32_CLK48SEL == STM32_CLK48SEL_NOCLK) || defined(__DOXYGEN__) +#define STM32_48CLK 0 +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 +#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL +#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI +#define STM32_48CLK STM32_MSICLK +#else +#error "invalid source selected for 48CLK clock" +#endif + +#else /* STM32_CLOCK_HAS_HSI48 */ + +#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) +#define STM32_48CLK STM32_HSI48CLK +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 +#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL +#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) +#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI +#define STM32_48CLK STM32_MSICLK +#else +#error "invalid source selected for 48CLK clock" +#endif + +#endif /* STM32_CLOCK_HAS_HSI48 */ + +/** + * @brief SAI1 clock frequency. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_SAI1CLK STM32_PLLSAI1_P_CLKOUT +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2 +#define STM32_SAI1CLK STM32_PLLSAI2_P_CLKOUT +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL +#define STM32_SAI1CLK STM32_PLL_P_CLKOUT +#elif STM32_SAI1SEL == STM32_SAI1SEL_EXTCLK +#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ +#elif STM32_SAI1SEL == STM32_SAI1SEL_OFF +#define STM32_SAI1CLK 0 +#else +#error "invalid source selected for SAI1 clock" +#endif + +/** + * @brief SAI2 clock frequency. + */ +#if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_SAI2CLK STM32_PLLSAI1_P_CLKOUT +#elif STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2 +#define STM32_SAI2CLK STM32_PLLSAI2_P_CLKOUT +#elif STM32_SAI2SEL == STM32_SAI2SEL_PLL +#define STM32_SAI2CLK STM32_PLL_P_CLKOUT +#elif STM32_SAI2SEL == STM32_SAI2SEL_EXTCLK +#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ +#elif STM32_SAI2SEL == STM32_SAI2SEL_OFF +#define STM32_SAI2CLK 0 +#else +#error "invalid source selected for SAI2 clock" +#endif + +/** + * @brief USB clock point. + */ +#define STM32_USBCLK STM32_48CLK + +/** + * @brief RNG clock point. + */ +#define STM32_RNGCLK STM32_48CLK + +/** + * @brief ADC clock frequency. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_NOCLK) || defined(__DOXYGEN__) +#define STM32_ADCCLK 0 +#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI1 +#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT +#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI2 +#define STM32_ADCCLK STM32_PLLSAI2_R_CLKOUT +#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK +#define STM32_ADCCLK STM32_SYSCLK +#else +#error "invalid source selected for ADC clock" +#endif + +/** + * @brief SWPMI1 clock frequency. + */ +#if (STM32_SWPMI1SEL == STM32_SWPMI1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_SWPMI1CLK STM32_PCLK1 +#elif STM32_SWPMI1SEL == STM32_SWPMI1SEL_HSI16 +#define STM32_SWPMI1CLK STM32_HSI16CLK +#else +#error "invalid source selected for SWPMI1 clock" +#endif + +/** + * @brief DFSDM clock frequency. + */ +#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_DFSDMCLK STM32_PCLK2 +#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK +#define STM32_DFSDMCLK STM32_SYSCLK +#else +#error "invalid source selected for DFSDM clock" +#endif + +/** + * @brief SDMMC frequency. + */ +#define STM32_SDMMC1CLK STM32_48CLK + +/** + * @brief Clock of timers connected to APB1 + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Clock of timers connected to APB2. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + +/** + * @brief Flash settings for MSI. + */ +#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_MSICLK <= STM32_1WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_MSICLK <= STM32_2WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_MSICLK <= STM32_3WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32L5xx/hal_lld.h b/os/hal/ports/STM32/STM32L5xx/hal_lld.h index 7425e45292..0cda830d6a 100644 --- a/os/hal/ports/STM32/STM32L5xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L5xx/hal_lld.h @@ -1,2699 +1,2699 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed 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. -*/ - -/** - * @file STM32L5xx/hal_lld.h - * @brief STM32L5xx HAL subsystem low level driver header. - * @pre This module requires the following macros to be defined in the - * @p board.h file: - * - STM32_LSECLK. - * - STM32_LSEDRV. - * - STM32_LSE_BYPASS (optionally). - * - STM32_HSECLK. - * - STM32_HSE_BYPASS (optionally). - * . - * One of the following macros must also be defined: - * - STM32L4R5xx, STM32L4R7xx, STM32L4R9xx. - * - STM32L4S5xx, STM32L4S7xx, STM32L4S9xx. - * . - * - * @addtogroup HAL - * @{ - */ - -#ifndef HAL_LLD_H -#define HAL_LLD_H - -#include "stm32_registry.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @name Platform identification - * @{ - */ -#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || \ - defined(__DOXYGEN__) -#define PLATFORM_NAME "STM32L4+ Ultra Low Power" - -#elif defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) -#define PLATFORM_NAME "STM32L4+ Ultra Low Power with Crypto" - -#else -#error "STM32L4+ device not specified" -#endif - -/** - * @brief Sub-family identifier. - */ -#if !defined(STM32L5XX) || defined(__DOXYGEN__) -#define STM32L5XX -#endif -/** @} */ - -/** - * @name Internal clock sources - * @{ - */ -#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ -#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ -#define STM32_LSICLK 32000 /**< Low speed internal clock. */ -/** @} */ - -/** - * @name PWR_CR1 register bits definitions - * @{ - */ -#define STM32_VOS_MASK (3 << 9) /**< Core voltage mask. */ -#define STM32_VOS_RANGE0 (0 << 9) /**< Core voltage 1.28 Volts. */ -#define STM32_VOS_RANGE1 (1 << 9) /**< Core voltage 1.2 Volts. */ -#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ -/** @} */ - -/** - * @name PWR_CR2 register bits definitions - * @{ - */ -#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */ -#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */ -#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */ -#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */ -#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */ -#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */ -#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */ -#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */ -#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */ -/** @} */ - -/** - * @name RCC_CR register bits definitions - * @{ - */ -#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */ -#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */ -#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */ -#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */ -#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */ -#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */ -#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */ -#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */ -#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */ -#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */ -#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */ -#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */ -#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */ -/** @} */ - -/** - * @name RCC_CFGR register bits definitions - * @{ - */ -#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ -#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ -#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI. */ -#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ -#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ - -#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ -#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ -#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ -#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ -#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ -#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ -#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ -#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ -#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ -#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ - -#define STM32_PPRE1_MASK (7 << 8) /**< PPRE1 field mask. */ -#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ -#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ -#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ -#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ -#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ - -#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ -#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ -#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ -#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ -#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ -#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ - -#define STM32_STOPWUCK_MASK (1 << 15) /**< STOPWUCK field mask. */ -#define STM32_STOPWUCK_MSI (0 << 15) /**< Wakeup clock is MSI. */ -#define STM32_STOPWUCK_HSI16 (1 << 15) /**< Wakeup clock is HSI16. */ - -#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ -#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ -#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ -#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ -#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ -#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ -#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ -#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ -#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ -#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ - -#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ -#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ -#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ -#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ -#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ -#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ -/** @} */ - -/** - * @name RCC_PLLCFGR register bits definitions - * @{ - */ -#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSRC_MSI (1 << 0) /**< PLL clock source is MSI. */ -#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ - -/** - * @name RCC_PLLSAI1CFGR register bits definitions - * @{ - */ -#define STM32_PLLSAI1SRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSAI1SRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSAI1SRC_MSI (1 << 0) /**< PLL clock source is MSI. */ -#define STM32_PLLSAI1SRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSAI1SRC_HSE (3 << 0) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_PLLSAI2CFGR register bits definitions - * @{ - */ -#define STM32_PLLSAI2SRC_MASK (3 << 0) /**< PLL clock source mask. */ -#define STM32_PLLSAI2SRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ -#define STM32_PLLSAI2SRC_MSI (1 << 0) /**< PLL clock source is MSI. */ -#define STM32_PLLSAI2SRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ -#define STM32_PLLSAI2SRC_HSE (3 << 0) /**< PLL clock source is HSE. */ -/** @} */ - -/** - * @name RCC_CCIPR register bits definitions - * @{ - */ -#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ -#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ -#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ -#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 source is HSI16. */ -#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ - -#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ -#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ -#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ -#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 source is HSI16. */ -#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ - -#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ -#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ -#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ -#define STM32_USART3SEL_HSI16 (2 << 4) /**< USART3 source is HSI16. */ -#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ - -#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ -#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ -#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ -#define STM32_UART4SEL_HSI16 (2 << 6) /**< UART4 source is HSI16. */ -#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ - -#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ -#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ -#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ -#define STM32_UART5SEL_HSI16 (2 << 8) /**< UART5 source is HSI16. */ -#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ - -#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 mask. */ -#define STM32_LPUART1SEL_PCLK1 (0 << 10) /**< LPUART1 source is PCLK1. */ -#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 source is SYSCLK. */ -#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 source is HSI16. */ -#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 source is LSE. */ - -#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1SEL mask. */ -#define STM32_I2C1SEL_PCLK1 (0 << 12) /**< I2C1 source is PCLK1. */ -#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 source is HSI16. */ - -#define STM32_I2C2SEL_MASK (3 << 14) /**< I2C2SEL mask. */ -#define STM32_I2C2SEL_PCLK1 (0 << 14) /**< I2C2 source is PCLK1. */ -#define STM32_I2C2SEL_SYSCLK (1 << 14) /**< I2C2 source is SYSCLK. */ -#define STM32_I2C2SEL_HSI16 (2 << 14) /**< I2C2 source is HSI16. */ - -#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3SEL mask. */ -#define STM32_I2C3SEL_PCLK1 (0 << 16) /**< I2C3 source is PCLK1. */ -#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 source is SYSCLK. */ -#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 source is HSI16. */ - -#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1SEL mask. */ -#define STM32_LPTIM1SEL_PCLK1 (0 << 18) /**< LPTIM1 source is PCLK1. */ -#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 source is LSI. */ -#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 source is HSI16. */ -#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 source is LSE. */ - -#define STM32_LPTIM2SEL_MASK (3 << 20) /**< LPTIM2SEL mask. */ -#define STM32_LPTIM2SEL_PCLK1 (0 << 20) /**< LPTIM2 source is PCLK1. */ -#define STM32_LPTIM2SEL_LSI (1 << 20) /**< LPTIM2 source is LSI. */ -#define STM32_LPTIM2SEL_HSI16 (2 << 20) /**< LPTIM2 source is HSI16. */ -#define STM32_LPTIM2SEL_LSE (3 << 20) /**< LPTIM2 source is LSE. */ - -#define STM32_LPTIM3SEL_MASK (3 << 22) /**< LPTIM3SEL mask. */ -#define STM32_LPTIM3SEL_PCLK1 (0 << 22) /**< LPTIM3 source is PCLK1. */ -#define STM32_LPTIM3SEL_LSI (1 << 22) /**< LPTIM3 source is LSI. */ -#define STM32_LPTIM3SEL_HSI16 (2 << 22) /**< LPTIM3 source is HSI16. */ -#define STM32_LPTIM3SEL_LSE (3 << 22) /**< LPTIM3 source is LSE. */ - -#define STM32_FDCANSEL_MASK (3 << 24) /**< FDCANSEL mask. */ -#define STM32_FDCANSEL_HSE (0 << 24) /**< FDCAN source is HSE. */ -#define STM32_FDCANSEL_PLL (1 << 24) /**< FDCAN source is PLL-Q. */ -#define STM32_FDCANSEL_PLLSAI1 (2 << 24) /**< FDCAN source is PLLSAI1-P. */ - -#define STM32_CLK48SEL_MASK (3 << 26) /**< CLK48SEL mask. */ -#define STM32_CLK48SEL_HSI48 (0 << 26) /**< CLK48 source is HSI48. */ -#define STM32_CLK48SEL_PLLSAI1 (1 << 26) /**< CLK48 source is PLLSAI1-Q. */ -#define STM32_CLK48SEL_PLL (2 << 26) /**< CLK48 source is PLL-Q. */ -#define STM32_CLK48SEL_MSI (3 << 26) /**< CLK48 source is MSI. */ - -#define STM32_ADCSEL_MASK (3 << 28) /**< ADCSEL mask. */ -#define STM32_ADCSEL_NOCLK (0 << 28) /**< ADC clock disabled. */ -#define STM32_ADCSEL_PLLSAI1 (1 << 28) /**< ADC source is PLLSAI1-R. */ -#define STM32_ADCSEL_SYSCLK (3 << 28) /**< ADC source is SYSCLK. */ -/** @} */ - -/** - * @name RCC_CCIPR2 register bits definitions - * @{ - */ -#define STM32_I2C4SEL_MASK (3 << 0) /**< I2C1SEL mask. */ -#define STM32_I2C4SEL_PCLK1 (0 << 0) /**< I2C1 source is PCLK1. */ -#define STM32_I2C4SEL_SYSCLK (1 << 0) /**< I2C1 source is SYSCLK. */ -#define STM32_I2C4SEL_HSI16 (2 << 0) /**< I2C1 source is HSI16. */ - -#define STM32_DFSDMSEL_MASK (1 << 2) /**< DFSDMSEL mask. */ -#define STM32_DFSDMSEL_PCLK2 (0 << 2) /**< DFSDMSEL source is PCLK2. */ -#define STM32_DFSDMSEL_SYSCLK (1 << 2) /**< DFSDMSEL source is SYSCLK. */ - -#define STM32_ADFSDMSEL_MASK (3 << 3) /**< ADFSDMSEL mask. */ -#define STM32_ADFSDMSEL_SAI1CLK (0 << 3) /**< ADFSDMSEL source is - SAI1CLK. */ -#define STM32_ADFSDMSEL_HSI16 (1 << 3) /**< ADFSDMSEL source is HSI16. */ -#define STM32_ADFSDMSEL_MSI (2 << 3) /**< ADFSDMSEL source is MSI. */ - -#define STM32_SAI1SEL_MASK (7 << 5) /**< SAI1SEL mask. */ -#define STM32_SAI1SEL_PLLSAI1 (0 << 5) /**< SAI1 source is PLLSAI1CLK. */ -#define STM32_SAI1SEL_PLLSAI2 (1 << 5) /**< SAI1 source is PLLSAI2CLK. */ -#define STM32_SAI1SEL_PLL (2 << 5) /**< SAI1 source is PLLSAI3CLK */ -#define STM32_SAI1SEL_EXTCLK (3 << 5) /**< SAI1 source is external. */ -#define STM32_SAI1SEL_HSI16 (4 << 5) /**< SAI1 source is HSI16. */ -#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ - -#define STM32_SAI2SEL_MASK (7 << 8) /**< SAI2SEL mask. */ -#define STM32_SAI2SEL_PLLSAI1 (0 << 8) /**< SAI2 source is PLLSAI1CLK. */ -#define STM32_SAI2SEL_PLLSAI2 (1 << 8) /**< SAI2 source is PLLSAI2CLK. */ -#define STM32_SAI2SEL_PLL (2 << 8) /**< SAI2 source is PLLSAI3CLK */ -#define STM32_SAI2SEL_EXTCLK (3 << 8) /**< SAI2 source is external. */ -#define STM32_SAI2SEL_HSI16 (4 << 8) /**< SAI2 source is HSI16. */ -#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ - -#define STM32_SDMMCSEL_MASK (1 << 14) /**< SDMMCSEL mask. */ -#define STM32_SDMMCSEL_48CLK (0 << 14) /**< SDMMCSEL source is 48CLK. */ -#define STM32_SDMMCSEL_PLL (1 << 14) /**< SDMMCSEL source is - PLLSAI3CLK. */ - -#define STM32_OSPISEL_MASK (3 << 20) /**< OSPISEL mask. */ -#define STM32_OSPISEL_SYSCLK (0 << 20) /**< OSPI source is SYSCLK. */ -#define STM32_OSPISEL_MSI (1 << 20) /**< OSPI source is MSI. */ -#define STM32_OSPISEL_48CLK (2 << 20) /**< OSPI source is 48CLK. */ -/** @} */ - -/** - * @name RCC_BDCR register bits definitions - * @{ - */ -#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ -#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ -#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ -#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ -#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ - -#define STM32_LSCOSEL_MASK (3 << 24) /**< LSCO pin clock source. */ -#define STM32_LSCOSEL_NOCLOCK (0 << 24) /**< No clock on LSCO pin. */ -#define STM32_LSCOSEL_LSI (1 << 24) /**< LSI on LSCO pin. */ -#define STM32_LSCOSEL_LSE (3 << 24) /**< LSE on LSCO pin. */ -/** @} */ - -/** - * @name RCC_CSR register bits definitions - * @{ - */ -#define STM32_MSISRANGE_MASK (15 << 8) /**< MSISRANGE field mask. */ -#define STM32_MSISRANGE_1M (4 << 8) /**< 1MHz nominal. */ -#define STM32_MSISRANGE_2M (5 << 8) /**< 2MHz nominal. */ -#define STM32_MSISRANGE_4M (6 << 8) /**< 4MHz nominal. */ -#define STM32_MSISRANGE_8M (7 << 8) /**< 8MHz nominal. */ -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief Disables the PWR/RCC initialization in the HAL. - */ -#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) -#define STM32_NO_INIT FALSE -#endif - -/** - * @brief Core voltage selection. - * @note This setting affects all the performance and clock related - * settings, the maximum performance is only obtainable selecting - * the maximum voltage. - */ -#if !defined(STM32_VOS) || defined(__DOXYGEN__) -#define STM32_VOS STM32_VOS_RANGE1 -#endif - -/** - * @brief Enables or disables the programmable voltage detector. - */ -#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) -#define STM32_PVD_ENABLE FALSE -#endif - -/** - * @brief Sets voltage level for programmable voltage detector. - */ -#if !defined(STM32_PLS) || defined(__DOXYGEN__) -#define STM32_PLS STM32_PLS_LEV0 -#endif - -/** - * @brief Enables or disables the HSI16 clock source. - */ -#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI16_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the HSI48 clock source. - */ -#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSI48_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSI clock source. - */ -#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSI_ENABLED TRUE -#endif - -/** - * @brief Enables or disables the HSE clock source. - */ -#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_HSE_ENABLED FALSE -#endif - -/** - * @brief Enables or disables the LSE clock source. - */ -#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) -#define STM32_LSE_ENABLED FALSE -#endif - -/** - * @brief Number of times to busy-loop waiting for LSE clock source. - * @note The default value of 0 disables this behavior. - * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX 0 -#endif - -/** - * @brief Fallback RTC clock source if stopped waiting for LSE clock source. - * @note If waiting for the LSE clock source times out due to - * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to - * fallback to another. - */ -#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) -#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE -#endif - -/** - * @brief Enables or disables the MSI PLL on LSE clock source. - */ -#if !defined(STM32_MSIPLL_ENABLED) || defined(__DOXYGEN__) -#define STM32_MSIPLL_ENABLED FALSE -#endif - -/** - * @brief MSI frequency setting. - */ -#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) -#define STM32_MSIRANGE STM32_MSIRANGE_4M -#endif - -/** - * @brief MSI frequency setting after standby. - */ -#if !defined(STM32_MSISRANGE) || defined(__DOXYGEN__) -#define STM32_MSISRANGE STM32_MSISRANGE_4M -#endif - -/** - * @brief Main clock source selection. - * @note If the selected clock source is not the PLL then the PLL is not - * initialized and started. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_SW) || defined(__DOXYGEN__) -#define STM32_SW STM32_SW_PLL -#endif - -/** - * @brief Clock source for the PLL. - * @note This setting has only effect if the PLL is selected as the - * system clock source. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) -#define STM32_PLLSRC STM32_PLLSRC_MSI -#endif - -/** - * @brief PLLM divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLM_VALUE 1 -#endif - -/** - * @brief PLLN multiplier value. - * @note The allowed values are 8..127. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLN_VALUE 60 -#endif - -/** - * @brief PLLPDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLPDIV_VALUE 0 -#endif - -/** - * @brief PLLP divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLP_VALUE 7 -#endif - -/** - * @brief PLLQ divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLQ_VALUE 4 -#endif - -/** - * @brief PLLR divider value. - * @note The allowed values are 2, 4, 6, 8. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLR_VALUE 2 -#endif - -/** - * @brief AHB prescaler value. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_HPRE) || defined(__DOXYGEN__) -#define STM32_HPRE STM32_HPRE_DIV1 -#endif - -/** - * @brief APB1 prescaler value. - */ -#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#endif - -/** - * @brief APB2 prescaler value. - */ -#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#endif - -/** - * @brief STOPWUCK clock setting. - */ -#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) -#define STM32_STOPWUCK STM32_STOPWUCK_MSI -#endif - -/** - * @brief MCO clock source. - */ -#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#endif - -/** - * @brief MCO divider setting. - */ -#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#endif - -/** - * @brief LSCO clock source. - */ -#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) -#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK -#endif - -/** - * @brief Clock source for the PLLSAL1. - */ -#if !defined(STM32_PLLSAI1SRC) || defined(__DOXYGEN__) -#define STM32_PLLSAI1SRC STM32_PLLSAI1SRC_MSI -#endif - -/** - * @brief PLLSAI1M divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSAI1M_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1M_VALUE 1 -#endif - -/** - * @brief PLLSAI1N multiplier value. - * @note The allowed values are 8..127. - */ -#if !defined(STM32_PLLSAI1N_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1N_VALUE 72 -#endif - -/** - * @brief PLLSAI1PDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLSAI1PDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1PDIV_VALUE 6 -#endif - -/** - * @brief PLLSAI1P divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLSAI1P_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1P_VALUE 7 -#endif - -/** - * @brief PLLSAI1Q divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI1Q_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1Q_VALUE 6 -#endif - -/** - * @brief PLLSAI1R divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI1R_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1R_VALUE 6 -#endif - -/** - * @brief Clock source for the PLLSAL2. - */ -#if !defined(STM32_PLLSAI2SRC) || defined(__DOXYGEN__) -#define STM32_PLLSAI2SRC STM32_PLLSAI2SRC_MSI -#endif - -/** - * @brief PLLSAI2M divider value. - * @note The allowed values are 1..16. - * @note The default value is calculated for a 120MHz system clock from - * the internal 4MHz MSI clock. - */ -#if !defined(STM32_PLLSAI2M_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2M_VALUE 1 -#endif - -/** - * @brief PLLSAI2N multiplier value. - * @note The allowed values are 8..127. - */ -#if !defined(STM32_PLLSAI2N_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2N_VALUE 72 -#endif - -/** - * @brief PLLSAI2PDIV divider value or zero if disabled. - * @note The allowed values are 0, 2..31. - */ -#if !defined(STM32_PLLSAI2PDIV_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2PDIV_VALUE 6 -#endif - -/** - * @brief PLLSAI2P divider value. - * @note The allowed values are 7, 17. - */ -#if !defined(STM32_PLLSAI2P_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2P_VALUE 7 -#endif - -/** - * @brief PLLSAI2Q divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI2Q_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2Q_VALUE 6 -#endif - -/** - * @brief PLLSAI2R divider value. - * @note The allowed values are 2, 4, 6, 8. - */ -#if !defined(STM32_PLLSAI2R_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2R_VALUE 6 -#endif - -/** - * @brief PLLSAI2DIVR value. - */ -#if !defined(STM32_PLLSAI2DIVR) || defined(__DOXYGEN__) -#define STM32_PLLSAI2DIVR STM32_PLLSAI2DIVR_DIV16 -#endif - -/** - * @brief USART1 clock source. - */ -#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) -#define STM32_USART1SEL STM32_USART1SEL_SYSCLK -#endif - -/** - * @brief USART2 clock source. - */ -#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) -#define STM32_USART2SEL STM32_USART2SEL_SYSCLK -#endif - -/** - * @brief USART3 clock source. - */ -#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) -#define STM32_USART3SEL STM32_USART3SEL_SYSCLK -#endif - -/** - * @brief UART4 clock source. - */ -#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) -#define STM32_UART4SEL STM32_UART4SEL_SYSCLK -#endif - -/** - * @brief UART5 clock source. - */ -#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) -#define STM32_UART5SEL STM32_UART5SEL_SYSCLK -#endif - -/** - * @brief LPUART1 clock source. - */ -#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) -#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK -#endif - -/** - * @brief I2C1 clock source. - */ -#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) -#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK -#endif - -/** - * @brief I2C2 clock source. - */ -#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) -#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK -#endif - -/** - * @brief I2C3 clock source. - */ -#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) -#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK -#endif - -/** - * @brief I2C4 clock source. - */ -#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) -#define STM32_I2C4SEL STM32_I2C4SEL_SYSCLK -#endif - -/** - * @brief LPTIM1 clock source. - */ -#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 -#endif - -/** - * @brief LPTIM2 clock source. - */ -#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 -#endif - -/** - * @brief LPTIM3 clock source. - */ -#if !defined(STM32_LPTIM3SEL) || defined(__DOXYGEN__) -#define STM32_LPTIM3SEL STM32_LPTIM3SEL_PCLK1 -#endif - -/** - * @brief FDCAN value (48MHz clock source). - */ -#if !defined(STM32_FDCANSEL) || defined(__DOXYGEN__) -#define STM32_FDCANSEL STM32_FDCANSEL_PLL -#endif - -/** - * @brief CLK48SEL value (48MHz clock source). - */ -#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) -#define STM32_CLK48SEL STM32_CLK48SEL_PLL -#endif - -/** - * @brief ADCSEL value (ADCs clock source). - */ -#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) -#define STM32_ADCSEL STM32_ADCSEL_SYSCLK -#endif - -/** - * @brief DFSDMSEL value (DFSDM clock source). - */ -#if !defined(STM32_DFSDMSEL) || defined(__DOXYGEN__) -#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 -#endif - -/** - * @brief ADFSDMSEL value (DFSDM clock source). - */ -#if !defined(STM32_ADFSDMSEL) || defined(__DOXYGEN__) -#define STM32_ADFSDMSEL STM32_ADFSDMSEL_SAI1CLK -#endif - -/** - * @brief SAI1SEL value (SAI1 clock source). - */ -#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#endif - -/** - * @brief SAI2SEL value (SAI2 clock source). - */ -#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) -#define STM32_SAI2SEL STM32_SAI2SEL_OFF -#endif - -/** - * @brief SDMMC value (SDMMC clock source). - */ -#if !defined(STM32_SDMMCSEL) || defined(__DOXYGEN__) -#define STM32_SDMMCSEL STM32_SDMMCSEL_48CLK -#endif - -/** - * @brief OSPISEL value (OSPISEL clock source). - */ -#if !defined(STM32_OSPISEL) || defined(__DOXYGEN__) -#define STM32_OSPISEL STM32_OSPISEL_SYSCLK -#endif - -/** - * @brief RTC/LCD clock source. - */ -#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) -#define STM32_RTCSEL STM32_RTCSEL_LSI -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/* - * Configuration-related checks. - */ -#if !defined(STM32L5xx_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L5xx_MCUCONF not defined" -#endif - -#if defined(STM32L5YYxx) && !defined(STM32L5YY_MCUCONF) -#error "Using a wrong mcuconf.h file, STM32L5YY_MCUCONF not defined" - -#endif - -/* - * Board files sanity checks. - */ -#if !defined(STM32_LSECLK) -#error "STM32_LSECLK not defined in board.h" -#endif - -#if !defined(STM32_LSEDRV) -#error "STM32_LSEDRV not defined in board.h" -#endif - -#if !defined(STM32_HSECLK) -#error "STM32_HSECLK not defined in board.h" -#endif - -/* Voltage related limits.*/ -#if (STM32_VOS == STM32_VOS_RANGE0) || defined(__DOXYGEN__) -/** - * @name System Limits - * @{ - */ -/** - * @brief Maximum SYSCLK clock frequency. - */ -#define STM32_SYSCLK_MAX 110000000 - -/** - * @brief Maximum HSE clock frequency at current voltage setting. - */ -#define STM32_HSECLK_MAX 48000000 - -/** - * @brief Maximum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MAX 48000000 - -/** - * @brief Minimum HSE clock frequency. - */ -#define STM32_HSECLK_MIN 4000000 - -/** - * @brief Minimum HSE clock frequency using an external source. - */ -#define STM32_HSECLK_BYP_MIN 8000000 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_MAX 32768 - -/** - * @brief Maximum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MAX 1000000 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_MIN 32768 - -/** - * @brief Minimum LSE clock frequency. - */ -#define STM32_LSECLK_BYP_MIN 32768 - -/** - * @brief Maximum PLLs input clock frequency. - */ -#define STM32_PLLIN_MAX 16000000 - -/** - * @brief Minimum PLLs input clock frequency. - */ -#define STM32_PLLIN_MIN 2660000 - -/** - * @brief Maximum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MAX 344000000 - -/** - * @brief Minimum VCO clock frequency at current voltage setting. - */ -#define STM32_PLLVCO_MIN 64000000 - -/** - * @brief Maximum PLL-P output clock frequency. - */ -#define STM32_PLLP_MAX 110000000 - -/** - * @brief Minimum PLL-P output clock frequency. - */ -#define STM32_PLLP_MIN 2064500 - -/** - * @brief Maximum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MAX 110000000 - -/** - * @brief Minimum PLL-Q output clock frequency. - */ -#define STM32_PLLQ_MIN 8000000 - -/** - * @brief Maximum PLL-R output clock frequency. - */ -#define STM32_PLLR_MAX 110000000 - -/** - * @brief Minimum PLL-R output clock frequency. - */ -#define STM32_PLLR_MIN 8000000 - -/** - * @brief Maximum APB1 clock frequency. - */ -#define STM32_PCLK1_MAX 110000000 - -/** - * @brief Maximum APB2 clock frequency. - */ -#define STM32_PCLK2_MAX 110000000 - -/** - * @brief Maximum ADC clock frequency. - */ -#define STM32_ADCCLK_MAX 80000000 -/** @} */ - -/** - * @name Flash Wait states - * @{ - */ -#define STM32_0WS_THRESHOLD 20000000 -#define STM32_1WS_THRESHOLD 40000000 -#define STM32_2WS_THRESHOLD 60000000 -#define STM32_3WS_THRESHOLD 80000000 -#define STM32_4WS_THRESHOLD 100000000 -#define STM32_5WS_THRESHOLD 110000000 -/** @} */ - -#elif STM32_VOS == STM32_VOS_RANGE1 -#define STM32_SYSCLK_MAX 80000000 -#define STM32_HSECLK_MAX 48000000 -#define STM32_HSECLK_BYP_MAX 48000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 8000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_LSECLK_BYP_MIN 32768 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLIN_MIN 2660000 -#define STM32_PLLVCO_MAX 344000000 -#define STM32_PLLVCO_MIN 64000000 -#define STM32_PLLP_MAX 110000000 -#define STM32_PLLP_MIN 2064500 -#define STM32_PLLQ_MAX 110000000 -#define STM32_PLLQ_MIN 8000000 -#define STM32_PLLR_MAX 110000000 -#define STM32_PLLR_MIN 8000000 -#define STM32_PCLK1_MAX 80000000 -#define STM32_PCLK2_MAX 80000000 -#define STM32_ADCCLK_MAX 80000000 - -#define STM32_0WS_THRESHOLD 20000000 -#define STM32_1WS_THRESHOLD 40000000 -#define STM32_2WS_THRESHOLD 60000000 -#define STM32_3WS_THRESHOLD 80000000 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 - -#elif STM32_VOS == STM32_VOS_RANGE2 -#define STM32_SYSCLK_MAX 26000000 -#define STM32_HSECLK_MAX 26000000 -#define STM32_HSECLK_BYP_MAX 26000000 -#define STM32_HSECLK_MIN 4000000 -#define STM32_HSECLK_BYP_MIN 8000000 -#define STM32_LSECLK_MAX 32768 -#define STM32_LSECLK_BYP_MAX 1000000 -#define STM32_LSECLK_MIN 32768 -#define STM32_LSECLK_BYP_MIN 32768 -#define STM32_PLLIN_MAX 16000000 -#define STM32_PLLIN_MIN 2660000 -#define STM32_PLLVCO_MAX 128000000 -#define STM32_PLLVCO_MIN 64000000 -#define STM32_PLLP_MAX 26000000 -#define STM32_PLLP_MIN 2064500 -#define STM32_PLLQ_MAX 26000000 -#define STM32_PLLQ_MIN 8000000 -#define STM32_PLLR_MAX 26000000 -#define STM32_PLLR_MIN 8000000 -#define STM32_PCLK1_MAX 26000000 -#define STM32_PCLK2_MAX 26000000 -#define STM32_ADCCLK_MAX 26000000 - -#define STM32_0WS_THRESHOLD 8000000 -#define STM32_1WS_THRESHOLD 16000000 -#define STM32_2WS_THRESHOLD 26000000 -#define STM32_3WS_THRESHOLD 0 -#define STM32_4WS_THRESHOLD 0 -#define STM32_5WS_THRESHOLD 0 - -#else - #error "invalid STM32_VOS value specified" -#endif - -/** - * @brief MSI frequency. - */ -#if STM32_MSIRANGE == STM32_MSIRANGE_100K - #define STM32_MSICLK 100000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_200K - #define STM32_MSICLK 200000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_400K - #define STM32_MSICLK 400000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_800K - #define STM32_MSICLK 800000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_1M - #define STM32_MSICLK 1000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_2M - #define STM32_MSICLK 2000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_4M - #define STM32_MSICLK 4000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_8M - #define STM32_MSICLK 8000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_16M - #define STM32_MSICLK 16000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_24M - #define STM32_MSICLK 24000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_32M - #define STM32_MSICLK 32000000 -#elif STM32_MSIRANGE == STM32_MSIRANGE_48M - #define STM32_MSICLK 48000000 -#else - #error "invalid STM32_MSIRANGE value specified" -#endif - -/** - * @brief MSIS frequency. - */ -#if STM32_MSISRANGE == STM32_MSISRANGE_1M - #define STM32_MSISCLK 1000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_2M - #define STM32_MSISCLK 2000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_4M - #define STM32_MSISCLK 4000000 -#elif STM32_MSISRANGE == STM32_MSISRANGE_8M - #define STM32_MSISCLK 8000000 -#else - #error "invalid STM32_MSISRANGE value specified" -#endif - -/* - * HSI16 related checks. - */ -#if STM32_HSI16_ENABLED -#else /* !STM32_HSI16_ENABLED */ - - #if STM32_SW == STM32_SW_HSI16 - #error "HSI16 not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) - #error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - /* MCO-related checks.*/ - #if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16)) - #error "HSI16 not enabled, required by STM32_MCOSEL" - #endif - - /* SAI1-related checks.*/ - #if STM32_SAI1SEL == STM32_SAI1SEL_HSI16 - #error "HSI16 not enabled, required by STM32_SAI1SEL" - #endif - - #if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16) - #error "HSI16 not enabled, required by STM32_SAI1SEL" - #endif - - #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) && \ - (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSI16) - #error "HSI16 not enabled, required by STM32_PLLSAI1SRC" - #endif - - #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) && \ - (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSI16) - #error "HSI16 not enabled, required by STM32_PLLSAI2SRC" - #endif - - /* SAI2-related checks.*/ - #if STM32_SAI2SEL == STM32_SAI12SEL_HSI16 - #error "HSI16 not enabled, required by STM32_SAI2SEL" - #endif - - #if (STM32_SAI2SEL == STM32_SAI2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSI16) - #error "HSI16 not enabled, required by STM32_SAI2SEL" - #endif - - #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) && \ - (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSI16) - #error "HSI16 not enabled, required by STM32_PLLSAI1SRC" - #endif - - #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) && \ - (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSI16) - #error "HSI16 not enabled, required by STM32_PLLSAI2SRC" - #endif - - /* USART/UART-related checks.*/ - #if (STM32_USART1SEL == STM32_USART1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_USART1SEL" - #endif - #if (STM32_USART2SEL == STM32_USART2SEL_HSI16) - #error "HSI16 not enabled, required by STM32_USART2SEL" - #endif - #if (STM32_USART3SEL == STM32_USART3SEL_HSI16) - #error "HSI16 not enabled, required by STM32_USART3SEL" - #endif - #if (STM32_UART4SEL == STM32_UART4SEL_HSI16) - #error "HSI16 not enabled, required by STM32_UART4SEL" - #endif - #if (STM32_UART5SEL == STM32_UART5SEL_HSI16) - #error "HSI16 not enabled, required by STM32_UART5SEL" - #endif - #if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) - #error "HSI16 not enabled, required by STM32_LPUART1SEL" - #endif - - /* I2C-related checks.*/ - #if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) - #error "HSI16 not enabled, required by I2C1SEL" - #endif - #if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) - #error "HSI16 not enabled, required by I2C2SEL" - #endif - #if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) - #error "HSI16 not enabled, required by I2C3SEL" - #endif - #if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) - #error "HSI16 not enabled, required by I2C4SEL" - #endif - - /* LPTIM-related checks.*/ - #if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) - #error "HSI16 not enabled, required by LPTIM1SEL" - #endif - #if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) - #error "HSI16 not enabled, required by LPTIM2SEL" - #endif - - #if (STM32_STOPWUCK == STM32_STOPWUCK_HSI16) - #error "HSI16 not enabled, required by STM32_STOPWUCK" - #endif - -#endif /* !STM32_HSI16_ENABLED */ - -#if STM32_HSI48_ENABLED -#else /* !STM32_HSI48_ENABLED */ - - #if STM32_MCOSEL == STM32_MCOSEL_HSI48 - #error "HSI48 not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 - #error "HSI48 not enabled, required by STM32_CLK48SEL" - #endif - -#endif /* !STM32_HSI48_ENABLED */ - -/* - * HSE related checks. - */ -#if STM32_HSE_ENABLED - - #if STM32_HSECLK == 0 - #error "HSE frequency not defined" - #else /* STM32_HSECLK != 0 */ - #if defined(STM32_HSE_BYPASS) - #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" - #endif - #else /* !defined(STM32_HSE_BYPASS) */ - #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) - #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" - #endif - #endif /* !defined(STM32_HSE_BYPASS) */ - #endif /* STM32_HSECLK != 0 */ - -#else /* !STM32_HSE_ENABLED */ - - #if STM32_SW == STM32_SW_HSE - #error "HSE not enabled, required by STM32_SW" - #endif - - #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" - #endif - - /* MCO-related checks.*/ - #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ - ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE)) - #error "HSE not enabled, required by STM32_MCOSEL" - #endif - - /* SAI1-related checks.*/ - #if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SAI1SEL" - #endif - - #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) && \ - (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSE) - #error "HSE not enabled, required by STM32_PLLSAI1SRC" - #endif - - #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) && \ - (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSE) - #error "HSE not enabled, required by STM32_PLLSAI2SRC" - #endif - - /* SAI2-related checks.*/ - #if (STM32_SAI2SEL == STM32_SAI2SEL_PLL) && \ - (STM32_PLLSRC == STM32_PLLSRC_HSE) - #error "HSE not enabled, required by STM32_SAI2SEL" - #endif - - #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) && \ - (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSE) - #error "HSE not enabled, required by STM32_PLLSAI1SRC" - #endif - - #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) && \ - (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSE) - #error "HSE not enabled, required by STM32_PLLSAI2SRC" - #endif - - /* RTC-related checks.*/ - #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV - #error "HSE not enabled, required by STM32_RTCSEL" - #endif - -#endif /* !STM32_HSE_ENABLED */ - -/* - * LSI related checks. - */ -#if STM32_LSI_ENABLED -#else /* !STM32_LSI_ENABLED */ - - #if STM32_RTCSEL == STM32_RTCSEL_LSI - #error "LSI not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSI - #error "LSI not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSI - #error "LSI not enabled, required by STM32_LSCOSEL" - #endif - -#endif /* !STM32_LSI_ENABLED */ - -/* - * LSE related checks. - */ -#if STM32_LSE_ENABLED - - #if (STM32_LSECLK == 0) - #error "LSE frequency not defined" - #endif - - #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) - #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" - #endif - -#else /* !STM32_LSE_ENABLED */ - - #if STM32_RTCSEL == STM32_RTCSEL_LSE - #error "LSE not enabled, required by STM32_RTCSEL" - #endif - - #if STM32_MCOSEL == STM32_MCOSEL_LSE - #error "LSE not enabled, required by STM32_MCOSEL" - #endif - - #if STM32_LSCOSEL == STM32_LSCOSEL_LSE - #error "LSE not enabled, required by STM32_LSCOSEL" - #endif - - #if STM32_MSIPLL_ENABLED == TRUE - #error "LSE not enabled, required by STM32_MSIPLL_ENABLED" - #endif - -#endif /* !STM32_LSE_ENABLED */ - -/* - * MSI related checks. - */ -#if (STM32_MSIRANGE == STM32_MSIRANGE_48M) && !STM32_MSIPLL_ENABLED - #warning "STM32_MSIRANGE_48M should be used with STM32_MSIPLL_ENABLED" -#endif - -/** - * @brief STM32_PLLM field. - */ -#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 16)) || \ - defined(__DOXYGEN__) - #define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) -#else - #error "invalid STM32_PLLM_VALUE value specified" -#endif - -/** - * @brief PLL input clock frequency. - */ -#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) - #define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_MSI - #define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 - #define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) - -#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK - #define STM32_PLLCLKIN 0 - -#else - #error "invalid STM32_PLLSRC value specified" -#endif - -/* - * PLL input frequency range check. - */ -#if (STM32_PLLCLKIN != 0) && \ - ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) - #error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLL enable check. - */ -#if (STM32_HSI48_ENABLED && (STM32_CLK48SEL == STM32_CLK48SEL_PLL)) || \ - (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ - defined(__DOXYGEN__) - - #if STM32_PLLCLKIN == 0 - #error "PLL activation required but no PLL clock selected" - #endif - -/** - * @brief PLL activation flag. - */ - #define STM32_ACTIVATE_PLL TRUE -#else - #define STM32_ACTIVATE_PLL FALSE -#endif - -/** - * @brief STM32_PLLN field. - */ -#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define STM32_PLLN (STM32_PLLN_VALUE << 8) -#else -#error "invalid STM32_PLLN_VALUE value specified" -#endif - -/** - * @brief STM32_PLLP field. - */ -#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLP (0 << 17) - -#elif STM32_PLLP_VALUE == 17 -#define STM32_PLLP (1 << 17) - -#else -#error "invalid STM32_PLLP_VALUE value specified" -#endif - -/** - * @brief STM32_PLLQ field. - */ -#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLQ (0 << 21) - -#elif STM32_PLLQ_VALUE == 4 -#define STM32_PLLQ (1 << 21) - -#elif STM32_PLLQ_VALUE == 6 -#define STM32_PLLQ (2 << 21) - -#elif STM32_PLLQ_VALUE == 8 -#define STM32_PLLQ (3 << 21) - -#else -#error "invalid STM32_PLLQ_VALUE value specified" -#endif - -/** - * @brief STM32_PLLR field. - */ -#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLR (0 << 25) - -#elif STM32_PLLR_VALUE == 4 -#define STM32_PLLR (1 << 25) - -#elif STM32_PLLR_VALUE == 6 -#define STM32_PLLR (2 << 25) - -#elif STM32_PLLR_VALUE == 8 -#define STM32_PLLR (3 << 25) - -#else -#error "invalid STM32_PLLR_VALUE value specified" -#endif - -/** - * @brief STM32_PLLPDIV field. - */ -#if (STM32_PLLPDIV_VALUE == 0) || \ - ((STM32_PLLPDIV_VALUE != 1) && (STM32_PLLPDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) -#else -#error "invalid STM32_PLLPDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLPEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ - defined(__DOXYGEN__) -#define STM32_PLLPEN (1 << 16) -#else -#define STM32_PLLPEN (0 << 16) -#endif - -/** - * @brief STM32_PLLQEN field. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__) -#define STM32_PLLQEN (1 << 20) -#else -#define STM32_PLLQEN (0 << 20) -#endif - -/** - * @brief STM32_PLLREN field. - */ -#if (STM32_SW == STM32_SW_PLL) || \ - (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ - defined(__DOXYGEN__) -#define STM32_PLLREN (1 << 24) -#else -#define STM32_PLLREN (0 << 24) -#endif - -/** - * @brief PLL VCO frequency. - */ -#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) - -/* - * PLL VCO frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLL P output clock frequency. - */ -#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) -#else -#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) -#endif - -/** - * @brief PLL Q output clock frequency. - */ -#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) - -/** - * @brief PLL R output clock frequency. - */ -#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) - -/* - * PLL-P output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLL-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLL-R output frequency range check. - */ -#if STM32_ACTIVATE_PLL && \ - ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief System clock source. - */ -#if STM32_NO_INIT || defined(__DOXYGEN__) -#define STM32_SYSCLK STM32_MSICLK - -#elif (STM32_SW == STM32_SW_MSI) -#define STM32_SYSCLK STM32_MSICLK - -#elif (STM32_SW == STM32_SW_HSI16) -#define STM32_SYSCLK STM32_HSI16CLK - -#elif (STM32_SW == STM32_SW_HSE) -#define STM32_SYSCLK STM32_HSECLK - -#elif (STM32_SW == STM32_SW_PLL) -#define STM32_SYSCLK STM32_PLL_R_CLKOUT - -#else -#error "invalid STM32_SW value specified" -#endif - -/* Check on the system clock.*/ -#if STM32_SYSCLK > STM32_SYSCLK_MAX -#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief AHB frequency. - */ -#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_HCLK (STM32_SYSCLK / 1) - -#elif STM32_HPRE == STM32_HPRE_DIV2 -#define STM32_HCLK (STM32_SYSCLK / 2) - -#elif STM32_HPRE == STM32_HPRE_DIV4 -#define STM32_HCLK (STM32_SYSCLK / 4) - -#elif STM32_HPRE == STM32_HPRE_DIV8 -#define STM32_HCLK (STM32_SYSCLK / 8) - -#elif STM32_HPRE == STM32_HPRE_DIV16 -#define STM32_HCLK (STM32_SYSCLK / 16) - -#elif STM32_HPRE == STM32_HPRE_DIV64 -#define STM32_HCLK (STM32_SYSCLK / 64) - -#elif STM32_HPRE == STM32_HPRE_DIV128 -#define STM32_HCLK (STM32_SYSCLK / 128) - -#elif STM32_HPRE == STM32_HPRE_DIV256 -#define STM32_HCLK (STM32_SYSCLK / 256) - -#elif STM32_HPRE == STM32_HPRE_DIV512 -#define STM32_HCLK (STM32_SYSCLK / 512) - -#else -#error "invalid STM32_HPRE value specified" -#endif - -/* - * AHB frequency check. - */ -#if STM32_HCLK > STM32_SYSCLK_MAX -#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" -#endif - -/** - * @brief APB1 frequency. - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK1 (STM32_HCLK / 1) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV2 -#define STM32_PCLK1 (STM32_HCLK / 2) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV4 -#define STM32_PCLK1 (STM32_HCLK / 4) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV8 -#define STM32_PCLK1 (STM32_HCLK / 8) - -#elif STM32_PPRE1 == STM32_PPRE1_DIV16 -#define STM32_PCLK1 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE1 value specified" -#endif - -/* - * APB1 frequency check. - */ -#if STM32_PCLK1 > STM32_PCLK1_MAX -#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" -#endif - -/** - * @brief APB2 frequency. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_PCLK2 (STM32_HCLK / 1) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV2 -#define STM32_PCLK2 (STM32_HCLK / 2) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV4 -#define STM32_PCLK2 (STM32_HCLK / 4) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV8 -#define STM32_PCLK2 (STM32_HCLK / 8) - -#elif STM32_PPRE2 == STM32_PPRE2_DIV16 -#define STM32_PCLK2 (STM32_HCLK / 16) - -#else -#error "invalid STM32_PPRE2 value specified" -#endif - -/* - * APB2 frequency check. - */ -#if STM32_PCLK2 > STM32_PCLK2_MAX -#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" -#endif - -/** - * @brief STM32_PLLSAI1M field. - */ -#if ((STM32_PLLSAI1M_VALUE >= 1) && (STM32_PLLSAI1M_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1M ((STM32_PLLSAI1M_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLSAI1M_VALUE value specified" -#endif - -/** - * @brief PLLSAI1 input clock frequency. - */ -#if (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSAI1CLKIN (STM32_HSECLK / STM32_PLLSAI1M_VALUE) - -#elif STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_MSI -#define STM32_PLLSAI1CLKIN (STM32_MSICLK / STM32_PLLSAI1M_VALUE) - -#elif STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSI16 -#define STM32_PLLSAI1CLKIN (STM32_HSI16CLK / STM32_PLLSAI1M_VALUE) - -#elif STM32_PLLSSAI1RC == STM32_PLLSAI1SRC_NOCLOCK -#define STM32_PLLSAI1CLKIN 0 - -#else -#error "invalid STM32_PLLSAI1SRC value specified" -#endif - -/* - * PLLSAI1 input frequency range check. - */ -#if (STM32_PLLSAI1CLKIN != 0) && \ - ((STM32_PLLSAI1CLKIN < STM32_PLLIN_MIN) || \ - (STM32_PLLSAI1CLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLSAI1CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLLSAI1 enable check. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ - (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ - defined(__DOXYGEN__) - -#if STM32_PLLSAI1CLKIN == 0 -#error "PLLSAI1 activation required but no PLL clock selected" -#endif - -/** - * @brief PLLSAI1 activation flag. - */ -#define STM32_ACTIVATE_PLLSAI1 TRUE -#else -#define STM32_ACTIVATE_PLLSAI1 FALSE -#endif - -/** - * @brief STM32_PLLSAI1N field. - */ -#if ((STM32_PLLSAI1N_VALUE >= 8) && (STM32_PLLSAI1N_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1N (STM32_PLLSAI1N_VALUE << 8) -#else -#error "invalid STM32_PLLSAI1N_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1P field. - */ -#if (STM32_PLLSAI1P_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLSAI1P (0 << 17) - -#elif STM32_PLLSAI1P_VALUE == 17 -#define STM32_PLLSAI1P (1 << 17) - -#else -#error "invalid STM32_PLLSAI1P_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1Q field. - */ -#if (STM32_PLLSAI1Q_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI1Q (0 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 4 -#define STM32_PLLSAI1Q (1 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 6 -#define STM32_PLLSAI1Q (2 << 21) - -#elif STM32_PLLSAI1Q_VALUE == 8 -#define STM32_PLLSAI1Q (3 << 21) - -#else -#error "invalid STM32_PLLSAI1Q_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1R field. - */ -#if (STM32_PLLSAI1R_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI1R (0 << 25) - -#elif STM32_PLLSAI1R_VALUE == 4 -#define STM32_PLLSAI1R (1 << 25) - -#elif STM32_PLLSAI1R_VALUE == 6 -#define STM32_PLLSAI1R (2 << 25) - -#elif STM32_PLLSAI1R_VALUE == 8 -#define STM32_PLLSAI1R (3 << 25) - -#else -#error "invalid STM32_PLLSAI1R_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1PDIV field. - */ -#if ((STM32_PLLSAI1PDIV_VALUE != 1) && (STM32_PLLSAI1PDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1PDIV (STM32_PLLSAI1PDIV_VALUE << 27) -#else -#error "invalid STM32_PLLSAI1PDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI1PEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI1PEN (1 << 16) -#else -#define STM32_PLLSAI1PEN (0 << 16) -#endif - -/** - * @brief STM32_PLLSAI1QEN field. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_PLLSAI1QEN (1 << 20) -#else -#define STM32_PLLSAI1QEN (0 << 20) -#endif - -/** - * @brief STM32_PLLSAI1REN field. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_PLLSAI1REN (1 << 24) -#else -#define STM32_PLLSAI1REN (0 << 24) -#endif - -/** - * @brief PLLSAI1 VCO frequency. - */ -#define STM32_PLLSAI1VCO (STM32_PLLSAI1CLKIN * STM32_PLLSAI1N_VALUE) - -/* - * PLLSAI1 VCO frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI1-P output clock frequency. - */ -#if (STM32_PLLSAI1PDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE) -#else -#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1PDIV_VALUE) -#endif - -/** - * @brief PLLSAI1-Q output clock frequency. - */ -#define STM32_PLLSAI1_Q_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) - -/** - * @brief PLLSAI1-R output clock frequency. - */ -#define STM32_PLLSAI1_R_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1R_VALUE) - -/* - * PLLSAI1-P output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLLSAI1-Q output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) -#error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" -#endif - -/* - * PLLSAI1-R output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI1 && \ - ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief STM32_PLLSAI2M field. - */ -#if ((STM32_PLLSAI2M_VALUE >= 1) && (STM32_PLLSAI2M_VALUE <= 16)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2M ((STM32_PLLSAI2M_VALUE - 1) << 4) -#else -#error "invalid STM32_PLLSAI2M_VALUE value specified" -#endif - -/** - * @brief PLLSAI2 input clock frequency. - */ -#if (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSE) || defined(__DOXYGEN__) -#define STM32_PLLSAI2CLKIN (STM32_HSECLK / STM32_PLLSAI2M_VALUE) - -#elif STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_MSI -#define STM32_PLLSAI2CLKIN (STM32_MSICLK / STM32_PLLSAI2M_VALUE) - -#elif STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSI16 -#define STM32_PLLSAI2CLKIN (STM32_HSI16CLK / STM32_PLLSAI2M_VALUE) - -#elif STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_NOCLOCK -#define STM32_PLLSAI2CLKIN 0 - -#else -#error "invalid STM32_PLLSAI2SRC value specified" -#endif - -/* - * PLLSAI2 input frequency range check. - */ -#if (STM32_PLLSAI2CLKIN != 0) && \ - ((STM32_PLLSAI2CLKIN < STM32_PLLIN_MIN) || \ - (STM32_PLLSAI2CLKIN > STM32_PLLIN_MAX)) -#error "STM32_PLLSAI2CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" -#endif - -/* - * PLLSAI2 enable check. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ - (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ - defined(__DOXYGEN__) - -#if STM32_PLLSAI2CLKIN == 0 -#error "PLLSAI2 activation required but no PLL clock selected" -#endif - -/** - * @brief PLLSAI2 activation flag. - */ -#define STM32_ACTIVATE_PLLSAI2 TRUE -#else -#define STM32_ACTIVATE_PLLSAI2 FALSE -#endif - -/** - * @brief STM32_PLLSAI2N field. - */ -#if ((STM32_PLLSAI2N_VALUE >= 8) && (STM32_PLLSAI2N_VALUE <= 127)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2N (STM32_PLLSAI2N_VALUE << 8) -#else -#error "invalid STM32_PLLSAI2N_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2P field. - */ -#if (STM32_PLLSAI2P_VALUE == 7) || defined(__DOXYGEN__) -#define STM32_PLLSAI2P (0 << 17) - -#elif STM32_PLLSAI2P_VALUE == 17 -#define STM32_PLLSAI2P (1 << 17) - -#else -#error "invalid STM32_PLLSAI2P_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2R field. - */ -#if (STM32_PLLSAI2R_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLSAI2R (0 << 25) - -#elif STM32_PLLSAI2R_VALUE == 4 -#define STM32_PLLSAI2R (1 << 25) - -#elif STM32_PLLSAI2R_VALUE == 6 -#define STM32_PLLSAI2R (2 << 25) - -#elif STM32_PLLSAI2R_VALUE == 8 -#define STM32_PLLSAI2R (3 << 25) - -#else -#error "invalid STM32_PLLSAI2R_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2PDIV field. - */ -#if ((STM32_PLLSAI2PDIV_VALUE != 1) && (STM32_PLLSAI2PDIV_VALUE <= 31)) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2PDIV (STM32_PLLSAI2PDIV_VALUE << 27) -#else -#error "invalid STM32_PLLSAI2PDIV_VALUE value specified" -#endif - -/** - * @brief STM32_PLLSAI2PEN field. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ - (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ - defined(__DOXYGEN__) -#define STM32_PLLSAI2PEN (1 << 16) -#else -#define STM32_PLLSAI2PEN (0 << 16) -#endif - -/** - * @brief STM32_PLLSAI2REN field. - * @note Always enabled. - * @note It should depend on some condition. - */ -#define STM32_PLLSAI2REN (1 << 24) - -/** - * @brief PLLSAI2 VCO frequency. - */ -#define STM32_PLLSAI2VCO (STM32_PLLSAI2CLKIN * STM32_PLLSAI2N_VALUE) - -/* - * PLLSAI2 VCO frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) -#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" -#endif - -/** - * @brief PLLSAI2-P output clock frequency. - */ -#if (STM32_PLLSAI2PDIV_VALUE == 0) || defined(__DOXYGEN__) -#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE) -#else -#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2PDIV_VALUE) -#endif - -/** - * @brief PLLSAI2-R output clock frequency. - */ -#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE) - -/* - * PLLSAI2-P output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) -#error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" -#endif - -/* - * PLLSAI2-R output frequency range check. - */ -#if STM32_ACTIVATE_PLLSAI2 && \ - ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) -#error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" -#endif - -/** - * @brief MCO divider clock frequency. - */ -#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_MCODIVCLK 0 - -#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK -#define STM32_MCODIVCLK STM32_SYSCLK - -#elif STM32_MCOSEL == STM32_MCOSEL_MSI -#define STM32_MCODIVCLK STM32_MSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 -#define STM32_MCODIVCLK STM32_HSI16CLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSE -#define STM32_MCODIVCLK STM32_HSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_PLL -#define STM32_MCODIVCLK STM32_PLL_P_CLKOUT - -#elif STM32_MCOSEL == STM32_MCOSEL_LSI -#define STM32_MCODIVCLK STM32_LSICLK - -#elif STM32_MCOSEL == STM32_MCOSEL_LSE -#define STM32_MCODIVCLK STM32_LSECLK - -#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 -#define STM32_MCODIVCLK STM32_HSI48CLK - -#else -#error "invalid STM32_MCOSEL value specified" -#endif - -/** - * @brief MCO output pin clock frequency. - */ -#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) -#define STM32_MCOCLK STM32_MCODIVCLK - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 -#define STM32_MCOCLK (STM32_MCODIVCLK / 2) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 -#define STM32_MCOCLK (STM32_MCODIVCLK / 4) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 -#define STM32_MCOCLK (STM32_MCODIVCLK / 8) - -#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 -#define STM32_MCOCLK (STM32_MCODIVCLK / 16) - -#else -#error "invalid STM32_MCOPRE value specified" -#endif - -/** - * @brief RTC clock frequency. - */ -#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) -#define STM32_RTCCLK 0 - -#elif STM32_RTCSEL == STM32_RTCSEL_LSE -#define STM32_RTCCLK STM32_LSECLK - -#elif STM32_RTCSEL == STM32_RTCSEL_LSI -#define STM32_RTCCLK STM32_LSICLK - -#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV -#define STM32_RTCCLK (STM32_HSECLK / 32) - -#else -#error "invalid STM32_RTCSEL value specified" -#endif - -/** - * @brief USART1 clock frequency. - */ -#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_USART1CLK STM32_PCLK2 - -#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK -#define STM32_USART1CLK STM32_SYSCLK - -#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 -#define STM32_USART1CLK STM32_HSI16CLK - -#elif STM32_USART1SEL == STM32_USART1SEL_LSE -#define STM32_USART1CLK STM32_LSECLK - -#else -#error "invalid source selected for USART1 clock" -#endif - -/** - * @brief USART2 clock frequency. - */ -#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART2CLK STM32_PCLK1 - -#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK -#define STM32_USART2CLK STM32_SYSCLK - -#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 -#define STM32_USART2CLK STM32_HSI16CLK - -#elif STM32_USART2SEL == STM32_USART2SEL_LSE -#define STM32_USART2CLK STM32_LSECLK - -#else -#error "invalid source selected for USART2 clock" -#endif - -/** - * @brief USART3 clock frequency. - */ -#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_USART3CLK STM32_PCLK1 - -#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK -#define STM32_USART3CLK STM32_SYSCLK - -#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 -#define STM32_USART3CLK STM32_HSI16CLK - -#elif STM32_USART3SEL == STM32_USART3SEL_LSE -#define STM32_USART3CLK STM32_LSECLK - -#else -#error "invalid source selected for USART3 clock" -#endif - -/** - * @brief UART4 clock frequency. - */ -#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART4CLK STM32_PCLK1 - -#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK -#define STM32_UART4CLK STM32_SYSCLK - -#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 -#define STM32_UART4CLK STM32_HSI16CLK - -#elif STM32_UART4SEL == STM32_UART4SEL_LSE -#define STM32_UART4CLK STM32_LSECLK - -#else -#error "invalid source selected for UART4 clock" -#endif - -/** - * @brief UART5 clock frequency. - */ -#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_UART5CLK STM32_PCLK1 - -#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK -#define STM32_UART5CLK STM32_SYSCLK - -#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 -#define STM32_UART5CLK STM32_HSI16CLK - -#elif STM32_UART5SEL == STM32_UART5SEL_LSE -#define STM32_UART5CLK STM32_LSECLK - -#else -#error "invalid source selected for UART5 clock" -#endif - -/** - * @brief LPUART1 clock frequency. - */ -#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPUART1CLK STM32_PCLK1 - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK -#define STM32_LPUART1CLK STM32_SYSCLK - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 -#define STM32_LPUART1CLK STM32_HSI16CLK - -#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE -#define STM32_LPUART1CLK STM32_LSECLK - -#else -#error "invalid source selected for LPUART1 clock" -#endif - -/** - * @brief I2C1 clock frequency. - */ -#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C1CLK STM32_PCLK1 - -#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK -#define STM32_I2C1CLK STM32_SYSCLK - -#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 -#define STM32_I2C1CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C1 clock" -#endif - -/** - * @brief I2C2 clock frequency. - */ -#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C2CLK STM32_PCLK1 - -#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK -#define STM32_I2C2CLK STM32_SYSCLK - -#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 -#define STM32_I2C2CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C2 clock" -#endif - -/** - * @brief I2C3 clock frequency. - */ -#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C3CLK STM32_PCLK1 - -#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK -#define STM32_I2C3CLK STM32_SYSCLK - -#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 -#define STM32_I2C3CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C3 clock" -#endif - -/** - * @brief I2C4 clock frequency. - */ -#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_I2C4CLK STM32_PCLK1 - -#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK -#define STM32_I2C4CLK STM32_SYSCLK - -#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 -#define STM32_I2C4CLK STM32_HSI16CLK - -#else -#error "invalid source selected for I2C4 clock" -#endif - -/** - * @brief LPTIM1 clock frequency. - */ -#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM1CLK STM32_PCLK1 - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI -#define STM32_LPTIM1CLK STM32_LSICLK - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 -#define STM32_LPTIM1CLK STM32_HSI16CLK - -#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE -#define STM32_LPTIM1CLK STM32_LSECLK - -#else -#error "invalid source selected for LPTIM1 clock" -#endif - -/** - * @brief LPTIM2 clock frequency. - */ -#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM2CLK STM32_PCLK1 - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI -#define STM32_LPTIM2CLK STM32_LSICLK - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 -#define STM32_LPTIM2CLK STM32_HSI16CLK - -#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE -#define STM32_LPTIM2CLK STM32_LSECLK - -#else -#error "invalid source selected for LPTIM2 clock" -#endif - -/** - * @brief LPTIM3 clock frequency. - */ -#if (STM32_LPTIM3SEL == STM32_LPTIM3SEL_PCLK1) || defined(__DOXYGEN__) -#define STM32_LPTIM3CLK STM32_PCLK1 - -#elif STM32_LPTIM3SEL == STM32_LPTIM3SEL_LSI -#define STM32_LPTIM3CLK STM32_LSICLK - -#elif STM32_LPTIM3SEL == STM32_LPTIM3SEL_HSI16 -#define STM32_LPTIM3CLK STM32_HSI16CLK - -#elif STM32_LPTIM3SEL == STM32_LPTIM3SEL_LSE -#define STM32_LPTIM3CLK STM32_LSECLK - -#else -#error "invalid source selected for LPTIM3 clock" -#endif - -/** - * @brief 48MHz clock frequency. - */ -#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) -#define STM32_48CLK STM32_HSI48CLK - -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 -#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) - -#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL -#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) - -#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI -#define STM32_48CLK STM32_MSICLK - -#else -#error "invalid source selected for 48CLK clock" -#endif - -/** - * @brief SAI1 clock frequency. - */ -#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_SAI1CLK STM32_PLLSAI1_P_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2 -#define STM32_SAI1CLK STM32_PLLSAI2_P_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL -#define STM32_SAI1CLK STM32_PLL_P_CLKOUT - -#elif STM32_SAI1SEL == STM32_SAI1SEL_EXTCLK -#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ - -#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16 -#define STM32_SAI1CLK STM32_HSI16CLK - -#elif STM32_SAI1SEL == STM32_SAI1SEL_OFF -#define STM32_SAI1CLK 0 - -#else -#error "invalid source selected for SAI1 clock" -#endif - -/** - * @brief SAI2 clock frequency. - */ -#if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || defined(__DOXYGEN__) -#define STM32_SAI2CLK STM32_PLLSAI1_P_CLKOUT - -#elif STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2 -#define STM32_SAI2CLK STM32_PLLSAI2_P_CLKOUT - -#elif STM32_SAI2SEL == STM32_SAI2SEL_PLL -#define STM32_SAI2CLK STM32_PLL_P_CLKOUT - -#elif STM32_SAI2SEL == STM32_SAI2SEL_EXTCLK -#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ - -#elif STM32_SAI2SEL == STM32_SAI2SEL_HSI16 -#define STM32_SAI2CLK STM32_HSI16CLK - -#elif STM32_SAI2SEL == STM32_SAI2SEL_OFF -#define STM32_SAI2CLK 0 - -#else -#error "invalid source selected for SAI2 clock" -#endif - -/** - * @brief SDMMC clock frequency. - */ -#if (STM32_SDMMCSEL == STM32_SDMMCSEL_48CLK) || defined(__DOXYGEN__) -#define STM32_SDMMCCLK STM32_48CLK - -#elif STM32_SDMMCSEL == STM32_SDMMCSEL_PLLSAI3CLK -#define STM32_SDMMCCLK STM32_PLL_P_CLKOUT - -#else -#error "invalid source selected for SDMMC clock" -#endif - -/** - * @brief USB clock point. - */ -#define STM32_USBCLK STM32_48CLK - -/** - * @brief RNG clock point. - */ -#define STM32_RNGCLK STM32_48CLK - -/** - * @brief ADC clock frequency. - */ -#if (STM32_ADCSEL == STM32_ADCSEL_NOCLK) || defined(__DOXYGEN__) -#define STM32_ADCCLK 0 - -#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI1 -#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT - -#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK -#define STM32_ADCCLK STM32_SYSCLK - -#else -#error "invalid source selected for ADC clock" -#endif - -/** - * @brief DFSDM clock frequency. - */ -#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) -#define STM32_DFSDMCLK STM32_PCLK2 - -#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK -#define STM32_DFSDMCLK STM32_SYSCLK - -#else -#error "invalid source selected for DFSDM clock" -#endif - -/** - * @brief SDMMC frequency. - */ -#define STM32_SDMMC1CLK STM32_48CLK - -/** - * @brief OSPI clock frequency. - */ -#if (STM32_OSPISEL == STM32_OSPISEL_SYSCLK) || defined(__DOXYGEN__) -#define STM32_OSPICLK STM32_SYSCLK - -#elif STM32_OSPISEL == STM32_OSPISEL_MSI -#define STM32_OSPICLK STM32_MSICLK - -#elif STM32_OSPISEL == STM32_OSPISEL_48CLK -#define STM32_OSPICLK STM32_PLLSAI1_Q_CLKOUT - -#else -#error "invalid source selected for OSPI clock" -#endif - -/** - * @brief Clock of timers connected to APB1 - */ -#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK1 (STM32_PCLK1 * 1) -#else -#define STM32_TIMCLK1 (STM32_PCLK1 * 2) -#endif - -/** - * @brief Clock of timers connected to APB2. - */ -#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) -#define STM32_TIMCLK2 (STM32_PCLK2 * 1) -#else -#define STM32_TIMCLK2 (STM32_PCLK2 * 2) -#endif - -/** - * @brief Flash settings. - */ -#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_HCLK <= STM32_1WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_HCLK <= STM32_2WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_HCLK <= STM32_3WS_THRESHOLD -#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS - -#else -#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS -#endif - -/** - * @brief Flash settings for MSI. - */ -#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS - -#elif STM32_MSICLK <= STM32_1WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS - -#elif STM32_MSICLK <= STM32_2WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS - -#elif STM32_MSICLK <= STM32_3WS_THRESHOLD -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS - -#else -#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -/* Various helpers.*/ -#include "nvic.h" -#include "cache.h" -#include "mpu_v7m.h" -#include "stm32_isr.h" -#include "stm32_dma.h" -#include "stm32_exti.h" -#include "stm32_rcc.h" -#include "stm32_tim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void hal_lld_init(void); - void stm32_clock_init(void); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_LLD_H */ - -/** @} */ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file STM32L5xx/hal_lld.h + * @brief STM32L5xx HAL subsystem low level driver header. + * @pre This module requires the following macros to be defined in the + * @p board.h file: + * - STM32_LSECLK. + * - STM32_LSEDRV. + * - STM32_LSE_BYPASS (optionally). + * - STM32_HSECLK. + * - STM32_HSE_BYPASS (optionally). + * . + * One of the following macros must also be defined: + * - STM32L4R5xx, STM32L4R7xx, STM32L4R9xx. + * - STM32L4S5xx, STM32L4S7xx, STM32L4S9xx. + * . + * + * @addtogroup HAL + * @{ + */ + +#ifndef HAL_LLD_H +#define HAL_LLD_H + +#include "stm32_registry.h" + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name Platform identification + * @{ + */ +#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || \ + defined(__DOXYGEN__) +#define PLATFORM_NAME "STM32L4+ Ultra Low Power" + +#elif defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) +#define PLATFORM_NAME "STM32L4+ Ultra Low Power with Crypto" + +#else +#error "STM32L4+ device not specified" +#endif + +/** + * @brief Sub-family identifier. + */ +#if !defined(STM32L5XX) || defined(__DOXYGEN__) +#define STM32L5XX +#endif +/** @} */ + +/** + * @name Internal clock sources + * @{ + */ +#define STM32_HSI16CLK 16000000 /**< 16MHz internal clock. */ +#define STM32_HSI48CLK 48000000 /**< 48MHz internal clock. */ +#define STM32_LSICLK 32000 /**< Low speed internal clock. */ +/** @} */ + +/** + * @name PWR_CR1 register bits definitions + * @{ + */ +#define STM32_VOS_MASK (3 << 9) /**< Core voltage mask. */ +#define STM32_VOS_RANGE0 (0 << 9) /**< Core voltage 1.28 Volts. */ +#define STM32_VOS_RANGE1 (1 << 9) /**< Core voltage 1.2 Volts. */ +#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ +/** @} */ + +/** + * @name PWR_CR2 register bits definitions + * @{ + */ +#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */ +#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */ +#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */ +#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */ +#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */ +#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */ +#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */ +#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */ +#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */ +/** @} */ + +/** + * @name RCC_CR register bits definitions + * @{ + */ +#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */ +#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */ +#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */ +#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */ +#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */ +#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */ +#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */ +#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */ +#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */ +#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */ +#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */ +#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */ +#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */ +/** @} */ + +/** + * @name RCC_CFGR register bits definitions + * @{ + */ +#define STM32_SW_MASK (3 << 0) /**< SW field mask. */ +#define STM32_SW_MSI (0 << 0) /**< SYSCLK source is MSI. */ +#define STM32_SW_HSI16 (1 << 0) /**< SYSCLK source is HSI. */ +#define STM32_SW_HSE (2 << 0) /**< SYSCLK source is HSE. */ +#define STM32_SW_PLL (3 << 0) /**< SYSCLK source is PLL. */ + +#define STM32_HPRE_MASK (15 << 4) /**< HPRE field mask. */ +#define STM32_HPRE_DIV1 (0 << 4) /**< SYSCLK divided by 1. */ +#define STM32_HPRE_DIV2 (8 << 4) /**< SYSCLK divided by 2. */ +#define STM32_HPRE_DIV4 (9 << 4) /**< SYSCLK divided by 4. */ +#define STM32_HPRE_DIV8 (10 << 4) /**< SYSCLK divided by 8. */ +#define STM32_HPRE_DIV16 (11 << 4) /**< SYSCLK divided by 16. */ +#define STM32_HPRE_DIV64 (12 << 4) /**< SYSCLK divided by 64. */ +#define STM32_HPRE_DIV128 (13 << 4) /**< SYSCLK divided by 128. */ +#define STM32_HPRE_DIV256 (14 << 4) /**< SYSCLK divided by 256. */ +#define STM32_HPRE_DIV512 (15 << 4) /**< SYSCLK divided by 512. */ + +#define STM32_PPRE1_MASK (7 << 8) /**< PPRE1 field mask. */ +#define STM32_PPRE1_DIV1 (0 << 8) /**< HCLK divided by 1. */ +#define STM32_PPRE1_DIV2 (4 << 8) /**< HCLK divided by 2. */ +#define STM32_PPRE1_DIV4 (5 << 8) /**< HCLK divided by 4. */ +#define STM32_PPRE1_DIV8 (6 << 8) /**< HCLK divided by 8. */ +#define STM32_PPRE1_DIV16 (7 << 8) /**< HCLK divided by 16. */ + +#define STM32_PPRE2_MASK (7 << 11) /**< PPRE2 field mask. */ +#define STM32_PPRE2_DIV1 (0 << 11) /**< HCLK divided by 1. */ +#define STM32_PPRE2_DIV2 (4 << 11) /**< HCLK divided by 2. */ +#define STM32_PPRE2_DIV4 (5 << 11) /**< HCLK divided by 4. */ +#define STM32_PPRE2_DIV8 (6 << 11) /**< HCLK divided by 8. */ +#define STM32_PPRE2_DIV16 (7 << 11) /**< HCLK divided by 16. */ + +#define STM32_STOPWUCK_MASK (1 << 15) /**< STOPWUCK field mask. */ +#define STM32_STOPWUCK_MSI (0 << 15) /**< Wakeup clock is MSI. */ +#define STM32_STOPWUCK_HSI16 (1 << 15) /**< Wakeup clock is HSI16. */ + +#define STM32_MCOSEL_MASK (15 << 24) /**< MCOSEL field mask. */ +#define STM32_MCOSEL_NOCLOCK (0 << 24) /**< No clock on MCO pin. */ +#define STM32_MCOSEL_SYSCLK (1 << 24) /**< SYSCLK on MCO pin. */ +#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ +#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ +#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ +#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ +#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ +#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ +#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ + +#define STM32_MCOPRE_MASK (7 << 28) /**< MCOPRE field mask. */ +#define STM32_MCOPRE_DIV1 (0 << 28) /**< MCO divided by 1. */ +#define STM32_MCOPRE_DIV2 (1 << 28) /**< MCO divided by 2. */ +#define STM32_MCOPRE_DIV4 (2 << 28) /**< MCO divided by 4. */ +#define STM32_MCOPRE_DIV8 (3 << 28) /**< MCO divided by 8. */ +#define STM32_MCOPRE_DIV16 (4 << 28) /**< MCO divided by 16. */ +/** @} */ + +/** + * @name RCC_PLLCFGR register bits definitions + * @{ + */ +#define STM32_PLLSRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSRC_MSI (1 << 0) /**< PLL clock source is MSI. */ +#define STM32_PLLSRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSRC_HSE (3 << 0) /**< PLL clock source is HSE. */ + +/** + * @name RCC_PLLSAI1CFGR register bits definitions + * @{ + */ +#define STM32_PLLSAI1SRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSAI1SRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSAI1SRC_MSI (1 << 0) /**< PLL clock source is MSI. */ +#define STM32_PLLSAI1SRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSAI1SRC_HSE (3 << 0) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_PLLSAI2CFGR register bits definitions + * @{ + */ +#define STM32_PLLSAI2SRC_MASK (3 << 0) /**< PLL clock source mask. */ +#define STM32_PLLSAI2SRC_NOCLOCK (0 << 0) /**< PLL clock source disabled. */ +#define STM32_PLLSAI2SRC_MSI (1 << 0) /**< PLL clock source is MSI. */ +#define STM32_PLLSAI2SRC_HSI16 (2 << 0) /**< PLL clock source is HSI16. */ +#define STM32_PLLSAI2SRC_HSE (3 << 0) /**< PLL clock source is HSE. */ +/** @} */ + +/** + * @name RCC_CCIPR register bits definitions + * @{ + */ +#define STM32_USART1SEL_MASK (3 << 0) /**< USART1SEL mask. */ +#define STM32_USART1SEL_PCLK2 (0 << 0) /**< USART1 source is PCLK2. */ +#define STM32_USART1SEL_SYSCLK (1 << 0) /**< USART1 source is SYSCLK. */ +#define STM32_USART1SEL_HSI16 (2 << 0) /**< USART1 source is HSI16. */ +#define STM32_USART1SEL_LSE (3 << 0) /**< USART1 source is LSE. */ + +#define STM32_USART2SEL_MASK (3 << 2) /**< USART2 mask. */ +#define STM32_USART2SEL_PCLK1 (0 << 2) /**< USART2 source is PCLK1. */ +#define STM32_USART2SEL_SYSCLK (1 << 2) /**< USART2 source is SYSCLK. */ +#define STM32_USART2SEL_HSI16 (2 << 2) /**< USART2 source is HSI16. */ +#define STM32_USART2SEL_LSE (3 << 2) /**< USART2 source is LSE. */ + +#define STM32_USART3SEL_MASK (3 << 4) /**< USART3 mask. */ +#define STM32_USART3SEL_PCLK1 (0 << 4) /**< USART3 source is PCLK1. */ +#define STM32_USART3SEL_SYSCLK (1 << 4) /**< USART3 source is SYSCLK. */ +#define STM32_USART3SEL_HSI16 (2 << 4) /**< USART3 source is HSI16. */ +#define STM32_USART3SEL_LSE (3 << 4) /**< USART3 source is LSE. */ + +#define STM32_UART4SEL_MASK (3 << 6) /**< UART4 mask. */ +#define STM32_UART4SEL_PCLK1 (0 << 6) /**< UART4 source is PCLK1. */ +#define STM32_UART4SEL_SYSCLK (1 << 6) /**< UART4 source is SYSCLK. */ +#define STM32_UART4SEL_HSI16 (2 << 6) /**< UART4 source is HSI16. */ +#define STM32_UART4SEL_LSE (3 << 6) /**< UART4 source is LSE. */ + +#define STM32_UART5SEL_MASK (3 << 8) /**< UART5 mask. */ +#define STM32_UART5SEL_PCLK1 (0 << 8) /**< UART5 source is PCLK1. */ +#define STM32_UART5SEL_SYSCLK (1 << 8) /**< UART5 source is SYSCLK. */ +#define STM32_UART5SEL_HSI16 (2 << 8) /**< UART5 source is HSI16. */ +#define STM32_UART5SEL_LSE (3 << 8) /**< UART5 source is LSE. */ + +#define STM32_LPUART1SEL_MASK (3 << 10) /**< LPUART1 mask. */ +#define STM32_LPUART1SEL_PCLK1 (0 << 10) /**< LPUART1 source is PCLK1. */ +#define STM32_LPUART1SEL_SYSCLK (1 << 10) /**< LPUART1 source is SYSCLK. */ +#define STM32_LPUART1SEL_HSI16 (2 << 10) /**< LPUART1 source is HSI16. */ +#define STM32_LPUART1SEL_LSE (3 << 10) /**< LPUART1 source is LSE. */ + +#define STM32_I2C1SEL_MASK (3 << 12) /**< I2C1SEL mask. */ +#define STM32_I2C1SEL_PCLK1 (0 << 12) /**< I2C1 source is PCLK1. */ +#define STM32_I2C1SEL_SYSCLK (1 << 12) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C1SEL_HSI16 (2 << 12) /**< I2C1 source is HSI16. */ + +#define STM32_I2C2SEL_MASK (3 << 14) /**< I2C2SEL mask. */ +#define STM32_I2C2SEL_PCLK1 (0 << 14) /**< I2C2 source is PCLK1. */ +#define STM32_I2C2SEL_SYSCLK (1 << 14) /**< I2C2 source is SYSCLK. */ +#define STM32_I2C2SEL_HSI16 (2 << 14) /**< I2C2 source is HSI16. */ + +#define STM32_I2C3SEL_MASK (3 << 16) /**< I2C3SEL mask. */ +#define STM32_I2C3SEL_PCLK1 (0 << 16) /**< I2C3 source is PCLK1. */ +#define STM32_I2C3SEL_SYSCLK (1 << 16) /**< I2C3 source is SYSCLK. */ +#define STM32_I2C3SEL_HSI16 (2 << 16) /**< I2C3 source is HSI16. */ + +#define STM32_LPTIM1SEL_MASK (3 << 18) /**< LPTIM1SEL mask. */ +#define STM32_LPTIM1SEL_PCLK1 (0 << 18) /**< LPTIM1 source is PCLK1. */ +#define STM32_LPTIM1SEL_LSI (1 << 18) /**< LPTIM1 source is LSI. */ +#define STM32_LPTIM1SEL_HSI16 (2 << 18) /**< LPTIM1 source is HSI16. */ +#define STM32_LPTIM1SEL_LSE (3 << 18) /**< LPTIM1 source is LSE. */ + +#define STM32_LPTIM2SEL_MASK (3 << 20) /**< LPTIM2SEL mask. */ +#define STM32_LPTIM2SEL_PCLK1 (0 << 20) /**< LPTIM2 source is PCLK1. */ +#define STM32_LPTIM2SEL_LSI (1 << 20) /**< LPTIM2 source is LSI. */ +#define STM32_LPTIM2SEL_HSI16 (2 << 20) /**< LPTIM2 source is HSI16. */ +#define STM32_LPTIM2SEL_LSE (3 << 20) /**< LPTIM2 source is LSE. */ + +#define STM32_LPTIM3SEL_MASK (3 << 22) /**< LPTIM3SEL mask. */ +#define STM32_LPTIM3SEL_PCLK1 (0 << 22) /**< LPTIM3 source is PCLK1. */ +#define STM32_LPTIM3SEL_LSI (1 << 22) /**< LPTIM3 source is LSI. */ +#define STM32_LPTIM3SEL_HSI16 (2 << 22) /**< LPTIM3 source is HSI16. */ +#define STM32_LPTIM3SEL_LSE (3 << 22) /**< LPTIM3 source is LSE. */ + +#define STM32_FDCANSEL_MASK (3 << 24) /**< FDCANSEL mask. */ +#define STM32_FDCANSEL_HSE (0 << 24) /**< FDCAN source is HSE. */ +#define STM32_FDCANSEL_PLL (1 << 24) /**< FDCAN source is PLL-Q. */ +#define STM32_FDCANSEL_PLLSAI1 (2 << 24) /**< FDCAN source is PLLSAI1-P. */ + +#define STM32_CLK48SEL_MASK (3 << 26) /**< CLK48SEL mask. */ +#define STM32_CLK48SEL_HSI48 (0 << 26) /**< CLK48 source is HSI48. */ +#define STM32_CLK48SEL_PLLSAI1 (1 << 26) /**< CLK48 source is PLLSAI1-Q. */ +#define STM32_CLK48SEL_PLL (2 << 26) /**< CLK48 source is PLL-Q. */ +#define STM32_CLK48SEL_MSI (3 << 26) /**< CLK48 source is MSI. */ + +#define STM32_ADCSEL_MASK (3 << 28) /**< ADCSEL mask. */ +#define STM32_ADCSEL_NOCLK (0 << 28) /**< ADC clock disabled. */ +#define STM32_ADCSEL_PLLSAI1 (1 << 28) /**< ADC source is PLLSAI1-R. */ +#define STM32_ADCSEL_SYSCLK (3 << 28) /**< ADC source is SYSCLK. */ +/** @} */ + +/** + * @name RCC_CCIPR2 register bits definitions + * @{ + */ +#define STM32_I2C4SEL_MASK (3 << 0) /**< I2C1SEL mask. */ +#define STM32_I2C4SEL_PCLK1 (0 << 0) /**< I2C1 source is PCLK1. */ +#define STM32_I2C4SEL_SYSCLK (1 << 0) /**< I2C1 source is SYSCLK. */ +#define STM32_I2C4SEL_HSI16 (2 << 0) /**< I2C1 source is HSI16. */ + +#define STM32_DFSDMSEL_MASK (1 << 2) /**< DFSDMSEL mask. */ +#define STM32_DFSDMSEL_PCLK2 (0 << 2) /**< DFSDMSEL source is PCLK2. */ +#define STM32_DFSDMSEL_SYSCLK (1 << 2) /**< DFSDMSEL source is SYSCLK. */ + +#define STM32_ADFSDMSEL_MASK (3 << 3) /**< ADFSDMSEL mask. */ +#define STM32_ADFSDMSEL_SAI1CLK (0 << 3) /**< ADFSDMSEL source is + SAI1CLK. */ +#define STM32_ADFSDMSEL_HSI16 (1 << 3) /**< ADFSDMSEL source is HSI16. */ +#define STM32_ADFSDMSEL_MSI (2 << 3) /**< ADFSDMSEL source is MSI. */ + +#define STM32_SAI1SEL_MASK (7 << 5) /**< SAI1SEL mask. */ +#define STM32_SAI1SEL_PLLSAI1 (0 << 5) /**< SAI1 source is PLLSAI1CLK. */ +#define STM32_SAI1SEL_PLLSAI2 (1 << 5) /**< SAI1 source is PLLSAI2CLK. */ +#define STM32_SAI1SEL_PLL (2 << 5) /**< SAI1 source is PLLSAI3CLK */ +#define STM32_SAI1SEL_EXTCLK (3 << 5) /**< SAI1 source is external. */ +#define STM32_SAI1SEL_HSI16 (4 << 5) /**< SAI1 source is HSI16. */ +#define STM32_SAI1SEL_OFF 0xFFFFFFFFU /**< SAI1 clock is not required.*/ + +#define STM32_SAI2SEL_MASK (7 << 8) /**< SAI2SEL mask. */ +#define STM32_SAI2SEL_PLLSAI1 (0 << 8) /**< SAI2 source is PLLSAI1CLK. */ +#define STM32_SAI2SEL_PLLSAI2 (1 << 8) /**< SAI2 source is PLLSAI2CLK. */ +#define STM32_SAI2SEL_PLL (2 << 8) /**< SAI2 source is PLLSAI3CLK */ +#define STM32_SAI2SEL_EXTCLK (3 << 8) /**< SAI2 source is external. */ +#define STM32_SAI2SEL_HSI16 (4 << 8) /**< SAI2 source is HSI16. */ +#define STM32_SAI2SEL_OFF 0xFFFFFFFFU /**< SAI2 clock is not required.*/ + +#define STM32_SDMMCSEL_MASK (1 << 14) /**< SDMMCSEL mask. */ +#define STM32_SDMMCSEL_48CLK (0 << 14) /**< SDMMCSEL source is 48CLK. */ +#define STM32_SDMMCSEL_PLL (1 << 14) /**< SDMMCSEL source is + PLLSAI3CLK. */ + +#define STM32_OSPISEL_MASK (3 << 20) /**< OSPISEL mask. */ +#define STM32_OSPISEL_SYSCLK (0 << 20) /**< OSPI source is SYSCLK. */ +#define STM32_OSPISEL_MSI (1 << 20) /**< OSPI source is MSI. */ +#define STM32_OSPISEL_48CLK (2 << 20) /**< OSPI source is 48CLK. */ +/** @} */ + +/** + * @name RCC_BDCR register bits definitions + * @{ + */ +#define STM32_RTCSEL_MASK (3 << 8) /**< RTC source mask. */ +#define STM32_RTCSEL_NOCLOCK (0 << 8) /**< No RTC source. */ +#define STM32_RTCSEL_LSE (1 << 8) /**< RTC source is LSE. */ +#define STM32_RTCSEL_LSI (2 << 8) /**< RTC source is LSI. */ +#define STM32_RTCSEL_HSEDIV (3 << 8) /**< RTC source is HSE divided. */ + +#define STM32_LSCOSEL_MASK (3 << 24) /**< LSCO pin clock source. */ +#define STM32_LSCOSEL_NOCLOCK (0 << 24) /**< No clock on LSCO pin. */ +#define STM32_LSCOSEL_LSI (1 << 24) /**< LSI on LSCO pin. */ +#define STM32_LSCOSEL_LSE (3 << 24) /**< LSE on LSCO pin. */ +/** @} */ + +/** + * @name RCC_CSR register bits definitions + * @{ + */ +#define STM32_MSISRANGE_MASK (15 << 8) /**< MSISRANGE field mask. */ +#define STM32_MSISRANGE_1M (4 << 8) /**< 1MHz nominal. */ +#define STM32_MSISRANGE_2M (5 << 8) /**< 2MHz nominal. */ +#define STM32_MSISRANGE_4M (6 << 8) /**< 4MHz nominal. */ +#define STM32_MSISRANGE_8M (7 << 8) /**< 8MHz nominal. */ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Disables the PWR/RCC initialization in the HAL. + */ +#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__) +#define STM32_NO_INIT FALSE +#endif + +/** + * @brief Core voltage selection. + * @note This setting affects all the performance and clock related + * settings, the maximum performance is only obtainable selecting + * the maximum voltage. + */ +#if !defined(STM32_VOS) || defined(__DOXYGEN__) +#define STM32_VOS STM32_VOS_RANGE1 +#endif + +/** + * @brief Enables or disables the programmable voltage detector. + */ +#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) +#define STM32_PVD_ENABLE FALSE +#endif + +/** + * @brief Sets voltage level for programmable voltage detector. + */ +#if !defined(STM32_PLS) || defined(__DOXYGEN__) +#define STM32_PLS STM32_PLS_LEV0 +#endif + +/** + * @brief Enables or disables the HSI16 clock source. + */ +#if !defined(STM32_HSI16_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI16_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the HSI48 clock source. + */ +#if !defined(STM32_HSI48_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSI48_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSI clock source. + */ +#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSI_ENABLED TRUE +#endif + +/** + * @brief Enables or disables the HSE clock source. + */ +#if !defined(STM32_HSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_HSE_ENABLED FALSE +#endif + +/** + * @brief Enables or disables the LSE clock source. + */ +#if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) +#define STM32_LSE_ENABLED FALSE +#endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * RUSEFI_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define RUSEFI_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + +/** + * @brief Enables or disables the MSI PLL on LSE clock source. + */ +#if !defined(STM32_MSIPLL_ENABLED) || defined(__DOXYGEN__) +#define STM32_MSIPLL_ENABLED FALSE +#endif + +/** + * @brief MSI frequency setting. + */ +#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__) +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#endif + +/** + * @brief MSI frequency setting after standby. + */ +#if !defined(STM32_MSISRANGE) || defined(__DOXYGEN__) +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#endif + +/** + * @brief Main clock source selection. + * @note If the selected clock source is not the PLL then the PLL is not + * initialized and started. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_SW) || defined(__DOXYGEN__) +#define STM32_SW STM32_SW_PLL +#endif + +/** + * @brief Clock source for the PLL. + * @note This setting has only effect if the PLL is selected as the + * system clock source. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__) +#define STM32_PLLSRC STM32_PLLSRC_MSI +#endif + +/** + * @brief PLLM divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLM_VALUE 1 +#endif + +/** + * @brief PLLN multiplier value. + * @note The allowed values are 8..127. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLN_VALUE 60 +#endif + +/** + * @brief PLLPDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLPDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLPDIV_VALUE 0 +#endif + +/** + * @brief PLLP divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLP_VALUE 7 +#endif + +/** + * @brief PLLQ divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLQ_VALUE 4 +#endif + +/** + * @brief PLLR divider value. + * @note The allowed values are 2, 4, 6, 8. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLR_VALUE 2 +#endif + +/** + * @brief AHB prescaler value. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_HPRE) || defined(__DOXYGEN__) +#define STM32_HPRE STM32_HPRE_DIV1 +#endif + +/** + * @brief APB1 prescaler value. + */ +#if !defined(STM32_PPRE1) || defined(__DOXYGEN__) +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#endif + +/** + * @brief APB2 prescaler value. + */ +#if !defined(STM32_PPRE2) || defined(__DOXYGEN__) +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#endif + +/** + * @brief STOPWUCK clock setting. + */ +#if !defined(STM32_STOPWUCK) || defined(__DOXYGEN__) +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#endif + +/** + * @brief MCO clock source. + */ +#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__) +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#endif + +/** + * @brief MCO divider setting. + */ +#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__) +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#endif + +/** + * @brief LSCO clock source. + */ +#if !defined(STM32_LSCOSEL) || defined(__DOXYGEN__) +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#endif + +/** + * @brief Clock source for the PLLSAL1. + */ +#if !defined(STM32_PLLSAI1SRC) || defined(__DOXYGEN__) +#define STM32_PLLSAI1SRC STM32_PLLSAI1SRC_MSI +#endif + +/** + * @brief PLLSAI1M divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSAI1M_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1M_VALUE 1 +#endif + +/** + * @brief PLLSAI1N multiplier value. + * @note The allowed values are 8..127. + */ +#if !defined(STM32_PLLSAI1N_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1N_VALUE 72 +#endif + +/** + * @brief PLLSAI1PDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLSAI1PDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1PDIV_VALUE 6 +#endif + +/** + * @brief PLLSAI1P divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLSAI1P_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1P_VALUE 7 +#endif + +/** + * @brief PLLSAI1Q divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI1Q_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1Q_VALUE 6 +#endif + +/** + * @brief PLLSAI1R divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI1R_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1R_VALUE 6 +#endif + +/** + * @brief Clock source for the PLLSAL2. + */ +#if !defined(STM32_PLLSAI2SRC) || defined(__DOXYGEN__) +#define STM32_PLLSAI2SRC STM32_PLLSAI2SRC_MSI +#endif + +/** + * @brief PLLSAI2M divider value. + * @note The allowed values are 1..16. + * @note The default value is calculated for a 120MHz system clock from + * the internal 4MHz MSI clock. + */ +#if !defined(STM32_PLLSAI2M_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2M_VALUE 1 +#endif + +/** + * @brief PLLSAI2N multiplier value. + * @note The allowed values are 8..127. + */ +#if !defined(STM32_PLLSAI2N_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2N_VALUE 72 +#endif + +/** + * @brief PLLSAI2PDIV divider value or zero if disabled. + * @note The allowed values are 0, 2..31. + */ +#if !defined(STM32_PLLSAI2PDIV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2PDIV_VALUE 6 +#endif + +/** + * @brief PLLSAI2P divider value. + * @note The allowed values are 7, 17. + */ +#if !defined(STM32_PLLSAI2P_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2P_VALUE 7 +#endif + +/** + * @brief PLLSAI2Q divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI2Q_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2Q_VALUE 6 +#endif + +/** + * @brief PLLSAI2R divider value. + * @note The allowed values are 2, 4, 6, 8. + */ +#if !defined(STM32_PLLSAI2R_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2R_VALUE 6 +#endif + +/** + * @brief PLLSAI2DIVR value. + */ +#if !defined(STM32_PLLSAI2DIVR) || defined(__DOXYGEN__) +#define STM32_PLLSAI2DIVR STM32_PLLSAI2DIVR_DIV16 +#endif + +/** + * @brief USART1 clock source. + */ +#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__) +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#endif + +/** + * @brief USART2 clock source. + */ +#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__) +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#endif + +/** + * @brief USART3 clock source. + */ +#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__) +#define STM32_USART3SEL STM32_USART3SEL_SYSCLK +#endif + +/** + * @brief UART4 clock source. + */ +#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__) +#define STM32_UART4SEL STM32_UART4SEL_SYSCLK +#endif + +/** + * @brief UART5 clock source. + */ +#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__) +#define STM32_UART5SEL STM32_UART5SEL_SYSCLK +#endif + +/** + * @brief LPUART1 clock source. + */ +#if !defined(STM32_LPUART1SEL) || defined(__DOXYGEN__) +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#endif + +/** + * @brief I2C1 clock source. + */ +#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__) +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#endif + +/** + * @brief I2C2 clock source. + */ +#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__) +#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK +#endif + +/** + * @brief I2C3 clock source. + */ +#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__) +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#endif + +/** + * @brief I2C4 clock source. + */ +#if !defined(STM32_I2C4SEL) || defined(__DOXYGEN__) +#define STM32_I2C4SEL STM32_I2C4SEL_SYSCLK +#endif + +/** + * @brief LPTIM1 clock source. + */ +#if !defined(STM32_LPTIM1SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#endif + +/** + * @brief LPTIM2 clock source. + */ +#if !defined(STM32_LPTIM2SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#endif + +/** + * @brief LPTIM3 clock source. + */ +#if !defined(STM32_LPTIM3SEL) || defined(__DOXYGEN__) +#define STM32_LPTIM3SEL STM32_LPTIM3SEL_PCLK1 +#endif + +/** + * @brief FDCAN value (48MHz clock source). + */ +#if !defined(STM32_FDCANSEL) || defined(__DOXYGEN__) +#define STM32_FDCANSEL STM32_FDCANSEL_PLL +#endif + +/** + * @brief CLK48SEL value (48MHz clock source). + */ +#if !defined(STM32_CLK48SEL) || defined(__DOXYGEN__) +#define STM32_CLK48SEL STM32_CLK48SEL_PLL +#endif + +/** + * @brief ADCSEL value (ADCs clock source). + */ +#if !defined(STM32_ADCSEL) || defined(__DOXYGEN__) +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#endif + +/** + * @brief DFSDMSEL value (DFSDM clock source). + */ +#if !defined(STM32_DFSDMSEL) || defined(__DOXYGEN__) +#define STM32_DFSDMSEL STM32_DFSDMSEL_PCLK2 +#endif + +/** + * @brief ADFSDMSEL value (DFSDM clock source). + */ +#if !defined(STM32_ADFSDMSEL) || defined(__DOXYGEN__) +#define STM32_ADFSDMSEL STM32_ADFSDMSEL_SAI1CLK +#endif + +/** + * @brief SAI1SEL value (SAI1 clock source). + */ +#if !defined(STM32_SAI1SEL) || defined(__DOXYGEN__) +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#endif + +/** + * @brief SAI2SEL value (SAI2 clock source). + */ +#if !defined(STM32_SAI2SEL) || defined(__DOXYGEN__) +#define STM32_SAI2SEL STM32_SAI2SEL_OFF +#endif + +/** + * @brief SDMMC value (SDMMC clock source). + */ +#if !defined(STM32_SDMMCSEL) || defined(__DOXYGEN__) +#define STM32_SDMMCSEL STM32_SDMMCSEL_48CLK +#endif + +/** + * @brief OSPISEL value (OSPISEL clock source). + */ +#if !defined(STM32_OSPISEL) || defined(__DOXYGEN__) +#define STM32_OSPISEL STM32_OSPISEL_SYSCLK +#endif + +/** + * @brief RTC/LCD clock source. + */ +#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__) +#define STM32_RTCSEL STM32_RTCSEL_LSI +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* + * Configuration-related checks. + */ +#if !defined(STM32L5xx_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L5xx_MCUCONF not defined" +#endif + +#if defined(STM32L5YYxx) && !defined(STM32L5YY_MCUCONF) +#error "Using a wrong mcuconf.h file, STM32L5YY_MCUCONF not defined" + +#endif + +/* + * Board files sanity checks. + */ +#if !defined(STM32_LSECLK) +#error "STM32_LSECLK not defined in board.h" +#endif + +#if !defined(STM32_LSEDRV) +#error "STM32_LSEDRV not defined in board.h" +#endif + +#if !defined(STM32_HSECLK) +#error "STM32_HSECLK not defined in board.h" +#endif + +/* Voltage related limits.*/ +#if (STM32_VOS == STM32_VOS_RANGE0) || defined(__DOXYGEN__) +/** + * @name System Limits + * @{ + */ +/** + * @brief Maximum SYSCLK clock frequency. + */ +#define STM32_SYSCLK_MAX 110000000 + +/** + * @brief Maximum HSE clock frequency at current voltage setting. + */ +#define STM32_HSECLK_MAX 48000000 + +/** + * @brief Maximum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MAX 48000000 + +/** + * @brief Minimum HSE clock frequency. + */ +#define STM32_HSECLK_MIN 4000000 + +/** + * @brief Minimum HSE clock frequency using an external source. + */ +#define STM32_HSECLK_BYP_MIN 8000000 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_MAX 32768 + +/** + * @brief Maximum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MAX 1000000 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_MIN 32768 + +/** + * @brief Minimum LSE clock frequency. + */ +#define STM32_LSECLK_BYP_MIN 32768 + +/** + * @brief Maximum PLLs input clock frequency. + */ +#define STM32_PLLIN_MAX 16000000 + +/** + * @brief Minimum PLLs input clock frequency. + */ +#define STM32_PLLIN_MIN 2660000 + +/** + * @brief Maximum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MAX 344000000 + +/** + * @brief Minimum VCO clock frequency at current voltage setting. + */ +#define STM32_PLLVCO_MIN 64000000 + +/** + * @brief Maximum PLL-P output clock frequency. + */ +#define STM32_PLLP_MAX 110000000 + +/** + * @brief Minimum PLL-P output clock frequency. + */ +#define STM32_PLLP_MIN 2064500 + +/** + * @brief Maximum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MAX 110000000 + +/** + * @brief Minimum PLL-Q output clock frequency. + */ +#define STM32_PLLQ_MIN 8000000 + +/** + * @brief Maximum PLL-R output clock frequency. + */ +#define STM32_PLLR_MAX 110000000 + +/** + * @brief Minimum PLL-R output clock frequency. + */ +#define STM32_PLLR_MIN 8000000 + +/** + * @brief Maximum APB1 clock frequency. + */ +#define STM32_PCLK1_MAX 110000000 + +/** + * @brief Maximum APB2 clock frequency. + */ +#define STM32_PCLK2_MAX 110000000 + +/** + * @brief Maximum ADC clock frequency. + */ +#define STM32_ADCCLK_MAX 80000000 +/** @} */ + +/** + * @name Flash Wait states + * @{ + */ +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 100000000 +#define STM32_5WS_THRESHOLD 110000000 +/** @} */ + +#elif STM32_VOS == STM32_VOS_RANGE1 +#define STM32_SYSCLK_MAX 80000000 +#define STM32_HSECLK_MAX 48000000 +#define STM32_HSECLK_BYP_MAX 48000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 8000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_LSECLK_BYP_MIN 32768 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLIN_MIN 2660000 +#define STM32_PLLVCO_MAX 344000000 +#define STM32_PLLVCO_MIN 64000000 +#define STM32_PLLP_MAX 110000000 +#define STM32_PLLP_MIN 2064500 +#define STM32_PLLQ_MAX 110000000 +#define STM32_PLLQ_MIN 8000000 +#define STM32_PLLR_MAX 110000000 +#define STM32_PLLR_MIN 8000000 +#define STM32_PCLK1_MAX 80000000 +#define STM32_PCLK2_MAX 80000000 +#define STM32_ADCCLK_MAX 80000000 + +#define STM32_0WS_THRESHOLD 20000000 +#define STM32_1WS_THRESHOLD 40000000 +#define STM32_2WS_THRESHOLD 60000000 +#define STM32_3WS_THRESHOLD 80000000 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 + +#elif STM32_VOS == STM32_VOS_RANGE2 +#define STM32_SYSCLK_MAX 26000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 26000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 8000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_LSECLK_BYP_MIN 32768 +#define STM32_PLLIN_MAX 16000000 +#define STM32_PLLIN_MIN 2660000 +#define STM32_PLLVCO_MAX 128000000 +#define STM32_PLLVCO_MIN 64000000 +#define STM32_PLLP_MAX 26000000 +#define STM32_PLLP_MIN 2064500 +#define STM32_PLLQ_MAX 26000000 +#define STM32_PLLQ_MIN 8000000 +#define STM32_PLLR_MAX 26000000 +#define STM32_PLLR_MIN 8000000 +#define STM32_PCLK1_MAX 26000000 +#define STM32_PCLK2_MAX 26000000 +#define STM32_ADCCLK_MAX 26000000 + +#define STM32_0WS_THRESHOLD 8000000 +#define STM32_1WS_THRESHOLD 16000000 +#define STM32_2WS_THRESHOLD 26000000 +#define STM32_3WS_THRESHOLD 0 +#define STM32_4WS_THRESHOLD 0 +#define STM32_5WS_THRESHOLD 0 + +#else + #error "invalid STM32_VOS value specified" +#endif + +/** + * @brief MSI frequency. + */ +#if STM32_MSIRANGE == STM32_MSIRANGE_100K + #define STM32_MSICLK 100000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_200K + #define STM32_MSICLK 200000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_400K + #define STM32_MSICLK 400000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_800K + #define STM32_MSICLK 800000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_1M + #define STM32_MSICLK 1000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_2M + #define STM32_MSICLK 2000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_4M + #define STM32_MSICLK 4000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_8M + #define STM32_MSICLK 8000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_16M + #define STM32_MSICLK 16000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_24M + #define STM32_MSICLK 24000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_32M + #define STM32_MSICLK 32000000 +#elif STM32_MSIRANGE == STM32_MSIRANGE_48M + #define STM32_MSICLK 48000000 +#else + #error "invalid STM32_MSIRANGE value specified" +#endif + +/** + * @brief MSIS frequency. + */ +#if STM32_MSISRANGE == STM32_MSISRANGE_1M + #define STM32_MSISCLK 1000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_2M + #define STM32_MSISCLK 2000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_4M + #define STM32_MSISCLK 4000000 +#elif STM32_MSISRANGE == STM32_MSISRANGE_8M + #define STM32_MSISCLK 8000000 +#else + #error "invalid STM32_MSISRANGE value specified" +#endif + +/* + * HSI16 related checks. + */ +#if STM32_HSI16_ENABLED +#else /* !STM32_HSI16_ENABLED */ + + #if STM32_SW == STM32_SW_HSI16 + #error "HSI16 not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSI16) + #error "HSI16 not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + /* MCO-related checks.*/ + #if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16)) + #error "HSI16 not enabled, required by STM32_MCOSEL" + #endif + + /* SAI1-related checks.*/ + #if STM32_SAI1SEL == STM32_SAI1SEL_HSI16 + #error "HSI16 not enabled, required by STM32_SAI1SEL" + #endif + + #if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16) + #error "HSI16 not enabled, required by STM32_SAI1SEL" + #endif + + #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) && \ + (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSI16) + #error "HSI16 not enabled, required by STM32_PLLSAI1SRC" + #endif + + #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) && \ + (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSI16) + #error "HSI16 not enabled, required by STM32_PLLSAI2SRC" + #endif + + /* SAI2-related checks.*/ + #if STM32_SAI2SEL == STM32_SAI12SEL_HSI16 + #error "HSI16 not enabled, required by STM32_SAI2SEL" + #endif + + #if (STM32_SAI2SEL == STM32_SAI2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSI16) + #error "HSI16 not enabled, required by STM32_SAI2SEL" + #endif + + #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) && \ + (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSI16) + #error "HSI16 not enabled, required by STM32_PLLSAI1SRC" + #endif + + #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) && \ + (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSI16) + #error "HSI16 not enabled, required by STM32_PLLSAI2SRC" + #endif + + /* USART/UART-related checks.*/ + #if (STM32_USART1SEL == STM32_USART1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_USART1SEL" + #endif + #if (STM32_USART2SEL == STM32_USART2SEL_HSI16) + #error "HSI16 not enabled, required by STM32_USART2SEL" + #endif + #if (STM32_USART3SEL == STM32_USART3SEL_HSI16) + #error "HSI16 not enabled, required by STM32_USART3SEL" + #endif + #if (STM32_UART4SEL == STM32_UART4SEL_HSI16) + #error "HSI16 not enabled, required by STM32_UART4SEL" + #endif + #if (STM32_UART5SEL == STM32_UART5SEL_HSI16) + #error "HSI16 not enabled, required by STM32_UART5SEL" + #endif + #if (STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16) + #error "HSI16 not enabled, required by STM32_LPUART1SEL" + #endif + + /* I2C-related checks.*/ + #if (STM32_I2C1SEL == STM32_I2C1SEL_HSI16) + #error "HSI16 not enabled, required by I2C1SEL" + #endif + #if (STM32_I2C2SEL == STM32_I2C2SEL_HSI16) + #error "HSI16 not enabled, required by I2C2SEL" + #endif + #if (STM32_I2C3SEL == STM32_I2C3SEL_HSI16) + #error "HSI16 not enabled, required by I2C3SEL" + #endif + #if (STM32_I2C4SEL == STM32_I2C4SEL_HSI16) + #error "HSI16 not enabled, required by I2C4SEL" + #endif + + /* LPTIM-related checks.*/ + #if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16) + #error "HSI16 not enabled, required by LPTIM1SEL" + #endif + #if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16) + #error "HSI16 not enabled, required by LPTIM2SEL" + #endif + + #if (STM32_STOPWUCK == STM32_STOPWUCK_HSI16) + #error "HSI16 not enabled, required by STM32_STOPWUCK" + #endif + +#endif /* !STM32_HSI16_ENABLED */ + +#if STM32_HSI48_ENABLED +#else /* !STM32_HSI48_ENABLED */ + + #if STM32_MCOSEL == STM32_MCOSEL_HSI48 + #error "HSI48 not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_CLK48SEL == STM32_CLK48SEL_HSI48 + #error "HSI48 not enabled, required by STM32_CLK48SEL" + #endif + +#endif /* !STM32_HSI48_ENABLED */ + +/* + * HSE related checks. + */ +#if STM32_HSE_ENABLED + + #if STM32_HSECLK == 0 + #error "HSE frequency not defined" + #else /* STM32_HSECLK != 0 */ + #if defined(STM32_HSE_BYPASS) + #if (STM32_HSECLK < STM32_HSECLK_BYP_MIN) || (STM32_HSECLK > STM32_HSECLK_BYP_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_BYP_MIN...STM32_HSECLK_BYP_MAX)" + #endif + #else /* !defined(STM32_HSE_BYPASS) */ + #if (STM32_HSECLK < STM32_HSECLK_MIN) || (STM32_HSECLK > STM32_HSECLK_MAX) + #error "STM32_HSECLK outside acceptable range (STM32_HSECLK_MIN...STM32_HSECLK_MAX)" + #endif + #endif /* !defined(STM32_HSE_BYPASS) */ + #endif /* STM32_HSECLK != 0 */ + +#else /* !STM32_HSE_ENABLED */ + + #if STM32_SW == STM32_SW_HSE + #error "HSE not enabled, required by STM32_SW" + #endif + + #if (STM32_SW == STM32_SW_PLL) && (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SW and STM32_PLLSRC" + #endif + + /* MCO-related checks.*/ + #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ + ((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE)) + #error "HSE not enabled, required by STM32_MCOSEL" + #endif + + /* SAI1-related checks.*/ + #if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SAI1SEL" + #endif + + #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) && \ + (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSE) + #error "HSE not enabled, required by STM32_PLLSAI1SRC" + #endif + + #if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) && \ + (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSE) + #error "HSE not enabled, required by STM32_PLLSAI2SRC" + #endif + + /* SAI2-related checks.*/ + #if (STM32_SAI2SEL == STM32_SAI2SEL_PLL) && \ + (STM32_PLLSRC == STM32_PLLSRC_HSE) + #error "HSE not enabled, required by STM32_SAI2SEL" + #endif + + #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) && \ + (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSE) + #error "HSE not enabled, required by STM32_PLLSAI1SRC" + #endif + + #if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) && \ + (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSE) + #error "HSE not enabled, required by STM32_PLLSAI2SRC" + #endif + + /* RTC-related checks.*/ + #if STM32_RTCSEL == STM32_RTCSEL_HSEDIV + #error "HSE not enabled, required by STM32_RTCSEL" + #endif + +#endif /* !STM32_HSE_ENABLED */ + +/* + * LSI related checks. + */ +#if STM32_LSI_ENABLED +#else /* !STM32_LSI_ENABLED */ + + #if STM32_RTCSEL == STM32_RTCSEL_LSI + #error "LSI not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSI + #error "LSI not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSI + #error "LSI not enabled, required by STM32_LSCOSEL" + #endif + +#endif /* !STM32_LSI_ENABLED */ + +/* + * LSE related checks. + */ +#if STM32_LSE_ENABLED + + #if (STM32_LSECLK == 0) + #error "LSE frequency not defined" + #endif + + #if (STM32_LSECLK < STM32_LSECLK_MIN) || (STM32_LSECLK > STM32_LSECLK_MAX) + #error "STM32_LSECLK outside acceptable range (STM32_LSECLK_MIN...STM32_LSECLK_MAX)" + #endif + +#else /* !STM32_LSE_ENABLED */ + + #if STM32_RTCSEL == STM32_RTCSEL_LSE + #error "LSE not enabled, required by STM32_RTCSEL" + #endif + + #if STM32_MCOSEL == STM32_MCOSEL_LSE + #error "LSE not enabled, required by STM32_MCOSEL" + #endif + + #if STM32_LSCOSEL == STM32_LSCOSEL_LSE + #error "LSE not enabled, required by STM32_LSCOSEL" + #endif + + #if STM32_MSIPLL_ENABLED == TRUE + #error "LSE not enabled, required by STM32_MSIPLL_ENABLED" + #endif + +#endif /* !STM32_LSE_ENABLED */ + +/* + * MSI related checks. + */ +#if (STM32_MSIRANGE == STM32_MSIRANGE_48M) && !STM32_MSIPLL_ENABLED + #warning "STM32_MSIRANGE_48M should be used with STM32_MSIPLL_ENABLED" +#endif + +/** + * @brief STM32_PLLM field. + */ +#if ((STM32_PLLM_VALUE >= 1) && (STM32_PLLM_VALUE <= 16)) || \ + defined(__DOXYGEN__) + #define STM32_PLLM ((STM32_PLLM_VALUE - 1) << 4) +#else + #error "invalid STM32_PLLM_VALUE value specified" +#endif + +/** + * @brief PLL input clock frequency. + */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) + #define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_MSI + #define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_HSI16 + #define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) + +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK + #define STM32_PLLCLKIN 0 + +#else + #error "invalid STM32_PLLSRC value specified" +#endif + +/* + * PLL input frequency range check. + */ +#if (STM32_PLLCLKIN != 0) && \ + ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) + #error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLL enable check. + */ +#if (STM32_HSI48_ENABLED && (STM32_CLK48SEL == STM32_CLK48SEL_PLL)) || \ + (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ + defined(__DOXYGEN__) + + #if STM32_PLLCLKIN == 0 + #error "PLL activation required but no PLL clock selected" + #endif + +/** + * @brief PLL activation flag. + */ + #define STM32_ACTIVATE_PLL TRUE +#else + #define STM32_ACTIVATE_PLL FALSE +#endif + +/** + * @brief STM32_PLLN field. + */ +#if ((STM32_PLLN_VALUE >= 8) && (STM32_PLLN_VALUE <= 127)) || \ + defined(__DOXYGEN__) +#define STM32_PLLN (STM32_PLLN_VALUE << 8) +#else +#error "invalid STM32_PLLN_VALUE value specified" +#endif + +/** + * @brief STM32_PLLP field. + */ +#if (STM32_PLLP_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLP (0 << 17) + +#elif STM32_PLLP_VALUE == 17 +#define STM32_PLLP (1 << 17) + +#else +#error "invalid STM32_PLLP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLQ field. + */ +#if (STM32_PLLQ_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLQ (0 << 21) + +#elif STM32_PLLQ_VALUE == 4 +#define STM32_PLLQ (1 << 21) + +#elif STM32_PLLQ_VALUE == 6 +#define STM32_PLLQ (2 << 21) + +#elif STM32_PLLQ_VALUE == 8 +#define STM32_PLLQ (3 << 21) + +#else +#error "invalid STM32_PLLQ_VALUE value specified" +#endif + +/** + * @brief STM32_PLLR field. + */ +#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLR (0 << 25) + +#elif STM32_PLLR_VALUE == 4 +#define STM32_PLLR (1 << 25) + +#elif STM32_PLLR_VALUE == 6 +#define STM32_PLLR (2 << 25) + +#elif STM32_PLLR_VALUE == 8 +#define STM32_PLLR (3 << 25) + +#else +#error "invalid STM32_PLLR_VALUE value specified" +#endif + +/** + * @brief STM32_PLLPDIV field. + */ +#if (STM32_PLLPDIV_VALUE == 0) || \ + ((STM32_PLLPDIV_VALUE != 1) && (STM32_PLLPDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLPDIV (STM32_PLLPDIV_VALUE << 27) +#else +#error "invalid STM32_PLLPDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLPEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ + defined(__DOXYGEN__) +#define STM32_PLLPEN (1 << 16) +#else +#define STM32_PLLPEN (0 << 16) +#endif + +/** + * @brief STM32_PLLQEN field. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__) +#define STM32_PLLQEN (1 << 20) +#else +#define STM32_PLLQEN (0 << 20) +#endif + +/** + * @brief STM32_PLLREN field. + */ +#if (STM32_SW == STM32_SW_PLL) || \ + (STM32_MCOSEL == STM32_MCOSEL_PLL) || \ + defined(__DOXYGEN__) +#define STM32_PLLREN (1 << 24) +#else +#define STM32_PLLREN (0 << 24) +#endif + +/** + * @brief PLL VCO frequency. + */ +#define STM32_PLLVCO (STM32_PLLCLKIN * STM32_PLLN_VALUE) + +/* + * PLL VCO frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLL P output clock frequency. + */ +#if (STM32_PLLPDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLP_VALUE) +#else +#define STM32_PLL_P_CLKOUT (STM32_PLLVCO / STM32_PLLPDIV_VALUE) +#endif + +/** + * @brief PLL Q output clock frequency. + */ +#define STM32_PLL_Q_CLKOUT (STM32_PLLVCO / STM32_PLLQ_VALUE) + +/** + * @brief PLL R output clock frequency. + */ +#define STM32_PLL_R_CLKOUT (STM32_PLLVCO / STM32_PLLR_VALUE) + +/* + * PLL-P output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLL-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLL-R output frequency range check. + */ +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief System clock source. + */ +#if STM32_NO_INIT || defined(__DOXYGEN__) +#define STM32_SYSCLK STM32_MSICLK + +#elif (STM32_SW == STM32_SW_MSI) +#define STM32_SYSCLK STM32_MSICLK + +#elif (STM32_SW == STM32_SW_HSI16) +#define STM32_SYSCLK STM32_HSI16CLK + +#elif (STM32_SW == STM32_SW_HSE) +#define STM32_SYSCLK STM32_HSECLK + +#elif (STM32_SW == STM32_SW_PLL) +#define STM32_SYSCLK STM32_PLL_R_CLKOUT + +#else +#error "invalid STM32_SW value specified" +#endif + +/* Check on the system clock.*/ +#if STM32_SYSCLK > STM32_SYSCLK_MAX +#error "STM32_SYSCLK above maximum rated frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief AHB frequency. + */ +#if (STM32_HPRE == STM32_HPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_HCLK (STM32_SYSCLK / 1) + +#elif STM32_HPRE == STM32_HPRE_DIV2 +#define STM32_HCLK (STM32_SYSCLK / 2) + +#elif STM32_HPRE == STM32_HPRE_DIV4 +#define STM32_HCLK (STM32_SYSCLK / 4) + +#elif STM32_HPRE == STM32_HPRE_DIV8 +#define STM32_HCLK (STM32_SYSCLK / 8) + +#elif STM32_HPRE == STM32_HPRE_DIV16 +#define STM32_HCLK (STM32_SYSCLK / 16) + +#elif STM32_HPRE == STM32_HPRE_DIV64 +#define STM32_HCLK (STM32_SYSCLK / 64) + +#elif STM32_HPRE == STM32_HPRE_DIV128 +#define STM32_HCLK (STM32_SYSCLK / 128) + +#elif STM32_HPRE == STM32_HPRE_DIV256 +#define STM32_HCLK (STM32_SYSCLK / 256) + +#elif STM32_HPRE == STM32_HPRE_DIV512 +#define STM32_HCLK (STM32_SYSCLK / 512) + +#else +#error "invalid STM32_HPRE value specified" +#endif + +/* + * AHB frequency check. + */ +#if STM32_HCLK > STM32_SYSCLK_MAX +#error "STM32_HCLK exceeding maximum frequency (STM32_SYSCLK_MAX)" +#endif + +/** + * @brief APB1 frequency. + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK1 (STM32_HCLK / 1) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV2 +#define STM32_PCLK1 (STM32_HCLK / 2) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV4 +#define STM32_PCLK1 (STM32_HCLK / 4) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV8 +#define STM32_PCLK1 (STM32_HCLK / 8) + +#elif STM32_PPRE1 == STM32_PPRE1_DIV16 +#define STM32_PCLK1 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE1 value specified" +#endif + +/* + * APB1 frequency check. + */ +#if STM32_PCLK1 > STM32_PCLK1_MAX +#error "STM32_PCLK1 exceeding maximum frequency (STM32_PCLK1_MAX)" +#endif + +/** + * @brief APB2 frequency. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_PCLK2 (STM32_HCLK / 1) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV2 +#define STM32_PCLK2 (STM32_HCLK / 2) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV4 +#define STM32_PCLK2 (STM32_HCLK / 4) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV8 +#define STM32_PCLK2 (STM32_HCLK / 8) + +#elif STM32_PPRE2 == STM32_PPRE2_DIV16 +#define STM32_PCLK2 (STM32_HCLK / 16) + +#else +#error "invalid STM32_PPRE2 value specified" +#endif + +/* + * APB2 frequency check. + */ +#if STM32_PCLK2 > STM32_PCLK2_MAX +#error "STM32_PCLK2 exceeding maximum frequency (STM32_PCLK2_MAX)" +#endif + +/** + * @brief STM32_PLLSAI1M field. + */ +#if ((STM32_PLLSAI1M_VALUE >= 1) && (STM32_PLLSAI1M_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1M ((STM32_PLLSAI1M_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLSAI1M_VALUE value specified" +#endif + +/** + * @brief PLLSAI1 input clock frequency. + */ +#if (STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSAI1CLKIN (STM32_HSECLK / STM32_PLLSAI1M_VALUE) + +#elif STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_MSI +#define STM32_PLLSAI1CLKIN (STM32_MSICLK / STM32_PLLSAI1M_VALUE) + +#elif STM32_PLLSAI1SRC == STM32_PLLSAI1SRC_HSI16 +#define STM32_PLLSAI1CLKIN (STM32_HSI16CLK / STM32_PLLSAI1M_VALUE) + +#elif STM32_PLLSSAI1RC == STM32_PLLSAI1SRC_NOCLOCK +#define STM32_PLLSAI1CLKIN 0 + +#else +#error "invalid STM32_PLLSAI1SRC value specified" +#endif + +/* + * PLLSAI1 input frequency range check. + */ +#if (STM32_PLLSAI1CLKIN != 0) && \ + ((STM32_PLLSAI1CLKIN < STM32_PLLIN_MIN) || \ + (STM32_PLLSAI1CLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLSAI1CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLLSAI1 enable check. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ + (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ + defined(__DOXYGEN__) + +#if STM32_PLLSAI1CLKIN == 0 +#error "PLLSAI1 activation required but no PLL clock selected" +#endif + +/** + * @brief PLLSAI1 activation flag. + */ +#define STM32_ACTIVATE_PLLSAI1 TRUE +#else +#define STM32_ACTIVATE_PLLSAI1 FALSE +#endif + +/** + * @brief STM32_PLLSAI1N field. + */ +#if ((STM32_PLLSAI1N_VALUE >= 8) && (STM32_PLLSAI1N_VALUE <= 127)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1N (STM32_PLLSAI1N_VALUE << 8) +#else +#error "invalid STM32_PLLSAI1N_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1P field. + */ +#if (STM32_PLLSAI1P_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLSAI1P (0 << 17) + +#elif STM32_PLLSAI1P_VALUE == 17 +#define STM32_PLLSAI1P (1 << 17) + +#else +#error "invalid STM32_PLLSAI1P_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1Q field. + */ +#if (STM32_PLLSAI1Q_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI1Q (0 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 4 +#define STM32_PLLSAI1Q (1 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 6 +#define STM32_PLLSAI1Q (2 << 21) + +#elif STM32_PLLSAI1Q_VALUE == 8 +#define STM32_PLLSAI1Q (3 << 21) + +#else +#error "invalid STM32_PLLSAI1Q_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1R field. + */ +#if (STM32_PLLSAI1R_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI1R (0 << 25) + +#elif STM32_PLLSAI1R_VALUE == 4 +#define STM32_PLLSAI1R (1 << 25) + +#elif STM32_PLLSAI1R_VALUE == 6 +#define STM32_PLLSAI1R (2 << 25) + +#elif STM32_PLLSAI1R_VALUE == 8 +#define STM32_PLLSAI1R (3 << 25) + +#else +#error "invalid STM32_PLLSAI1R_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1PDIV field. + */ +#if ((STM32_PLLSAI1PDIV_VALUE != 1) && (STM32_PLLSAI1PDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1PDIV (STM32_PLLSAI1PDIV_VALUE << 27) +#else +#error "invalid STM32_PLLSAI1PDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI1PEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI1PEN (1 << 16) +#else +#define STM32_PLLSAI1PEN (0 << 16) +#endif + +/** + * @brief STM32_PLLSAI1QEN field. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_PLLSAI1QEN (1 << 20) +#else +#define STM32_PLLSAI1QEN (0 << 20) +#endif + +/** + * @brief STM32_PLLSAI1REN field. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_PLLSAI1REN (1 << 24) +#else +#define STM32_PLLSAI1REN (0 << 24) +#endif + +/** + * @brief PLLSAI1 VCO frequency. + */ +#define STM32_PLLSAI1VCO (STM32_PLLSAI1CLKIN * STM32_PLLSAI1N_VALUE) + +/* + * PLLSAI1 VCO frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI1-P output clock frequency. + */ +#if (STM32_PLLSAI1PDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE) +#else +#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1PDIV_VALUE) +#endif + +/** + * @brief PLLSAI1-Q output clock frequency. + */ +#define STM32_PLLSAI1_Q_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) + +/** + * @brief PLLSAI1-R output clock frequency. + */ +#define STM32_PLLSAI1_R_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1R_VALUE) + +/* + * PLLSAI1-P output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLLSAI1-Q output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) +#error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" +#endif + +/* + * PLLSAI1-R output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief STM32_PLLSAI2M field. + */ +#if ((STM32_PLLSAI2M_VALUE >= 1) && (STM32_PLLSAI2M_VALUE <= 16)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2M ((STM32_PLLSAI2M_VALUE - 1) << 4) +#else +#error "invalid STM32_PLLSAI2M_VALUE value specified" +#endif + +/** + * @brief PLLSAI2 input clock frequency. + */ +#if (STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLSAI2CLKIN (STM32_HSECLK / STM32_PLLSAI2M_VALUE) + +#elif STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_MSI +#define STM32_PLLSAI2CLKIN (STM32_MSICLK / STM32_PLLSAI2M_VALUE) + +#elif STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_HSI16 +#define STM32_PLLSAI2CLKIN (STM32_HSI16CLK / STM32_PLLSAI2M_VALUE) + +#elif STM32_PLLSAI2SRC == STM32_PLLSAI2SRC_NOCLOCK +#define STM32_PLLSAI2CLKIN 0 + +#else +#error "invalid STM32_PLLSAI2SRC value specified" +#endif + +/* + * PLLSAI2 input frequency range check. + */ +#if (STM32_PLLSAI2CLKIN != 0) && \ + ((STM32_PLLSAI2CLKIN < STM32_PLLIN_MIN) || \ + (STM32_PLLSAI2CLKIN > STM32_PLLIN_MAX)) +#error "STM32_PLLSAI2CLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" +#endif + +/* + * PLLSAI2 enable check. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ + (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ + defined(__DOXYGEN__) + +#if STM32_PLLSAI2CLKIN == 0 +#error "PLLSAI2 activation required but no PLL clock selected" +#endif + +/** + * @brief PLLSAI2 activation flag. + */ +#define STM32_ACTIVATE_PLLSAI2 TRUE +#else +#define STM32_ACTIVATE_PLLSAI2 FALSE +#endif + +/** + * @brief STM32_PLLSAI2N field. + */ +#if ((STM32_PLLSAI2N_VALUE >= 8) && (STM32_PLLSAI2N_VALUE <= 127)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2N (STM32_PLLSAI2N_VALUE << 8) +#else +#error "invalid STM32_PLLSAI2N_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2P field. + */ +#if (STM32_PLLSAI2P_VALUE == 7) || defined(__DOXYGEN__) +#define STM32_PLLSAI2P (0 << 17) + +#elif STM32_PLLSAI2P_VALUE == 17 +#define STM32_PLLSAI2P (1 << 17) + +#else +#error "invalid STM32_PLLSAI2P_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2R field. + */ +#if (STM32_PLLSAI2R_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLSAI2R (0 << 25) + +#elif STM32_PLLSAI2R_VALUE == 4 +#define STM32_PLLSAI2R (1 << 25) + +#elif STM32_PLLSAI2R_VALUE == 6 +#define STM32_PLLSAI2R (2 << 25) + +#elif STM32_PLLSAI2R_VALUE == 8 +#define STM32_PLLSAI2R (3 << 25) + +#else +#error "invalid STM32_PLLSAI2R_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2PDIV field. + */ +#if ((STM32_PLLSAI2PDIV_VALUE != 1) && (STM32_PLLSAI2PDIV_VALUE <= 31)) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2PDIV (STM32_PLLSAI2PDIV_VALUE << 27) +#else +#error "invalid STM32_PLLSAI2PDIV_VALUE value specified" +#endif + +/** + * @brief STM32_PLLSAI2PEN field. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2) || \ + (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ + defined(__DOXYGEN__) +#define STM32_PLLSAI2PEN (1 << 16) +#else +#define STM32_PLLSAI2PEN (0 << 16) +#endif + +/** + * @brief STM32_PLLSAI2REN field. + * @note Always enabled. + * @note It should depend on some condition. + */ +#define STM32_PLLSAI2REN (1 << 24) + +/** + * @brief PLLSAI2 VCO frequency. + */ +#define STM32_PLLSAI2VCO (STM32_PLLSAI2CLKIN * STM32_PLLSAI2N_VALUE) + +/* + * PLLSAI2 VCO frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#endif + +/** + * @brief PLLSAI2-P output clock frequency. + */ +#if (STM32_PLLSAI2PDIV_VALUE == 0) || defined(__DOXYGEN__) +#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE) +#else +#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2PDIV_VALUE) +#endif + +/** + * @brief PLLSAI2-R output clock frequency. + */ +#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE) + +/* + * PLLSAI2-P output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) +#error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" +#endif + +/* + * PLLSAI2-R output frequency range check. + */ +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) +#error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" +#endif + +/** + * @brief MCO divider clock frequency. + */ +#if (STM32_MCOSEL == STM32_MCOSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_MCODIVCLK 0 + +#elif STM32_MCOSEL == STM32_MCOSEL_SYSCLK +#define STM32_MCODIVCLK STM32_SYSCLK + +#elif STM32_MCOSEL == STM32_MCOSEL_MSI +#define STM32_MCODIVCLK STM32_MSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI16 +#define STM32_MCODIVCLK STM32_HSI16CLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSE +#define STM32_MCODIVCLK STM32_HSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_PLL +#define STM32_MCODIVCLK STM32_PLL_P_CLKOUT + +#elif STM32_MCOSEL == STM32_MCOSEL_LSI +#define STM32_MCODIVCLK STM32_LSICLK + +#elif STM32_MCOSEL == STM32_MCOSEL_LSE +#define STM32_MCODIVCLK STM32_LSECLK + +#elif STM32_MCOSEL == STM32_MCOSEL_HSI48 +#define STM32_MCODIVCLK STM32_HSI48CLK + +#else +#error "invalid STM32_MCOSEL value specified" +#endif + +/** + * @brief MCO output pin clock frequency. + */ +#if (STM32_MCOPRE == STM32_MCOPRE_DIV1) || defined(__DOXYGEN__) +#define STM32_MCOCLK STM32_MCODIVCLK + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV2 +#define STM32_MCOCLK (STM32_MCODIVCLK / 2) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV4 +#define STM32_MCOCLK (STM32_MCODIVCLK / 4) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV8 +#define STM32_MCOCLK (STM32_MCODIVCLK / 8) + +#elif STM32_MCOPRE == STM32_MCOPRE_DIV16 +#define STM32_MCOCLK (STM32_MCODIVCLK / 16) + +#else +#error "invalid STM32_MCOPRE value specified" +#endif + +/** + * @brief RTC clock frequency. + */ +#if (STM32_RTCSEL == STM32_RTCSEL_NOCLOCK) || defined(__DOXYGEN__) +#define STM32_RTCCLK 0 + +#elif STM32_RTCSEL == STM32_RTCSEL_LSE +#define STM32_RTCCLK STM32_LSECLK + +#elif STM32_RTCSEL == STM32_RTCSEL_LSI +#define STM32_RTCCLK STM32_LSICLK + +#elif STM32_RTCSEL == STM32_RTCSEL_HSEDIV +#define STM32_RTCCLK (STM32_HSECLK / 32) + +#else +#error "invalid STM32_RTCSEL value specified" +#endif + +/** + * @brief USART1 clock frequency. + */ +#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_USART1CLK STM32_PCLK2 + +#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK +#define STM32_USART1CLK STM32_SYSCLK + +#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 +#define STM32_USART1CLK STM32_HSI16CLK + +#elif STM32_USART1SEL == STM32_USART1SEL_LSE +#define STM32_USART1CLK STM32_LSECLK + +#else +#error "invalid source selected for USART1 clock" +#endif + +/** + * @brief USART2 clock frequency. + */ +#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART2CLK STM32_PCLK1 + +#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK +#define STM32_USART2CLK STM32_SYSCLK + +#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 +#define STM32_USART2CLK STM32_HSI16CLK + +#elif STM32_USART2SEL == STM32_USART2SEL_LSE +#define STM32_USART2CLK STM32_LSECLK + +#else +#error "invalid source selected for USART2 clock" +#endif + +/** + * @brief USART3 clock frequency. + */ +#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_USART3CLK STM32_PCLK1 + +#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK +#define STM32_USART3CLK STM32_SYSCLK + +#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 +#define STM32_USART3CLK STM32_HSI16CLK + +#elif STM32_USART3SEL == STM32_USART3SEL_LSE +#define STM32_USART3CLK STM32_LSECLK + +#else +#error "invalid source selected for USART3 clock" +#endif + +/** + * @brief UART4 clock frequency. + */ +#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART4CLK STM32_PCLK1 + +#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK +#define STM32_UART4CLK STM32_SYSCLK + +#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 +#define STM32_UART4CLK STM32_HSI16CLK + +#elif STM32_UART4SEL == STM32_UART4SEL_LSE +#define STM32_UART4CLK STM32_LSECLK + +#else +#error "invalid source selected for UART4 clock" +#endif + +/** + * @brief UART5 clock frequency. + */ +#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_UART5CLK STM32_PCLK1 + +#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK +#define STM32_UART5CLK STM32_SYSCLK + +#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 +#define STM32_UART5CLK STM32_HSI16CLK + +#elif STM32_UART5SEL == STM32_UART5SEL_LSE +#define STM32_UART5CLK STM32_LSECLK + +#else +#error "invalid source selected for UART5 clock" +#endif + +/** + * @brief LPUART1 clock frequency. + */ +#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPUART1CLK STM32_PCLK1 + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK +#define STM32_LPUART1CLK STM32_SYSCLK + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 +#define STM32_LPUART1CLK STM32_HSI16CLK + +#elif STM32_LPUART1SEL == STM32_LPUART1SEL_LSE +#define STM32_LPUART1CLK STM32_LSECLK + +#else +#error "invalid source selected for LPUART1 clock" +#endif + +/** + * @brief I2C1 clock frequency. + */ +#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C1CLK STM32_PCLK1 + +#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK +#define STM32_I2C1CLK STM32_SYSCLK + +#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 +#define STM32_I2C1CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C1 clock" +#endif + +/** + * @brief I2C2 clock frequency. + */ +#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C2CLK STM32_PCLK1 + +#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK +#define STM32_I2C2CLK STM32_SYSCLK + +#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 +#define STM32_I2C2CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C2 clock" +#endif + +/** + * @brief I2C3 clock frequency. + */ +#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C3CLK STM32_PCLK1 + +#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK +#define STM32_I2C3CLK STM32_SYSCLK + +#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 +#define STM32_I2C3CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C3 clock" +#endif + +/** + * @brief I2C4 clock frequency. + */ +#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_I2C4CLK STM32_PCLK1 + +#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK +#define STM32_I2C4CLK STM32_SYSCLK + +#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 +#define STM32_I2C4CLK STM32_HSI16CLK + +#else +#error "invalid source selected for I2C4 clock" +#endif + +/** + * @brief LPTIM1 clock frequency. + */ +#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM1CLK STM32_PCLK1 + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI +#define STM32_LPTIM1CLK STM32_LSICLK + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_HSI16 +#define STM32_LPTIM1CLK STM32_HSI16CLK + +#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSE +#define STM32_LPTIM1CLK STM32_LSECLK + +#else +#error "invalid source selected for LPTIM1 clock" +#endif + +/** + * @brief LPTIM2 clock frequency. + */ +#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM2CLK STM32_PCLK1 + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI +#define STM32_LPTIM2CLK STM32_LSICLK + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_HSI16 +#define STM32_LPTIM2CLK STM32_HSI16CLK + +#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSE +#define STM32_LPTIM2CLK STM32_LSECLK + +#else +#error "invalid source selected for LPTIM2 clock" +#endif + +/** + * @brief LPTIM3 clock frequency. + */ +#if (STM32_LPTIM3SEL == STM32_LPTIM3SEL_PCLK1) || defined(__DOXYGEN__) +#define STM32_LPTIM3CLK STM32_PCLK1 + +#elif STM32_LPTIM3SEL == STM32_LPTIM3SEL_LSI +#define STM32_LPTIM3CLK STM32_LSICLK + +#elif STM32_LPTIM3SEL == STM32_LPTIM3SEL_HSI16 +#define STM32_LPTIM3CLK STM32_HSI16CLK + +#elif STM32_LPTIM3SEL == STM32_LPTIM3SEL_LSE +#define STM32_LPTIM3CLK STM32_LSECLK + +#else +#error "invalid source selected for LPTIM3 clock" +#endif + +/** + * @brief 48MHz clock frequency. + */ +#if (STM32_CLK48SEL == STM32_CLK48SEL_HSI48) || defined(__DOXYGEN__) +#define STM32_48CLK STM32_HSI48CLK + +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1 +#define STM32_48CLK (STM32_PLLSAI1VCO / STM32_PLLSAI1Q_VALUE) + +#elif STM32_CLK48SEL == STM32_CLK48SEL_PLL +#define STM32_48CLK (STM32_PLLVCO / STM32_PLLQ_VALUE) + +#elif STM32_CLK48SEL == STM32_CLK48SEL_MSI +#define STM32_48CLK STM32_MSICLK + +#else +#error "invalid source selected for 48CLK clock" +#endif + +/** + * @brief SAI1 clock frequency. + */ +#if (STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_SAI1CLK STM32_PLLSAI1_P_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI2 +#define STM32_SAI1CLK STM32_PLLSAI2_P_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_PLL +#define STM32_SAI1CLK STM32_PLL_P_CLKOUT + +#elif STM32_SAI1SEL == STM32_SAI1SEL_EXTCLK +#define STM32_SAI1CLK 0 /* Unknown, would require a board value */ + +#elif STM32_SAI1SEL == STM32_SAI1SEL_HSI16 +#define STM32_SAI1CLK STM32_HSI16CLK + +#elif STM32_SAI1SEL == STM32_SAI1SEL_OFF +#define STM32_SAI1CLK 0 + +#else +#error "invalid source selected for SAI1 clock" +#endif + +/** + * @brief SAI2 clock frequency. + */ +#if (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI1) || defined(__DOXYGEN__) +#define STM32_SAI2CLK STM32_PLLSAI1_P_CLKOUT + +#elif STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2 +#define STM32_SAI2CLK STM32_PLLSAI2_P_CLKOUT + +#elif STM32_SAI2SEL == STM32_SAI2SEL_PLL +#define STM32_SAI2CLK STM32_PLL_P_CLKOUT + +#elif STM32_SAI2SEL == STM32_SAI2SEL_EXTCLK +#define STM32_SAI2CLK 0 /* Unknown, would require a board value */ + +#elif STM32_SAI2SEL == STM32_SAI2SEL_HSI16 +#define STM32_SAI2CLK STM32_HSI16CLK + +#elif STM32_SAI2SEL == STM32_SAI2SEL_OFF +#define STM32_SAI2CLK 0 + +#else +#error "invalid source selected for SAI2 clock" +#endif + +/** + * @brief SDMMC clock frequency. + */ +#if (STM32_SDMMCSEL == STM32_SDMMCSEL_48CLK) || defined(__DOXYGEN__) +#define STM32_SDMMCCLK STM32_48CLK + +#elif STM32_SDMMCSEL == STM32_SDMMCSEL_PLLSAI3CLK +#define STM32_SDMMCCLK STM32_PLL_P_CLKOUT + +#else +#error "invalid source selected for SDMMC clock" +#endif + +/** + * @brief USB clock point. + */ +#define STM32_USBCLK STM32_48CLK + +/** + * @brief RNG clock point. + */ +#define STM32_RNGCLK STM32_48CLK + +/** + * @brief ADC clock frequency. + */ +#if (STM32_ADCSEL == STM32_ADCSEL_NOCLK) || defined(__DOXYGEN__) +#define STM32_ADCCLK 0 + +#elif STM32_ADCSEL == STM32_ADCSEL_PLLSAI1 +#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT + +#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK +#define STM32_ADCCLK STM32_SYSCLK + +#else +#error "invalid source selected for ADC clock" +#endif + +/** + * @brief DFSDM clock frequency. + */ +#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) +#define STM32_DFSDMCLK STM32_PCLK2 + +#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK +#define STM32_DFSDMCLK STM32_SYSCLK + +#else +#error "invalid source selected for DFSDM clock" +#endif + +/** + * @brief SDMMC frequency. + */ +#define STM32_SDMMC1CLK STM32_48CLK + +/** + * @brief OSPI clock frequency. + */ +#if (STM32_OSPISEL == STM32_OSPISEL_SYSCLK) || defined(__DOXYGEN__) +#define STM32_OSPICLK STM32_SYSCLK + +#elif STM32_OSPISEL == STM32_OSPISEL_MSI +#define STM32_OSPICLK STM32_MSICLK + +#elif STM32_OSPISEL == STM32_OSPISEL_48CLK +#define STM32_OSPICLK STM32_PLLSAI1_Q_CLKOUT + +#else +#error "invalid source selected for OSPI clock" +#endif + +/** + * @brief Clock of timers connected to APB1 + */ +#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK1 (STM32_PCLK1 * 1) +#else +#define STM32_TIMCLK1 (STM32_PCLK1 * 2) +#endif + +/** + * @brief Clock of timers connected to APB2. + */ +#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) +#define STM32_TIMCLK2 (STM32_PCLK2 * 1) +#else +#define STM32_TIMCLK2 (STM32_PCLK2 * 2) +#endif + +/** + * @brief Flash settings. + */ +#if (STM32_HCLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_HCLK <= STM32_1WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_HCLK <= STM32_2WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_HCLK <= STM32_3WS_THRESHOLD +#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + +/** + * @brief Flash settings for MSI. + */ +#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_MSICLK <= STM32_1WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_MSICLK <= STM32_2WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_MSICLK <= STM32_3WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Various helpers.*/ +#include "nvic.h" +#include "cache.h" +#include "mpu_v7m.h" +#include "stm32_isr.h" +#include "stm32_dma.h" +#include "stm32_exti.h" +#include "stm32_rcc.h" +#include "stm32_tim.h" + +#ifdef __cplusplus +extern "C" { +#endif + void hal_lld_init(void); + void stm32_clock_init(void); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_LLD_H */ + +/** @} */ diff --git a/testhal/AT32/AT32F4xx/ADC/Makefile b/testhal/AT32/AT32F4xx/ADC/Makefile new file mode 100644 index 0000000000..3ec838bf30 --- /dev/null +++ b/testhal/AT32/AT32F4xx/ADC/Makefile @@ -0,0 +1,214 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -Og -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO) +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# If enabled, this option allows to compile the application in THUMB mode. +ifeq ($(USE_THUMB),) + USE_THUMB = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = yes +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x400 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# Enables the use of FPU (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = no +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Define project name here +PROJECT = ch + +# Imported source files and paths +CHIBIOS = ../../../.. + +# Licensing files. +include $(CHIBIOS)/os/license/license.mk +# Startup files. +include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f4xx.mk +# HAL-OSAL files (optional). +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx/platform.mk +include $(CHIBIOS)/os/hal/boards/AT_START_F435/board.mk +include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk +# Other files (optional). +#include $(CHIBIOS)/test/lib/test.mk +#include $(CHIBIOS)/test/rt/rt_test.mk +#include $(CHIBIOS)/test/oslib/oslib_test.mk + +# Define linker script file here +LDSCRIPT= $(STARTUPLD)/AT32F435ZMxx.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(ALLCSRC) \ + $(TESTSRC) \ + main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = $(ALLCPPSRC) + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACSRC = + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACPPSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCPPSRC = + +# List ASM source files here +ASMSRC = $(ALLASMSRC) +ASMXSRC = $(ALLXASMSRC) + +INCDIR = $(ALLINC) $(TESTINC) + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +MCU = cortex-m4 + +#TRGT = arm-elf- +TRGT = arm-none-eabi- +CC = $(TRGT)gcc +CPPC = $(TRGT)g++ +# Enable loading with g++ only if you need C++ runtime support. +# NOTE: You can use C++ even without C++ support if you are careful. C++ +# runtime support makes code size explode. +LD = $(TRGT)gcc +#LD = $(TRGT)g++ +CP = $(TRGT)objcopy +AS = $(TRGT)gcc -x assembler-with-cpp +AR = $(TRGT)ar +OD = $(TRGT)objdump +SZ = $(TRGT)size +HEX = $(CP) -O ihex +BIN = $(CP) -O binary + +# ARM-specific options here +AOPT = + +# THUMB-specific options here +TOPT = -mthumb -DTHUMB + +# Define C warning options here +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes + +# Define C++ warning options here +CPPWARN = -Wall -Wextra -Wundef + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user defines +############################################################################## + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk +include $(RULESPATH)/rules.mk diff --git a/testhal/AT32/AT32F4xx/ADC/chconf.h b/testhal/AT32/AT32F4xx/ADC/chconf.h new file mode 100644 index 0000000000..e0261697f6 --- /dev/null +++ b/testhal/AT32/AT32F4xx/ADC/chconf.h @@ -0,0 +1,842 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file rt/templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_6_1_ + +#define ON_LOCK_HOOK {} +#define ON_UNLOCK_HOOK {} + +/*===========================================================================*/ +/** + * @name System settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Handling of instances. + * @note If enabled then threads assigned to various instances can + * interact each other using the same synchronization objects. + * If disabled then each OS instance is a separate world, no + * direct interactions are handled by the OS. + */ +#if !defined(CH_CFG_SMP_MODE) +#define CH_CFG_SMP_MODE FALSE +#endif + +/** @} */ + + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_ST_RESOLUTION) +#define CH_CFG_ST_RESOLUTION 32 +#endif + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_CFG_ST_FREQUENCY) +#define CH_CFG_ST_FREQUENCY 10000 +#endif + +/** + * @brief Time intervals data size. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_INTERVALS_SIZE) +#define CH_CFG_INTERVALS_SIZE 32 +#endif + +/** + * @brief Time types data size. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#define CH_CFG_TIME_TYPES_SIZE 32 +#endif + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#if !defined(CH_CFG_ST_TIMEDELTA) +#define CH_CFG_ST_TIMEDELTA 2 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#if !defined(CH_CFG_TIME_QUANTUM) +#define CH_CFG_TIME_QUANTUM 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#if !defined(CH_CFG_NO_IDLE_THREAD) +#define CH_CFG_NO_IDLE_THREAD FALSE +#endif + +/** + * @brief Kernel hardening level. + * @details This option is the level of functional-safety checks enabled + * in the kerkel. The meaning is: + * - 0: No checks, maximum performance. + * - 1: Reasonable checks. + * - 2: All checks. + * . + */ +#if !defined(CH_CFG_HARDENING_LEVEL) +#define CH_CFG_HARDENING_LEVEL 0 +#endif +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#define CH_CFG_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TM) +#define CH_CFG_USE_TM TRUE +#endif + +/** + * @brief Time Stamps APIs. + * @details If enabled then the time stamps APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TIMESTAMP) +#define CH_CFG_USE_TIMESTAMP TRUE +#endif + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_REGISTRY) +#define CH_CFG_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_WAITEXIT) +#define CH_CFG_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_SEMAPHORES) +#define CH_CFG_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MUTEXES) +#define CH_CFG_USE_MUTEXES TRUE +#endif + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_CONDVARS) +#define CH_CFG_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_EVENTS) +#define CH_CFG_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MESSAGES) +#define CH_CFG_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#if !defined(CH_CFG_USE_DYNAMIC) +#define CH_CFG_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name OSLIB options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_MAILBOXES) +#define CH_CFG_USE_MAILBOXES TRUE +#endif + +/** + * @brief Memory checks APIs. + * @details If enabled then the memory checks APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCHECKS) +#define CH_CFG_USE_MEMCHECKS TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCORE) +#define CH_CFG_USE_MEMCORE TRUE +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#if !defined(CH_CFG_MEMCORE_SIZE) +#define CH_CFG_MEMCORE_SIZE 0 +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_CFG_USE_HEAP) +#define CH_CFG_USE_HEAP TRUE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMPOOLS) +#define CH_CFG_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS TRUE +#endif + +/** + * @brief Pipes APIs. + * @details If enabled then the pipes APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_PIPES) +#define CH_CFG_USE_PIPES TRUE +#endif + +/** + * @brief Objects Caches APIs. + * @details If enabled then the objects caches APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_CACHES) +#define CH_CFG_USE_OBJ_CACHES TRUE +#endif + +/** + * @brief Delegate threads APIs. + * @details If enabled then the delegate threads APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_DELEGATES) +#define CH_CFG_USE_DELEGATES TRUE +#endif + +/** + * @brief Jobs Queues APIs. + * @details If enabled then the jobs queues APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_JOBS) +#define CH_CFG_USE_JOBS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Objects factory options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Objects Factory APIs. + * @details If enabled then the objects factory APIs are included in the + * kernel. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_CFG_USE_FACTORY) +#define CH_CFG_USE_FACTORY TRUE +#endif + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#endif + +/** + * @brief Enables the registry of generic objects. + */ +#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#endif + +/** + * @brief Enables factory for generic buffers. + */ +#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/** + * @brief Enables factory for mailboxes. + */ +#if !defined(CH_CFG_FACTORY_MAILBOXES) +#define CH_CFG_FACTORY_MAILBOXES TRUE +#endif + +/** + * @brief Enables factory for objects FIFOs. + */ +#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#endif + +/** + * @brief Enables factory for Pipes. + */ +#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_PIPES TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_STATISTICS) +#define CH_DBG_STATISTICS FALSE +#endif + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#define CH_DBG_SYSTEM_STATE_CHECK TRUE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) +#define CH_DBG_ENABLE_CHECKS TRUE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) +#define CH_DBG_ENABLE_ASSERTS TRUE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_MASK) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_ALL +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#define CH_DBG_ENABLE_STACK_CHECK TRUE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) +#define CH_DBG_FILL_THREADS TRUE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#if !defined(CH_DBG_THREADS_PROFILING) +#define CH_DBG_THREADS_PROFILING FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System structure extension. + * @details User fields added to the end of the @p ch_system_t structure. + */ +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add system custom fields here.*/ + +/** + * @brief System initialization hook. + * @details User initialization code added to the @p chSysInit() function + * just before interrupts are enabled globally. + */ +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add system initialization code here.*/ \ +} +/** + * @brief OS instance structure extension. + * @details User fields added to the end of the @p os_instance_t structure. + */ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ + /* Add OS instance custom fields here.*/ + +/** + * @brief OS instance initialization hook. + * + * @param[in] oip pointer to the @p os_instance_t structure + */ +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ + /* Add OS instance initialization code here.*/ \ +} + + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p _thread_init() function. + * + * @note It is invoked from within @p _thread_init() and implicitly from all + * the threads creation APIs. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + * + * @param[in] ntp thread being switched in + * @param[in] otp thread being switched out + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** + * @brief Runtime Faults Collection Unit hook. + * @details This hook is invoked each time new faults are collected and stored. + */ +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ + /* Faults handling code here.*/ \ +} +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/testhal/AT32/AT32F4xx/ADC/halconf.h b/testhal/AT32/AT32F4xx/ADC/halconf.h new file mode 100644 index 0000000000..97e01635f7 --- /dev/null +++ b/testhal/AT32/AT32F4xx/ADC/halconf.h @@ -0,0 +1,531 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#define _CHIBIOS_HAL_CONF_ +#define _CHIBIOS_HAL_CONF_VER_7_1_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC TRUE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the cryptographic subsystem. + */ +#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__) +#define HAL_USE_CRY FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EFlash subsystem. + */ +#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__) +#define HAL_USE_EFL FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the TRNG subsystem. + */ +#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__) +#define HAL_USE_TRNG FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB FALSE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/** + * @brief Enables the WSPI subsystem. + */ +#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) +#define HAL_USE_WSPI FALSE +#endif + +/*===========================================================================*/ +/* PAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS FALSE +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) +#define PAL_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/** + * @brief Enforces the driver to use direct callbacks rather than OSAL events. + */ +#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__) +#define CAN_ENFORCE_USE_CALLBACKS FALSE +#endif + +/*===========================================================================*/ +/* CRY driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + +/*===========================================================================*/ +/* DAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the zero-copy API. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief OCR initialization constant for V20 cards. + */ +#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__) +#define SDC_INIT_OCR_V20 0x50FF8000U +#endif + +/** + * @brief OCR initialization constant for non-V20 cards. + */ +#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__) +#define SDC_INIT_OCR 0x80100000U +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables circular transfers APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__) +#define SPI_USE_CIRCULAR FALSE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* WSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__) +#define WSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define WSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/testhal/AT32/AT32F4xx/ADC/main.c b/testhal/AT32/AT32F4xx/ADC/main.c new file mode 100644 index 0000000000..9e865ffd60 --- /dev/null +++ b/testhal/AT32/AT32F4xx/ADC/main.c @@ -0,0 +1,167 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "ch.h" +#include "hal.h" + +#define LINE_LED LINE_LED1 //++VS + +#define ADC_GRP1_NUM_CHANNELS 1 +#define ADC_GRP1_BUF_DEPTH 8 + +#define ADC_GRP2_NUM_CHANNELS 8 +#define ADC_GRP2_BUF_DEPTH 16 + +static adcsample_t samples1[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; +static adcsample_t samples2[ADC_GRP2_NUM_CHANNELS * ADC_GRP2_BUF_DEPTH]; + +/* + * ADC streaming callback. + */ +size_t nx = 0, ny = 0; +static void adccallback(ADCDriver *adcp) { + + if (adcIsBufferComplete(adcp)) { + nx += 1; + } + else { + ny += 1; + } +} + +static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) { + + (void)adcp; + (void)err; +} + +/* + * ADC conversion group. + * Mode: Linear buffer, 8 samples of 1 channel, SW triggered. + * Channels: IN11. + */ +static const ADCConversionGroup adcgrpcfg1 = { + FALSE, + ADC_GRP1_NUM_CHANNELS, + NULL, + adcerrorcallback, + 0, /* CR1 */ + ADC_CR2_SWSTART, /* CR2 */ + ADC_SMPR1_SMP_AN11(ADC_SAMPLE_3), + 0, /* SMPR2 */ + 0, /* HTR */ + 0, /* LTR */ + 0, /* SQR1 */ + 0, /* SQR2 */ + ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11) +}; + +/* + * ADC conversion group. + * Mode: Continuous, 16 samples of 8 channels, SW triggered. + * Channels: IN11, IN12, IN11, IN12, IN11, IN12, Sensor, VRef. + */ +static const ADCConversionGroup adcgrpcfg2 = { + TRUE, + ADC_GRP2_NUM_CHANNELS, + adccallback, + adcerrorcallback, + 0, /* CR1 */ + ADC_CR2_SWSTART, /* CR2 */ + ADC_SMPR1_SMP_AN12(ADC_SAMPLE_56) | ADC_SMPR1_SMP_AN11(ADC_SAMPLE_56) | + ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_144) | ADC_SMPR1_SMP_VREF(ADC_SAMPLE_144), + 0, /* SMPR2 */ + 0, /* HTR */ + 0, /* LTR */ + 0, /* SQR1 */ + ADC_SQR2_SQ8_N(ADC_CHANNEL_SENSOR) | ADC_SQR2_SQ7_N(ADC_CHANNEL_VREFINT), + ADC_SQR3_SQ6_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ5_N(ADC_CHANNEL_IN11) | + ADC_SQR3_SQ4_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ3_N(ADC_CHANNEL_IN11) | + ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11) +}; + +/* + * Red LED blinker thread, times are in milliseconds. + */ +static THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { + + (void)arg; + chRegSetThreadName("blinker"); + while (true) { +// palSetPad(GPIOD, GPIOD_LED5); + palSetLine(LINE_LED); + chThdSleepMilliseconds(500); +// palClearPad(GPIOD, GPIOD_LED5); + palClearLine(LINE_LED); + chThdSleepMilliseconds(500); + } +} + +/* + * Application entry point. + */ +int main(void) { + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* + * Setting up analog inputs used by the demo. + */ + palSetGroupMode(GPIOC, PAL_PORT_BIT(1) | PAL_PORT_BIT(2), + 0, PAL_MODE_INPUT_ANALOG); + + /* + * Creates the blinker thread. + */ + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); + + /* + * Activates the ADC1 driver and the temperature sensor. + */ + adcStart(&ADCD1, NULL); + adcSTM32EnableTSVREFE(); + + /* + * Linear conversion. + */ + adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH); + chThdSleepMilliseconds(1000); + + /* + * Starts an ADC continuous conversion. + */ + adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH); + + /* + * Normal main() thread activity, in this demo it does nothing. + */ + while (true) { + if (palReadPad(GPIOA, GPIOA_BUTTON)) { + adcStopConversion(&ADCD1); + adcSTM32DisableTSVREFE(); + } + chThdSleepMilliseconds(500); + } +} diff --git a/testhal/AT32/AT32F4xx/ADC/mcuconf.h b/testhal/AT32/AT32F4xx/ADC/mcuconf.h new file mode 100644 index 0000000000..2bdcf37266 --- /dev/null +++ b/testhal/AT32/AT32F4xx/ADC/mcuconf.h @@ -0,0 +1,407 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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 MCUCONF_H +#define MCUCONF_H + +/* + * STM32F4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#define STM32F4xx_MCUCONF +#define STM32F437_MCUCONF + +/* + * Config pll clock resource + * common frequency config list: pll source selected hick or hext (8mhz) + * _________________________________________________________________________________________________ + * | | | | | | | | | | | + * |pll(mhz)| 288 | 252 | 216 | 192 | 180 | 144 | 108 | 72 | 36 | + * |________|_________|_________|_________|_________|_________|_________|_________|_________________| + * | | | | | | | | | | | + * |pll_ns | 144 | 126 | 108 | 96 | 90 | 72 | 108 | 72 | 72 | + * | | | | | | | | | | | + * |pll_ms | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + * | | | | | | | | | | | + * |pll_fr | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_8 | FR_8 | FR_16| + * |________|_________|_________|_________|_________|_________|_________|_________|________|________| + * + * if pll clock source selects hext with other frequency values, or configure pll to other + * frequency values, please use the at32 new clock configuration tool for configuration. + */ + +#if 0 +/* Defaults for 96MHz from DS */ +#define STM32_PLLM_VALUE 2 +#define STM32_PLLN_VALUE 192 +#define STM32_PLLP_VALUE 8 +#define STM32_PPRE1 STM32_PPRE1_DIV1 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV1 /* max 144 MHz */ +#endif + +#if 0 +/* 144 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 72 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV1 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV1 /* max 144 MHz */ +#endif + +#if 0 +/* 216 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 108 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV2 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV2 /* max 144 MHz */ +#endif + +#if 1 +/* 288 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 144 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV2 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV2 /* max 144 MHz */ +#endif + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_BKPRAM_ENABLE FALSE +#define STM32_HSI_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED TRUE +#define STM32_LSE_ENABLED FALSE +#define STM32_CLOCK48_REQUIRED TRUE +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_RTCSEL STM32_RTCSEL_LSI +#define STM32_RTCPRE_VALUE 8 +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI16_PRIORITY 6 +#define STM32_IRQ_EXTI17_PRIORITY 15 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_PRIORITY 15 +#define STM32_IRQ_EXTI22_PRIORITY 15 + +#define STM32_IRQ_TIM1_BRK_TIM9_PRIORITY 7 +#define STM32_IRQ_TIM1_UP_TIM10_PRIORITY 7 +#define STM32_IRQ_TIM1_TRGCO_TIM11_PRIORITY 7 +#define STM32_IRQ_TIM1_CC_PRIORITY 7 +#define STM32_IRQ_TIM2_PRIORITY 7 +#define STM32_IRQ_TIM3_PRIORITY 7 +#define STM32_IRQ_TIM4_PRIORITY 7 +#define STM32_IRQ_TIM5_PRIORITY 7 +#define STM32_IRQ_TIM6_PRIORITY 7 +#define STM32_IRQ_TIM7_PRIORITY 7 +#define STM32_IRQ_TIM8_BRK_TIM12_PRIORITY 7 +#define STM32_IRQ_TIM8_UP_TIM13_PRIORITY 7 +#define STM32_IRQ_TIM8_TRGCO_TIM14_PRIORITY 7 +#define STM32_IRQ_TIM8_CC_PRIORITY 7 + +#define STM32_IRQ_USART1_PRIORITY 12 +#define STM32_IRQ_USART2_PRIORITY 12 +#define STM32_IRQ_USART3_PRIORITY 12 +#define STM32_IRQ_UART4_PRIORITY 12 +#define STM32_IRQ_UART5_PRIORITY 12 +#define STM32_IRQ_USART6_PRIORITY 12 +#define STM32_IRQ_UART7_PRIORITY 12 +#define STM32_IRQ_UART8_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4 +#define STM32_ADC_USE_ADC1 TRUE +#define STM32_ADC_USE_ADC2 TRUE +#define STM32_ADC_USE_ADC3 TRUE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#define STM32_ADC_IRQ_PRIORITY 6 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6 +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6 +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_USE_CAN2 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 +#define STM32_CAN_CAN2_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM5 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM8 FALSE +#define STM32_GPT_USE_TIM9 FALSE +#define STM32_GPT_USE_TIM10 FALSE +#define STM32_GPT_USE_TIM11 FALSE +#define STM32_GPT_USE_TIM12 FALSE +#define STM32_GPT_USE_TIM13 FALSE +#define STM32_GPT_USE_TIM14 FALSE + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C2_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C2_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * I2S driver system settings. + */ +#define STM32_I2S_USE_SPI2 FALSE +#define STM32_I2S_USE_SPI3 FALSE +#define STM32_I2S_SPI2_IRQ_PRIORITY 10 +#define STM32_I2S_SPI3_IRQ_PRIORITY 10 +#define STM32_I2S_SPI2_DMA_PRIORITY 1 +#define STM32_I2S_SPI3_DMA_PRIORITY 1 +#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM5 FALSE +#define STM32_ICU_USE_TIM8 FALSE +#define STM32_ICU_USE_TIM9 FALSE +#define STM32_ICU_USE_TIM10 FALSE +#define STM32_ICU_USE_TIM11 FALSE +#define STM32_ICU_USE_TIM12 FALSE +#define STM32_ICU_USE_TIM13 FALSE +#define STM32_ICU_USE_TIM14 FALSE + +/* + * MAC driver system settings. + */ +#define STM32_MAC_TRANSMIT_BUFFERS 2 +#define STM32_MAC_RECEIVE_BUFFERS 4 +#define STM32_MAC_BUFFERS_SIZE 1522 +#define STM32_MAC_PHY_TIMEOUT 100 +#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE +#define STM32_MAC_ETH1_IRQ_PRIORITY 13 +#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM5 FALSE +#define STM32_PWM_USE_TIM8 FALSE +#define STM32_PWM_USE_TIM9 FALSE +#define STM32_PWM_USE_TIM10 FALSE +#define STM32_PWM_USE_TIM11 FALSE +#define STM32_PWM_USE_TIM12 FALSE +#define STM32_PWM_USE_TIM13 FALSE +#define STM32_PWM_USE_TIM14 FALSE + +/* + * RTC driver system settings. + */ +#define STM32_RTC_PRESA_VALUE 32 +#define STM32_RTC_PRESS_VALUE 1024 +#define STM32_RTC_CR_INIT 0 +#define STM32_RTC_TAMPCR_INIT 0 + +/* + * SDC driver system settings. + */ +#define STM32_SDC_SDIO_DMA_PRIORITY 3 +#define STM32_SDC_SDIO_IRQ_PRIORITY 9 +#define STM32_SDC_WRITE_TIMEOUT_MS 1000 +#define STM32_SDC_READ_TIMEOUT_MS 1000 +#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 +#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USE_USART6 FALSE + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_USE_SPI4 FALSE +#define STM32_SPI_USE_SPI5 FALSE +#define STM32_SPI_USE_SPI6 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_SPI_SPI6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI4_DMA_PRIORITY 1 +#define STM32_SPI_SPI5_DMA_PRIORITY 1 +#define STM32_SPI_SPI6_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_SPI4_IRQ_PRIORITY 10 +#define STM32_SPI_SPI5_IRQ_PRIORITY 10 +#define STM32_SPI_SPI6_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USE_UART4 FALSE +#define STM32_UART_USE_UART5 FALSE +#define STM32_UART_USE_USART6 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_UART4_DMA_PRIORITY 0 +#define STM32_UART_UART5_DMA_PRIORITY 0 +#define STM32_UART_USART6_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_OTG1 FALSE +#define STM32_USB_USE_OTG2 FALSE +#define STM32_USB_OTG1_IRQ_PRIORITY 14 +#define STM32_USB_OTG2_IRQ_PRIORITY 14 +#define STM32_USB_OTG1_RX_FIFO_SIZE 512 +#define STM32_USB_OTG2_RX_FIFO_SIZE 1024 +#define STM32_USB_HOST_WAKEUP_DURATION 2 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +#endif /* MCUCONF_H */ diff --git a/testhal/AT32/AT32F4xx/ADC/readme.txt b/testhal/AT32/AT32F4xx/ADC/readme.txt new file mode 100644 index 0000000000..edcccea68a --- /dev/null +++ b/testhal/AT32/AT32F4xx/ADC/readme.txt @@ -0,0 +1,30 @@ +***************************************************************************** +** ChibiOS/HAL - ADC driver demo for STM32F4xx. ** +***************************************************************************** + +** TARGET ** + +The demo runs on an STMicroelectronics STM32F4-Discovery board. + +** The Demo ** + +The application demonstrates the use of the STM32F4xx ADC driver. + +** Board Setup ** + +- Connect PC1 to 3.3V and PC2 to GND for analog measurements. + +** Build Procedure ** + +The demo has been tested using the free Codesourcery GCC-based toolchain +and YAGARTO. +Just modify the TRGT line in the makefile in order to use different GCC ports. + +** Notes ** + +Some files used by the demo are not part of ChibiOS/RT but are copyright of +ST Microelectronics and are licensed under a different license. +Also note that not all the files present in the ST library are distributed +with ChibiOS/RT, you can find the whole library on the ST web site: + + http://www.st.com diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/Makefile b/testhal/AT32/AT32F4xx/USB_CDC_IAD/Makefile new file mode 100644 index 0000000000..55640ff629 --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/Makefile @@ -0,0 +1,216 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -Og -ggdb -fomit-frame-pointer -falign-functions=16 +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# Linker extra options here. +ifeq ($(USE_LDOPT),) + USE_LDOPT = +endif + +# Enable this if you want link time optimizations (LTO) +ifeq ($(USE_LTO),) + USE_LTO = yes +endif + +# If enabled, this option allows to compile the application in THUMB mode. +ifeq ($(USE_THUMB),) + USE_THUMB = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# If enabled, this option makes the build process faster by not compiling +# modules not used in the current configuration. +ifeq ($(USE_SMART_BUILD),) + USE_SMART_BUILD = yes +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x400 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# Enables the use of FPU (no, softfp, hard). +ifeq ($(USE_FPU),) + USE_FPU = no +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Define project name here +PROJECT = ch + +# Imported source files and paths +CHIBIOS = ../../../.. + +# Licensing files. +include $(CHIBIOS)/os/license/license.mk +# Startup files. +include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_at32f4xx.mk +# HAL-OSAL files (optional). +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS)/os/hal/ports/AT32/AT32F4xx/platform.mk +include $(CHIBIOS)/os/hal/boards/AT_START_F435/board.mk +include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk +# RTOS files (optional). +include $(CHIBIOS)/os/rt/rt.mk +include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk +# Other files (optional). +include $(CHIBIOS)/test/lib/test.mk +include $(CHIBIOS)/test/rt/rt_test.mk +include $(CHIBIOS)/test/oslib/oslib_test.mk +include $(CHIBIOS)/os/hal/lib/streams/streams.mk +include $(CHIBIOS)/os/various/shell/shell.mk + +# Define linker script file here +LDSCRIPT= $(STARTUPLD)/AT32F435ZMxx.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(ALLCSRC) \ + $(TESTSRC) \ + usbcfg.c main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = $(ALLCPPSRC) + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACSRC = + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACPPSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCPPSRC = + +# List ASM source files here +ASMSRC = $(ALLASMSRC) +ASMXSRC = $(ALLXASMSRC) + +INCDIR = $(ALLINC) $(TESTINC) + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +MCU = cortex-m4 + +#TRGT = arm-elf- +TRGT = arm-none-eabi- +CC = $(TRGT)gcc +CPPC = $(TRGT)g++ +# Enable loading with g++ only if you need C++ runtime support. +# NOTE: You can use C++ even without C++ support if you are careful. C++ +# runtime support makes code size explode. +LD = $(TRGT)gcc +#LD = $(TRGT)g++ +CP = $(TRGT)objcopy +AS = $(TRGT)gcc -x assembler-with-cpp +AR = $(TRGT)ar +OD = $(TRGT)objdump +SZ = $(TRGT)size +HEX = $(CP) -O ihex +BIN = $(CP) -O binary + +# ARM-specific options here +AOPT = + +# THUMB-specific options here +TOPT = -mthumb -DTHUMB + +# Define C warning options here +CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes + +# Define C++ warning options here +CPPWARN = -Wall -Wextra -Wundef + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user defines +############################################################################## + +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk +include $(RULESPATH)/rules.mk diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/chconf.h b/testhal/AT32/AT32F4xx/USB_CDC_IAD/chconf.h new file mode 100644 index 0000000000..b4fb7f1668 --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/chconf.h @@ -0,0 +1,843 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file rt/templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ +#define _CHIBIOS_RT_CONF_VER_6_1_ + +#define ON_LOCK_HOOK {} +#define ON_UNLOCK_HOOK {} + +/*===========================================================================*/ +/** + * @name System settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Handling of instances. + * @note If enabled then threads assigned to various instances can + * interact each other using the same synchronization objects. + * If disabled then each OS instance is a separate world, no + * direct interactions are handled by the OS. + */ +#if !defined(CH_CFG_SMP_MODE) +#define CH_CFG_SMP_MODE FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_ST_RESOLUTION) +#define CH_CFG_ST_RESOLUTION 32 +#endif + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_CFG_ST_FREQUENCY) +#define CH_CFG_ST_FREQUENCY 10000 +#endif + +/** + * @brief Time intervals data size. + * @note Allowed values are 16, 32 or 64 bits. + */ +#if !defined(CH_CFG_INTERVALS_SIZE) +#define CH_CFG_INTERVALS_SIZE 32 +#endif + +/** + * @brief Time types data size. + * @note Allowed values are 16 or 32 bits. + */ +#if !defined(CH_CFG_TIME_TYPES_SIZE) +#define CH_CFG_TIME_TYPES_SIZE 32 +#endif + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#if !defined(CH_CFG_ST_TIMEDELTA) +#define CH_CFG_ST_TIMEDELTA 2 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#if !defined(CH_CFG_TIME_QUANTUM) +#define CH_CFG_TIME_QUANTUM 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#if !defined(CH_CFG_NO_IDLE_THREAD) +#define CH_CFG_NO_IDLE_THREAD FALSE +#endif + +/** + * @brief Kernel hardening level. + * @details This option is the level of functional-safety checks enabled + * in the kerkel. The meaning is: + * - 0: No checks, maximum performance. + * - 1: Reasonable checks. + * - 2: All checks. + * . + */ +#if !defined(CH_CFG_HARDENING_LEVEL) +#define CH_CFG_HARDENING_LEVEL 0 +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_OPTIMIZE_SPEED) +#define CH_CFG_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TM) +#define CH_CFG_USE_TM TRUE +#endif + +/** + * @brief Time Stamps APIs. + * @details If enabled then the time stamps APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_TIMESTAMP) +#define CH_CFG_USE_TIMESTAMP TRUE +#endif + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_REGISTRY) +#define CH_CFG_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_WAITEXIT) +#define CH_CFG_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_SEMAPHORES) +#define CH_CFG_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MUTEXES) +#define CH_CFG_USE_MUTEXES TRUE +#endif + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#if !defined(CH_CFG_USE_CONDVARS) +#define CH_CFG_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_EVENTS) +#define CH_CFG_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#if !defined(CH_CFG_USE_EVENTS_TIMEOUT) +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MESSAGES) +#define CH_CFG_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#if !defined(CH_CFG_USE_MESSAGES_PRIORITY) +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#if !defined(CH_CFG_USE_DYNAMIC) +#define CH_CFG_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name OSLIB options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#if !defined(CH_CFG_USE_MAILBOXES) +#define CH_CFG_USE_MAILBOXES TRUE +#endif + +/** + * @brief Memory checks APIs. + * @details If enabled then the memory checks APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCHECKS) +#define CH_CFG_USE_MEMCHECKS TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMCORE) +#define CH_CFG_USE_MEMCORE TRUE +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#if !defined(CH_CFG_MEMCORE_SIZE) +#define CH_CFG_MEMCORE_SIZE 0 +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_CFG_USE_HEAP) +#define CH_CFG_USE_HEAP TRUE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_MEMPOOLS) +#define CH_CFG_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Objects FIFOs APIs. + * @details If enabled then the objects FIFOs APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_FIFOS) +#define CH_CFG_USE_OBJ_FIFOS TRUE +#endif + +/** + * @brief Pipes APIs. + * @details If enabled then the pipes APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_PIPES) +#define CH_CFG_USE_PIPES TRUE +#endif + +/** + * @brief Objects Caches APIs. + * @details If enabled then the objects caches APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_OBJ_CACHES) +#define CH_CFG_USE_OBJ_CACHES TRUE +#endif + +/** + * @brief Delegate threads APIs. + * @details If enabled then the delegate threads APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_DELEGATES) +#define CH_CFG_USE_DELEGATES TRUE +#endif + +/** + * @brief Jobs Queues APIs. + * @details If enabled then the jobs queues APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_CFG_USE_JOBS) +#define CH_CFG_USE_JOBS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Objects factory options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Objects Factory APIs. + * @details If enabled then the objects factory APIs are included in the + * kernel. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_CFG_USE_FACTORY) +#define CH_CFG_USE_FACTORY TRUE +#endif + +/** + * @brief Maximum length for object names. + * @details If the specified length is zero then the name is stored by + * pointer but this could have unintended side effects. + */ +#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#endif + +/** + * @brief Enables the registry of generic objects. + */ +#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#endif + +/** + * @brief Enables factory for generic buffers. + */ +#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#endif + +/** + * @brief Enables factory for semaphores. + */ +#if !defined(CH_CFG_FACTORY_SEMAPHORES) +#define CH_CFG_FACTORY_SEMAPHORES TRUE +#endif + +/** + * @brief Enables factory for mailboxes. + */ +#if !defined(CH_CFG_FACTORY_MAILBOXES) +#define CH_CFG_FACTORY_MAILBOXES TRUE +#endif + +/** + * @brief Enables factory for objects FIFOs. + */ +#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#endif + +/** + * @brief Enables factory for Pipes. + */ +#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) +#define CH_CFG_FACTORY_PIPES TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_STATISTICS) +#define CH_DBG_STATISTICS FALSE +#endif + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) +#define CH_DBG_SYSTEM_STATE_CHECK TRUE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) +#define CH_DBG_ENABLE_CHECKS TRUE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) +#define CH_DBG_ENABLE_ASSERTS TRUE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_MASK) +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_ALL +#endif + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#if !defined(CH_DBG_TRACE_BUFFER_SIZE) +#define CH_DBG_TRACE_BUFFER_SIZE 128 +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) +#define CH_DBG_ENABLE_STACK_CHECK TRUE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) +#define CH_DBG_FILL_THREADS TRUE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#if !defined(CH_DBG_THREADS_PROFILING) +#define CH_DBG_THREADS_PROFILING FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System structure extension. + * @details User fields added to the end of the @p ch_system_t structure. + */ +#define CH_CFG_SYSTEM_EXTRA_FIELDS \ + /* Add system custom fields here.*/ + +/** + * @brief System initialization hook. + * @details User initialization code added to the @p chSysInit() function + * just before interrupts are enabled globally. + */ +#define CH_CFG_SYSTEM_INIT_HOOK() { \ + /* Add system initialization code here.*/ \ +} + +/** + * @brief OS instance structure extension. + * @details User fields added to the end of the @p os_instance_t structure. + */ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ + /* Add OS instance custom fields here.*/ + +/** + * @brief OS instance initialization hook. + * + * @param[in] oip pointer to the @p os_instance_t structure + */ +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ + /* Add OS instance initialization code here.*/ \ +} + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p _thread_init() function. + * + * @note It is invoked from within @p _thread_init() and implicitly from all + * the threads creation APIs. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @param[in] tp pointer to the @p thread_t structure + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + * + * @param[in] ntp thread being switched in + * @param[in] otp thread being switched out + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** + * @brief Runtime Faults Collection Unit hook. + * @details This hook is invoked each time new faults are collected and stored. + */ +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ + /* Faults handling code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/driver/ChibiOS Virtual COM.inf b/testhal/AT32/AT32F4xx/USB_CDC_IAD/driver/ChibiOS Virtual COM.inf new file mode 100644 index 0000000000..75936882bc --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/driver/ChibiOS Virtual COM.inf @@ -0,0 +1,57 @@ +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%PRVDR% +CatalogFile=stmcdc.cat +DriverVer=02/06/2015,1.0.1 + +[SourceDisksNames] + +[SourceDisksFiles] + +[Manufacturer] +%MFGNAME%=DeviceList,NT,NTamd64 + +[DestinationDirs] +DefaultDestDir = 12 + +[DeviceList.NT] +%DESCRIPTION1%=DriverInstall,USB\VID_F055&PID_E063&MI_00 +%DESCRIPTION2%=DriverInstall,USB\VID_F055&PID_E063&MI_02 +%DESCRIPTION3%=DriverInstall,USB\VID_F055&PID_E063&MI_04 + +[DeviceList.NTamd64] +%DESCRIPTION1%=DriverInstall,USB\VID_F055&PID_E063&MI_00 +%DESCRIPTION2%=DriverInstall,USB\VID_F055&PID_E063&MI_02 +%DESCRIPTION3%=DriverInstall,USB\VID_F055&PID_E063&MI_04 + +[DriverInstall.NT] +Include=mdmcpq.inf +CopyFiles=FakeModemCopyFileSection +AddReg=DriverInstall.NT.AddReg + +[DriverInstall.NT.AddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,usbser.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.NT.Services] +AddService=usbser, 0x00000002, DriverServiceInst + +[DriverServiceInst] +DisplayName=%SERVICE% +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; SERVICE_DEMAND_START +ErrorControl = 1 ; SERVICE_ERROR_NORMAL +ServiceBinary= %12%\usbser.sys +LoadOrderGroup = Base + +[Strings] +PRVDR = "www.chibios.org" +MFGNAME = "ChibiOS." +DESCRIPTION1 = "ChibiOS Virtual COM Port 1" +DESCRIPTION2 = "ChibiOS Virtual COM Port 2" +DESCRIPTION3 = "ChibiOS Virtual COM Port 3" +SERVICE = "ChibiOS Virtual COM Port" +DriversDisk = "ChibiOS Drivers Disk" diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/halconf.h b/testhal/AT32/AT32F4xx/USB_CDC_IAD/halconf.h new file mode 100644 index 0000000000..7fd4dc3ff6 --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/halconf.h @@ -0,0 +1,553 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef HALCONF_H +#define HALCONF_H + +#define _CHIBIOS_HAL_CONF_ +#define _CHIBIOS_HAL_CONF_VER_7_1_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the cryptographic subsystem. + */ +#if !defined(HAL_USE_CRY) || defined(__DOXYGEN__) +#define HAL_USE_CRY FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EFlash subsystem. + */ +#if !defined(HAL_USE_EFL) || defined(__DOXYGEN__) +#define HAL_USE_EFL FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB TRUE +#endif + +/** + * @brief Enables the SIO subsystem. + */ +#if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) +#define HAL_USE_SIO FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the TRNG subsystem. + */ +#if !defined(HAL_USE_TRNG) || defined(__DOXYGEN__) +#define HAL_USE_TRNG FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/** + * @brief Enables the WSPI subsystem. + */ +#if !defined(HAL_USE_WSPI) || defined(__DOXYGEN__) +#define HAL_USE_WSPI FALSE +#endif + +/*===========================================================================*/ +/* PAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) +#define PAL_USE_CALLBACKS FALSE +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) +#define PAL_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/** + * @brief Enforces the driver to use direct callbacks rather than OSAL events. + */ +#if !defined(CAN_ENFORCE_USE_CALLBACKS) || defined(__DOXYGEN__) +#define CAN_ENFORCE_USE_CALLBACKS FALSE +#endif + +/*===========================================================================*/ +/* CRY driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + +/*===========================================================================*/ +/* DAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the zero-copy API. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Timeout before assuming a failure while waiting for card idle. + * @note Time is in milliseconds. + */ +#if !defined(MMC_IDLE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define MMC_IDLE_TIMEOUT_MS 1000 +#endif + +/** + * @brief Mutual exclusion on the SPI bus. + */ +#if !defined(MMC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define MMC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief OCR initialization constant for V20 cards. + */ +#if !defined(SDC_INIT_OCR_V20) || defined(__DOXYGEN__) +#define SDC_INIT_OCR_V20 0x50FF8000U +#endif + +/** + * @brief OCR initialization constant for non-V20 cards. + */ +#if !defined(SDC_INIT_OCR) || defined(__DOXYGEN__) +#define SDC_INIT_OCR 0x80100000U +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 16 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SIO driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SIO_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SIO_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Support for thread synchronization API. + */ +#if !defined(SIO_USE_SYNCHRONIZATION) || defined(__DOXYGEN__) +#define SIO_USE_SYNCHRONIZATION TRUE +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 256 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/** + * @brief Serial over USB number of buffers. + * @note The default is 2 buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_NUMBER 2 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Inserts an assertion on function errors before returning. + */ +#if !defined(SPI_USE_ASSERT_ON_ERROR) || defined(__DOXYGEN__) +#define SPI_USE_ASSERT_ON_ERROR TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +#endif + +/*===========================================================================*/ +/* UART driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__) +#define UART_USE_WAIT FALSE +#endif + +/** + * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define UART_USE_MUTUAL_EXCLUSION FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT FALSE +#endif + +/*===========================================================================*/ +/* WSPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__) +#define WSPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define WSPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* HALCONF_H */ + +/** @} */ diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/main.c b/testhal/AT32/AT32F4xx/USB_CDC_IAD/main.c new file mode 100644 index 0000000000..ff61145549 --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/main.c @@ -0,0 +1,192 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include + +#include "ch.h" +#include "hal.h" + +#include "shell.h" +#include "chprintf.h" + +#include "usbcfg.h" + +#define LINE_LED LINE_LED1 + +/*===========================================================================*/ +/* Command line related. */ +/*===========================================================================*/ + +#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(2048) + +/* Can be measured using dd if=/dev/xxxx of=/dev/null bs=512 count=10000.*/ +static void cmd_write(BaseSequentialStream *chp, int argc, char *argv[]) { + static uint8_t buf[] = + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + + (void)argv; + if (argc > 0) { + chprintf(chp, "Usage: write\r\n"); + return; + } + + while (chnGetTimeout((BaseChannel *)chp, TIME_IMMEDIATE) == Q_TIMEOUT) { +#if 1 + /* Writing in channel mode.*/ + chnWrite(&SDU1, buf, sizeof buf - 1); +#else + /* Writing in buffer mode.*/ + (void) obqGetEmptyBufferTimeout(&SDU1.obqueue, TIME_INFINITE); + memcpy(SDU1.obqueue.ptr, buf, SERIAL_USB_BUFFERS_SIZE); + obqPostFullBuffer(&SDU1.obqueue, SERIAL_USB_BUFFERS_SIZE); +#endif + } + chprintf(chp, "\r\n\nstopped\r\n"); +} + +static const ShellCommand commands[] = { + {"write", cmd_write}, + {NULL, NULL} +}; + +static const ShellConfig shell_cfg1 = { + (BaseSequentialStream *)&SDU1, + commands +}; + +static const ShellConfig shell_cfg2 = { + (BaseSequentialStream *)&SDU2, + commands +}; + +/*===========================================================================*/ +/* Generic code. */ +/*===========================================================================*/ + +/* + * Red LED blinker thread, times are in milliseconds. + */ +static THD_WORKING_AREA(waThread1, 128); +static THD_FUNCTION(Thread1, arg) { + + (void)arg; + chRegSetThreadName("blinker"); + while (true) { + systime_t time = serusbcfg1.usbp->state == USB_ACTIVE ? 250 : 500; + palClearLine(LINE_LED); + chThdSleepMilliseconds(time); + palSetLine(LINE_LED); + chThdSleepMilliseconds(time); + } +} + +/* + * Application entry point. + */ +int main(void) { + thread_t *shelltp1 = NULL; + thread_t *shelltp2 = NULL; + event_listener_t shell_el; + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* + * Initializes two serial-over-USB CDC drivers. + */ + sduObjectInit(&SDU1); + sduStart(&SDU1, &serusbcfg1); + sduObjectInit(&SDU2); + sduStart(&SDU2, &serusbcfg2); + + /* + * Activates the USB driver and then the USB bus pull-up on D+. + * Note, a delay is inserted in order to not have to disconnect the cable + * after a reset. + */ + usbDisconnectBus(serusbcfg1.usbp); + chThdSleepMilliseconds(1500); + usbStart(serusbcfg1.usbp, &usbcfg); + usbConnectBus(serusbcfg1.usbp); + + /* + * Shell manager initialization. + * Event zero is shell exit. + */ + shellInit(); + chEvtRegister(&shell_terminated, &shell_el, 0); + + /* + * Creates the blinker thread. + */ + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); + + /* + * Normal main() thread activity, managing two shells. + */ + while (true) { + if (SDU1.config->usbp->state == USB_ACTIVE) { + /* Starting shells.*/ + if (shelltp1 == NULL) { + shelltp1 = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, + "shell1", NORMALPRIO + 1, + shellThread, (void *)&shell_cfg1); + } + if (shelltp2 == NULL) { + shelltp2 = chThdCreateFromHeap(NULL, SHELL_WA_SIZE, + "shell2", NORMALPRIO + 1, + shellThread, (void *)&shell_cfg2); + } + + /* Waiting for an exit event then freeing terminated shells.*/ + chEvtWaitAny(EVENT_MASK(0)); + if (chThdTerminatedX(shelltp1)) { + chThdRelease(shelltp1); + shelltp1 = NULL; + } + if (chThdTerminatedX(shelltp2)) { + chThdRelease(shelltp2); + shelltp2 = NULL; + } + } + else { + chThdSleepMilliseconds(1000); + } + } +} diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/mcuconf.h b/testhal/AT32/AT32F4xx/USB_CDC_IAD/mcuconf.h new file mode 100644 index 0000000000..819613e15d --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/mcuconf.h @@ -0,0 +1,407 @@ +/* + ChibiOS - Copyright (C) 2006..2020 Giovanni Di Sirio + + Licensed 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 MCUCONF_H +#define MCUCONF_H + +/* + * STM32F4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#define STM32F4xx_MCUCONF +#define STM32F437_MCUCONF + +/* + * Config pll clock resource + * common frequency config list: pll source selected hick or hext (8mhz) + * _________________________________________________________________________________________________ + * | | | | | | | | | | | + * |pll(mhz)| 288 | 252 | 216 | 192 | 180 | 144 | 108 | 72 | 36 | + * |________|_________|_________|_________|_________|_________|_________|_________|_________________| + * | | | | | | | | | | | + * |pll_ns | 144 | 126 | 108 | 96 | 90 | 72 | 108 | 72 | 72 | + * | | | | | | | | | | | + * |pll_ms | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | + * | | | | | | | | | | | + * |pll_fr | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_4 | FR_8 | FR_8 | FR_16| + * |________|_________|_________|_________|_________|_________|_________|_________|________|________| + * + * if pll clock source selects hext with other frequency values, or configure pll to other + * frequency values, please use the at32 new clock configuration tool for configuration. + */ + +#if 0 +/* Defaults for 96MHz from DS */ +#define STM32_PLLM_VALUE 2 +#define STM32_PLLN_VALUE 192 +#define STM32_PLLP_VALUE 8 +#define STM32_PPRE1 STM32_PPRE1_DIV1 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV1 /* max 144 MHz */ +#endif + +#if 0 +/* 144 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 72 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV1 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV1 /* max 144 MHz */ +#endif + +#if 0 +/* 216 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 108 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV2 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV2 /* max 144 MHz */ +#endif + +#if 1 +/* 288 MHz */ +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 144 +#define STM32_PLLP_VALUE 4 +#define STM32_PPRE1 STM32_PPRE1_DIV2 /* max 144 MHz */ +#define STM32_PPRE2 STM32_PPRE2_DIV2 /* max 144 MHz */ +#endif + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_BKPRAM_ENABLE FALSE +#define STM32_HSI_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED TRUE +#define STM32_LSE_ENABLED FALSE +#define STM32_CLOCK48_REQUIRED TRUE +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_RTCSEL STM32_RTCSEL_LSI +#define STM32_RTCPRE_VALUE 8 +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI16_PRIORITY 6 +#define STM32_IRQ_EXTI17_PRIORITY 15 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_PRIORITY 15 +#define STM32_IRQ_EXTI22_PRIORITY 15 + +#define STM32_IRQ_TIM1_BRK_TIM9_PRIORITY 7 +#define STM32_IRQ_TIM1_UP_TIM10_PRIORITY 7 +#define STM32_IRQ_TIM1_TRGCO_TIM11_PRIORITY 7 +#define STM32_IRQ_TIM1_CC_PRIORITY 7 +#define STM32_IRQ_TIM2_PRIORITY 7 +#define STM32_IRQ_TIM3_PRIORITY 7 +#define STM32_IRQ_TIM4_PRIORITY 7 +#define STM32_IRQ_TIM5_PRIORITY 7 +#define STM32_IRQ_TIM6_PRIORITY 7 +#define STM32_IRQ_TIM7_PRIORITY 7 +#define STM32_IRQ_TIM8_BRK_TIM12_PRIORITY 7 +#define STM32_IRQ_TIM8_UP_TIM13_PRIORITY 7 +#define STM32_IRQ_TIM8_TRGCO_TIM14_PRIORITY 7 +#define STM32_IRQ_TIM8_CC_PRIORITY 7 + +#define STM32_IRQ_USART1_PRIORITY 12 +#define STM32_IRQ_USART2_PRIORITY 12 +#define STM32_IRQ_USART3_PRIORITY 12 +#define STM32_IRQ_UART4_PRIORITY 12 +#define STM32_IRQ_UART5_PRIORITY 12 +#define STM32_IRQ_USART6_PRIORITY 12 +#define STM32_IRQ_UART7_PRIORITY 12 +#define STM32_IRQ_UART8_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4 +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_USE_ADC2 FALSE +#define STM32_ADC_USE_ADC3 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#define STM32_ADC_IRQ_PRIORITY 6 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6 +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6 +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_USE_CAN2 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 +#define STM32_CAN_CAN2_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM5 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM8 FALSE +#define STM32_GPT_USE_TIM9 FALSE +#define STM32_GPT_USE_TIM10 FALSE +#define STM32_GPT_USE_TIM11 FALSE +#define STM32_GPT_USE_TIM12 FALSE +#define STM32_GPT_USE_TIM13 FALSE +#define STM32_GPT_USE_TIM14 FALSE + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C2_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C2_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * I2S driver system settings. + */ +#define STM32_I2S_USE_SPI2 FALSE +#define STM32_I2S_USE_SPI3 FALSE +#define STM32_I2S_SPI2_IRQ_PRIORITY 10 +#define STM32_I2S_SPI3_IRQ_PRIORITY 10 +#define STM32_I2S_SPI2_DMA_PRIORITY 1 +#define STM32_I2S_SPI3_DMA_PRIORITY 1 +#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2S_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM5 FALSE +#define STM32_ICU_USE_TIM8 FALSE +#define STM32_ICU_USE_TIM9 FALSE +#define STM32_ICU_USE_TIM10 FALSE +#define STM32_ICU_USE_TIM11 FALSE +#define STM32_ICU_USE_TIM12 FALSE +#define STM32_ICU_USE_TIM13 FALSE +#define STM32_ICU_USE_TIM14 FALSE + +/* + * MAC driver system settings. + */ +#define STM32_MAC_TRANSMIT_BUFFERS 2 +#define STM32_MAC_RECEIVE_BUFFERS 4 +#define STM32_MAC_BUFFERS_SIZE 1522 +#define STM32_MAC_PHY_TIMEOUT 100 +#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE +#define STM32_MAC_ETH1_IRQ_PRIORITY 13 +#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM4 FALSE +#define STM32_PWM_USE_TIM5 FALSE +#define STM32_PWM_USE_TIM8 FALSE +#define STM32_PWM_USE_TIM9 FALSE +#define STM32_PWM_USE_TIM10 FALSE +#define STM32_PWM_USE_TIM11 FALSE +#define STM32_PWM_USE_TIM12 FALSE +#define STM32_PWM_USE_TIM13 FALSE +#define STM32_PWM_USE_TIM14 FALSE + +/* + * RTC driver system settings. + */ +#define STM32_RTC_PRESA_VALUE 32 +#define STM32_RTC_PRESS_VALUE 1024 +#define STM32_RTC_CR_INIT 0 +#define STM32_RTC_TAMPCR_INIT 0 + +/* + * SDC driver system settings. + */ +#define STM32_SDC_SDIO_DMA_PRIORITY 3 +#define STM32_SDC_SDIO_IRQ_PRIORITY 9 +#define STM32_SDC_WRITE_TIMEOUT_MS 1000 +#define STM32_SDC_READ_TIMEOUT_MS 1000 +#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10 +#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE +#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USE_USART6 FALSE + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_USE_SPI4 FALSE +#define STM32_SPI_USE_SPI5 FALSE +#define STM32_SPI_USE_SPI6 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_SPI_SPI6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI4_DMA_PRIORITY 1 +#define STM32_SPI_SPI5_DMA_PRIORITY 1 +#define STM32_SPI_SPI6_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_SPI4_IRQ_PRIORITY 10 +#define STM32_SPI_SPI5_IRQ_PRIORITY 10 +#define STM32_SPI_SPI6_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USE_UART4 FALSE +#define STM32_UART_USE_UART5 FALSE +#define STM32_UART_USE_USART6 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_UART4_DMA_PRIORITY 0 +#define STM32_UART_UART5_DMA_PRIORITY 0 +#define STM32_UART_USART6_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_OTG1 TRUE +#define STM32_USB_USE_OTG2 TRUE +#define STM32_USB_OTG1_IRQ_PRIORITY 14 +#define STM32_USB_OTG2_IRQ_PRIORITY 14 +#define STM32_USB_OTG1_RX_FIFO_SIZE 512 +#define STM32_USB_OTG2_RX_FIFO_SIZE 1024 +#define STM32_USB_HOST_WAKEUP_DURATION 2 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +#endif /* MCUCONF_H */ diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/readme.txt b/testhal/AT32/AT32F4xx/USB_CDC_IAD/readme.txt new file mode 100644 index 0000000000..87bd704f6f --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/readme.txt @@ -0,0 +1,26 @@ +***************************************************************************** +** ChibiOS/HAL - USB-CDC (IAD descriptors) driver demo for STM32F4xx. ** +***************************************************************************** + +** TARGET ** + +The demo runs on an Olimex STM32-E407 board. + +** The Demo ** + +The application demonstrates the use of the STM32F4xx USB driver. + +** Build Procedure ** + +The demo has been tested using the free Codesourcery GCC-based toolchain +and YAGARTO. +Just modify the TRGT line in the makefile in order to use different GCC ports. + +** Notes ** + +Some files used by the demo are not part of ChibiOS/RT but are copyright of +ST Microelectronics and are licensed under a different license. +Also note that not all the files present in the ST library are distributed +with ChibiOS/RT, you can find the whole library on the ST web site: + + http://www.st.com diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/usbcfg.c b/testhal/AT32/AT32F4xx/USB_CDC_IAD/usbcfg.c new file mode 100644 index 0000000000..f3c2a54c49 --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/usbcfg.c @@ -0,0 +1,483 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "hal.h" + +/* + * Virtual serial ports over USB. + */ +SerialUSBDriver SDU1; +SerialUSBDriver SDU2; + +#define USB_DEVICE_VID 0xF055 /* You MUST change this.*/ +#define USB_DEVICE_PID 0xE063 /* You MUST change this.*/ + +/* + * Endpoints. + */ +#define USB_INTERRUPT_REQUEST_EP_A 1 +#define USB_DATA_AVAILABLE_EP_A 2 +#define USB_DATA_REQUEST_EP_A 2 +#define USB_INTERRUPT_REQUEST_EP_B 3 +#define USB_DATA_AVAILABLE_EP_B 4 +#define USB_DATA_REQUEST_EP_B 4 + +#define USB_INTERRUPT_REQUEST_SIZE 0x10 +#define USB_DATA_SIZE 0x40 + +/* + * Interfaces + */ +#define USB_NUM_INTERFACES 4 +#define USB_CDC_CIF_NUM0 0 +#define USB_CDC_DIF_NUM0 1 +#define USB_CDC_CIF_NUM1 2 +#define USB_CDC_DIF_NUM1 3 + +/* + * USB Device Descriptor. + */ +static const uint8_t vcom_device_descriptor_data[] = { + USB_DESC_DEVICE( + 0x0200, /* bcdUSB (1.1). */ + 0xEF, /* bDeviceClass (misc). */ + 0x02, /* bDeviceSubClass (common). */ + 0x01, /* bDeviceProtocol (IAD). */ + USB_DATA_SIZE, /* bMaxPacketSize. */ + USB_DEVICE_VID, /* idVendor. */ + USB_DEVICE_PID, /* idProduct. */ + 0x0200, /* bcdDevice. */ + 1, /* iManufacturer. */ + 2, /* iProduct. */ + 3, /* iSerialNumber. */ + 1) /* bNumConfigurations. */ +}; + +/* + * Device Descriptor wrapper. + */ +static const USBDescriptor vcom_device_descriptor = { + sizeof vcom_device_descriptor_data, + vcom_device_descriptor_data +}; + +#define CDC_IF_DESC_SET_SIZE \ + (USB_DESC_INTERFACE_SIZE + 5 + 5 + 4 + 5 + USB_DESC_ENDPOINT_SIZE + \ + USB_DESC_INTERFACE_SIZE + (USB_DESC_ENDPOINT_SIZE * 2)) + +#define CDC_IF_DESC_SET(comIfNum, datIfNum, comInEp, datOutEp, datInEp) \ + /* Interface Descriptor.*/ \ + USB_DESC_INTERFACE( \ + comIfNum, /* bInterfaceNumber. */ \ + 0x00, /* bAlternateSetting. */ \ + 0x01, /* bNumEndpoints. */ \ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass. */ \ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass. */ \ + 0x01, /* bInterfaceProtocol (AT + commands, CDC section + 4.4). */ \ + 0), /* iInterface. */ \ + /* Header Functional Descriptor (CDC section 5.2.3).*/ \ + USB_DESC_BYTE (5), /* bLength. */ \ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType. */ \ + USB_DESC_BYTE (CDC_HEADER), /* bDescriptorSubtype. */ \ + USB_DESC_BCD (0x0110), /* bcdCDC. */ \ + /* Call Management Functional Descriptor.*/ \ + USB_DESC_BYTE (5), /* bFunctionLength. */ \ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType. */ \ + USB_DESC_BYTE (CDC_CALL_MANAGEMENT), /* bDescriptorSubtype. */ \ + USB_DESC_BYTE (0x03), /*******/ /* bmCapabilities. */ \ + USB_DESC_BYTE (datIfNum), /* bDataInterface. */ \ + /* Abstract Control Management Functional Descriptor.*/ \ + USB_DESC_BYTE (4), /* bFunctionLength. */ \ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType. */ \ + USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT), \ + USB_DESC_BYTE (0x02), /* bmCapabilities. */ \ + /* Union Functional Descriptor.*/ \ + USB_DESC_BYTE (5), /* bFunctionLength. */ \ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType. */ \ + USB_DESC_BYTE (CDC_UNION), /* bDescriptorSubtype. */ \ + USB_DESC_BYTE (comIfNum), /* bMasterInterface. */ \ + USB_DESC_BYTE (datIfNum), /* bSlaveInterface. */ \ + /* Endpoint, Interrupt IN.*/ \ + USB_DESC_ENDPOINT ( \ + comInEp, \ + USB_EP_MODE_TYPE_INTR, /* bmAttributes. */ \ + USB_INTERRUPT_REQUEST_SIZE, /* wMaxPacketSize. */ \ + 0x01), /* bInterval. */ \ + \ + /* CDC Data Interface Descriptor.*/ \ + USB_DESC_INTERFACE( \ + datIfNum, /* bInterfaceNumber. */ \ + 0x00, /* bAlternateSetting. */ \ + 0x02, /* bNumEndpoints. */ \ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass. */ \ + 0x00, /* bInterfaceSubClass (CDC + section 4.6). */ \ + 0x00, /* bInterfaceProtocol (CDC + section 4.7). */ \ + 0x00), /* iInterface. */ \ + /* Endpoint, Bulk OUT.*/ \ + USB_DESC_ENDPOINT( \ + datOutEp, /* bEndpointAddress. */ \ + USB_EP_MODE_TYPE_BULK, /* bmAttributes. */ \ + USB_DATA_SIZE, /* wMaxPacketSize. */ \ + 0x00), /* bInterval. */ \ + /* Endpoint, Bulk IN.*/ \ + USB_DESC_ENDPOINT( \ + datInEp, /* bEndpointAddress. */ \ + USB_EP_MODE_TYPE_BULK, /* bmAttributes. */ \ + USB_DATA_SIZE, /* wMaxPacketSize. */ \ + 0x00) /* bInterval. */ + +#define IAD_CDC_IF_DESC_SET_SIZE \ + (USB_DESC_INTERFACE_ASSOCIATION_SIZE + CDC_IF_DESC_SET_SIZE) + +#define IAD_CDC_IF_DESC_SET(comIfNum, datIfNum, comInEp, datOutEp, datInEp) \ + /* Interface Association Descriptor.*/ \ + USB_DESC_INTERFACE_ASSOCIATION( \ + comIfNum, /* bFirstInterface. */ \ + 2, /* bInterfaceCount. */ \ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass. */ \ + CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass. */ \ + 1, /* bFunctionProcotol. */ \ + 0 /* iInterface. */ \ + ), \ + /* CDC Interface descriptor set */ \ + CDC_IF_DESC_SET(comIfNum, datIfNum, comInEp, datOutEp, datInEp) + +/* Configuration Descriptor tree for a CDC.*/ +static const uint8_t vcom_configuration_descriptor_data[] = { + /* Configuration Descriptor.*/ + USB_DESC_CONFIGURATION( + USB_DESC_CONFIGURATION_SIZE + + (IAD_CDC_IF_DESC_SET_SIZE * 2), /* wTotalLength. */ + USB_NUM_INTERFACES, /* bNumInterfaces. */ + 0x01, /* bConfigurationValue. */ + 0, /* iConfiguration. */ + 0xC0, /* bmAttributes (self powered). */ + 50 /* bMaxPower (100mA). */ + ), + IAD_CDC_IF_DESC_SET( + USB_CDC_CIF_NUM0, + USB_CDC_DIF_NUM0, + USB_ENDPOINT_IN(USB_INTERRUPT_REQUEST_EP_A), + USB_ENDPOINT_OUT(USB_DATA_AVAILABLE_EP_A), + USB_ENDPOINT_IN(USB_DATA_REQUEST_EP_A) + ), + IAD_CDC_IF_DESC_SET( + USB_CDC_CIF_NUM1, + USB_CDC_DIF_NUM1, + USB_ENDPOINT_IN(USB_INTERRUPT_REQUEST_EP_B), + USB_ENDPOINT_OUT(USB_DATA_AVAILABLE_EP_B), + USB_ENDPOINT_IN(USB_DATA_REQUEST_EP_B) + ), +}; + +/* + * Configuration Descriptor wrapper. + */ +static const USBDescriptor vcom_configuration_descriptor = { + sizeof vcom_configuration_descriptor_data, + vcom_configuration_descriptor_data +}; + +/* + * U.S. English language identifier. + */ +static const uint8_t vcom_string0[] = { + USB_DESC_BYTE(4), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */ +}; + +/* + * Vendor string. + */ +static const uint8_t vcom_string1[] = { + USB_DESC_BYTE(38), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0, + 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0, + 'c', 0, 's', 0 +}; + +/* + * Device Description string. + */ +static const uint8_t vcom_string2[] = { + USB_DESC_BYTE(56), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0, + 'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, + 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, + 'o', 0, 'r', 0, 't', 0 +}; + +/* + * Serial Number string. + */ +static const uint8_t vcom_string3[] = { + USB_DESC_BYTE(8), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + '0' + CH_KERNEL_MAJOR, 0, + '0' + CH_KERNEL_MINOR, 0, + '0' + CH_KERNEL_PATCH, 0 +}; + +/* + * Strings wrappers array. + */ +static const USBDescriptor vcom_strings[] = { + {sizeof vcom_string0, vcom_string0}, + {sizeof vcom_string1, vcom_string1}, + {sizeof vcom_string2, vcom_string2}, + {sizeof vcom_string3, vcom_string3} +}; + +/* + * Handles the GET_DESCRIPTOR callback. All required descriptors must be + * handled here. + */ +static const USBDescriptor *get_descriptor(USBDriver *usbp, + uint8_t dtype, + uint8_t dindex, + uint16_t lang) { + + (void)usbp; + (void)lang; + switch (dtype) { + case USB_DESCRIPTOR_DEVICE: + return &vcom_device_descriptor; + case USB_DESCRIPTOR_CONFIGURATION: + return &vcom_configuration_descriptor; + case USB_DESCRIPTOR_STRING: + if (dindex < 4) + return &vcom_strings[dindex]; + } + return NULL; +} + +/** + * @brief IN EP1 state. + */ +static USBInEndpointState ep1instate; + +/** + * @brief EP1 initialization structure (IN only). + */ +static const USBEndpointConfig ep1config = { + USB_EP_MODE_TYPE_INTR, + NULL, + sduInterruptTransmitted, + NULL, + USB_INTERRUPT_REQUEST_SIZE, + 0x0000, + &ep1instate, + NULL, + 1, + NULL +}; + +/** + * @brief IN EP2 state. + */ +static USBInEndpointState ep2instate; + +/** + * @brief OUT EP2 state. + */ +static USBOutEndpointState ep2outstate; + +/** + * @brief EP2 initialization structure (both IN and OUT). + */ +static const USBEndpointConfig ep2config = { + USB_EP_MODE_TYPE_BULK, + NULL, + sduDataTransmitted, + sduDataReceived, + USB_DATA_SIZE, + USB_DATA_SIZE, + &ep2instate, + &ep2outstate, + 2, + NULL +}; + +/** + * @brief IN EP3 state. + */ +static USBInEndpointState ep3instate; + +/** + * @brief EP3 initialization structure (IN only). + */ +static const USBEndpointConfig ep3config = { + USB_EP_MODE_TYPE_INTR, + NULL, + sduInterruptTransmitted, + NULL, + USB_INTERRUPT_REQUEST_SIZE, + 0x0000, + &ep3instate, + NULL, + 1, + NULL +}; + +/** + * @brief IN EP4 state. + */ +static USBInEndpointState ep4instate; + +/** + * @brief OUT EP4 state. + */ +static USBOutEndpointState ep4outstate; + +/** + * @brief EP4 initialization structure (both IN and OUT). + */ +static const USBEndpointConfig ep4config = { + USB_EP_MODE_TYPE_BULK, + NULL, + sduDataTransmitted, + sduDataReceived, + USB_DATA_SIZE, + USB_DATA_SIZE, + &ep4instate, + &ep4outstate, + 2, + NULL +}; + +/* + * Handles the USB driver global events. + */ +static void usb_event(USBDriver *usbp, usbevent_t event) { + extern SerialUSBDriver SDU1; + extern SerialUSBDriver SDU2; + + switch (event) { + case USB_EVENT_ADDRESS: + return; + case USB_EVENT_CONFIGURED: + chSysLockFromISR(); + + if (usbp->state == USB_ACTIVE) { + /* Enables the endpoints specified into the configuration. + Note, this callback is invoked from an ISR so I-Class functions + must be used.*/ + usbInitEndpointI(usbp, USB_INTERRUPT_REQUEST_EP_A, &ep1config); + usbInitEndpointI(usbp, USB_DATA_REQUEST_EP_A, &ep2config); + usbInitEndpointI(usbp, USB_INTERRUPT_REQUEST_EP_B, &ep3config); + usbInitEndpointI(usbp, USB_DATA_REQUEST_EP_B, &ep4config); + + /* Resetting the state of the CDC subsystem.*/ + sduConfigureHookI(&SDU1); + sduConfigureHookI(&SDU2); + } + else if (usbp->state == USB_SELECTED) { + usbDisableEndpointsI(usbp); + } + + chSysUnlockFromISR(); + return; + case USB_EVENT_RESET: + /* Falls into.*/ + case USB_EVENT_UNCONFIGURED: + /* Falls into.*/ + case USB_EVENT_SUSPEND: + chSysLockFromISR(); + + /* Disconnection event on suspend.*/ + sduSuspendHookI(&SDU1); + sduSuspendHookI(&SDU2); + + chSysUnlockFromISR(); + return; + case USB_EVENT_WAKEUP: + chSysLockFromISR(); + + /* Connection event on wakeup.*/ + sduWakeupHookI(&SDU1); + sduWakeupHookI(&SDU2); + + chSysUnlockFromISR(); + return; + case USB_EVENT_STALLED: + return; + } + return; +} + +/* + * Handling messages not implemented in the default handler nor in the + * SerialUSB handler. + */ +static bool requests_hook(USBDriver *usbp) { + + if (((usbp->setup[0] & USB_RTYPE_RECIPIENT_MASK) == USB_RTYPE_RECIPIENT_INTERFACE) && + (usbp->setup[1] == USB_REQ_SET_INTERFACE)) { + usbSetupTransfer(usbp, NULL, 0, NULL); + return true; + } + return sduRequestsHook(usbp); +} + +/* + * Handles the USB driver global events. + */ +static void sof_handler(USBDriver *usbp) { + + (void)usbp; + + osalSysLockFromISR(); + sduSOFHookI(&SDU1); + sduSOFHookI(&SDU2); + osalSysUnlockFromISR(); +} + +/* + * USB driver configuration. + */ +const USBConfig usbcfg = { + usb_event, + get_descriptor, + requests_hook, + sof_handler +}; + +/* + * Serial over USB driver configuration 1. + */ +const SerialUSBConfig serusbcfg1 = { + &USBD1, + USB_DATA_REQUEST_EP_A, + USB_DATA_AVAILABLE_EP_A, + USB_INTERRUPT_REQUEST_EP_A +}; + +/* + * Serial over USB driver configuration 2. + */ +const SerialUSBConfig serusbcfg2 = { + &USBD1, + USB_DATA_REQUEST_EP_B, + USB_DATA_AVAILABLE_EP_B, + USB_INTERRUPT_REQUEST_EP_B +}; diff --git a/testhal/AT32/AT32F4xx/USB_CDC_IAD/usbcfg.h b/testhal/AT32/AT32F4xx/USB_CDC_IAD/usbcfg.h new file mode 100644 index 0000000000..e08d8461a8 --- /dev/null +++ b/testhal/AT32/AT32F4xx/USB_CDC_IAD/usbcfg.h @@ -0,0 +1,28 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + Licensed 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 USBCFG_H +#define USBCFG_H + +extern const USBConfig usbcfg; +extern SerialUSBConfig serusbcfg1; +extern SerialUSBConfig serusbcfg2; +extern SerialUSBDriver SDU1; +extern SerialUSBDriver SDU2; + +#endif /* USBCFG_H */ + +/** @} */ diff --git a/tools/provide_gcc.sh b/tools/provide_gcc.sh new file mode 100755 index 0000000000..867ff13821 --- /dev/null +++ b/tools/provide_gcc.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# Download and extract GCC arm-none-eabi toolchain + +set -e + +# URL to download original toolchain from +URL="https://github.com/rusefi/build_support/raw/master/rusefi-arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi.tar.xz" +# This is the md5sum of the /bin/arm-none-eabi-ld executable within the archive, used for verifying we have the proper version. +# If you change the above URL, you will need to update this checksum as well. +MANIFEST_SUM="8e50ee1adb41acfd56fc38d74d6bb18e" +# colloquial directory name, to afford re-use of script +COLLOQUIAL="gcc-arm-none-eabi" +# temporary working directory +TMP_DIR="/tmp/rusefi-provide_gcc" + +archive="${URL##*/}" + +SWD="$PWD" + +# If the checksum file doesn't exist, or if its checksum doesn't match, then download and install the archive. +if [ ! -f "${TMP_DIR}"/*/bin/arm-none-eabi-ld ] ||\ + [ "$MANIFEST_SUM" != "$(md5sum ${TMP_DIR}/*/bin/arm-none-eabi-ld | cut -d ' ' -f 1)" ]; then + rm -rf "${TMP_DIR}" + # Download and extract archive + echo Downloading and extracting ${archive} + mkdir -p "${TMP_DIR}" + cd "${TMP_DIR}" + curl -L -o "${archive}" "${URL}" + tar -xaf "${archive}" + rm "${archive}" +else + echo "Toolkit already present" +fi + +# Create colloquially named link +cd "$SWD" +ln -sf "${TMP_DIR}"/* "${COLLOQUIAL}"