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}"