aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/STM32/STM32L4xx
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-11-12 15:13:56 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-11-12 15:13:56 +0000
commita23a891953e5c2cd96f2ba067c5c1661fd0c76b8 (patch)
tree1b3bc0e9871f6ccafa44aa6a19b35c6b88b971d0 /os/hal/ports/STM32/STM32L4xx
parentdc3bc84a7168edd0b36f5eed12d4e712c10144b4 (diff)
downloadChibiOS-a23a891953e5c2cd96f2ba067c5c1661fd0c76b8.tar.gz
ChibiOS-a23a891953e5c2cd96f2ba067c5c1661fd0c76b8.tar.bz2
ChibiOS-a23a891953e5c2cd96f2ba067c5c1661fd0c76b8.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8472 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/ports/STM32/STM32L4xx')
-rw-r--r--os/hal/ports/STM32/STM32L4xx/hal_lld.c167
-rw-r--r--os/hal/ports/STM32/STM32L4xx/hal_lld.h733
-rw-r--r--os/hal/ports/STM32/STM32L4xx/stm32_rcc.h18
-rw-r--r--os/hal/ports/STM32/STM32L4xx/stm32_registry.h2
4 files changed, 813 insertions, 107 deletions
diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.c b/os/hal/ports/STM32/STM32L4xx/hal_lld.c
index 0be1fa067..2991c420b 100644
--- a/os/hal/ports/STM32/STM32L4xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.c
@@ -15,15 +15,13 @@
*/
/**
- * @file STM32L1xx/hal_lld.c
- * @brief STM32L1xx HAL subsystem low level driver source.
+ * @file STM32L4xx/hal_lld.c
+ * @brief STM32L4xx HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
-/* TODO: LSEBYP like in F3.*/
-
#include "hal.h"
/*===========================================================================*/
@@ -36,9 +34,9 @@
/**
* @brief CMSIS system core clock variable.
- * @note It is declared in system_stm32l1xx.h.
+ * @note It is declared in system_stm32f7xx.h.
*/
-uint32_t SystemCoreClock = STM32_SYSCLK;
+uint32_t SystemCoreClock = STM32_HCLK;
/*===========================================================================*/
/* Driver local variables and types. */
@@ -50,37 +48,45 @@ uint32_t SystemCoreClock = STM32_SYSCLK;
/**
* @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;
+ PWR->CR1 |= PWR_CR1_DBP;
/* Reset BKP domain if different clock source selected.*/
- if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL){
+ if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) {
/* Backup domain reset.*/
- RCC->CSR |= RCC_CSR_RTCRST;
- RCC->CSR &= ~RCC_CSR_RTCRST;
+ RCC->BDCR = RCC_BDCR_BDRST;
+ RCC->BDCR = 0;
}
/* If enabled then the LSE is started.*/
#if STM32_LSE_ENABLED
- RCC->CSR |= RCC_CSR_LSEON;
- while ((RCC->CSR & RCC_CSR_LSERDY) == 0)
- ; /* Waits until LSE is stable. */
+#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_RTCSEL != STM32_RTCSEL_NOCLOCK
+#if HAL_USE_RTC
/* If the backup domain hasn't been initialized yet then proceed with
initialization.*/
- if ((RCC->CSR & RCC_CSR_RTCEN) == 0) {
+ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) {
/* Selects clock source.*/
- RCC->CSR |= STM32_RTCSEL;
+ RCC->BDCR |= STM32_RTCSEL;
/* RTC clock enabled.*/
- RCC->CSR |= RCC_CSR_RTCEN;
+ RCC->BDCR |= RCC_BDCR_RTCEN;
}
-#endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */
+#endif /* HAL_USE_RTC */
}
/*===========================================================================*/
@@ -98,9 +104,13 @@ static void hal_lld_backup_domain_init(void) {
*/
void hal_lld_init(void) {
- /* Reset of all peripherals.*/
- rccResetAHB(~RCC_AHBRSTR_FLITFRST);
- rccResetAPB1(~RCC_APB1RSTR_PWRRST);
+ /* Reset of all peripherals. AHB3 is not reseted because it could have
+ been initialized in the board initialization file (board.c).*/
+ rccResetAHB1(~0);
+ rccResetAHB2(~0);
+ rccResetAHB3(~0);
+ rccResetAPB1R1(~RCC_APB1RSTR1_PWRRST);
+ rccResetAPB1R2(~0);
rccResetAPB2(~0);
/* PWR clock enabled.*/
@@ -115,47 +125,45 @@ void hal_lld_init(void) {
/* Programmable voltage detector enable.*/
#if STM32_PVD_ENABLE
- PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK);
+ PWR->CR1 |= PWR_CR1_PVDE | (STM32_PLS & STM32_PLS_MASK);
#endif /* STM32_PVD_ENABLE */
}
/**
- * @brief STM32L1xx voltage, clocks and PLL initialization.
+ * @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
*/
-/**
- * @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. */
+ RCC->APB1ENR1 = RCC_APB1ENR1_PWREN;
/* 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;
+ RCC->CR = RCC_CR_MSION | STM32_MSIRANGE_4M;
while ((RCC->CR & RCC_CR_MSIRDY) == 0)
- ; /* Waits until MSI is stable. */
+ ; /* 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. */
-#if STM32_HSI_ENABLED
+ /* 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)
- ; /* Waits until HSI is stable. */
+ ; /* Wait until HSI is stable. */
#endif
#if STM32_HSE_ENABLED
@@ -166,51 +174,72 @@ void stm32_clock_init(void) {
/* HSE activation.*/
RCC->CR |= RCC_CR_HSEON;
while ((RCC->CR & RCC_CR_HSERDY) == 0)
- ; /* Waits until HSE is stable. */
+ ; /* Wait 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. */
+ ; /* Wait until LSI 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. */
+ RCC->PLLCFGR = STM32_PLLQ | STM32_PLLSRC | STM32_PLLP | STM32_PLLN |
+ STM32_PLLM;
+ RCC->CR |= RCC_CR_PLLON;
+
+ /* Waiting for PLL lock.*/
+ while ((RCC->CR & RCC_CR_PLLRDY) == 0)
+ ;
+#endif /* STM32_OVERDRIVE_REQUIRED */
+
+#if STM32_ACTIVATE_PLLSAI1
+ /* PLLSAI activation.*/
+ RCC->PLLSAI1CFGR = STM32_PLLSAI1R | STM32_PLLSAI1Q | STM32_PLLSAI1P |
+ STM32_PLLSAI1N;
+ RCC->CR |= RCC_CR_PLLSAI1ON;
+
+ /* Waiting for PLL lock.*/
+ while ((RCC->CR & RCC_CR_PLLSAI1RDY) == 0)
+ ;
#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;
+ 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 = 0;
+#if STM32_SAI2SEL != STM32_SAI2SEL_OFF
+ dckcfgr1 |= STM32_SAI2SEL;
+#endif
+#if STM32_SAI1SEL != STM32_SAI1SEL_OFF
+ dckcfgr1 |= STM32_SAI1SEL;
#endif
-#if defined(STM32_FLASHBITS2)
- FLASH->ACR = STM32_FLASHBITS2;
+#if STM32_PLLSAIDIVR != STM32_PLLSAIDIVR_OFF
+ dckcfgr1 |= STM32_PLLSAIDIVR;
#endif
+ RCC->DCKCFGR1 = dckcfgr1;
+ }
+
+ /* Peripheral clock sources.*/
+ RCC->DCKCFGR2 = STM32_SDMMCSEL | STM32_CK48MSEL | STM32_CECSEL |
+ STM32_LPTIM1SEL | STM32_I2C4SEL | 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;
- /* Switching to the configured clock source if it is different from MSI.*/
-#if (STM32_SW != STM32_SW_MSI)
+ /* 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))
;
diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.h b/os/hal/ports/STM32/STM32L4xx/hal_lld.h
index f0255badb..9a468b5ef 100644
--- a/os/hal/ports/STM32/STM32L4xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.h
@@ -70,7 +70,7 @@
* @name Internal clock sources
* @{
*/
-#define STM32_HSICLK 16000000 /**< High speed internal clock. */
+#define STM32_HSI16CLK 16000000 /**< High speed internal clock. */
#define STM32_LSICLK 38000 /**< Low speed internal clock. */
/** @} */
@@ -606,56 +606,56 @@
* @brief USART1 clock source.
*/
#if !defined(STM32_USART1SEL) || defined(__DOXYGEN__)
-#define STM32_USART1SEL STM32_USART1SEL_PCLK2
+#define STM32_USART1SEL STM32_USART1SEL_SYSCLK
#endif
/**
* @brief USART2 clock source.
*/
#if !defined(STM32_USART2SEL) || defined(__DOXYGEN__)
-#define STM32_USART2SEL STM32_USART2SEL_PCLK1
+#define STM32_USART2SEL STM32_USART2SEL_SYSCLK
#endif
/**
* @brief USART3 clock source.
*/
#if !defined(STM32_USART3SEL) || defined(__DOXYGEN__)
-#define STM32_USART3SEL STM32_USART3SEL_PCLK1
+#define STM32_USART3SEL STM32_USART3SEL_SYSCLK
#endif
/**
* @brief UART4 clock source.
*/
#if !defined(STM32_UART4SEL) || defined(__DOXYGEN__)
-#define STM32_UART4SEL STM32_UART4SEL_PCLK1
+#define STM32_UART4SEL STM32_UART4SEL_SYSCLK
#endif
/**
* @brief UART5 clock source.
*/
#if !defined(STM32_UART5SEL) || defined(__DOXYGEN__)
-#define STM32_UART5SEL STM32_UART5SEL_PCLK1
+#define STM32_UART5SEL STM32_UART5SEL_SYSCLK
#endif
/**
* @brief I2C1 clock source.
*/
#if !defined(STM32_I2C1SEL) || defined(__DOXYGEN__)
-#define STM32_I2C1SEL STM32_I2C1SEL_PCLK1
+#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK
#endif
/**
* @brief I2C2 clock source.
*/
#if !defined(STM32_I2C2SEL) || defined(__DOXYGEN__)
-#define STM32_I2C2SEL STM32_I2C2SEL_PCLK1
+#define STM32_I2C2SEL STM32_I2C2SEL_SYSCLK
#endif
/**
* @brief I2C3 clock source.
*/
#if !defined(STM32_I2C3SEL) || defined(__DOXYGEN__)
-#define STM32_I2C3SEL STM32_I2C3SEL_PCLK1
+#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK
#endif
/**
@@ -736,6 +736,10 @@
/* 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
@@ -839,6 +843,17 @@
* @brief Maximum APB2 clock frequency.
*/
#define STM32_PCLK2_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
@@ -863,6 +878,11 @@
#define STM32_PCLK1_MAX 26000000
#define STM32_PCLK2_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
@@ -979,7 +999,7 @@
#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \
((STM32_MCOSEL == STM32_MCOSEL_PLL) && \
(STM32_PLLSRC == STM32_PLLSRC_HSE))
- #error "HSE not enabled, required by STM32_MCO1SEL"
+ #error "HSE not enabled, required by STM32_MCOSEL"
#endif
#if ((STM32_SAI1SEL == STM32_SAI1SEL_PLLSAI1) | \
@@ -1069,7 +1089,7 @@
#define STM32_PLLCLKIN (STM32_MSICLK / STM32_PLLM_VALUE)
#elif STM32_PLLSRC == STM32_PLLSRC_HSI16
-#define STM32_PLLCLKIN (STM32_HSICLK / STM32_PLLM_VALUE)
+#define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE)
#else
#error "invalid STM32_PLLSRC value specified"
@@ -1135,7 +1155,7 @@
#define STM32_PLLQ (2 << 21)
#elif STM32_PLLQ_VALUE == 8
-#define STM32_PLLQ (3 << 121)
+#define STM32_PLLQ (3 << 21)
#else
#error "invalid STM32_PLLQ_VALUE value specified"
@@ -1145,16 +1165,16 @@
* @brief STM32_PLLR field.
*/
#if (STM32_PLLR_VALUE == 2) || defined(__DOXYGEN__)
-#define STM32_PLLR (0 << 21)
+#define STM32_PLLR (0 << 25)
#elif STM32_PLLR_VALUE == 4
-#define STM32_PLLR (1 << 21)
+#define STM32_PLLR (1 << 25)
#elif STM32_PLLR_VALUE == 6
-#define STM32_PLLR (2 << 21)
+#define STM32_PLLR (2 << 25)
#elif STM32_PLLR_VALUE == 8
-#define STM32_PLLR (3 << 21)
+#define STM32_PLLR (3 << 25)
#else
#error "invalid STM32_PLLR_VALUE value specified"
@@ -1164,7 +1184,8 @@
* @brief STM32_PLLPEN field.
*/
#if (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \
- (STM32_SAI2SEL == STM32_SAI2SEL_PLL)
+ (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \
+ defined(__DOXYGEN__)
#define STM32_PLLPEN (1 << 16)
#else
#define STM32_PLLPEN (0 << 16)
@@ -1173,7 +1194,7 @@
/**
* @brief STM32_PLLQEN field.
*/
-#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL)
+#if (STM32_CLK48SEL == STM32_CLK48SEL_PLL) || defined(__DOXYGEN__)
#define STM32_PLLQEN (1 << 20)
#else
#define STM32_PLLQEN (0 << 20)
@@ -1183,7 +1204,8 @@
* @brief STM32_PLLREN field.
*/
#if (STM32_SW == STM32_SW_PLL) || \
- (STM32_MCOSEL == STM32_MCOSEL_PLL)
+ (STM32_MCOSEL == STM32_MCOSEL_PLL) || \
+ defined(__DOXYGEN__)
#define STM32_PLLREN (1 << 24)
#else
#define STM32_PLLREN (0 << 24)
@@ -1237,6 +1259,679 @@
#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_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
+
+/**
+ * @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_PLL) || \
+ (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \
+ defined(__DOXYGEN__)
+/**
+ * @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
+
+/**
+ * @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_PLL) || 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)
+
+/*
+ * PLLSAI2 VCO frequency range check.
+ */
+#if (STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || \
+ (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)
+#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)"
+#endif
+
+/**
+ * @brief PLLSAI1-P output clock frequency.
+ */
+#define STM32_PLLSAI1_P_CLKOUT (STM32_PLLSAI1VCO / STM32_PLLSAI1P_VALUE)
+
+/**
+ * @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_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_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_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__)
+/**
+ * @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
+
+/**
+ * @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_PLLSAI2VCO < STM32_PLLVCO_MIN) || \
+ (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)
+#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)"
+#endif
+
+/**
+ * @brief PLLSAI2-P output clock frequency.
+ */
+#define STM32_PLLSAI2_P_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2P_VALUE)
+
+/**
+ * @brief PLLSAI2-R output clock frequency.
+ */
+#define STM32_PLLSAI2_R_CLKOUT (STM32_PLLSAI2VCO / STM32_PLLSAI2R_VALUE)
+
+/*
+ * PLLSAI2-P output frequency range check.
+ */
+#if (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_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
+
+#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 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 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 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 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 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 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_HSI16
+#define STM32_I2C1CLK STM32_HSI16CLK
+#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_HSI16
+#define STM32_I2C2CLK STM32_HSI16CLK
+#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_HSI16
+#define STM32_I2C3CLK STM32_HSI16CLK
+#else
+#error "invalid source selected for I2C3 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_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 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_NOCLK) || defined(__DOXYGEN__)
+#define STM32_48CLK 0
+#elif STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1
+#define STM32_48CLK (STM32_PLLVCO / 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 SDMMC frequency.
+ */
+#define STM32_SDMMCCLK 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 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
+
+#else
+#define STM32_FLASHBITS 0x00000004
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h b/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h
index 6fe564702..434ddde16 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h
@@ -60,8 +60,6 @@
*/
#define rccEnableAPB1R1(mask, lp) { \
RCC->APB1ENR1 |= (mask); \
- if (lp) \
- RCC->APB1LPENR1 |= (mask); \
}
/**
@@ -74,7 +72,6 @@
*/
#define rccDisableAPB1R1(mask, lp) { \
RCC->APB1ENR1 &= ~(mask); \
- RCC->APB1LPENR1 &= ~(mask); \
}
/**
@@ -99,8 +96,6 @@
*/
#define rccEnableAPB1R2(mask, lp) { \
RCC->APB1ENR2 |= (mask); \
- if (lp) \
- RCC->APB1LPENR2 |= (mask); \
}
/**
@@ -113,7 +108,6 @@
*/
#define rccDisableAPB1R2(mask, lp) { \
RCC->APB1ENR2 &= ~(mask); \
- RCC->APB1LPENR2 &= ~(mask); \
}
/**
@@ -138,8 +132,6 @@
*/
#define rccEnableAPB2(mask, lp) { \
RCC->APB2ENR |= (mask); \
- if (lp) \
- RCC->APB2LPENR |= (mask); \
}
/**
@@ -152,7 +144,6 @@
*/
#define rccDisableAPB2(mask, lp) { \
RCC->APB2ENR &= ~(mask); \
- RCC->APB2LPENR &= ~(mask); \
}
/**
@@ -177,8 +168,6 @@
*/
#define rccEnableAHB1(mask, lp) { \
RCC->AHB1ENR |= (mask); \
- if (lp) \
- RCC->AHB1LPENR |= (mask); \
}
/**
@@ -191,7 +180,6 @@
*/
#define rccDisableAHB1(mask, lp) { \
RCC->AHB1ENR &= ~(mask); \
- RCC->AHB1LPENR &= ~(mask); \
}
/**
@@ -216,8 +204,6 @@
*/
#define rccEnableAHB2(mask, lp) { \
RCC->AHB2ENR |= (mask); \
- if (lp) \
- RCC->AHB2LPENR |= (mask); \
}
/**
@@ -230,7 +216,6 @@
*/
#define rccDisableAHB2(mask, lp) { \
RCC->AHB2ENR &= ~(mask); \
- RCC->AHB2LPENR &= ~(mask); \
}
/**
@@ -255,8 +240,6 @@
*/
#define rccEnableAHB3(mask, lp) { \
RCC->AHB3ENR |= (mask); \
- if (lp) \
- RCC->AHB3LPENR |= (mask); \
}
/**
@@ -269,7 +252,6 @@
*/
#define rccDisableAHB3(mask, lp) { \
RCC->AHB3ENR &= ~(mask); \
- RCC->AHB3LPENR &= ~(mask); \
}
/**
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
index 9564a541b..9c9a9ed78 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
@@ -254,7 +254,7 @@
#define STM32_TIM1_CC_NUMBER 27
#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_IS_32BITS TRUE
#define STM32_TIM2_CHANNELS 4
#define STM32_TIM2_HANDLER VectorB0
#define STM32_TIM2_NUMBER 28