diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..ed4609fb18
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,35 @@
+#
+# see https://help.github.com/articles/dealing-with-line-endings/
+#
+
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
+
+# Explicitly declare text files you want to always be normalized and converted
+# to Unix line endings on checkout.
+*.c text eol=lf
+*.cpp text eol=lf
+*.h text eol=lf
+*.xml text eol=lf
+*.mk text eol=lf
+*.java text eol=lf
+*.bat text eol=lf
+*.sh text eol=lf
+*.iml text eol=lf
+*.txt text eol=lf
+*.yaml text eol=lf
+*.ini text eol=lf
+*.input text eol=lf
+*.rules text eol=lf
+
+# KiCad files
+*.dsn text eol=lf
+*.kicad_pcb text eol=lf
+*.net text eol=lf
+*.pro text eol=lf
+*.sch text eol=lf
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+
diff --git a/os/hal/ports/STM32/LLD/ADCv1/driver.mk b/os/hal/ports/STM32/LLD/ADCv1/driver.mk
index a3b76492a7..b0d340498d 100644
--- a/os/hal/ports/STM32/LLD/ADCv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/ADCv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1
diff --git a/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
index a8733f9340..e2076fb4ca 100644
--- a/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
+++ b/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.c
@@ -1,485 +1,485 @@
-/*
- 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 ADCv1/hal_adc_lld.c
- * @brief STM32 ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define ADC1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
-
-/* Headers differences patches.*/
-#if defined(ADC_IER_AWDIE) && !defined(ADC_IER_AWD1IE)
-#define ADC_IER_AWD1IE ADC_IER_AWDIE
-#endif
-
-#if defined(ADC_ISR_AWD) && !defined(ADC_ISR_AWD1)
-#define ADC_ISR_AWD1 ADC_ISR_AWD
-#endif
-
-#define TR1 TR
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief ADC voltage regulator enable.
- *
- * @param[in] adc pointer to the ADC registers block
- */
-NOINLINE static void adc_lld_vreg_on(ADC_TypeDef *adc) {
-
- osalDbgAssert(adc->CR == 0, "invalid register state");
-
-#if defined(ADC_CR_ADVREGEN)
- adc->CR = ADC_CR_ADVREGEN;
- volatile uint32_t loop = (STM32_HCLK >> 20) << 4;
- do {
- loop--;
- } while (loop > 0);
-#else
-#endif
-}
-
-/**
- * @brief Stops an ongoing conversion, if any.
- *
- * @param[in] adc pointer to the ADC registers block
- */
-static void adc_lld_stop_adc(ADC_TypeDef *adc) {
-
- if (adc->CR & ADC_CR_ADSTART) {
- adc->CR |= ADC_CR_ADSTP;
- while (adc->CR & ADC_CR_ADSTP)
- ;
- adc->IER = 0;
- }
-}
-
-/**
- * @brief ADC DMA service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-#if !defined(STM32_ADC1_HANDLER)
-#error "STM32_ADC1_HANDLER not defined"
-#endif
-/**
- * @brief ADC interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- adc_lld_serve_interrupt(&ADCD1);
-
-#if defined(STM32_ADC_ADC1_IRQ_HOOK)
- STM32_ADC_ADC1_IRQ_HOOK
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = ADC1;
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-
- /* The vector is initialized on driver initialization and never
- disabled.*/
- nvicEnableVector(12, STM32_ADC_ADC1_IRQ_PRIORITY);
-#endif
-
- /* Calibration procedure.*/
- rccEnableADC1(true);
-
- /* CCR setup.*/
-#if STM32_ADC_SUPPORTS_PRESCALER
- ADC->CCR = STM32_ADC_PRESC << 18;
-#else
- ADC->CCR = 0;
-#endif
-
- /* Regulator enabled and stabilized before calibration.*/
- adc_lld_vreg_on(ADC1);
-
- ADC1->CR |= ADC_CR_ADCAL;
- while (ADC1->CR & ADC_CR_ADCAL)
- ;
- ADC1->CR = 0;
- rccDisableADC1();
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
- STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
- rccEnableADC1(true);
-
- /* DMA setup.*/
- dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1);
-#endif
-
- /* Clock settings.*/
- adcp->adc->CFGR2 = STM32_ADC_ADC1_CKMODE;
- }
-#endif /* STM32_ADC_USE_ADC1 */
-
- /* Regulator enabled and stabilized before calibration.*/
- adc_lld_vreg_on(ADC1);
-
- /* ADC initial setup, starting the analog part here in order to reduce
- the latency when starting a conversion.*/
- adcp->adc->CR = ADC_CR_ADEN;
- while (!(adcp->adc->ISR & ADC_ISR_ADRDY))
- ;
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock and analog part.*/
- if (adcp->state == ADC_READY) {
-
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
- /* Restoring CCR default.*/
-#if STM32_ADC_SUPPORTS_PRESCALER
- ADC->CCR = STM32_ADC_PRESC << 18;
-#else
- ADC->CCR = 0;
-#endif
-
- /* Disabling ADC.*/
- if (adcp->adc->CR & ADC_CR_ADEN) {
- adc_lld_stop_adc(adcp->adc);
- adcp->adc->CR |= ADC_CR_ADDIS;
- while (adcp->adc->CR & ADC_CR_ADDIS)
- ;
- }
-
- /* Regulator and anything else off.*/
- adcp->adc->CR = 0;
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp)
- rccDisableADC1();
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t mode, cfgr1;
- const ADCConversionGroup *grpp = adcp->grpp;
-
- /* DMA setup.*/
- mode = adcp->dmamode;
- cfgr1 = grpp->cfgr1 | ADC_CFGR1_DMAEN;
- if (grpp->circular) {
- mode |= STM32_DMA_CR_CIRC;
- cfgr1 |= ADC_CFGR1_DMACFG;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- mode |= STM32_DMA_CR_HTIE;
- }
- }
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
- dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- dmaStreamSetMode(adcp->dmastp, mode);
- dmaStreamEnable(adcp->dmastp);
-
- /* ADC setup, if it is defined a callback for the analog watch dog then it
- is enabled.*/
- adcp->adc->ISR = adcp->adc->ISR;
- adcp->adc->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE;
- adcp->adc->TR1 = grpp->tr;
- adcp->adc->SMPR = grpp->smpr;
- adcp->adc->CHSELR = grpp->chselr;
-
- /* ADC configuration and start.*/
- adcp->adc->CFGR1 = cfgr1;
-#if STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE
- {
- uint32_t cfgr2 = adcp->adc->CFGR2 & STM32_ADC_CKMODE_MASK;
- adcp->adc->CFGR2 = cfgr2 | grpp->cfgr2;
- }
-#endif
-
- /* ADC conversion start.*/
- adcp->adc->CR |= ADC_CR_ADSTART;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- dmaStreamDisable(adcp->dmastp);
- adc_lld_stop_adc(adcp->adc);
-}
-
-/**
- * @brief ISR code.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_serve_interrupt(ADCDriver *adcp) {
- uint32_t isr;
-
- isr = adcp->adc->ISR;
- adcp->adc->ISR = isr;
-
- /* It could be a spurious interrupt caused by overflows after DMA disabling,
- just ignore it in this case.*/
- if (adcp->grpp != NULL) {
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((isr & ADC_ISR_OVR) &&
- (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
- }
- if (isr & ADC_ISR_AWD1) {
- /* Analog watchdog error.*/
- _adc_isr_error_code(adcp, ADC_ERR_AWD);
- }
- }
-}
-
-/**
- * @brief Enables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVREF(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC->CCR |= ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Disables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVREF(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC->CCR &= ~ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Enables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableTS(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC->CCR |= ADC_CCR_TSEN;
-}
-
-/**
- * @brief Disables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableTS(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC->CCR &= ~ADC_CCR_TSEN;
-}
-
-#if defined(ADC_CCR_VBATEN) || defined(__DOXYGEN__)
-/**
- * @brief Enables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVBAT(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC->CCR |= ADC_CCR_VBATEN;
-}
-
-/**
- * @brief Disables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVBAT(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC->CCR &= ~ADC_CCR_VBATEN;
-}
-#endif /* defined(ADC_CCR_VBATEN) */
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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 ADCv1/hal_adc_lld.c
+ * @brief STM32 ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define ADC1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
+
+/* Headers differences patches.*/
+#if defined(ADC_IER_AWDIE) && !defined(ADC_IER_AWD1IE)
+#define ADC_IER_AWD1IE ADC_IER_AWDIE
+#endif
+
+#if defined(ADC_ISR_AWD) && !defined(ADC_ISR_AWD1)
+#define ADC_ISR_AWD1 ADC_ISR_AWD
+#endif
+
+#define TR1 TR
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC voltage regulator enable.
+ *
+ * @param[in] adc pointer to the ADC registers block
+ */
+NOINLINE static void adc_lld_vreg_on(ADC_TypeDef *adc) {
+
+ osalDbgAssert(adc->CR == 0, "invalid register state");
+
+#if defined(ADC_CR_ADVREGEN)
+ adc->CR = ADC_CR_ADVREGEN;
+ volatile uint32_t loop = (STM32_HCLK >> 20) << 4;
+ do {
+ loop--;
+ } while (loop > 0);
+#else
+#endif
+}
+
+/**
+ * @brief Stops an ongoing conversion, if any.
+ *
+ * @param[in] adc pointer to the ADC registers block
+ */
+static void adc_lld_stop_adc(ADC_TypeDef *adc) {
+
+ if (adc->CR & ADC_CR_ADSTART) {
+ adc->CR |= ADC_CR_ADSTP;
+ while (adc->CR & ADC_CR_ADSTP)
+ ;
+ adc->IER = 0;
+ }
+}
+
+/**
+ * @brief ADC DMA service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+#if !defined(STM32_ADC1_HANDLER)
+#error "STM32_ADC1_HANDLER not defined"
+#endif
+/**
+ * @brief ADC interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ adc_lld_serve_interrupt(&ADCD1);
+
+#if defined(STM32_ADC_ADC1_IRQ_HOOK)
+ STM32_ADC_ADC1_IRQ_HOOK
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = ADC1;
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+
+ /* The vector is initialized on driver initialization and never
+ disabled.*/
+ nvicEnableVector(12, STM32_ADC_ADC1_IRQ_PRIORITY);
+#endif
+
+ /* Calibration procedure.*/
+ rccEnableADC1(true);
+
+ /* CCR setup.*/
+#if STM32_ADC_SUPPORTS_PRESCALER
+ ADC->CCR = STM32_ADC_PRESC << 18;
+#else
+ ADC->CCR = 0;
+#endif
+
+ /* Regulator enabled and stabilized before calibration.*/
+ adc_lld_vreg_on(ADC1);
+
+ ADC1->CR |= ADC_CR_ADCAL;
+ while (ADC1->CR & ADC_CR_ADCAL)
+ ;
+ ADC1->CR = 0;
+ rccDisableADC1();
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+ rccEnableADC1(true);
+
+ /* DMA setup.*/
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1);
+#endif
+
+ /* Clock settings.*/
+ adcp->adc->CFGR2 = STM32_ADC_ADC1_CKMODE;
+ }
+#endif /* STM32_ADC_USE_ADC1 */
+
+ /* Regulator enabled and stabilized before calibration.*/
+ adc_lld_vreg_on(ADC1);
+
+ /* ADC initial setup, starting the analog part here in order to reduce
+ the latency when starting a conversion.*/
+ adcp->adc->CR = ADC_CR_ADEN;
+ while (!(adcp->adc->ISR & ADC_ISR_ADRDY))
+ ;
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock and analog part.*/
+ if (adcp->state == ADC_READY) {
+
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+ /* Restoring CCR default.*/
+#if STM32_ADC_SUPPORTS_PRESCALER
+ ADC->CCR = STM32_ADC_PRESC << 18;
+#else
+ ADC->CCR = 0;
+#endif
+
+ /* Disabling ADC.*/
+ if (adcp->adc->CR & ADC_CR_ADEN) {
+ adc_lld_stop_adc(adcp->adc);
+ adcp->adc->CR |= ADC_CR_ADDIS;
+ while (adcp->adc->CR & ADC_CR_ADDIS)
+ ;
+ }
+
+ /* Regulator and anything else off.*/
+ adcp->adc->CR = 0;
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp)
+ rccDisableADC1();
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t mode, cfgr1;
+ const ADCConversionGroup *grpp = adcp->grpp;
+
+ /* DMA setup.*/
+ mode = adcp->dmamode;
+ cfgr1 = grpp->cfgr1 | ADC_CFGR1_DMAEN;
+ if (grpp->circular) {
+ mode |= STM32_DMA_CR_CIRC;
+ cfgr1 |= ADC_CFGR1_DMACFG;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ mode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+ dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ dmaStreamSetMode(adcp->dmastp, mode);
+ dmaStreamEnable(adcp->dmastp);
+
+ /* ADC setup, if it is defined a callback for the analog watch dog then it
+ is enabled.*/
+ adcp->adc->ISR = adcp->adc->ISR;
+ adcp->adc->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE;
+ adcp->adc->TR1 = grpp->tr;
+ adcp->adc->SMPR = grpp->smpr;
+ adcp->adc->CHSELR = grpp->chselr;
+
+ /* ADC configuration and start.*/
+ adcp->adc->CFGR1 = cfgr1;
+#if STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE
+ {
+ uint32_t cfgr2 = adcp->adc->CFGR2 & STM32_ADC_CKMODE_MASK;
+ adcp->adc->CFGR2 = cfgr2 | grpp->cfgr2;
+ }
+#endif
+
+ /* ADC conversion start.*/
+ adcp->adc->CR |= ADC_CR_ADSTART;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ dmaStreamDisable(adcp->dmastp);
+ adc_lld_stop_adc(adcp->adc);
+}
+
+/**
+ * @brief ISR code.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_serve_interrupt(ADCDriver *adcp) {
+ uint32_t isr;
+
+ isr = adcp->adc->ISR;
+ adcp->adc->ISR = isr;
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (adcp->grpp != NULL) {
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((isr & ADC_ISR_OVR) &&
+ (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
+ }
+ if (isr & ADC_ISR_AWD1) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(adcp, ADC_ERR_AWD);
+ }
+ }
+}
+
+/**
+ * @brief Enables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVREF(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC->CCR |= ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Disables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVREF(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC->CCR &= ~ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Enables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableTS(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC->CCR |= ADC_CCR_TSEN;
+}
+
+/**
+ * @brief Disables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableTS(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC->CCR &= ~ADC_CCR_TSEN;
+}
+
+#if defined(ADC_CCR_VBATEN) || defined(__DOXYGEN__)
+/**
+ * @brief Enables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVBAT(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC->CCR |= ADC_CCR_VBATEN;
+}
+
+/**
+ * @brief Disables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVBAT(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC->CCR &= ~ADC_CCR_VBATEN;
+}
+#endif /* defined(ADC_CCR_VBATEN) */
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.h
index 9f8a2aa3f9..c0263cc290 100644
--- a/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv1/hal_adc_lld.h
@@ -1,417 +1,417 @@
-/*
- 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 ADCv1/hal_adc_lld.h
- * @brief STM32 ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Sampling rates
- * @{
- */
-#if defined(STM32F0XX) || defined(__DOXYGEN__)
-#define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */
-#define ADC_SMPR_SMP_7P5 1U /**< @brief 21 cycles conversion time. */
-#define ADC_SMPR_SMP_13P5 2U /**< @brief 28 cycles conversion time. */
-#define ADC_SMPR_SMP_28P5 3U /**< @brief 41 cycles conversion time. */
-#define ADC_SMPR_SMP_41P5 4U /**< @brief 54 cycles conversion time. */
-#define ADC_SMPR_SMP_55P5 5U /**< @brief 68 cycles conversion time. */
-#define ADC_SMPR_SMP_71P5 6U /**< @brief 84 cycles conversion time. */
-#define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */
-#elif defined(STM32L0XX)
-#define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */
-#define ADC_SMPR_SMP_3P5 1U /**< @brief 16 cycles conversion time. */
-#define ADC_SMPR_SMP_7P5 2U /**< @brief 20 cycles conversion time. */
-#define ADC_SMPR_SMP_12P5 3U /**< @brief 25 cycles conversion time. */
-#define ADC_SMPR_SMP_19P5 4U /**< @brief 31 cycles conversion time. */
-#define ADC_SMPR_SMP_39P5 5U /**< @brief 52 cycles conversion time. */
-#define ADC_SMPR_SMP_79P5 6U /**< @brief 92 cycles conversion time. */
-#define ADC_SMPR_SMP_160P5 7U /**< @brief 173 cycles conversion time. */
-#endif
-/** @} */
-
-/**
- * @name CFGR1 register configuration helpers
- * @{
- */
-#define ADC_CFGR1_RES_12BIT (0U << 3U)
-#define ADC_CFGR1_RES_10BIT (1U << 3U)
-#define ADC_CFGR1_RES_8BIT (2U << 3U)
-#define ADC_CFGR1_RES_6BIT (3U << 3U)
-
-#define ADC_CFGR1_EXTSEL_MASK (15U << 6U)
-#define ADC_CFGR1_EXTSEL_SRC(n) ((n) << 6U)
-
-#define ADC_CFGR1_EXTEN_MASK (3U << 10U)
-#define ADC_CFGR1_EXTEN_DISABLED (0U << 10U)
-#define ADC_CFGR1_EXTEN_RISING (1U << 10U)
-#define ADC_CFGR1_EXTEN_FALLING (2U << 10U)
-#define ADC_CFGR1_EXTEN_BOTH (3U << 10U)
-/** @} */
-
-/**
- * @name CFGR2 register configuration helpers
- * @{
- */
-#define STM32_ADC_CKMODE_MASK (3U << 30U)
-#define STM32_ADC_CKMODE_ADCCLK (0U << 30U)
-#define STM32_ADC_CKMODE_PCLK_DIV2 (1U << 30U)
-#define STM32_ADC_CKMODE_PCLK_DIV4 (2U << 30U)
-#define STM32_ADC_CKMODE_PCLK (3U << 30U)
-
-#if (STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
-#define ADC_CFGR2_OVSR_MASK (7U << 2U)
-#define ADC_CFGR2_OVSR_2X (0U << 2U)
-#define ADC_CFGR2_OVSR_4X (1U << 2U)
-#define ADC_CFGR2_OVSR_8X (2U << 2U)
-#define ADC_CFGR2_OVSR_16X (3U << 2U)
-#define ADC_CFGR2_OVSR_32X (4U << 2U)
-#define ADC_CFGR2_OVSR_64X (5U << 2U)
-#define ADC_CFGR2_OVSR_128X (6U << 2U)
-#define ADC_CFGR2_OVSR_256X (7U << 2U)
-
-#define ADC_CFGR2_OVSS_MASK (15 << 5U)
-#define ADC_CFGR2_OVSS_SHIFT(n) ((n) << 5U)
-#endif
-/** @} */
-
-/**
- * @name Threashold register initializer
- * @{
- */
-#define ADC_TR(low, high) (((uint32_t)(high) << 16U) | \
- (uint32_t)(low))
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC1 clock source selection.
- */
-#if !defined(STM32_ADC_ADC1_CKMODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_CKMODE STM32_ADC_CKMODE_ADCCLK
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_IRQ_PRIORITY 2
-#endif
-
-/**
- * @brief ADC1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
-#endif
-
-#if (STM32_ADC_SUPPORTS_PRESCALER == TRUE) || defined(__DOXYGEN__)
-/*
- * @brief ADC prescaler setting.
- * @note This setting has effect only in asynchronous clock mode (the
- * default, @p STM32_ADC_CKMODE_ADCCLK).
- */
-#if !defined(STM32_ADC_PRESCALER_VALUE) || defined(__DOXYGEN__)
-#define STM32_ADC_PRESCALER_VALUE 2
-#endif
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Supported devices checks.*/
-#if !defined(STM32F0XX) && !defined(STM32L0XX)
-#error "ADCv1 only supports F0 and L0 STM32 devices"
-#endif
-
-#if defined(STM32L0XX) || defined(__DOXYGEN__)
-#define STM32_ADCV1_OVERSAMPLING TRUE
-#else
-#define STM32_ADCV1_OVERSAMPLING FALSE
-#endif
-
-/* Registry checks.*/
-#if !defined(STM32_HAS_ADC1)
-#error "STM32_HAS_ADC1 not defined in registry"
-#endif
-
-#if !defined(STM32_ADC_SUPPORTS_PRESCALER)
-#error "STM32_ADC_SUPPORTS_PRESCALER not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER))
-#error "STM32_ADC1_HANDLER not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER))
-#error "STM32_ADC1_NUMBER not defined in registry"
-#endif
-
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-/* Units checks.*/
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-/* At least one ADC must be assigned.*/
-#if !STM32_ADC_USE_ADC1
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-/* ADC IRQ priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-/* DMA IRQ priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1 DMA"
-#endif
-
-/* DMA priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC1"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_ADC_USE_ADC1 && !defined(STM32_ADC_ADC1_DMA_STREAM)
-#error "ADC DMA stream not defined"
-#endif
-#if STM32_DMA_SUPPORTS_DMAMUX
-
-#else /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
-#error "invalid DMA stream associated to ADC1"
-#endif
-
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* ADC clock source checks.*/
-#if STM32_ADC_SUPPORTS_PRESCALER == TRUE
-#if STM32_ADC_PRESCALER_VALUE == 1
-#define STM32_ADC_PRESC 0U
-#elif STM32_ADC_PRESCALER_VALUE == 2
-#define STM32_ADC_PRESC 1U
-#elif STM32_ADC_PRESCALER_VALUE == 4
-#define STM32_ADC_PRESC 2U
-#elif STM32_ADC_PRESCALER_VALUE == 6
-#define STM32_ADC_PRESC 3U
-#elif STM32_ADC_PRESCALER_VALUE == 8
-#define STM32_ADC_PRESC 4U
-#elif STM32_ADC_PRESCALER_VALUE == 10
-#define STM32_ADC_PRESC 5U
-#elif STM32_ADC_PRESCALER_VALUE == 12
-#define STM32_ADC_PRESC 6U
-#elif STM32_ADC_PRESCALER_VALUE == 16
-#define STM32_ADC_PRESC 7U
-#elif STM32_ADC_PRESCALER_VALUE == 32
-#define STM32_ADC_PRESC 8U
-#elif STM32_ADC_PRESCALER_VALUE == 64
-#define STM32_ADC_PRESC 9U
-#elif STM32_ADC_PRESCALER_VALUE == 128
-#define STM32_ADC_PRESC 10U
-#elif STM32_ADC_PRESCALER_VALUE == 256
-#define STM32_ADC_PRESC 11U
-#else
-#error "Invalid value assigned to STM32_ADC_PRESCALER_VALUE"
-#endif
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Possible ADC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
- ADC_ERR_AWD = 2 /**< Analog watchdog triggered. */
-} adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* Dummy configuration, it is not needed.*/ \
- uint32_t dummy
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#if (STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
-#define adc_lld_configuration_group_fields \
- /* ADC CFGR1 register initialization data. \
- NOTE: The bits DMAEN and DMACFG are enforced internally \
- to the driver, keep them to zero. \
- NOTE: The bits @p ADC_CFGR1_CONT or @p ADC_CFGR1_DISCEN must be \
- specified in continuous more or if the buffer depth is \
- greater than one.*/ \
- uint32_t cfgr1; \
- /* ADC CFGR2 register initialization data. \
- NOTE: CKMODE bits must not be specified in this field and left to \
- zero.*/ \
- uint32_t cfgr2; \
- /* ADC TR register initialization data.*/ \
- uint32_t tr; \
- /* ADC SMPR register initialization data.*/ \
- uint32_t smpr; \
- /* ADC CHSELR register initialization data. \
- NOTE: The number of bits at logic level one in this register must \
- be equal to the number in the @p num_channels field.*/ \
- uint32_t chselr
-#else
-#define adc_lld_configuration_group_fields \
- /* ADC CFGR1 register initialization data. \
- NOTE: The bits DMAEN and DMACFG are enforced internally \
- to the driver, keep them to zero. \
- NOTE: The bits @p ADC_CFGR1_CONT or @p ADC_CFGR1_DISCEN must be \
- specified in continuous more or if the buffer depth is \
- greater than one.*/ \
- uint32_t cfgr1; \
- /* ADC TR register initialization data.*/ \
- uint32_t tr; \
- /* ADC SMPR register initialization data.*/ \
- uint32_t smpr; \
- /* ADC CHSELR register initialization data. \
- NOTE: The number of bits at logic level one in this register must \
- be equal to the number in the @p num_channels field.*/ \
- uint32_t chselr
-#endif
-
-/**
- * @brief Changes the value of the ADC CCR register.
- * @details Use this function in order to enable or disable the internal
- * analog sources. See the documentation in the STM32 Reference
- * Manual.
- * @note PRESC bits must not be specified and left to zero.
- */
-#define adcSTM32SetCCR(ccr) (ADC->CCR = (ccr))
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adc_lld_serve_interrupt(ADCDriver *adcp);
- void adcSTM32EnableVREF(ADCDriver *adcp);
- void adcSTM32DisableVREF(ADCDriver *adcp);
- void adcSTM32EnableTS(ADCDriver *adcp);
- void adcSTM32DisableTS(ADCDriver *adcp);
-#if defined(ADC_CCR_VBATEN)
- void adcSTM32EnableVBAT(ADCDriver *adcp);
- void adcSTM32DisableVBAT(ADCDriver *adcp);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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 ADCv1/hal_adc_lld.h
+ * @brief STM32 ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#if defined(STM32F0XX) || defined(__DOXYGEN__)
+#define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */
+#define ADC_SMPR_SMP_7P5 1U /**< @brief 21 cycles conversion time. */
+#define ADC_SMPR_SMP_13P5 2U /**< @brief 28 cycles conversion time. */
+#define ADC_SMPR_SMP_28P5 3U /**< @brief 41 cycles conversion time. */
+#define ADC_SMPR_SMP_41P5 4U /**< @brief 54 cycles conversion time. */
+#define ADC_SMPR_SMP_55P5 5U /**< @brief 68 cycles conversion time. */
+#define ADC_SMPR_SMP_71P5 6U /**< @brief 84 cycles conversion time. */
+#define ADC_SMPR_SMP_239P5 7U /**< @brief 252 cycles conversion time. */
+#elif defined(STM32L0XX)
+#define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */
+#define ADC_SMPR_SMP_3P5 1U /**< @brief 16 cycles conversion time. */
+#define ADC_SMPR_SMP_7P5 2U /**< @brief 20 cycles conversion time. */
+#define ADC_SMPR_SMP_12P5 3U /**< @brief 25 cycles conversion time. */
+#define ADC_SMPR_SMP_19P5 4U /**< @brief 31 cycles conversion time. */
+#define ADC_SMPR_SMP_39P5 5U /**< @brief 52 cycles conversion time. */
+#define ADC_SMPR_SMP_79P5 6U /**< @brief 92 cycles conversion time. */
+#define ADC_SMPR_SMP_160P5 7U /**< @brief 173 cycles conversion time. */
+#endif
+/** @} */
+
+/**
+ * @name CFGR1 register configuration helpers
+ * @{
+ */
+#define ADC_CFGR1_RES_12BIT (0U << 3U)
+#define ADC_CFGR1_RES_10BIT (1U << 3U)
+#define ADC_CFGR1_RES_8BIT (2U << 3U)
+#define ADC_CFGR1_RES_6BIT (3U << 3U)
+
+#define ADC_CFGR1_EXTSEL_MASK (15U << 6U)
+#define ADC_CFGR1_EXTSEL_SRC(n) ((n) << 6U)
+
+#define ADC_CFGR1_EXTEN_MASK (3U << 10U)
+#define ADC_CFGR1_EXTEN_DISABLED (0U << 10U)
+#define ADC_CFGR1_EXTEN_RISING (1U << 10U)
+#define ADC_CFGR1_EXTEN_FALLING (2U << 10U)
+#define ADC_CFGR1_EXTEN_BOTH (3U << 10U)
+/** @} */
+
+/**
+ * @name CFGR2 register configuration helpers
+ * @{
+ */
+#define STM32_ADC_CKMODE_MASK (3U << 30U)
+#define STM32_ADC_CKMODE_ADCCLK (0U << 30U)
+#define STM32_ADC_CKMODE_PCLK_DIV2 (1U << 30U)
+#define STM32_ADC_CKMODE_PCLK_DIV4 (2U << 30U)
+#define STM32_ADC_CKMODE_PCLK (3U << 30U)
+
+#if (STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
+#define ADC_CFGR2_OVSR_MASK (7U << 2U)
+#define ADC_CFGR2_OVSR_2X (0U << 2U)
+#define ADC_CFGR2_OVSR_4X (1U << 2U)
+#define ADC_CFGR2_OVSR_8X (2U << 2U)
+#define ADC_CFGR2_OVSR_16X (3U << 2U)
+#define ADC_CFGR2_OVSR_32X (4U << 2U)
+#define ADC_CFGR2_OVSR_64X (5U << 2U)
+#define ADC_CFGR2_OVSR_128X (6U << 2U)
+#define ADC_CFGR2_OVSR_256X (7U << 2U)
+
+#define ADC_CFGR2_OVSS_MASK (15 << 5U)
+#define ADC_CFGR2_OVSS_SHIFT(n) ((n) << 5U)
+#endif
+/** @} */
+
+/**
+ * @name Threashold register initializer
+ * @{
+ */
+#define ADC_TR(low, high) (((uint32_t)(high) << 16U) | \
+ (uint32_t)(low))
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief ADC1 clock source selection.
+ */
+#if !defined(STM32_ADC_ADC1_CKMODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_CKMODE STM32_ADC_CKMODE_ADCCLK
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+#endif
+
+#if (STM32_ADC_SUPPORTS_PRESCALER == TRUE) || defined(__DOXYGEN__)
+/*
+ * @brief ADC prescaler setting.
+ * @note This setting has effect only in asynchronous clock mode (the
+ * default, @p STM32_ADC_CKMODE_ADCCLK).
+ */
+#if !defined(STM32_ADC_PRESCALER_VALUE) || defined(__DOXYGEN__)
+#define STM32_ADC_PRESCALER_VALUE 2
+#endif
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Supported devices checks.*/
+#if !defined(STM32F0XX) && !defined(STM32L0XX)
+#error "ADCv1 only supports F0 and L0 STM32 devices"
+#endif
+
+#if defined(STM32L0XX) || defined(__DOXYGEN__)
+#define STM32_ADCV1_OVERSAMPLING TRUE
+#else
+#define STM32_ADCV1_OVERSAMPLING FALSE
+#endif
+
+/* Registry checks.*/
+#if !defined(STM32_HAS_ADC1)
+#error "STM32_HAS_ADC1 not defined in registry"
+#endif
+
+#if !defined(STM32_ADC_SUPPORTS_PRESCALER)
+#error "STM32_ADC_SUPPORTS_PRESCALER not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER))
+#error "STM32_ADC1_HANDLER not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER))
+#error "STM32_ADC1_NUMBER not defined in registry"
+#endif
+
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+/* Units checks.*/
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+/* At least one ADC must be assigned.*/
+#if !STM32_ADC_USE_ADC1
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+/* ADC IRQ priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1"
+#endif
+
+/* DMA IRQ priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1 DMA"
+#endif
+
+/* DMA priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC1"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_ADC_USE_ADC1 && !defined(STM32_ADC_ADC1_DMA_STREAM)
+#error "ADC DMA stream not defined"
+#endif
+#if STM32_DMA_SUPPORTS_DMAMUX
+
+#else /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
+#error "invalid DMA stream associated to ADC1"
+#endif
+
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* ADC clock source checks.*/
+#if STM32_ADC_SUPPORTS_PRESCALER == TRUE
+#if STM32_ADC_PRESCALER_VALUE == 1
+#define STM32_ADC_PRESC 0U
+#elif STM32_ADC_PRESCALER_VALUE == 2
+#define STM32_ADC_PRESC 1U
+#elif STM32_ADC_PRESCALER_VALUE == 4
+#define STM32_ADC_PRESC 2U
+#elif STM32_ADC_PRESCALER_VALUE == 6
+#define STM32_ADC_PRESC 3U
+#elif STM32_ADC_PRESCALER_VALUE == 8
+#define STM32_ADC_PRESC 4U
+#elif STM32_ADC_PRESCALER_VALUE == 10
+#define STM32_ADC_PRESC 5U
+#elif STM32_ADC_PRESCALER_VALUE == 12
+#define STM32_ADC_PRESC 6U
+#elif STM32_ADC_PRESCALER_VALUE == 16
+#define STM32_ADC_PRESC 7U
+#elif STM32_ADC_PRESCALER_VALUE == 32
+#define STM32_ADC_PRESC 8U
+#elif STM32_ADC_PRESCALER_VALUE == 64
+#define STM32_ADC_PRESC 9U
+#elif STM32_ADC_PRESCALER_VALUE == 128
+#define STM32_ADC_PRESC 10U
+#elif STM32_ADC_PRESCALER_VALUE == 256
+#define STM32_ADC_PRESC 11U
+#else
+#error "Invalid value assigned to STM32_ADC_PRESCALER_VALUE"
+#endif
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint16_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
+ ADC_ERR_AWD = 2 /**< Analog watchdog triggered. */
+} adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* Dummy configuration, it is not needed.*/ \
+ uint32_t dummy
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#if (STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
+#define adc_lld_configuration_group_fields \
+ /* ADC CFGR1 register initialization data. \
+ NOTE: The bits DMAEN and DMACFG are enforced internally \
+ to the driver, keep them to zero. \
+ NOTE: The bits @p ADC_CFGR1_CONT or @p ADC_CFGR1_DISCEN must be \
+ specified in continuous more or if the buffer depth is \
+ greater than one.*/ \
+ uint32_t cfgr1; \
+ /* ADC CFGR2 register initialization data. \
+ NOTE: CKMODE bits must not be specified in this field and left to \
+ zero.*/ \
+ uint32_t cfgr2; \
+ /* ADC TR register initialization data.*/ \
+ uint32_t tr; \
+ /* ADC SMPR register initialization data.*/ \
+ uint32_t smpr; \
+ /* ADC CHSELR register initialization data. \
+ NOTE: The number of bits at logic level one in this register must \
+ be equal to the number in the @p num_channels field.*/ \
+ uint32_t chselr
+#else
+#define adc_lld_configuration_group_fields \
+ /* ADC CFGR1 register initialization data. \
+ NOTE: The bits DMAEN and DMACFG are enforced internally \
+ to the driver, keep them to zero. \
+ NOTE: The bits @p ADC_CFGR1_CONT or @p ADC_CFGR1_DISCEN must be \
+ specified in continuous more or if the buffer depth is \
+ greater than one.*/ \
+ uint32_t cfgr1; \
+ /* ADC TR register initialization data.*/ \
+ uint32_t tr; \
+ /* ADC SMPR register initialization data.*/ \
+ uint32_t smpr; \
+ /* ADC CHSELR register initialization data. \
+ NOTE: The number of bits at logic level one in this register must \
+ be equal to the number in the @p num_channels field.*/ \
+ uint32_t chselr
+#endif
+
+/**
+ * @brief Changes the value of the ADC CCR register.
+ * @details Use this function in order to enable or disable the internal
+ * analog sources. See the documentation in the STM32 Reference
+ * Manual.
+ * @note PRESC bits must not be specified and left to zero.
+ */
+#define adcSTM32SetCCR(ccr) (ADC->CCR = (ccr))
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adc_lld_serve_interrupt(ADCDriver *adcp);
+ void adcSTM32EnableVREF(ADCDriver *adcp);
+ void adcSTM32DisableVREF(ADCDriver *adcp);
+ void adcSTM32EnableTS(ADCDriver *adcp);
+ void adcSTM32DisableTS(ADCDriver *adcp);
+#if defined(ADC_CCR_VBATEN)
+ void adcSTM32EnableVBAT(ADCDriver *adcp);
+ void adcSTM32DisableVBAT(ADCDriver *adcp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv1/notes.txt b/os/hal/ports/STM32/LLD/ADCv1/notes.txt
index 92241172a3..ec7103c3e5 100644
--- a/os/hal/ports/STM32/LLD/ADCv1/notes.txt
+++ b/os/hal/ports/STM32/LLD/ADCv1/notes.txt
@@ -1,16 +1,16 @@
-STM32 ADCv1 driver.
-
-Driver capability:
-
-- Supports the STM32 "simple" ADC, the one found on small devices (F0, L0).
-
-The file registry must export:
-
-STM32_HAS_ADC1 - ADC1 presence flag.
-STM32_ADC_SUPPORTS_PRESCALER - Support of CCR PRESC field.
-STM32_ADC_SUPPORTS_OVERSAMPLING - Support of oversampling-related fields.
-STM32_ADC1_IRQ_SHARED_WITH_EXTI - TRUE if the IRQ is shared with EXTI.
-STM32_ADC1_HANDLER - IRQ vector name.
-STM32_ADC1_NUMBER - IRQ vector number.
-STM32_ADC1_DMA_MSK - Mask of the compatible DMA channels.
-STM32_ADC1_DMA_CHN - Mask of the channels mapping.
+STM32 ADCv1 driver.
+
+Driver capability:
+
+- Supports the STM32 "simple" ADC, the one found on small devices (F0, L0).
+
+The file registry must export:
+
+STM32_HAS_ADC1 - ADC1 presence flag.
+STM32_ADC_SUPPORTS_PRESCALER - Support of CCR PRESC field.
+STM32_ADC_SUPPORTS_OVERSAMPLING - Support of oversampling-related fields.
+STM32_ADC1_IRQ_SHARED_WITH_EXTI - TRUE if the IRQ is shared with EXTI.
+STM32_ADC1_HANDLER - IRQ vector name.
+STM32_ADC1_NUMBER - IRQ vector number.
+STM32_ADC1_DMA_MSK - Mask of the compatible DMA channels.
+STM32_ADC1_DMA_CHN - Mask of the channels mapping.
diff --git a/os/hal/ports/STM32/LLD/ADCv2/driver.mk b/os/hal/ports/STM32/LLD/ADCv2/driver.mk
index 9be6513bb1..c3fa0ada15 100644
--- a/os/hal/ports/STM32/LLD/ADCv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/ADCv2/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv2
diff --git a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
index 53a5439cd4..b7a57b9793 100644
--- a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
+++ b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.c
@@ -1,452 +1,452 @@
-/*
- 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 ADCv2/hal_adc_lld.c
- * @brief STM32 ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define ADC1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
-
-#define ADC2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_CHN)
-
-#define ADC3_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/** @brief ADC2 driver identifier.*/
-#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
-ADCDriver ADCD2;
-#endif
-
-/** @brief ADC3 driver identifier.*/
-#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
-ADCDriver ADCD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief ADC DMA service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
-
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || STM32_ADC_USE_ADC3 || \
- defined(__DOXYGEN__)
-/**
- * @brief ADC interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC_HANDLER) {
- uint32_t sr;
-
- OSAL_IRQ_PROLOGUE();
-
-#if STM32_ADC_USE_ADC1
- sr = ADC1->SR;
- ADC1->SR = 0;
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- if (ADCD1.grpp != NULL)
- _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
- }
- if (sr & ADC_SR_AWD) {
- if (ADCD1.grpp != NULL) {
- _adc_isr_error_code(&ADCD1, ADC_ERR_WATCHDOG);
- }
- }
-#if defined(STM32_ADC_ADC1_IRQ_HOOK)
- STM32_ADC_ADC1_IRQ_HOOK
-#endif
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_ADC2
- sr = ADC2->SR;
- ADC2->SR = 0;
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD2.dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- if (ADCD2.grpp != NULL)
- _adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW);
- }
- if (sr & ADC_SR_AWD) {
- if (ADCD2.grpp != NULL) {
- _adc_isr_error_code(&ADCD2, ADC_ERR_WATCHDOG);
- }
- }
-#if defined(STM32_ADC_ADC2_IRQ_HOOK)
- STM32_ADC_ADC2_IRQ_HOOK
-#endif
-#endif /* STM32_ADC_USE_ADC2 */
-
-#if STM32_ADC_USE_ADC3
- sr = ADC3->SR;
- ADC3->SR = 0;
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD3.dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- if (ADCD3.grpp != NULL)
- _adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW);
- }
- if (sr & ADC_SR_AWD) {
- if (ADCD3.grpp != NULL) {
- _adc_isr_error_code(&ADCD3, ADC_ERR_WATCHDOG);
- }
- }
-#if defined(STM32_ADC_ADC3_IRQ_HOOK)
- STM32_ADC_ADC3_IRQ_HOOK
-#endif
-#endif /* STM32_ADC_USE_ADC3 */
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = ADC1;
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_ADC_USE_ADC2
- /* Driver initialization.*/
- adcObjectInit(&ADCD2);
- ADCD2.adc = ADC2;
- ADCD2.dmastp = NULL;
- ADCD2.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_ADC_USE_ADC3
- /* Driver initialization.*/
- adcObjectInit(&ADCD3);
- ADCD3.adc = ADC3;
- ADCD3.dmastp = NULL;
- ADCD3.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif
-
- /* The shared vector is initialized on driver initialization and never
- disabled because sharing.*/
- nvicEnableVector(STM32_ADC_NUMBER, STM32_ADC_IRQ_PRIORITY);
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
- STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
- dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
- rccEnableADC1(true);
- }
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_ADC2
- if (&ADCD2 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC2_DMA_STREAM,
- STM32_ADC_ADC2_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
- dmaStreamSetPeripheral(adcp->dmastp, &ADC2->DR);
- rccEnableADC2(true);
- }
-#endif /* STM32_ADC_USE_ADC2 */
-
-#if STM32_ADC_USE_ADC3
- if (&ADCD3 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC3_DMA_STREAM,
- STM32_ADC_ADC3_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
- dmaStreamSetPeripheral(adcp->dmastp, &ADC3->DR);
- rccEnableADC3(true);
- }
-#endif /* STM32_ADC_USE_ADC3 */
-
- /* This is a common register but apparently it requires that at least one
- of the ADCs is clocked in order to allow writing, see bug 3575297.*/
- ADC->CCR = (ADC->CCR & (ADC_CCR_TSVREFE | ADC_CCR_VBATE)) |
- (STM32_ADC_ADCPRE << 16);
-
- /* ADC initial setup, starting the analog part here in order to reduce
- the latency when starting a conversion.*/
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
- adcp->adc->CR2 = ADC_CR2_ADON;
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock.*/
- if (adcp->state == ADC_READY) {
-
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp)
- rccDisableADC1();
-#endif
-
-#if STM32_ADC_USE_ADC2
- if (&ADCD2 == adcp)
- rccDisableADC2();
-#endif
-
-#if STM32_ADC_USE_ADC3
- if (&ADCD3 == adcp)
- rccDisableADC3();
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t mode;
- uint32_t cr2;
- const ADCConversionGroup *grpp = adcp->grpp;
-
- /* DMA setup.*/
- mode = adcp->dmamode;
- if (grpp->circular) {
- mode |= STM32_DMA_CR_CIRC;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- mode |= STM32_DMA_CR_HTIE;
- }
- }
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
- dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- dmaStreamSetMode(adcp->dmastp, mode);
- dmaStreamEnable(adcp->dmastp);
-
- /* ADC setup.*/
- adcp->adc->SR = 0;
- adcp->adc->SMPR1 = grpp->smpr1;
- adcp->adc->SMPR2 = grpp->smpr2;
- adcp->adc->HTR = grpp->htr;
- adcp->adc->LTR = grpp->ltr;
- adcp->adc->SQR1 = grpp->sqr1 | ADC_SQR1_NUM_CH(grpp->num_channels);
- adcp->adc->SQR2 = grpp->sqr2;
- adcp->adc->SQR3 = grpp->sqr3;
-
- /* ADC configuration and start.*/
- adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;
-
- /* Enforcing the mandatory bits in CR2.*/
- cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON;
-
- /* The start method is different dependign if HW or SW triggered, the
- start is performed using the method specified in the CR2 configuration.*/
- if ((cr2 & ADC_CR2_SWSTART) != 0) {
- /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/
- adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART;
-
- /* Finally enabling ADC_CR2_SWSTART.*/
- adcp->adc->CR2 = (cr2 | ADC_CR2_CONT);
- }
- else
- adcp->adc->CR2 = cr2;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- dmaStreamDisable(adcp->dmastp);
- adcp->adc->CR1 = 0;
- /* Because ticket #822, preserving injected conversions.*/
- adcp->adc->CR2 &= ~(ADC_CR2_SWSTART);
- adcp->adc->CR2 = ADC_CR2_ADON;
-}
-
-/**
- * @brief Enables the TSVREFE bit.
- * @details The TSVREFE bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- */
-void adcSTM32EnableTSVREFE(void) {
-
- ADC->CCR |= ADC_CCR_TSVREFE;
-}
-
-/**
- * @brief Disables the TSVREFE bit.
- * @details The TSVREFE bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- */
-void adcSTM32DisableTSVREFE(void) {
-
- ADC->CCR &= ~ADC_CCR_TSVREFE;
-}
-
-/**
- * @brief Enables the VBATE bit.
- * @details The VBATE bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- */
-void adcSTM32EnableVBATE(void) {
-
- ADC->CCR |= ADC_CCR_VBATE;
-}
-
-/**
- * @brief Disables the VBATE bit.
- * @details The VBATE bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- */
-void adcSTM32DisableVBATE(void) {
-
- ADC->CCR &= ~ADC_CCR_VBATE;
-}
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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 ADCv2/hal_adc_lld.c
+ * @brief STM32 ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define ADC1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
+
+#define ADC2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_CHN)
+
+#define ADC3_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/** @brief ADC2 driver identifier.*/
+#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
+ADCDriver ADCD2;
+#endif
+
+/** @brief ADC3 driver identifier.*/
+#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
+ADCDriver ADCD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC DMA service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || STM32_ADC_USE_ADC3 || \
+ defined(__DOXYGEN__)
+/**
+ * @brief ADC interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC_HANDLER) {
+ uint32_t sr;
+
+ OSAL_IRQ_PROLOGUE();
+
+#if STM32_ADC_USE_ADC1
+ sr = ADC1->SR;
+ ADC1->SR = 0;
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ if (ADCD1.grpp != NULL)
+ _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
+ }
+ if (sr & ADC_SR_AWD) {
+ if (ADCD1.grpp != NULL) {
+ _adc_isr_error_code(&ADCD1, ADC_ERR_WATCHDOG);
+ }
+ }
+#if defined(STM32_ADC_ADC1_IRQ_HOOK)
+ STM32_ADC_ADC1_IRQ_HOOK
+#endif
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_ADC2
+ sr = ADC2->SR;
+ ADC2->SR = 0;
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD2.dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ if (ADCD2.grpp != NULL)
+ _adc_isr_error_code(&ADCD2, ADC_ERR_OVERFLOW);
+ }
+ if (sr & ADC_SR_AWD) {
+ if (ADCD2.grpp != NULL) {
+ _adc_isr_error_code(&ADCD2, ADC_ERR_WATCHDOG);
+ }
+ }
+#if defined(STM32_ADC_ADC2_IRQ_HOOK)
+ STM32_ADC_ADC2_IRQ_HOOK
+#endif
+#endif /* STM32_ADC_USE_ADC2 */
+
+#if STM32_ADC_USE_ADC3
+ sr = ADC3->SR;
+ ADC3->SR = 0;
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD3.dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ if (ADCD3.grpp != NULL)
+ _adc_isr_error_code(&ADCD3, ADC_ERR_OVERFLOW);
+ }
+ if (sr & ADC_SR_AWD) {
+ if (ADCD3.grpp != NULL) {
+ _adc_isr_error_code(&ADCD3, ADC_ERR_WATCHDOG);
+ }
+ }
+#if defined(STM32_ADC_ADC3_IRQ_HOOK)
+ STM32_ADC_ADC3_IRQ_HOOK
+#endif
+#endif /* STM32_ADC_USE_ADC3 */
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = ADC1;
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_ADC_USE_ADC2
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD2);
+ ADCD2.adc = ADC2;
+ ADCD2.dmastp = NULL;
+ ADCD2.dmamode = STM32_DMA_CR_CHSEL(ADC2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_ADC_USE_ADC3
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD3);
+ ADCD3.adc = ADC3;
+ ADCD3.dmastp = NULL;
+ ADCD3.dmamode = STM32_DMA_CR_CHSEL(ADC3_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif
+
+ /* The shared vector is initialized on driver initialization and never
+ disabled because sharing.*/
+ nvicEnableVector(STM32_ADC_NUMBER, STM32_ADC_IRQ_PRIORITY);
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+ rccEnableADC1(true);
+ }
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_ADC2
+ if (&ADCD2 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC2_DMA_STREAM,
+ STM32_ADC_ADC2_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC2->DR);
+ rccEnableADC2(true);
+ }
+#endif /* STM32_ADC_USE_ADC2 */
+
+#if STM32_ADC_USE_ADC3
+ if (&ADCD3 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC3_DMA_STREAM,
+ STM32_ADC_ADC3_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC3->DR);
+ rccEnableADC3(true);
+ }
+#endif /* STM32_ADC_USE_ADC3 */
+
+ /* This is a common register but apparently it requires that at least one
+ of the ADCs is clocked in order to allow writing, see bug 3575297.*/
+ ADC->CCR = (ADC->CCR & (ADC_CCR_TSVREFE | ADC_CCR_VBATE)) |
+ (STM32_ADC_ADCPRE << 16);
+
+ /* ADC initial setup, starting the analog part here in order to reduce
+ the latency when starting a conversion.*/
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+ adcp->adc->CR2 = ADC_CR2_ADON;
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock.*/
+ if (adcp->state == ADC_READY) {
+
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp)
+ rccDisableADC1();
+#endif
+
+#if STM32_ADC_USE_ADC2
+ if (&ADCD2 == adcp)
+ rccDisableADC2();
+#endif
+
+#if STM32_ADC_USE_ADC3
+ if (&ADCD3 == adcp)
+ rccDisableADC3();
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t mode;
+ uint32_t cr2;
+ const ADCConversionGroup *grpp = adcp->grpp;
+
+ /* DMA setup.*/
+ mode = adcp->dmamode;
+ if (grpp->circular) {
+ mode |= STM32_DMA_CR_CIRC;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ mode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+ dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ dmaStreamSetMode(adcp->dmastp, mode);
+ dmaStreamEnable(adcp->dmastp);
+
+ /* ADC setup.*/
+ adcp->adc->SR = 0;
+ adcp->adc->SMPR1 = grpp->smpr1;
+ adcp->adc->SMPR2 = grpp->smpr2;
+ adcp->adc->HTR = grpp->htr;
+ adcp->adc->LTR = grpp->ltr;
+ adcp->adc->SQR1 = grpp->sqr1 | ADC_SQR1_NUM_CH(grpp->num_channels);
+ adcp->adc->SQR2 = grpp->sqr2;
+ adcp->adc->SQR3 = grpp->sqr3;
+
+ /* ADC configuration and start.*/
+ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;
+
+ /* Enforcing the mandatory bits in CR2.*/
+ cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON;
+
+ /* The start method is different dependign if HW or SW triggered, the
+ start is performed using the method specified in the CR2 configuration.*/
+ if ((cr2 & ADC_CR2_SWSTART) != 0) {
+ /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/
+ adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART;
+
+ /* Finally enabling ADC_CR2_SWSTART.*/
+ adcp->adc->CR2 = (cr2 | ADC_CR2_CONT);
+ }
+ else
+ adcp->adc->CR2 = cr2;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ dmaStreamDisable(adcp->dmastp);
+ adcp->adc->CR1 = 0;
+ /* Because ticket #822, preserving injected conversions.*/
+ adcp->adc->CR2 &= ~(ADC_CR2_SWSTART);
+ adcp->adc->CR2 = ADC_CR2_ADON;
+}
+
+/**
+ * @brief Enables the TSVREFE bit.
+ * @details The TSVREFE bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ */
+void adcSTM32EnableTSVREFE(void) {
+
+ ADC->CCR |= ADC_CCR_TSVREFE;
+}
+
+/**
+ * @brief Disables the TSVREFE bit.
+ * @details The TSVREFE bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ */
+void adcSTM32DisableTSVREFE(void) {
+
+ ADC->CCR &= ~ADC_CCR_TSVREFE;
+}
+
+/**
+ * @brief Enables the VBATE bit.
+ * @details The VBATE bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ */
+void adcSTM32EnableVBATE(void) {
+
+ ADC->CCR |= ADC_CCR_VBATE;
+}
+
+/**
+ * @brief Disables the VBATE bit.
+ * @details The VBATE bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ */
+void adcSTM32DisableVBATE(void) {
+
+ ADC->CCR &= ~ADC_CCR_VBATE;
+}
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h
index 5202f946b7..914a7ebbe7 100644
--- a/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv2/hal_adc_lld.h
@@ -1,486 +1,486 @@
-/*
- 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 ADCv2/hal_adc_lld.h
- * @brief STM32 ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Absolute Maximum Ratings
- * @{
- */
-/**
- * @brief Minimum ADC clock frequency.
- */
-#define STM32_ADCCLK_MIN 600000
-
-/**
- * @brief Maximum ADC clock frequency.
- */
-#if defined(STM32F4XX) || defined(__DOXYGEN__)
-#define STM32_ADCCLK_MAX 36000000
-#else
-#define STM32_ADCCLK_MAX 30000000
-#endif
-/** @} */
-
-/**
- * @name Triggers selection
- * @{
- */
-#define ADC_CR2_EXTEN_MASK (3U << 28U)
-#define ADC_CR2_EXTEN_DISABLED (0U << 28U)
-#define ADC_CR2_EXTEN_RISING (1U << 28U)
-#define ADC_CR2_EXTEN_FALLING (2U << 28U)
-#define ADC_CR2_EXTEN_BOTH (3U << 28U)
-
-#define ADC_CR2_EXTSEL_MASK (15U << 24U)
-#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24U)
-/** @} */
-
-/**
- * @name ADC clock divider settings
- * @{
- */
-#define ADC_CCR_ADCPRE_DIV2 0
-#define ADC_CCR_ADCPRE_DIV4 1
-#define ADC_CCR_ADCPRE_DIV6 2
-#define ADC_CCR_ADCPRE_DIV8 3
-/** @} */
-
-/**
- * @name Available analog channels
- * @{
- */
-#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
-#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
-#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
-#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
-#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
-#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
-#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
-#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
-#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
-#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
-#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
-#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
-#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
-#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
-#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
-#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
-#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.
- @note Available onADC1 only. */
-#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference.
- @note Available onADC1 only. */
-#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT.
- @note Available onADC1 only. */
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#define ADC_SAMPLE_3 0 /**< @brief 3 cycles sampling time. */
-#define ADC_SAMPLE_15 1 /**< @brief 15 cycles sampling time. */
-#define ADC_SAMPLE_28 2 /**< @brief 28 cycles sampling time. */
-#define ADC_SAMPLE_56 3 /**< @brief 56 cycles sampling time. */
-#define ADC_SAMPLE_84 4 /**< @brief 84 cycles sampling time. */
-#define ADC_SAMPLE_112 5 /**< @brief 112 cycles sampling time. */
-#define ADC_SAMPLE_144 6 /**< @brief 144 cycles sampling time. */
-#define ADC_SAMPLE_480 7 /**< @brief 480 cycles sampling time. */
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC common clock divider.
- * @note This setting is influenced by the VDDA voltage and other
- * external conditions, please refer to the datasheet for more
- * info.
- * See section 5.3.20 "12-bit ADC characteristics".
- */
-#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV2
-#endif
-
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC2 driver enable switch.
- * @details If set to @p TRUE the support for ADC2 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_ADC_USE_ADC2) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC2 FALSE
-#endif
-
-/**
- * @brief ADC3 driver enable switch.
- * @details If set to @p TRUE the support for ADC3 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC3 FALSE
-#endif
-
-/**
- * @brief DMA stream used for ADC1 operations.
- */
-#if !defined(STM32_ADC_ADC1_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-#endif
-
-/**
- * @brief DMA stream used for ADC2 operations.
- */
-#if !defined(STM32_ADC_ADC2_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#endif
-
-/**
- * @brief DMA stream used for ADC3 operations.
- */
-#if !defined(STM32_ADC_ADC3_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC2_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC3 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC interrupt priority level setting.
- * @note This setting is shared among ADC1, ADC2 and ADC3 because
- * all ADCs share the same vector.
- */
-#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC2 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC3 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_ADC2 && !STM32_HAS_ADC2
-#error "ADC2 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
-#error "ADC3 not present in the selected device"
-#endif
-
-#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
-#error "invalid DMA stream associated to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC2 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_MSK)
-#error "invalid DMA stream associated to ADC2"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_MSK)
-#error "invalid DMA stream associated to ADC3"
-#endif
-
-/* ADC clock related settings and checks.*/
-#if STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV2
-#define STM32_ADCCLK (STM32_PCLK2 / 2)
-#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV4
-#define STM32_ADCCLK (STM32_PCLK2 / 4)
-#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV6
-#define STM32_ADCCLK (STM32_PCLK2 / 6)
-#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV8
-#define STM32_ADCCLK (STM32_PCLK2 / 8)
-#else
-#error "invalid STM32_ADC_ADCPRE value specified"
-#endif
-
-#if (STM32_ADCCLK < STM32_ADCCLK_MIN) || (STM32_ADCCLK > STM32_ADCCLK_MAX)
-#error "STM32_ADCCLK outside acceptable range (STM32_ADCCLK_MIN...STM32_ADCCLK_MAX)"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Possible ADC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
- ADC_ERR_WATCHDOG = 2 /**< ADC watchdog condition. */
-} adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* Dummy configuration, it is not needed.*/ \
- uint32_t dummy
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_configuration_group_fields \
- /* ADC CR1 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
- uint32_t cr1; \
- /* ADC CR2 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
- enforced inside the driver.*/ \
- uint32_t cr2; \
- /* ADC SMPR1 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 10...18.*/ \
- uint32_t smpr1; \
- /* ADC SMPR2 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 0...9.*/ \
- uint32_t smpr2; \
- /* ADC watchdog high threshold register. \
- NOTE: This field defines the high threshold of the analog watchdog.*/ \
- uint16_t htr; \
- /* ADC watchdog low threshold register. \
- NOTE: This field defines the low threshold of the analog watchdog.*/ \
- uint16_t ltr; \
- /* ADC SQR1 register initialization data. \
- NOTE: Conversion group sequence 13...16 + sequence length.*/ \
- uint32_t sqr1; \
- /* ADC SQR2 register initialization data. \
- NOTE: Conversion group sequence 7...12.*/ \
- uint32_t sqr2; \
- /* ADC SQR3 register initialization data. \
- NOTE: Conversion group sequence 1...6.*/ \
- uint32_t sqr3
-
-/**
- * @name Sequences building helper macros
- * @{
- */
-/**
- * @brief Number of channels in a conversion sequence.
- */
-#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
-
-#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
-#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
-#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
-#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
-#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
-#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
-
-#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
-#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
-#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
-#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
-#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
-#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
-
-#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
-#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
-#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
-#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
-/** @} */
-
-/**
- * @name Sampling rate settings helper macros
- * @{
- */
-#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
-#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
-#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
-#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
-#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
-#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
-#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
-#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
-#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
-#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
-
-#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
-#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
-#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
-#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
-#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
-#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
-#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
- sampling time. */
-#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
- sampling time. */
-#define ADC_SMPR1_SMP_VBAT(n) ((n) << 24) /**< @brief VBAT sampling time. */
-/** @} */
-
-/**
- * @name Threshold settings helper macros
- * @{
- */
-/**
- * @brief High threshold limitation.
- */
-#define ADC_HTR(n) ((n > ADC_HTR_HT) ? ADC_HTR_HT : n)
-/**
- * @brief Low threshold limitation.
- */
-#define ADC_LTR(n) ((n > ADC_LTR_LT) ? ADC_LTR_LT : n)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#if STM32_ADC_USE_ADC2 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD2;
-#endif
-
-#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adcSTM32EnableTSVREFE(void);
- void adcSTM32DisableTSVREFE(void);
- void adcSTM32EnableVBATE(void);
- void adcSTM32DisableVBATE(void);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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 ADCv2/hal_adc_lld.h
+ * @brief STM32 ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Absolute Maximum Ratings
+ * @{
+ */
+/**
+ * @brief Minimum ADC clock frequency.
+ */
+#define STM32_ADCCLK_MIN 600000
+
+/**
+ * @brief Maximum ADC clock frequency.
+ */
+#if defined(STM32F4XX) || defined(__DOXYGEN__)
+#define STM32_ADCCLK_MAX 36000000
+#else
+#define STM32_ADCCLK_MAX 30000000
+#endif
+/** @} */
+
+/**
+ * @name Triggers selection
+ * @{
+ */
+#define ADC_CR2_EXTEN_MASK (3U << 28U)
+#define ADC_CR2_EXTEN_DISABLED (0U << 28U)
+#define ADC_CR2_EXTEN_RISING (1U << 28U)
+#define ADC_CR2_EXTEN_FALLING (2U << 28U)
+#define ADC_CR2_EXTEN_BOTH (3U << 28U)
+
+#define ADC_CR2_EXTSEL_MASK (15U << 24U)
+#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24U)
+/** @} */
+
+/**
+ * @name ADC clock divider settings
+ * @{
+ */
+#define ADC_CCR_ADCPRE_DIV2 0
+#define ADC_CCR_ADCPRE_DIV4 1
+#define ADC_CCR_ADCPRE_DIV6 2
+#define ADC_CCR_ADCPRE_DIV8 3
+/** @} */
+
+/**
+ * @name Available analog channels
+ * @{
+ */
+#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
+#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
+#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
+#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
+#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
+#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
+#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
+#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
+#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
+#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
+#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
+#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
+#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
+#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
+#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
+#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
+#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.
+ @note Available onADC1 only. */
+#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference.
+ @note Available onADC1 only. */
+#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT.
+ @note Available onADC1 only. */
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#define ADC_SAMPLE_3 0 /**< @brief 3 cycles sampling time. */
+#define ADC_SAMPLE_15 1 /**< @brief 15 cycles sampling time. */
+#define ADC_SAMPLE_28 2 /**< @brief 28 cycles sampling time. */
+#define ADC_SAMPLE_56 3 /**< @brief 56 cycles sampling time. */
+#define ADC_SAMPLE_84 4 /**< @brief 84 cycles sampling time. */
+#define ADC_SAMPLE_112 5 /**< @brief 112 cycles sampling time. */
+#define ADC_SAMPLE_144 6 /**< @brief 144 cycles sampling time. */
+#define ADC_SAMPLE_480 7 /**< @brief 480 cycles sampling time. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC common clock divider.
+ * @note This setting is influenced by the VDDA voltage and other
+ * external conditions, please refer to the datasheet for more
+ * info.
+ * See section 5.3.20 "12-bit ADC characteristics".
+ */
+#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV2
+#endif
+
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief ADC2 driver enable switch.
+ * @details If set to @p TRUE the support for ADC2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ADC_USE_ADC2) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC2 FALSE
+#endif
+
+/**
+ * @brief ADC3 driver enable switch.
+ * @details If set to @p TRUE the support for ADC3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC3 FALSE
+#endif
+
+/**
+ * @brief DMA stream used for ADC1 operations.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+#endif
+
+/**
+ * @brief DMA stream used for ADC2 operations.
+ */
+#if !defined(STM32_ADC_ADC2_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#endif
+
+/**
+ * @brief DMA stream used for ADC3 operations.
+ */
+#if !defined(STM32_ADC_ADC3_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC2_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC interrupt priority level setting.
+ * @note This setting is shared among ADC1, ADC2 and ADC3 because
+ * all ADCs share the same vector.
+ */
+#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC2 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC3 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_ADC2 && !STM32_HAS_ADC2
+#error "ADC2 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
+#error "ADC3 not present in the selected device"
+#endif
+
+#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && !STM32_ADC_USE_ADC3
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
+#error "invalid DMA stream associated to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_MSK)
+#error "invalid DMA stream associated to ADC2"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_MSK)
+#error "invalid DMA stream associated to ADC3"
+#endif
+
+/* ADC clock related settings and checks.*/
+#if STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV2
+#define STM32_ADCCLK (STM32_PCLK2 / 2)
+#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV4
+#define STM32_ADCCLK (STM32_PCLK2 / 4)
+#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV6
+#define STM32_ADCCLK (STM32_PCLK2 / 6)
+#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV8
+#define STM32_ADCCLK (STM32_PCLK2 / 8)
+#else
+#error "invalid STM32_ADC_ADCPRE value specified"
+#endif
+
+#if (STM32_ADCCLK < STM32_ADCCLK_MIN) || (STM32_ADCCLK > STM32_ADCCLK_MAX)
+#error "STM32_ADCCLK outside acceptable range (STM32_ADCCLK_MIN...STM32_ADCCLK_MAX)"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint16_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
+ ADC_ERR_WATCHDOG = 2 /**< ADC watchdog condition. */
+} adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* Dummy configuration, it is not needed.*/ \
+ uint32_t dummy
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_configuration_group_fields \
+ /* ADC CR1 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
+ uint32_t cr1; \
+ /* ADC CR2 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
+ enforced inside the driver.*/ \
+ uint32_t cr2; \
+ /* ADC SMPR1 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 10...18.*/ \
+ uint32_t smpr1; \
+ /* ADC SMPR2 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 0...9.*/ \
+ uint32_t smpr2; \
+ /* ADC watchdog high threshold register. \
+ NOTE: This field defines the high threshold of the analog watchdog.*/ \
+ uint16_t htr; \
+ /* ADC watchdog low threshold register. \
+ NOTE: This field defines the low threshold of the analog watchdog.*/ \
+ uint16_t ltr; \
+ /* ADC SQR1 register initialization data. \
+ NOTE: Conversion group sequence 13...16 + sequence length.*/ \
+ uint32_t sqr1; \
+ /* ADC SQR2 register initialization data. \
+ NOTE: Conversion group sequence 7...12.*/ \
+ uint32_t sqr2; \
+ /* ADC SQR3 register initialization data. \
+ NOTE: Conversion group sequence 1...6.*/ \
+ uint32_t sqr3
+
+/**
+ * @name Sequences building helper macros
+ * @{
+ */
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
+#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
+
+#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
+#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
+#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
+#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
+#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
+#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
+
+#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
+#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
+#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
+#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
+#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
+#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
+
+#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
+#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
+#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
+#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
+/** @} */
+
+/**
+ * @name Sampling rate settings helper macros
+ * @{
+ */
+#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
+#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
+#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
+#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
+#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
+#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
+#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
+#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
+#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
+#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
+
+#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
+#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
+#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
+#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
+#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
+#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
+#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
+ sampling time. */
+#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
+ sampling time. */
+#define ADC_SMPR1_SMP_VBAT(n) ((n) << 24) /**< @brief VBAT sampling time. */
+/** @} */
+
+/**
+ * @name Threshold settings helper macros
+ * @{
+ */
+/**
+ * @brief High threshold limitation.
+ */
+#define ADC_HTR(n) ((n > ADC_HTR_HT) ? ADC_HTR_HT : n)
+/**
+ * @brief Low threshold limitation.
+ */
+#define ADC_LTR(n) ((n > ADC_LTR_LT) ? ADC_LTR_LT : n)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#if STM32_ADC_USE_ADC2 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD2;
+#endif
+
+#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adcSTM32EnableTSVREFE(void);
+ void adcSTM32DisableTSVREFE(void);
+ void adcSTM32EnableVBATE(void);
+ void adcSTM32DisableVBATE(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv2/notes.txt b/os/hal/ports/STM32/LLD/ADCv2/notes.txt
index a13d3274de..4b79a3467c 100644
--- a/os/hal/ports/STM32/LLD/ADCv2/notes.txt
+++ b/os/hal/ports/STM32/LLD/ADCv2/notes.txt
@@ -1,13 +1,13 @@
-STM32 ADCv2 driver.
-
-Driver capability:
-
-- Supports the STM32 "advanced" ADC found on F2, F4 and F7 sub-families.
-
-The file registry must export:
-
-STM32_HAS_ADCx - ADCx presence flag (1..3).
-STM32_ADC_HANDLER - IRQ vector name for ADCs (shared).
-STM32_ADC_NUMBER - IRQ vector number for ADCs (shared).
-STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels.
-STM32_ADCx_DMA_CHN - Mask of the channels mapping.
+STM32 ADCv2 driver.
+
+Driver capability:
+
+- Supports the STM32 "advanced" ADC found on F2, F4 and F7 sub-families.
+
+The file registry must export:
+
+STM32_HAS_ADCx - ADCx presence flag (1..3).
+STM32_ADC_HANDLER - IRQ vector name for ADCs (shared).
+STM32_ADC_NUMBER - IRQ vector number for ADCs (shared).
+STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels.
+STM32_ADCx_DMA_CHN - Mask of the channels mapping.
diff --git a/os/hal/ports/STM32/LLD/ADCv3/driver.mk b/os/hal/ports/STM32/LLD/ADCv3/driver.mk
index 049021c693..5812df4a24 100644
--- a/os/hal/ports/STM32/LLD/ADCv3/driver.mk
+++ b/os/hal/ports/STM32/LLD/ADCv3/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv3
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv3
diff --git a/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
index 7db9e694c4..5c5cfea1b0 100644
--- a/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
+++ b/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.c
@@ -1,1020 +1,1020 @@
-/*
- 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 ADCv3/hal_adc_lld.c
- * @brief STM32 ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define ADC1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
-
-#define ADC2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_CHN)
-
-#define ADC3_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_CHN)
-
-#define ADC4_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC4_DMA_STREAM, STM32_ADC4_DMA_CHN)
-
-#if STM32_ADC_DUAL_MODE
-#if STM32_ADC_COMPACT_SAMPLES
-/* Compact type dual mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
-#define ADC_DMA_MDMA ADC_CCR_MDMA_HWORD
-
-#else /* !STM32_ADC_COMPACT_SAMPLES */
-/* Large type dual mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
-#define ADC_DMA_MDMA ADC_CCR_MDMA_WORD
-#endif /* !STM32_ADC_COMPACT_SAMPLES */
-
-#else /* !STM32_ADC_DUAL_MODE */
-#if STM32_ADC_COMPACT_SAMPLES
-/* Compact type single mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE)
-#define ADC_DMA_MDMA ADC_CCR_MDMA_DISABLED
-
-#else /* !STM32_ADC_COMPACT_SAMPLES */
-/* Large type single mode.*/
-#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
-#define ADC_DMA_MDMA ADC_CCR_MDMA_DISABLED
-#endif /* !STM32_ADC_COMPACT_SAMPLES */
-#endif /* !STM32_ADC_DUAL_MODE */
-
-/* Addressing header differences.*/
-#if !defined(ADC_IER_OVRIE)
-#define ADC_IER_OVRIE ADC_IER_OVR
-#endif
-
-#if !defined(ADC_IER_AWD1IE)
-#define ADC_IER_AWD1IE ADC_IER_AWD1
-#endif
-
-#if !defined(ADC_ISR_ADRDY)
-#define ADC_ISR_ADRDY ADC_ISR_ADRD
-#endif
-
-/* The following bits are too different in the various headers, just
- redefining those here. Values can be overridden by placing definitions
- in hal_lld.h.*/
-#if !defined(STM32_ADC_CR_ADVREGEN)
-#define STM32_ADC_CR_ADVREGEN (1U << 28)
-#endif
-
-#if !defined(STM32_ADC_CR_DEEPPWD)
-#define STM32_ADC_CR_DEEPPWD (1U << 29)
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/** @brief ADC2 driver identifier.*/
-#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
-ADCDriver ADCD2;
-#endif
-
-/** @brief ADC3 driver identifier.*/
-#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
-ADCDriver ADCD3;
-#endif
-
-/** @brief ADC4 driver identifier.*/
-#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__)
-ADCDriver ADCD4;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const ADCConfig default_config = {
- .difsel = 0
-};
-
-static uint32_t clkmask;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables the ADC voltage regulator.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_vreg_on(ADCDriver *adcp) {
-
- adcp->adcm->CR = 0; /* See RM.*/
- adcp->adcm->CR = STM32_ADC_CR_ADVREGEN;
-#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR = STM32_ADC_CR_ADVREGEN;
-#endif
- osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
-}
-
-/**
- * @brief Disables the ADC voltage regulator.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_vreg_off(ADCDriver *adcp) {
-
- adcp->adcm->CR = 0; /* See RM.*/
- adcp->adcm->CR = STM32_ADC_CR_DEEPPWD;
-#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR = 0;
- adcp->adcs->CR = STM32_ADC_CR_DEEPPWD;
-#endif
-}
-
-/**
- * @brief Calibrates and ADC unit.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_calibrate(ADCDriver *adcp) {
-
- osalDbgAssert(adcp->adcm->CR == STM32_ADC_CR_ADVREGEN, "invalid register state");
-
- /* Differential calibration for master ADC.*/
- adcp->adcm->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF;
- adcp->adcm->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF | ADC_CR_ADCAL;
- while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0)
- ;
-
- osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
-
- /* Single-ended calibration for master ADC.*/
- adcp->adcm->CR = STM32_ADC_CR_ADVREGEN;
- adcp->adcm->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCAL;
- while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0)
- ;
-
- osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
-
-#if STM32_ADC_DUAL_MODE
- osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state");
-
- /* Differential calibration for slave ADC.*/
- adcp->adcs->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF;
- adcp->adcs->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF | ADC_CR_ADCAL;
- while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0)
- ;
-
- osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
-
- /* Single-ended calibration for slave ADC.*/
- adcp->adcs->CR = STM32_ADC_CR_ADVREGEN;
- adcp->adcs->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCAL;
- while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0)
- ;
-
- osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
-#endif
-}
-
-/**
- * @brief Enables the ADC analog circuit.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_analog_on(ADCDriver *adcp) {
-
- adcp->adcm->CR |= ADC_CR_ADEN;
- while ((adcp->adcm->ISR & ADC_ISR_ADRDY) == 0)
- ;
-#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR |= ADC_CR_ADEN;
- while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0)
- ;
-#endif
-}
-
-/**
- * @brief Disables the ADC analog circuit.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_analog_off(ADCDriver *adcp) {
-
- adcp->adcm->CR |= ADC_CR_ADDIS;
- while ((adcp->adcm->CR & ADC_CR_ADDIS) != 0)
- ;
-#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR |= ADC_CR_ADDIS;
- while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0)
- ;
-#endif
-}
-
-/**
- * @brief Stops an ongoing conversion, if any.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_stop_adc(ADCDriver *adcp) {
-
- if (adcp->adcm->CR & ADC_CR_ADSTART) {
- adcp->adcm->CR |= ADC_CR_ADSTP;
- while (adcp->adcm->CR & ADC_CR_ADSTP)
- ;
- adcp->adcm->IER = 0;
- }
-}
-
-/**
- * @brief ADC DMA service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-
-/**
- * @brief ADC IRQ service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] isr content of the ISR register
- */
-static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
-
- /* It could be a spurious interrupt caused by overflows after DMA disabling,
- just ignore it in this case.*/
- if (adcp->grpp != NULL) {
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((isr & ADC_ISR_OVR) &&
- (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
- }
- if (isr & ADC_ISR_AWD1) {
- /* Analog watchdog error.*/
- _adc_isr_error_code(adcp, ADC_ERR_AWD1);
- }
- if (isr & ADC_ISR_AWD2) {
- /* Analog watchdog error.*/
- _adc_isr_error_code(adcp, ADC_ERR_AWD2);
- }
- if (isr & ADC_ISR_AWD3) {
- /* Analog watchdog error.*/
- _adc_isr_error_code(adcp, ADC_ERR_AWD3);
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
-/**
- * @brief ADC1/ADC2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
-#if STM32_ADC_DUAL_MODE
-
- isr = ADC1->ISR;
- isr |= ADC2->ISR;
- ADC1->ISR = isr;
- ADC2->ISR = isr;
-#if defined(STM32_ADC_ADC12_IRQ_HOOK)
- STM32_ADC_ADC12_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD1, isr);
-
-#else /* !STM32_ADC_DUAL_MODE */
-
-#if STM32_ADC_USE_ADC1
- isr = ADC1->ISR;
- ADC1->ISR = isr;
-#if defined(STM32_ADC_ADC1_IRQ_HOOK)
- STM32_ADC_ADC1_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD1, isr);
-#endif
-
-#if STM32_ADC_USE_ADC2
- isr = ADC2->ISR;
- ADC2->ISR = isr;
-#if defined(STM32_ADC_ADC2_IRQ_HOOK)
- STM32_ADC_ADC2_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD2, isr);
-#endif
-
-#endif /* !STM32_ADC_DUAL_MODE */
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
-/**
- * @brief ADC3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = ADC3->ISR;
- ADC3->ISR = isr;
-#if defined(STM32_ADC_ADC3_IRQ_HOOK)
- STM32_ADC_ADC3_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#if STM32_ADC_DUAL_MODE
-/**
- * @brief ADC4 interrupt handler (as ADC3 slave).
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = ADC4->ISR;
- ADC4->ISR = isr;
-
- adc_lld_serve_interrupt(&ADCD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_DUAL_MODE */
-#endif /* STM32_ADC_USE_ADC3 */
-
-#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__)
-/**
- * @brief ADC4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = ADC4->ISR;
- ADC4->ISR = isr;
-
- adc_lld_serve_interrupt(&ADCD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_ADC4 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
- clkmask = 0;
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
-#if defined(ADC1_2_COMMON)
- ADCD1.adcc = ADC1_2_COMMON;
-#elif defined(ADC12_COMMON)
- ADCD1.adcc = ADC12_COMMON;
-#elif defined(ADC123_COMMON)
- ADCD1.adcc = ADC123_COMMON;
-#else
- ADCD1.adcc = ADC1_COMMON;
-#endif
- ADCD1.adcm = ADC1;
-#if STM32_ADC_DUAL_MODE
- ADCD1.adcs = ADC2;
-#endif
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = ADC_DMA_SIZE |
- STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_ADC2
- /* Driver initialization.*/
- adcObjectInit(&ADCD2);
-#if defined(ADC1_2_COMMON)
- ADCD2.adcc = ADC1_2_COMMON;
-#elif defined(ADC12_COMMON)
- ADCD2.adcc = ADC12_COMMON;
-#elif defined(ADC123_COMMON)
- ADCD2.adcc = ADC123_COMMON;
-#endif
- ADCD2.adcm = ADC2;
- ADCD2.dmastp = NULL;
- ADCD2.dmamode = ADC_DMA_SIZE |
- STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif /* STM32_ADC_USE_ADC2 */
-
-#if STM32_ADC_USE_ADC3
- /* Driver initialization.*/
- adcObjectInit(&ADCD3);
-#if defined(ADC3_4_COMMON)
- ADCD3.adcc = ADC3_4_COMMON;
-#elif defined(ADC345_COMMON)
- ADCD3.adcc = ADC345_COMMON;
-#elif defined(ADC123_COMMON)
- ADCD3.adcc = ADC123_COMMON;
-#else
- ADCD3.adcc = ADC3_COMMON;
-#endif
- ADCD3.adcm = ADC3;
-#if STM32_ADC_DUAL_MODE
- ADCD3.adcs = ADC4;
-#endif
- ADCD3.dmastp = NULL;
- ADCD3.dmamode = ADC_DMA_SIZE |
- STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif /* STM32_ADC_USE_ADC3 */
-
-#if STM32_ADC_USE_ADC4
- /* Driver initialization.*/
- adcObjectInit(&ADCD4);
-#if defined(ADC3_4_COMMON)
- ADCD4.adcc = ADC3_4_COMMON;
-#elif defined(ADC345_COMMON)
- ADCD4.adcc = ADC345_COMMON;
-#endif
- ADCD4.adcm = ADC4;
- ADCD4.dmastp = NULL;
- ADCD4.dmamode = ADC_DMA_SIZE |
- STM32_DMA_CR_PL(STM32_ADC_ADC4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif /* STM32_ADC_USE_ADC4 */
-
- /* IRQs setup.*/
-#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
- nvicEnableVector(STM32_ADC1_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY);
-#endif
-#if STM32_ADC_USE_ADC3
- nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
-#if STM32_ADC_DUAL_MODE
- nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
-#endif
-#endif
-#if STM32_ADC_USE_ADC4
- nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC4_IRQ_PRIORITY);
-#endif
-
- /* ADC units pre-initializations.*/
-#if defined(STM32F3XX)
-#if STM32_HAS_ADC1 && STM32_HAS_ADC2
-#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
- rccEnableADC12(true);
- rccResetADC12();
- ADC1_2_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA;
- rccDisableADC12();
-#endif
-#else
-#if STM32_ADC_USE_ADC1
- rccEnableADC12(true);
- rccResetADC12();
- ADC1_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA;
- rccDisableADC12();
-#endif
-#endif
-#if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4
- rccEnableADC34(true);
- rccResetADC34();
- ADC3_4_COMMON->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA;
- rccDisableADC34();
-#endif
-#endif
-
-#if defined(STM32L4XX) || defined(STM32L4XXP)
- rccEnableADC123(true);
- rccResetADC123();
-#if defined(ADC1_2_COMMON)
- ADC1_2_COMMON->CCR = STM32_ADC_ADC123_PRESC | STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA;
-#elif defined(ADC123_COMMON)
- ADC123_COMMON->CCR = STM32_ADC_ADC123_PRESC | STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA;
-#else
- ADC1_COMMON->CCR = STM32_ADC_ADC123_PRESC | STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA;
-#endif
-
- rccDisableADC123();
-#endif
-
-#if defined(STM32G4XX)
-#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
- rccEnableADC12(true);
- rccResetADC12();
- ADC12_COMMON->CCR = STM32_ADC_ADC12_PRESC | STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA;
- rccDisableADC12();
-#endif
-#if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4
- rccEnableADC345(true);
- rccResetADC345();
- ADC345_COMMON->CCR = STM32_ADC_ADC345_PRESC | STM32_ADC_ADC345_CLOCK_MODE | ADC_DMA_MDMA;
- rccDisableADC345();
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* Handling the default configuration.*/
- if (adcp->config == NULL) {
- adcp->config = &default_config;
- }
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
- STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- clkmask |= (1 << 0);
-#if defined(STM32F3XX) || defined(STM32G4XX)
- rccEnableADC12(true);
-#endif
-#if defined(STM32L4XX) || defined(STM32L4XXP)
- rccEnableADC123(true);
-#endif
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1);
-#endif
- }
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_ADC2
- if (&ADCD2 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC2_DMA_STREAM,
- STM32_ADC_ADC2_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- clkmask |= (1 << 1);
-#if defined(STM32F3XX) || defined(STM32G4XX)
- rccEnableADC12(true);
-#endif
-#if defined(STM32L4XX) || defined(STM32L4XXP)
- rccEnableADC123(true);
-#endif
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC2);
-#endif
- }
-#endif /* STM32_ADC_USE_ADC2 */
-
-#if STM32_ADC_USE_ADC3
- if (&ADCD3 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC3_DMA_STREAM,
- STM32_ADC_ADC3_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- clkmask |= (1 << 2);
-#if defined(STM32F3XX)
- rccEnableADC34(true);
-#endif
-#if defined(STM32L4XX) || defined(STM32L4XXP)
- rccEnableADC123(true);
-#endif
-#if defined(STM32G4XX)
- rccEnableADC345(true);
-#endif
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC3);
-#endif
- }
-#endif /* STM32_ADC_USE_ADC3 */
-
-#if STM32_ADC_USE_ADC4
- if (&ADCD4 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC4_DMA_STREAM,
- STM32_ADC_ADC4_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- clkmask |= (1 << 3);
-#if defined(STM32F3XX)
- rccEnableADC34(true);
-#endif
-#if defined(STM32L4XX) || defined(STM32L4XXP)
- rccEnableADC123(true);
-#endif
-#if defined(STM32G4XX)
- rccEnableADC345(true);
-#endif
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC4);
-#endif
- }
-#endif /* STM32_ADC_USE_ADC4 */
-
- /* Setting DMA peripheral-side pointer.*/
-#if STM32_ADC_DUAL_MODE
- dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcc->CDR);
-#else
- dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcm->DR);
-#endif
-
- /* Differential channels setting.*/
-#if STM32_ADC_DUAL_MODE
- adcp->adcm->DIFSEL = adcp->config->difsel;
- adcp->adcs->DIFSEL = adcp->config->difsel;
-#else
- adcp->adcm->DIFSEL = adcp->config->difsel;
-#endif
-
- /* Master ADC calibration.*/
- adc_lld_vreg_on(adcp);
- adc_lld_calibrate(adcp);
-
- /* Master ADC enabled here in order to reduce conversions latencies.*/
- adc_lld_analog_on(adcp);
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock and analog part.*/
- if (adcp->state == ADC_READY) {
-
- /* Releasing the associated DMA channel.*/
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
- /* Stopping the ongoing conversion, if any.*/
- adc_lld_stop_adc(adcp);
-
- /* Disabling ADC analog circuit and regulator.*/
- adc_lld_analog_off(adcp);
- adc_lld_vreg_off(adcp);
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- /* Resetting CCR options except default ones.*/
- clkmask &= ~(1 << 0);
- }
-#endif
-
-#if STM32_ADC_USE_ADC2
- if (&ADCD2 == adcp) {
- clkmask &= ~(1 << 1);
- }
-#endif
-
-#if STM32_ADC_USE_ADC3
- if (&ADCD3 == adcp) {
- clkmask &= ~(1 << 2);
- }
-#endif
-
-#if STM32_ADC_USE_ADC4
- if (&ADCD4 == adcp) {
- clkmask &= ~(1 << 3);
- }
-#endif
-
-#if defined(STM32F3XX)
-#if STM32_HAS_ADC1 || STM32_HAS_ADC2
- if ((clkmask & 0x3) == 0) {
- rccDisableADC12();
- }
-#endif
-
-#if STM32_HAS_ADC3 || STM32_HAS_ADC4
- if ((clkmask & 0xC) == 0) {
- rccDisableADC34();
- }
-#endif
-#endif
-
-#if defined(STM32L4XX) || defined(STM32L4XXP)
- if ((clkmask & 0x7) == 0) {
- rccDisableADC123();
- }
-#endif
-
-#if defined(STM32G4XX)
-#if STM32_HAS_ADC1 || STM32_HAS_ADC2
- if ((clkmask & 0x3) == 0) {
- rccDisableADC12();
- }
-#endif
-
-#if STM32_HAS_ADC3 || STM32_HAS_ADC4
- if ((clkmask & 0xC) == 0) {
- rccDisableADC345();
- }
-#endif
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t dmamode, cfgr;
- const ADCConversionGroup *grpp = adcp->grpp;
-#if STM32_ADC_DUAL_MODE
- uint32_t ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_MDMA_MASK);
-#endif
-
- osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
- "odd number of channels in dual mode");
-
- /* Calculating control registers values.*/
- dmamode = adcp->dmamode;
- cfgr = grpp->cfgr | ADC_CFGR_DMAEN;
- if (grpp->circular) {
- dmamode |= STM32_DMA_CR_CIRC;
-#if STM32_ADC_DUAL_MODE
- ccr |= ADC_CCR_DMACFG_CIRCULAR;
-#else
- cfgr |= ADC_CFGR_DMACFG_CIRCULAR;
-#endif
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- dmamode |= STM32_DMA_CR_HTIE;
- }
- }
-
- /* DMA setup.*/
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
-#if STM32_ADC_DUAL_MODE
- dmaStreamSetTransactionSize(adcp->dmastp, ((uint32_t)grpp->num_channels/2) *
- (uint32_t)adcp->depth);
-#else
- dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
-#endif
- dmaStreamSetMode(adcp->dmastp, dmamode);
- dmaStreamEnable(adcp->dmastp);
-
- /* ADC setup, if it is defined a callback for the analog watch dog then it
- is enabled.*/
- adcp->adcm->ISR = adcp->adcm->ISR;
- if (grpp->error_cb != NULL) {
- adcp->adcm->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
- | ADC_IER_AWD2IE
- | ADC_IER_AWD3IE;
- adcp->adcm->TR1 = grpp->tr1;
- adcp->adcm->TR2 = grpp->tr2;
- adcp->adcm->TR3 = grpp->tr3;
- adcp->adcm->AWD2CR = grpp->awd2cr;
- adcp->adcm->AWD3CR = grpp->awd3cr;
- }
-
-#if STM32_ADC_DUAL_MODE
-
- /* Configuring the CCR register with the user-specified settings
- in the conversion group configuration structure, static settings are
- preserved.*/
- adcp->adcc->CCR = (adcp->adcc->CCR &
- (ADC_CCR_CKMODE_MASK | ADC_CCR_MDMA_MASK)) | ccr;
-
- adcp->adcm->SMPR1 = grpp->smpr[0];
- adcp->adcm->SMPR2 = grpp->smpr[1];
- adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
- adcp->adcm->SQR2 = grpp->sqr[1];
- adcp->adcm->SQR3 = grpp->sqr[2];
- adcp->adcm->SQR4 = grpp->sqr[3];
- adcp->adcs->SMPR1 = grpp->ssmpr[0];
- adcp->adcs->SMPR2 = grpp->ssmpr[1];
- adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
- adcp->adcs->SQR2 = grpp->ssqr[1];
- adcp->adcs->SQR3 = grpp->ssqr[2];
- adcp->adcs->SQR4 = grpp->ssqr[3];
-
-#else /* !STM32_ADC_DUAL_MODE */
- adcp->adcm->SMPR1 = grpp->smpr[0];
- adcp->adcm->SMPR2 = grpp->smpr[1];
- adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
- adcp->adcm->SQR2 = grpp->sqr[1];
- adcp->adcm->SQR3 = grpp->sqr[2];
- adcp->adcm->SQR4 = grpp->sqr[3];
-#endif /* !STM32_ADC_DUAL_MODE */
-
- /* ADC configuration.*/
- adcp->adcm->CFGR = cfgr;
-#if (STM32_ADCV3_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
- adcp->adcm->CFGR2 = grpp->cfgr2;
-#endif
-
- /* Starting conversion.*/
- adcp->adcm->CR |= ADC_CR_ADSTART;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- dmaStreamDisable(adcp->dmastp);
- adc_lld_stop_adc(adcp);
-}
-
-/**
- * @brief Enables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVREF(ADCDriver *adcp) {
-
- adcp->adcc->CCR |= ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Disables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVREF(ADCDriver *adcp) {
-
- adcp->adcc->CCR &= ~ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Enables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableTS(ADCDriver *adcp) {
-
- adcp->adcc->CCR |= ADC_CCR_TSEN;
-}
-
-/**
- * @brief Disables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableTS(ADCDriver *adcp) {
-
- adcp->adcc->CCR &= ~ADC_CCR_TSEN;
-}
-
-/**
- * @brief Enables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVBAT(ADCDriver *adcp) {
-
- adcp->adcc->CCR |= ADC_CCR_VBATEN;
-}
-
-/**
- * @brief Disables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVBAT(ADCDriver *adcp) {
-
- adcp->adcc->CCR &= ~ADC_CCR_VBATEN;
-}
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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 ADCv3/hal_adc_lld.c
+ * @brief STM32 ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define ADC1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
+
+#define ADC2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_CHN)
+
+#define ADC3_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_CHN)
+
+#define ADC4_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC4_DMA_STREAM, STM32_ADC4_DMA_CHN)
+
+#if STM32_ADC_DUAL_MODE
+#if STM32_ADC_COMPACT_SAMPLES
+/* Compact type dual mode.*/
+#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+#define ADC_DMA_MDMA ADC_CCR_MDMA_HWORD
+
+#else /* !STM32_ADC_COMPACT_SAMPLES */
+/* Large type dual mode.*/
+#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
+#define ADC_DMA_MDMA ADC_CCR_MDMA_WORD
+#endif /* !STM32_ADC_COMPACT_SAMPLES */
+
+#else /* !STM32_ADC_DUAL_MODE */
+#if STM32_ADC_COMPACT_SAMPLES
+/* Compact type single mode.*/
+#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE)
+#define ADC_DMA_MDMA ADC_CCR_MDMA_DISABLED
+
+#else /* !STM32_ADC_COMPACT_SAMPLES */
+/* Large type single mode.*/
+#define ADC_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+#define ADC_DMA_MDMA ADC_CCR_MDMA_DISABLED
+#endif /* !STM32_ADC_COMPACT_SAMPLES */
+#endif /* !STM32_ADC_DUAL_MODE */
+
+/* Addressing header differences.*/
+#if !defined(ADC_IER_OVRIE)
+#define ADC_IER_OVRIE ADC_IER_OVR
+#endif
+
+#if !defined(ADC_IER_AWD1IE)
+#define ADC_IER_AWD1IE ADC_IER_AWD1
+#endif
+
+#if !defined(ADC_ISR_ADRDY)
+#define ADC_ISR_ADRDY ADC_ISR_ADRD
+#endif
+
+/* The following bits are too different in the various headers, just
+ redefining those here. Values can be overridden by placing definitions
+ in hal_lld.h.*/
+#if !defined(STM32_ADC_CR_ADVREGEN)
+#define STM32_ADC_CR_ADVREGEN (1U << 28)
+#endif
+
+#if !defined(STM32_ADC_CR_DEEPPWD)
+#define STM32_ADC_CR_DEEPPWD (1U << 29)
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/** @brief ADC2 driver identifier.*/
+#if STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
+ADCDriver ADCD2;
+#endif
+
+/** @brief ADC3 driver identifier.*/
+#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
+ADCDriver ADCD3;
+#endif
+
+/** @brief ADC4 driver identifier.*/
+#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__)
+ADCDriver ADCD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const ADCConfig default_config = {
+ .difsel = 0
+};
+
+static uint32_t clkmask;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the ADC voltage regulator.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_vreg_on(ADCDriver *adcp) {
+
+ adcp->adcm->CR = 0; /* See RM.*/
+ adcp->adcm->CR = STM32_ADC_CR_ADVREGEN;
+#if STM32_ADC_DUAL_MODE
+ adcp->adcs->CR = STM32_ADC_CR_ADVREGEN;
+#endif
+ osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
+}
+
+/**
+ * @brief Disables the ADC voltage regulator.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_vreg_off(ADCDriver *adcp) {
+
+ adcp->adcm->CR = 0; /* See RM.*/
+ adcp->adcm->CR = STM32_ADC_CR_DEEPPWD;
+#if STM32_ADC_DUAL_MODE
+ adcp->adcs->CR = 0;
+ adcp->adcs->CR = STM32_ADC_CR_DEEPPWD;
+#endif
+}
+
+/**
+ * @brief Calibrates and ADC unit.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_calibrate(ADCDriver *adcp) {
+
+ osalDbgAssert(adcp->adcm->CR == STM32_ADC_CR_ADVREGEN, "invalid register state");
+
+ /* Differential calibration for master ADC.*/
+ adcp->adcm->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF;
+ adcp->adcm->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF | ADC_CR_ADCAL;
+ while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0)
+ ;
+
+ osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
+
+ /* Single-ended calibration for master ADC.*/
+ adcp->adcm->CR = STM32_ADC_CR_ADVREGEN;
+ adcp->adcm->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCAL;
+ while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0)
+ ;
+
+ osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
+
+#if STM32_ADC_DUAL_MODE
+ osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state");
+
+ /* Differential calibration for slave ADC.*/
+ adcp->adcs->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF;
+ adcp->adcs->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCALDIF | ADC_CR_ADCAL;
+ while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0)
+ ;
+
+ osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
+
+ /* Single-ended calibration for slave ADC.*/
+ adcp->adcs->CR = STM32_ADC_CR_ADVREGEN;
+ adcp->adcs->CR = STM32_ADC_CR_ADVREGEN | ADC_CR_ADCAL;
+ while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0)
+ ;
+
+ osalSysPolledDelayX(OSAL_US2RTC(STM32_HCLK, 20));
+#endif
+}
+
+/**
+ * @brief Enables the ADC analog circuit.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_analog_on(ADCDriver *adcp) {
+
+ adcp->adcm->CR |= ADC_CR_ADEN;
+ while ((adcp->adcm->ISR & ADC_ISR_ADRDY) == 0)
+ ;
+#if STM32_ADC_DUAL_MODE
+ adcp->adcs->CR |= ADC_CR_ADEN;
+ while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0)
+ ;
+#endif
+}
+
+/**
+ * @brief Disables the ADC analog circuit.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_analog_off(ADCDriver *adcp) {
+
+ adcp->adcm->CR |= ADC_CR_ADDIS;
+ while ((adcp->adcm->CR & ADC_CR_ADDIS) != 0)
+ ;
+#if STM32_ADC_DUAL_MODE
+ adcp->adcs->CR |= ADC_CR_ADDIS;
+ while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0)
+ ;
+#endif
+}
+
+/**
+ * @brief Stops an ongoing conversion, if any.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_stop_adc(ADCDriver *adcp) {
+
+ if (adcp->adcm->CR & ADC_CR_ADSTART) {
+ adcp->adcm->CR |= ADC_CR_ADSTP;
+ while (adcp->adcm->CR & ADC_CR_ADSTP)
+ ;
+ adcp->adcm->IER = 0;
+ }
+}
+
+/**
+ * @brief ADC DMA service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+
+/**
+ * @brief ADC IRQ service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] isr content of the ISR register
+ */
+static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (adcp->grpp != NULL) {
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((isr & ADC_ISR_OVR) &&
+ (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
+ }
+ if (isr & ADC_ISR_AWD1) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(adcp, ADC_ERR_AWD1);
+ }
+ if (isr & ADC_ISR_AWD2) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(adcp, ADC_ERR_AWD2);
+ }
+ if (isr & ADC_ISR_AWD3) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(adcp, ADC_ERR_AWD3);
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 || defined(__DOXYGEN__)
+/**
+ * @brief ADC1/ADC2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+#if STM32_ADC_DUAL_MODE
+
+ isr = ADC1->ISR;
+ isr |= ADC2->ISR;
+ ADC1->ISR = isr;
+ ADC2->ISR = isr;
+#if defined(STM32_ADC_ADC12_IRQ_HOOK)
+ STM32_ADC_ADC12_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD1, isr);
+
+#else /* !STM32_ADC_DUAL_MODE */
+
+#if STM32_ADC_USE_ADC1
+ isr = ADC1->ISR;
+ ADC1->ISR = isr;
+#if defined(STM32_ADC_ADC1_IRQ_HOOK)
+ STM32_ADC_ADC1_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD1, isr);
+#endif
+
+#if STM32_ADC_USE_ADC2
+ isr = ADC2->ISR;
+ ADC2->ISR = isr;
+#if defined(STM32_ADC_ADC2_IRQ_HOOK)
+ STM32_ADC_ADC2_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD2, isr);
+#endif
+
+#endif /* !STM32_ADC_DUAL_MODE */
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
+/**
+ * @brief ADC3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = ADC3->ISR;
+ ADC3->ISR = isr;
+#if defined(STM32_ADC_ADC3_IRQ_HOOK)
+ STM32_ADC_ADC3_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#if STM32_ADC_DUAL_MODE
+/**
+ * @brief ADC4 interrupt handler (as ADC3 slave).
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = ADC4->ISR;
+ ADC4->ISR = isr;
+
+ adc_lld_serve_interrupt(&ADCD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_DUAL_MODE */
+#endif /* STM32_ADC_USE_ADC3 */
+
+#if STM32_ADC_USE_ADC4 || defined(__DOXYGEN__)
+/**
+ * @brief ADC4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC4_HANDLER) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = ADC4->ISR;
+ ADC4->ISR = isr;
+
+ adc_lld_serve_interrupt(&ADCD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_ADC4 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+ clkmask = 0;
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+#if defined(ADC1_2_COMMON)
+ ADCD1.adcc = ADC1_2_COMMON;
+#elif defined(ADC12_COMMON)
+ ADCD1.adcc = ADC12_COMMON;
+#elif defined(ADC123_COMMON)
+ ADCD1.adcc = ADC123_COMMON;
+#else
+ ADCD1.adcc = ADC1_COMMON;
+#endif
+ ADCD1.adcm = ADC1;
+#if STM32_ADC_DUAL_MODE
+ ADCD1.adcs = ADC2;
+#endif
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = ADC_DMA_SIZE |
+ STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_ADC2
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD2);
+#if defined(ADC1_2_COMMON)
+ ADCD2.adcc = ADC1_2_COMMON;
+#elif defined(ADC12_COMMON)
+ ADCD2.adcc = ADC12_COMMON;
+#elif defined(ADC123_COMMON)
+ ADCD2.adcc = ADC123_COMMON;
+#endif
+ ADCD2.adcm = ADC2;
+ ADCD2.dmastp = NULL;
+ ADCD2.dmamode = ADC_DMA_SIZE |
+ STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif /* STM32_ADC_USE_ADC2 */
+
+#if STM32_ADC_USE_ADC3
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD3);
+#if defined(ADC3_4_COMMON)
+ ADCD3.adcc = ADC3_4_COMMON;
+#elif defined(ADC345_COMMON)
+ ADCD3.adcc = ADC345_COMMON;
+#elif defined(ADC123_COMMON)
+ ADCD3.adcc = ADC123_COMMON;
+#else
+ ADCD3.adcc = ADC3_COMMON;
+#endif
+ ADCD3.adcm = ADC3;
+#if STM32_ADC_DUAL_MODE
+ ADCD3.adcs = ADC4;
+#endif
+ ADCD3.dmastp = NULL;
+ ADCD3.dmamode = ADC_DMA_SIZE |
+ STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif /* STM32_ADC_USE_ADC3 */
+
+#if STM32_ADC_USE_ADC4
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD4);
+#if defined(ADC3_4_COMMON)
+ ADCD4.adcc = ADC3_4_COMMON;
+#elif defined(ADC345_COMMON)
+ ADCD4.adcc = ADC345_COMMON;
+#endif
+ ADCD4.adcm = ADC4;
+ ADCD4.dmastp = NULL;
+ ADCD4.dmamode = ADC_DMA_SIZE |
+ STM32_DMA_CR_PL(STM32_ADC_ADC4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif /* STM32_ADC_USE_ADC4 */
+
+ /* IRQs setup.*/
+#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
+ nvicEnableVector(STM32_ADC1_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY);
+#endif
+#if STM32_ADC_USE_ADC3
+ nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
+#if STM32_ADC_DUAL_MODE
+ nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
+#endif
+#endif
+#if STM32_ADC_USE_ADC4
+ nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC4_IRQ_PRIORITY);
+#endif
+
+ /* ADC units pre-initializations.*/
+#if defined(STM32F3XX)
+#if STM32_HAS_ADC1 && STM32_HAS_ADC2
+#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
+ rccEnableADC12(true);
+ rccResetADC12();
+ ADC1_2_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA;
+ rccDisableADC12();
+#endif
+#else
+#if STM32_ADC_USE_ADC1
+ rccEnableADC12(true);
+ rccResetADC12();
+ ADC1_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA;
+ rccDisableADC12();
+#endif
+#endif
+#if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4
+ rccEnableADC34(true);
+ rccResetADC34();
+ ADC3_4_COMMON->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA;
+ rccDisableADC34();
+#endif
+#endif
+
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+ rccEnableADC123(true);
+ rccResetADC123();
+#if defined(ADC1_2_COMMON)
+ ADC1_2_COMMON->CCR = STM32_ADC_ADC123_PRESC | STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA;
+#elif defined(ADC123_COMMON)
+ ADC123_COMMON->CCR = STM32_ADC_ADC123_PRESC | STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA;
+#else
+ ADC1_COMMON->CCR = STM32_ADC_ADC123_PRESC | STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA;
+#endif
+
+ rccDisableADC123();
+#endif
+
+#if defined(STM32G4XX)
+#if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2
+ rccEnableADC12(true);
+ rccResetADC12();
+ ADC12_COMMON->CCR = STM32_ADC_ADC12_PRESC | STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA;
+ rccDisableADC12();
+#endif
+#if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4
+ rccEnableADC345(true);
+ rccResetADC345();
+ ADC345_COMMON->CCR = STM32_ADC_ADC345_PRESC | STM32_ADC_ADC345_CLOCK_MODE | ADC_DMA_MDMA;
+ rccDisableADC345();
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* Handling the default configuration.*/
+ if (adcp->config == NULL) {
+ adcp->config = &default_config;
+ }
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ clkmask |= (1 << 0);
+#if defined(STM32F3XX) || defined(STM32G4XX)
+ rccEnableADC12(true);
+#endif
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+ rccEnableADC123(true);
+#endif
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1);
+#endif
+ }
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_ADC2
+ if (&ADCD2 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC2_DMA_STREAM,
+ STM32_ADC_ADC2_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ clkmask |= (1 << 1);
+#if defined(STM32F3XX) || defined(STM32G4XX)
+ rccEnableADC12(true);
+#endif
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+ rccEnableADC123(true);
+#endif
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC2);
+#endif
+ }
+#endif /* STM32_ADC_USE_ADC2 */
+
+#if STM32_ADC_USE_ADC3
+ if (&ADCD3 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC3_DMA_STREAM,
+ STM32_ADC_ADC3_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ clkmask |= (1 << 2);
+#if defined(STM32F3XX)
+ rccEnableADC34(true);
+#endif
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+ rccEnableADC123(true);
+#endif
+#if defined(STM32G4XX)
+ rccEnableADC345(true);
+#endif
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC3);
+#endif
+ }
+#endif /* STM32_ADC_USE_ADC3 */
+
+#if STM32_ADC_USE_ADC4
+ if (&ADCD4 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC4_DMA_STREAM,
+ STM32_ADC_ADC4_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ clkmask |= (1 << 3);
+#if defined(STM32F3XX)
+ rccEnableADC34(true);
+#endif
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+ rccEnableADC123(true);
+#endif
+#if defined(STM32G4XX)
+ rccEnableADC345(true);
+#endif
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC4);
+#endif
+ }
+#endif /* STM32_ADC_USE_ADC4 */
+
+ /* Setting DMA peripheral-side pointer.*/
+#if STM32_ADC_DUAL_MODE
+ dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcc->CDR);
+#else
+ dmaStreamSetPeripheral(adcp->dmastp, &adcp->adcm->DR);
+#endif
+
+ /* Differential channels setting.*/
+#if STM32_ADC_DUAL_MODE
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+ adcp->adcs->DIFSEL = adcp->config->difsel;
+#else
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+#endif
+
+ /* Master ADC calibration.*/
+ adc_lld_vreg_on(adcp);
+ adc_lld_calibrate(adcp);
+
+ /* Master ADC enabled here in order to reduce conversions latencies.*/
+ adc_lld_analog_on(adcp);
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock and analog part.*/
+ if (adcp->state == ADC_READY) {
+
+ /* Releasing the associated DMA channel.*/
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+ /* Stopping the ongoing conversion, if any.*/
+ adc_lld_stop_adc(adcp);
+
+ /* Disabling ADC analog circuit and regulator.*/
+ adc_lld_analog_off(adcp);
+ adc_lld_vreg_off(adcp);
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ /* Resetting CCR options except default ones.*/
+ clkmask &= ~(1 << 0);
+ }
+#endif
+
+#if STM32_ADC_USE_ADC2
+ if (&ADCD2 == adcp) {
+ clkmask &= ~(1 << 1);
+ }
+#endif
+
+#if STM32_ADC_USE_ADC3
+ if (&ADCD3 == adcp) {
+ clkmask &= ~(1 << 2);
+ }
+#endif
+
+#if STM32_ADC_USE_ADC4
+ if (&ADCD4 == adcp) {
+ clkmask &= ~(1 << 3);
+ }
+#endif
+
+#if defined(STM32F3XX)
+#if STM32_HAS_ADC1 || STM32_HAS_ADC2
+ if ((clkmask & 0x3) == 0) {
+ rccDisableADC12();
+ }
+#endif
+
+#if STM32_HAS_ADC3 || STM32_HAS_ADC4
+ if ((clkmask & 0xC) == 0) {
+ rccDisableADC34();
+ }
+#endif
+#endif
+
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+ if ((clkmask & 0x7) == 0) {
+ rccDisableADC123();
+ }
+#endif
+
+#if defined(STM32G4XX)
+#if STM32_HAS_ADC1 || STM32_HAS_ADC2
+ if ((clkmask & 0x3) == 0) {
+ rccDisableADC12();
+ }
+#endif
+
+#if STM32_HAS_ADC3 || STM32_HAS_ADC4
+ if ((clkmask & 0xC) == 0) {
+ rccDisableADC345();
+ }
+#endif
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t dmamode, cfgr;
+ const ADCConversionGroup *grpp = adcp->grpp;
+#if STM32_ADC_DUAL_MODE
+ uint32_t ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_MDMA_MASK);
+#endif
+
+ osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
+ "odd number of channels in dual mode");
+
+ /* Calculating control registers values.*/
+ dmamode = adcp->dmamode;
+ cfgr = grpp->cfgr | ADC_CFGR_DMAEN;
+ if (grpp->circular) {
+ dmamode |= STM32_DMA_CR_CIRC;
+#if STM32_ADC_DUAL_MODE
+ ccr |= ADC_CCR_DMACFG_CIRCULAR;
+#else
+ cfgr |= ADC_CFGR_DMACFG_CIRCULAR;
+#endif
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ dmamode |= STM32_DMA_CR_HTIE;
+ }
+ }
+
+ /* DMA setup.*/
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+#if STM32_ADC_DUAL_MODE
+ dmaStreamSetTransactionSize(adcp->dmastp, ((uint32_t)grpp->num_channels/2) *
+ (uint32_t)adcp->depth);
+#else
+ dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+#endif
+ dmaStreamSetMode(adcp->dmastp, dmamode);
+ dmaStreamEnable(adcp->dmastp);
+
+ /* ADC setup, if it is defined a callback for the analog watch dog then it
+ is enabled.*/
+ adcp->adcm->ISR = adcp->adcm->ISR;
+ if (grpp->error_cb != NULL) {
+ adcp->adcm->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
+ | ADC_IER_AWD2IE
+ | ADC_IER_AWD3IE;
+ adcp->adcm->TR1 = grpp->tr1;
+ adcp->adcm->TR2 = grpp->tr2;
+ adcp->adcm->TR3 = grpp->tr3;
+ adcp->adcm->AWD2CR = grpp->awd2cr;
+ adcp->adcm->AWD3CR = grpp->awd3cr;
+ }
+
+#if STM32_ADC_DUAL_MODE
+
+ /* Configuring the CCR register with the user-specified settings
+ in the conversion group configuration structure, static settings are
+ preserved.*/
+ adcp->adcc->CCR = (adcp->adcc->CCR &
+ (ADC_CCR_CKMODE_MASK | ADC_CCR_MDMA_MASK)) | ccr;
+
+ adcp->adcm->SMPR1 = grpp->smpr[0];
+ adcp->adcm->SMPR2 = grpp->smpr[1];
+ adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
+ adcp->adcm->SQR2 = grpp->sqr[1];
+ adcp->adcm->SQR3 = grpp->sqr[2];
+ adcp->adcm->SQR4 = grpp->sqr[3];
+ adcp->adcs->SMPR1 = grpp->ssmpr[0];
+ adcp->adcs->SMPR2 = grpp->ssmpr[1];
+ adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
+ adcp->adcs->SQR2 = grpp->ssqr[1];
+ adcp->adcs->SQR3 = grpp->ssqr[2];
+ adcp->adcs->SQR4 = grpp->ssqr[3];
+
+#else /* !STM32_ADC_DUAL_MODE */
+ adcp->adcm->SMPR1 = grpp->smpr[0];
+ adcp->adcm->SMPR2 = grpp->smpr[1];
+ adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
+ adcp->adcm->SQR2 = grpp->sqr[1];
+ adcp->adcm->SQR3 = grpp->sqr[2];
+ adcp->adcm->SQR4 = grpp->sqr[3];
+#endif /* !STM32_ADC_DUAL_MODE */
+
+ /* ADC configuration.*/
+ adcp->adcm->CFGR = cfgr;
+#if (STM32_ADCV3_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
+ adcp->adcm->CFGR2 = grpp->cfgr2;
+#endif
+
+ /* Starting conversion.*/
+ adcp->adcm->CR |= ADC_CR_ADSTART;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ dmaStreamDisable(adcp->dmastp);
+ adc_lld_stop_adc(adcp);
+}
+
+/**
+ * @brief Enables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVREF(ADCDriver *adcp) {
+
+ adcp->adcc->CCR |= ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Disables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVREF(ADCDriver *adcp) {
+
+ adcp->adcc->CCR &= ~ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Enables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableTS(ADCDriver *adcp) {
+
+ adcp->adcc->CCR |= ADC_CCR_TSEN;
+}
+
+/**
+ * @brief Disables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableTS(ADCDriver *adcp) {
+
+ adcp->adcc->CCR &= ~ADC_CCR_TSEN;
+}
+
+/**
+ * @brief Enables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVBAT(ADCDriver *adcp) {
+
+ adcp->adcc->CCR |= ADC_CCR_VBATEN;
+}
+
+/**
+ * @brief Disables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVBAT(ADCDriver *adcp) {
+
+ adcp->adcc->CCR &= ~ADC_CCR_VBATEN;
+}
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h
index 8d6c6153d0..a42f9a3940 100644
--- a/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv3/hal_adc_lld.h
@@ -1,1026 +1,1026 @@
-/*
- 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 ADCv3/hal_adc_lld.h
- * @brief STM32 ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Available analog channels
- * @{
- */
-#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
-#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
-#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
-#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
-#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
-#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
-#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
-#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
-#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
-#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
-#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
-#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
-#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
-#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
-#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
-#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
-#define ADC_CHANNEL_IN16 16 /**< @brief External analog input 16. */
-#define ADC_CHANNEL_IN17 17 /**< @brief External analog input 17. */
-#define ADC_CHANNEL_IN18 18 /**< @brief External analog input 18. */
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#if defined(STM32F3XX) || defined(__DOXYGEN__)
-#define ADC_SMPR_SMP_1P5 0 /**< @brief 14 cycles conversion time */
-#define ADC_SMPR_SMP_2P5 1 /**< @brief 15 cycles conversion time. */
-#define ADC_SMPR_SMP_4P5 2 /**< @brief 17 cycles conversion time. */
-#define ADC_SMPR_SMP_7P5 3 /**< @brief 20 cycles conversion time. */
-#define ADC_SMPR_SMP_19P5 4 /**< @brief 32 cycles conversion time. */
-#define ADC_SMPR_SMP_61P5 5 /**< @brief 74 cycles conversion time. */
-#define ADC_SMPR_SMP_181P5 6 /**< @brief 194 cycles conversion time. */
-#define ADC_SMPR_SMP_601P5 7 /**< @brief 614 cycles conversion time. */
-#endif
-#if defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ADC_SMPR_SMP_2P5 0 /**< @brief 15 cycles conversion time */
-#define ADC_SMPR_SMP_6P5 1 /**< @brief 19 cycles conversion time. */
-#define ADC_SMPR_SMP_12P5 2 /**< @brief 25 cycles conversion time. */
-#define ADC_SMPR_SMP_24P5 3 /**< @brief 37 cycles conversion time. */
-#define ADC_SMPR_SMP_47P5 4 /**< @brief 60 cycles conversion time. */
-#define ADC_SMPR_SMP_92P5 5 /**< @brief 105 cycles conversion time. */
-#define ADC_SMPR_SMP_247P5 6 /**< @brief 260 cycles conversion time. */
-#define ADC_SMPR_SMP_640P5 7 /**< @brief 653 cycles conversion time. */
-#endif
-/** @} */
-
-/**
- * @name CFGR register configuration helpers
- * @{
- */
-#define ADC_CFGR_DMACFG_MASK (1 << 1)
-#define ADC_CFGR_DMACFG_ONESHOT (0 << 1)
-#define ADC_CFGR_DMACFG_CIRCULAR (1 << 1)
-
-#define ADC_CFGR_RES_MASK (3 << 3)
-#define ADC_CFGR_RES_12BITS (0 << 3)
-#define ADC_CFGR_RES_10BITS (1 << 3)
-#define ADC_CFGR_RES_8BITS (2 << 3)
-#define ADC_CFGR_RES_6BITS (3 << 3)
-
-#if defined(STM32F3XX) || defined(STM32L4XX) || defined(STM32L4XXP) || \
- defined(__DOXYGEN__)
-#define ADC_CFGR_ALIGN_MASK (1 << 5)
-#define ADC_CFGR_ALIGN_RIGHT (0 << 5)
-#define ADC_CFGR_ALIGN_LEFT (1 << 5)
-
-#define ADC_CFGR_EXTSEL_MASK (15 << 6)
-#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 6)
-#endif
-#if defined(STM32G4XX)
-#define ADC_CFGR_ALIGN_MASK (1 << 15)
-#define ADC_CFGR_ALIGN_RIGHT (0 << 15)
-#define ADC_CFGR_ALIGN_LEFT (1 << 15)
-
-#define ADC_CFGR_EXTSEL_MASK (31 << 5)
-#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 5)
-#endif
-
-#define ADC_CFGR_EXTEN_MASK (3 << 10)
-#define ADC_CFGR_EXTEN_DISABLED (0 << 10)
-#define ADC_CFGR_EXTEN_RISING (1 << 10)
-#define ADC_CFGR_EXTEN_FALLING (2 << 10)
-#define ADC_CFGR_EXTEN_BOTH (3 << 10)
-
-#define ADC_CFGR_DISCEN_MASK (1 << 16)
-#define ADC_CFGR_DISCEN_DISABLED (0 << 16)
-#define ADC_CFGR_DISCEN_ENABLED (1 << 16)
-
-#define ADC_CFGR_DISCNUM_MASK (7 << 17)
-#define ADC_CFGR_DISCNUM_VAL(n) ((n) << 17)
-
-#define ADC_CFGR_AWD1_DISABLED 0
-#define ADC_CFGR_AWD1_ALL (1 << 23)
-#define ADC_CFGR_AWD1_SINGLE(n) (((n) << 26) | (1 << 23) | (1 << 22))
-/** @} */
-
-/**
- * @name CCR register configuration helpers
- * @{
- */
-#define ADC_CCR_DUAL_MASK (31 << 0)
-#define ADC_CCR_DUAL_FIELD(n) ((n) << 0)
-
-#define ADC_CCR_DELAY_MASK (15 << 8)
-#define ADC_CCR_DELAY_FIELD(n) ((n) << 8)
-
-#define ADC_CCR_DMACFG_MASK (1 << 13)
-#define ADC_CCR_DMACFG_ONESHOT (0 << 13)
-#define ADC_CCR_DMACFG_CIRCULAR (1 << 13)
-
-#define ADC_CCR_MDMA_MASK (3 << 14)
-#define ADC_CCR_MDMA_DISABLED (0 << 14)
-#define ADC_CCR_MDMA_WORD (2 << 14)
-#define ADC_CCR_MDMA_HWORD (3 << 14)
-
-#define ADC_CCR_CKMODE_MASK (3 << 16)
-#define ADC_CCR_CKMODE_ADCCK (0 << 16)
-#define ADC_CCR_CKMODE_AHB_DIV1 (1 << 16)
-#define ADC_CCR_CKMODE_AHB_DIV2 (2 << 16)
-#define ADC_CCR_CKMODE_AHB_DIV4 (3 << 16)
-
-#if !defined(STM32F3XX)
-#define ADC_CCR_PRESC_MASK (15 << 18)
-#define ADC_CCR_PRESC_NOCLOCK (0 << 18)
-#define ADC_CCR_PRESC_DIV2 (1 << 18)
-#define ADC_CCR_PRESC_DIV4 (2 << 18)
-#define ADC_CCR_PRESC_DIV6 (3 << 18)
-#define ADC_CCR_PRESC_DIV8 (4 << 18)
-#define ADC_CCR_PRESC_DIV10 (5 << 18)
-#define ADC_CCR_PRESC_DIV12 (6 << 18)
-#define ADC_CCR_PRESC_DIV16 (7 << 18)
-#define ADC_CCR_PRESC_DIV32 (8 << 18)
-#define ADC_CCR_PRESC_DIV64 (9 << 18)
-#define ADC_CCR_PRESC_DIV128 (10 << 18)
-#define ADC_CCR_PRESC_DIV256 (11 << 18)
-#endif /* !defined(STM32F3XX) */
-
-/* F3 headers do not define the following macros, L4 headers do.*/
-#if !defined(ADC_CCR_VREFEN) || defined(__DOXYGEN__)
-#define ADC_CCR_VREFEN (1 << 22)
-#endif
-
-#if !defined(ADC_CCR_TSEN) || defined(__DOXYGEN__)
-#define ADC_CCR_TSEN (1 << 23)
-#endif
-
-#if !defined(ADC_CCR_VBATEN) || defined(__DOXYGEN__)
-#define ADC_CCR_VBATEN (1 << 24)
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief Enables the ADC master/slave mode.
- * @note In dual mode only ADCD1 and ADCD3 are available.
- */
-#if !defined(STM32_ADC_DUAL_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_DUAL_MODE FALSE
-#endif
-
-/**
- * @brief Makes the ADC samples type an 8bits one.
- * @note 10 and 12 bits sampling mode must not be used when this option
- * is enabled.
- */
-#if !defined(STM32_ADC_COMPACT_SAMPLES) || defined(__DOXYGEN__)
-#define STM32_ADC_COMPACT_SAMPLES FALSE
-#endif
-
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC2 driver enable switch.
- * @details If set to @p TRUE the support for ADC2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC2) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC2 FALSE
-#endif
-
-/**
- * @brief ADC3 driver enable switch.
- * @details If set to @p TRUE the support for ADC3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC3 FALSE
-#endif
-/**
- * @brief ADC4 driver enable switch.
- * @details If set to @p TRUE the support for ADC4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC4) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC4 FALSE
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC2_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC3 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC4 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC4_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC1/ADC2 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC12_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC3 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC4 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC4_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC2 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC3 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC4 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC4_DMA_IRQ_PRIORITY 5
-#endif
-
-#if defined(STM32F3XX) || defined(__DOXYGEN__)
-/**
- * @brief ADC1/ADC2 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC12_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
-#endif
-
-/**
- * @brief ADC3/ADC4 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC34_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC34_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
-#endif
-#endif /* defined(STM32F3XX) */
-
-#if defined(STM32L4XX) || defined(STM32L4XXP) || defined(__DOXYGEN__)
-/**
- * @brief ADC1/ADC2/ADC3 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC123_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
-#endif
-
-/**
- * @brief ADC1/ADC2/ADC3 clock prescaler.
- */
-#if !defined(STM32_ADC_ADC123_PRESC) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2
-#endif
-#endif /* defined(STM32L4XX) || defined(STM32L4XXP) */
-
-#if defined(STM32G4XX) || defined(__DOXYGEN__)
-/**
- * @brief ADC1/ADC2 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC12_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
-#endif
-
-/**
- * @brief ADC3/ADC4/ADC5 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC345_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC345_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
-#endif
-
-/**
- * @brief ADC1/ADC2 clock prescaler.
- */
-#if !defined(STM32_ADC_ADC12_PRESC) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_PRESC ADC_CCR_PRESC_DIV2
-#endif
-
-/**
- * @brief ADC3/ADC4/ADC5 clock prescaler.
- */
-#if !defined(STM32_ADC_ADC345_PRESC) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC345_PRESC ADC_CCR_PRESC_DIV2
-#endif
-#endif /* defined(STM32G4XX) */
-
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Supported devices checks.*/
-#if !defined(STM32F3XX) && !defined(STM32L4XX) && !defined(STM32L4XXP) && \
- !defined(STM32G4XX)
-#error "ADCv3 only supports F3, L4, L4+ and G4 STM32 devices"
-#endif
-
-#if defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX) || \
- defined(__DOXYGEN__)
-#define STM32_ADCV3_OVERSAMPLING TRUE
-#else
-#define STM32_ADCV3_OVERSAMPLING FALSE
-#endif
-
-/* Registry checks.*/
-#if !defined(STM32_HAS_ADC1) || !defined(STM32_HAS_ADC2) || \
- !defined(STM32_HAS_ADC3) || !defined(STM32_HAS_ADC4)
-#error "STM32_HAS_ADCx not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER)) || \
- (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_HANDLER)) || \
- (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_HANDLER)) || \
- (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_HANDLER))
-#error "STM32_ADCx_HANDLER not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER)) || \
- (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_NUMBER)) || \
- (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_NUMBER)) || \
- (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_NUMBER))
-#error "STM32_ADCx_NUMBER not defined in registry"
-#endif
-
-#if !STM32_DMA_SUPPORTS_DMAMUX
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_DMA_MSK)) || \
- (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_DMA_MSK)) || \
- (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_DMA_MSK)) || \
- (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_DMA_MSK))
-#error "STM32_ADCx_DMA_MSK not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_DMA_CHN)) || \
- (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_DMA_CHN)) || \
- (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_DMA_CHN)) || \
- (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_DMA_CHN))
-#error "STM32_ADCx_DMA_CHN not defined in registry"
-#endif
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* Units checks.*/
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_ADC2 && !STM32_HAS_ADC2
-#error "ADC2 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
-#error "ADC3 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_ADC4 && !STM32_HAS_ADC4
-#error "ADC4 not present in the selected device"
-#endif
-
-/* Units checks related to dual mode.*/
-#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC1 && !STM32_HAS_ADC2
-#error "ADC2 not present in the selected device, required for dual mode"
-#endif
-
-#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC3 && !STM32_HAS_ADC4
-#error "ADC4 not present in the selected device, required for dual mode"
-#endif
-
-#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC2
-#error "ADC2 cannot be used in dual mode"
-#endif
-
-#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC4
-#error "ADC4 cannot be used in dual mode"
-#endif
-
-/* At least one ADC must be assigned.*/
-#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && \
- !STM32_ADC_USE_ADC3 && !STM32_ADC_USE_ADC4
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-/* ISR arrangements checks.*/
-#if STM32_HAS_ADC1 && STM32_HAS_ADC2
-#if STM32_ADC1_NUMBER != STM32_ADC2_NUMBER
-#error "ADCv3 driver expects STM32_ADC1_NUMBER == STM32_ADC2_NUMBER from registry"
-#endif
-#endif
-
-/* ADC IRQ priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC2"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC3"
-#endif
-
-#if STM32_ADC_USE_ADC4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC4"
-#endif
-
-/* DMA IRQ priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1 DMA"
-#endif
-
-#if STM32_ADC_USE_ADC2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC2_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC2 DMA"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC3 DMA"
-#endif
-
-#if STM32_ADC_USE_ADC4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC4_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC4 DMA"
-#endif
-
-/* DMA priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC2"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC3"
-#endif
-
-#if STM32_ADC_USE_ADC4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC4"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_ADC_USE_ADC1 && !defined(STM32_ADC_ADC1_DMA_STREAM)
-#error "ADC1 DMA stream not defined"
-#endif
-
-#if STM32_ADC_USE_ADC2 && !defined(STM32_ADC_ADC2_DMA_STREAM)
-#error "ADC2 DMA stream not defined"
-#endif
-
-#if STM32_ADC_USE_ADC3 && !defined(STM32_ADC_ADC3_DMA_STREAM)
-#error "ADC3 DMA stream not defined"
-#endif
-
-#if STM32_ADC_USE_ADC4 && !defined(STM32_ADC_ADC4_DMA_STREAM)
-#error "ADC4 DMA stream not defined"
-#endif
-
-#if STM32_DMA_SUPPORTS_DMAMUX
-
-#else /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
-#error "invalid DMA stream associated to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC2 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_MSK)
-#error "invalid DMA stream associated to ADC2"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_MSK)
-#error "invalid DMA stream associated to ADC3"
-#endif
-
-#if STM32_ADC_USE_ADC4 && \
- !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC4_DMA_STREAM, STM32_ADC4_DMA_MSK)
-#error "invalid DMA stream associated to ADC4"
-#endif
-
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* ADC clock prescaler checks.*/
-#if defined(STM32F3XX)
-#endif /* defined(STM32F3XX) */
-
-#if defined(STM32L4XX) || defined(STM32L4XXP)
-#if STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV2
-#define ADC123_PRESC_VALUE 2
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV4
-#define ADC123_PRESC_VALUE 4
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV6
-#define ADC123_PRESC_VALUE 6
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV8
-#define ADC123_PRESC_VALUE 8
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV10
-#define ADC123_PRESC_VALUE 10
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV12
-#define ADC123_PRESC_VALUE 12
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV16
-#define ADC123_PRESC_VALUE 16
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV32
-#define ADC123_PRESC_VALUE 32
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV64
-#define ADC123_PRESC_VALUE 64
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV128
-#define ADC123_PRESC_VALUE 128
-#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV256
-#define ADC123_PRESC_VALUE 256
-#error "invalid clock divider selected for STM32_ADC_ADC12_PRESC"
-#endif
-#endif /* defined(STM32L4XX) || defined(STM32L4XXP) */
-
-#if defined(STM32G4XX)
-#if STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV2
-#define ADC12_PRESC_VALUE 2
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV4
-#define ADC12_PRESC_VALUE 4
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV6
-#define ADC12_PRESC_VALUE 6
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV8
-#define ADC12_PRESC_VALUE 8
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV10
-#define ADC12_PRESC_VALUE 10
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV12
-#define ADC12_PRESC_VALUE 12
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV16
-#define ADC12_PRESC_VALUE 16
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV32
-#define ADC12_PRESC_VALUE 32
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV64
-#define ADC12_PRESC_VALUE 64
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV128
-#define ADC12_PRESC_VALUE 128
-#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV256
-#define ADC12_PRESC_VALUE 256
-#error "invalid clock divider selected for STM32_ADC_ADC12_PRESC"
-#endif
-
-#if STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV2
-#define ADC345_PRESC_VALUE 2
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV4
-#define ADC345_PRESC_VALUE 4
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV6
-#define ADC345_PRESC_VALUE 6
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV8
-#define ADC345_PRESC_VALUE 8
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV10
-#define ADC345_PRESC_VALUE 10
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV12
-#define ADC345_PRESC_VALUE 12
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV16
-#define ADC345_PRESC_VALUE 16
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV32
-#define ADC345_PRESC_VALUE 32
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV64
-#define ADC345_PRESC_VALUE 64
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV128
-#define ADC345_PRESC_VALUE 128
-#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV256
-#define ADC345_PRESC_VALUE 256
-#error "invalid clock divider selected for STM32_ADC_ADC345_PRESC"
-#endif
-#endif /* defined(STM32G4XX) */
-
-/* ADC clock source checks.*/
-#if defined(STM32F3XX)
-#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC12_CLOCK STM32_ADC12CLK
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC12_CLOCK (STM32_HCLK / 1)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC12_CLOCK (STM32_HCLK / 2)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC12_CLOCK (STM32_HCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
-#endif
-
-#if STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC34_CLOCK STM32_ADC34CLK
-#elif STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC34_CLOCK (STM32_HCLK / 1)
-#elif STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC34_CLOCK (STM32_HCLK / 2)
-#elif STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC34_CLOCK (STM32_HCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC34_CLOCK_MODE"
-#endif
-
-#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-
-#if STM32_ADC34_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC34_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-#endif /* defined(STM32F3XX) */
-
-#if defined(STM32L4XX) || defined(STM32L4XXP)
-#if STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC123_CLOCK (STM32_ADCCLK / ADC123_PRESC_VALUE)
-#elif STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC123_CLOCK (STM32_ADCCLK / 1)
-#elif STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC123_CLOCK (STM32_ADCCLK / 2)
-#elif STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC123_CLOCK (STM32_ADCCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC123_CLOCK_MODE"
-#endif
-
-#if STM32_ADC123_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC123_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-#endif /* defined(STM32L4XX) || defined(STM32L4XXP) */
-
-#if defined(STM32G4XX)
-#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC12_CLOCK (STM32_ADC12CLK / ADC12_PRESC_VALUE)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC12_CLOCK (STM32_HCLK / 1)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC12_CLOCK (STM32_HCLK / 2)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC12_CLOCK (STM32_HCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
-#endif
-
-#if STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC345_CLOCK (STM32_ADC345CLK / ADC345_PRESC_VALUE)
-#elif STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC345_CLOCK (STM32_HCLK / 1)
-#elif STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC345_CLOCK (STM32_HCLK / 2)
-#elif STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC345_CLOCK (STM32_HCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC345_CLOCK_MODE"
-#endif
-
-#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-
-#if STM32_ADC345_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC345_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-#endif /* defined(STM32G4XX) */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-#if !STM32_ADC_COMPACT_SAMPLES || defined(__DOXYGEN__)
-typedef uint16_t adcsample_t;
-#else
-typedef uint8_t adcsample_t;
-#endif
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Possible ADC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
- ADC_ERR_AWD1 = 2, /**< Watchdog 1 triggered. */
- ADC_ERR_AWD2 = 3, /**< Watchdog 2 triggered. */
- ADC_ERR_AWD3 = 4 /**< Watchdog 3 triggered. */
-} adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
-#define adc_lld_driver_fields \
- /* Pointer to the master ADCx registers block.*/ \
- ADC_TypeDef *adcm; \
- /* Pointer to the slave ADCx registers block.*/ \
- ADC_TypeDef *adcs; \
- /* Pointer to the common ADCx_y registers block.*/ \
- ADC_Common_TypeDef *adcc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-#else
-#define adc_lld_driver_fields \
- /* Pointer to the master ADCx registers block.*/ \
- ADC_TypeDef *adcm; \
- /* Pointer to the slave ADCx registers block.*/ \
- ADC_Common_TypeDef *adcc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-#endif
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* ADC DIFSEL register initialization data.*/ \
- uint32_t difsel
-
-/**
- * @brief Low level fields of the ADC group configuration structure.
- */
-#if (STM32_ADCV3_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
-#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
-#define adc_lld_configuration_group_fields \
- /* ADC CFGR register initialization data. \
- NOTE: The bits DMAEN and DMACFG are enforced internally \
- to the driver, keep them to zero. \
- NOTE: The bits @p ADC_CFGR_CONT or @p ADC_CFGR_DISCEN must be \
- specified in continuous mode or if the buffer depth is \
- greater than one.*/ \
- uint32_t cfgr; \
- /* ADC CFGR2 register initialization data.*/ \
- uint32_t cfgr2; \
- /* ADC TR1 register initialization data.*/ \
- uint32_t tr1; \
- /* ADC TR2 register initialization data.*/ \
- uint32_t tr2; \
- /* ADC TR3 register initialization data.*/ \
- uint32_t tr3; \
- /* ADC AWD2CR register initialization data.*/ \
- uint32_t awd2cr; \
- /* ADC AWD3CR register initialization data.*/ \
- uint32_t awd3cr; \
- /* ADC CCR register initialization data. \
- NOTE: Put this field to zero if not using oversampling.*/ \
- uint32_t ccr; \
- /* ADC SMPRx registers initialization data.*/ \
- uint32_t smpr[2]; \
- /* ADC SQRx register initialization data.*/ \
- uint32_t sqr[4]; \
- /* Slave ADC SMPRx registers initialization data. \
- NOTE: This field is only present in dual mode.*/ \
- uint32_t ssmpr[2]; \
- /* Slave ADC SQRx register initialization data. \
- NOTE: This field is only present in dual mode.*/ \
- uint32_t ssqr[4]
-#else /* STM32_ADC_DUAL_MODE == FALSE */
-#define adc_lld_configuration_group_fields \
- uint32_t cfgr; \
- uint32_t cfgr2; \
- uint32_t tr1; \
- uint32_t tr2; \
- uint32_t tr3; \
- uint32_t awd2cr; \
- uint32_t awd3cr; \
- uint32_t smpr[2]; \
- uint32_t sqr[4]
-#endif /* STM32_ADC_DUAL_MODE == FALSE */
-
-#else /* STM32_ADCV3_OVERSAMPLING == FALSE */
-#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
-#define adc_lld_configuration_group_fields \
- uint32_t cfgr; \
- uint32_t tr1; \
- uint32_t tr2; \
- uint32_t tr3; \
- uint32_t awd2cr; \
- uint32_t awd3cr; \
- uint32_t ccr; \
- uint32_t smpr[2]; \
- uint32_t sqr[4]; \
- uint32_t ssmpr[2]; \
- uint32_t ssqr[4]
-#else /* STM32_ADC_DUAL_MODE == FALSE */
-#define adc_lld_configuration_group_fields \
- uint32_t cfgr; \
- uint32_t tr1; \
- uint32_t tr2; \
- uint32_t tr3; \
- uint32_t awd2cr; \
- uint32_t awd3cr; \
- uint32_t smpr[2]; \
- uint32_t sqr[4]
-#endif /* STM32_ADC_DUAL_MODE == FALSE */
-#endif /* STM32_ADCV3_OVERSAMPLING == FALSE */
-
-/**
- * @name Threshold registers initializers
- * @{
- */
-#define ADC_TR(low, high) (((uint32_t)(high) << 16) | (uint32_t)(low))
-#define ADC_TR_DISABLED ADC_TR(0U, 0x0FFFU)
-#define ADC_AWDCR_ENABLE(n) (1U << (n))
-/** @} */
-
-/**
- * @name Sequences building helper macros
- * @{
- */
-/**
- * @brief Number of channels in a conversion sequence.
- */
-#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 0)
-
-#define ADC_SQR1_SQ1_N(n) ((n) << 6) /**< @brief 1st channel in seq. */
-#define ADC_SQR1_SQ2_N(n) ((n) << 12) /**< @brief 2nd channel in seq. */
-#define ADC_SQR1_SQ3_N(n) ((n) << 18) /**< @brief 3rd channel in seq. */
-#define ADC_SQR1_SQ4_N(n) ((n) << 24) /**< @brief 4th channel in seq. */
-
-#define ADC_SQR2_SQ5_N(n) ((n) << 0) /**< @brief 5th channel in seq. */
-#define ADC_SQR2_SQ6_N(n) ((n) << 6) /**< @brief 6th channel in seq. */
-#define ADC_SQR2_SQ7_N(n) ((n) << 12) /**< @brief 7th channel in seq. */
-#define ADC_SQR2_SQ8_N(n) ((n) << 18) /**< @brief 8th channel in seq. */
-#define ADC_SQR2_SQ9_N(n) ((n) << 24) /**< @brief 9th channel in seq. */
-
-#define ADC_SQR3_SQ10_N(n) ((n) << 0) /**< @brief 10th channel in seq.*/
-#define ADC_SQR3_SQ11_N(n) ((n) << 6) /**< @brief 11th channel in seq.*/
-#define ADC_SQR3_SQ12_N(n) ((n) << 12) /**< @brief 12th channel in seq.*/
-#define ADC_SQR3_SQ13_N(n) ((n) << 18) /**< @brief 13th channel in seq.*/
-#define ADC_SQR3_SQ14_N(n) ((n) << 24) /**< @brief 14th channel in seq.*/
-
-#define ADC_SQR4_SQ15_N(n) ((n) << 0) /**< @brief 15th channel in seq.*/
-#define ADC_SQR4_SQ16_N(n) ((n) << 6) /**< @brief 16th channel in seq.*/
-/** @} */
-
-/**
- * @name Sampling rate settings helper macros
- * @{
- */
-#define ADC_SMPR1_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
-#define ADC_SMPR1_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
-#define ADC_SMPR1_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
-#define ADC_SMPR1_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
-#define ADC_SMPR1_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
-#define ADC_SMPR1_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
-#define ADC_SMPR1_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
-#define ADC_SMPR1_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
-#define ADC_SMPR1_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
-#define ADC_SMPR1_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
-
-#define ADC_SMPR2_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
-#define ADC_SMPR2_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
-#define ADC_SMPR2_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
-#define ADC_SMPR2_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
-#define ADC_SMPR2_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
-#define ADC_SMPR2_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
-#define ADC_SMPR2_SMP_AN16(n) ((n) << 18) /**< @brief AN16 sampling time. */
-#define ADC_SMPR2_SMP_AN17(n) ((n) << 21) /**< @brief AN17 sampling time. */
-#define ADC_SMPR2_SMP_AN18(n) ((n) << 24) /**< @brief AN18 sampling time. */
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#if STM32_ADC_USE_ADC2 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD2;
-#endif
-
-#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD3;
-#endif
-
-#if STM32_ADC_USE_ADC4 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD4;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adcSTM32EnableVREF(ADCDriver *adcp);
- void adcSTM32DisableVREF(ADCDriver *adcp);
- void adcSTM32EnableTS(ADCDriver *adcp);
- void adcSTM32DisableTS(ADCDriver *adcp);
- void adcSTM32EnableVBAT(ADCDriver *adcp);
- void adcSTM32DisableVBAT(ADCDriver *adcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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 ADCv3/hal_adc_lld.h
+ * @brief STM32 ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Available analog channels
+ * @{
+ */
+#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
+#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
+#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
+#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
+#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
+#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
+#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
+#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
+#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
+#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
+#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
+#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
+#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
+#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
+#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
+#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
+#define ADC_CHANNEL_IN16 16 /**< @brief External analog input 16. */
+#define ADC_CHANNEL_IN17 17 /**< @brief External analog input 17. */
+#define ADC_CHANNEL_IN18 18 /**< @brief External analog input 18. */
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#if defined(STM32F3XX) || defined(__DOXYGEN__)
+#define ADC_SMPR_SMP_1P5 0 /**< @brief 14 cycles conversion time */
+#define ADC_SMPR_SMP_2P5 1 /**< @brief 15 cycles conversion time. */
+#define ADC_SMPR_SMP_4P5 2 /**< @brief 17 cycles conversion time. */
+#define ADC_SMPR_SMP_7P5 3 /**< @brief 20 cycles conversion time. */
+#define ADC_SMPR_SMP_19P5 4 /**< @brief 32 cycles conversion time. */
+#define ADC_SMPR_SMP_61P5 5 /**< @brief 74 cycles conversion time. */
+#define ADC_SMPR_SMP_181P5 6 /**< @brief 194 cycles conversion time. */
+#define ADC_SMPR_SMP_601P5 7 /**< @brief 614 cycles conversion time. */
+#endif
+#if defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ADC_SMPR_SMP_2P5 0 /**< @brief 15 cycles conversion time */
+#define ADC_SMPR_SMP_6P5 1 /**< @brief 19 cycles conversion time. */
+#define ADC_SMPR_SMP_12P5 2 /**< @brief 25 cycles conversion time. */
+#define ADC_SMPR_SMP_24P5 3 /**< @brief 37 cycles conversion time. */
+#define ADC_SMPR_SMP_47P5 4 /**< @brief 60 cycles conversion time. */
+#define ADC_SMPR_SMP_92P5 5 /**< @brief 105 cycles conversion time. */
+#define ADC_SMPR_SMP_247P5 6 /**< @brief 260 cycles conversion time. */
+#define ADC_SMPR_SMP_640P5 7 /**< @brief 653 cycles conversion time. */
+#endif
+/** @} */
+
+/**
+ * @name CFGR register configuration helpers
+ * @{
+ */
+#define ADC_CFGR_DMACFG_MASK (1 << 1)
+#define ADC_CFGR_DMACFG_ONESHOT (0 << 1)
+#define ADC_CFGR_DMACFG_CIRCULAR (1 << 1)
+
+#define ADC_CFGR_RES_MASK (3 << 3)
+#define ADC_CFGR_RES_12BITS (0 << 3)
+#define ADC_CFGR_RES_10BITS (1 << 3)
+#define ADC_CFGR_RES_8BITS (2 << 3)
+#define ADC_CFGR_RES_6BITS (3 << 3)
+
+#if defined(STM32F3XX) || defined(STM32L4XX) || defined(STM32L4XXP) || \
+ defined(__DOXYGEN__)
+#define ADC_CFGR_ALIGN_MASK (1 << 5)
+#define ADC_CFGR_ALIGN_RIGHT (0 << 5)
+#define ADC_CFGR_ALIGN_LEFT (1 << 5)
+
+#define ADC_CFGR_EXTSEL_MASK (15 << 6)
+#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 6)
+#endif
+#if defined(STM32G4XX)
+#define ADC_CFGR_ALIGN_MASK (1 << 15)
+#define ADC_CFGR_ALIGN_RIGHT (0 << 15)
+#define ADC_CFGR_ALIGN_LEFT (1 << 15)
+
+#define ADC_CFGR_EXTSEL_MASK (31 << 5)
+#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 5)
+#endif
+
+#define ADC_CFGR_EXTEN_MASK (3 << 10)
+#define ADC_CFGR_EXTEN_DISABLED (0 << 10)
+#define ADC_CFGR_EXTEN_RISING (1 << 10)
+#define ADC_CFGR_EXTEN_FALLING (2 << 10)
+#define ADC_CFGR_EXTEN_BOTH (3 << 10)
+
+#define ADC_CFGR_DISCEN_MASK (1 << 16)
+#define ADC_CFGR_DISCEN_DISABLED (0 << 16)
+#define ADC_CFGR_DISCEN_ENABLED (1 << 16)
+
+#define ADC_CFGR_DISCNUM_MASK (7 << 17)
+#define ADC_CFGR_DISCNUM_VAL(n) ((n) << 17)
+
+#define ADC_CFGR_AWD1_DISABLED 0
+#define ADC_CFGR_AWD1_ALL (1 << 23)
+#define ADC_CFGR_AWD1_SINGLE(n) (((n) << 26) | (1 << 23) | (1 << 22))
+/** @} */
+
+/**
+ * @name CCR register configuration helpers
+ * @{
+ */
+#define ADC_CCR_DUAL_MASK (31 << 0)
+#define ADC_CCR_DUAL_FIELD(n) ((n) << 0)
+
+#define ADC_CCR_DELAY_MASK (15 << 8)
+#define ADC_CCR_DELAY_FIELD(n) ((n) << 8)
+
+#define ADC_CCR_DMACFG_MASK (1 << 13)
+#define ADC_CCR_DMACFG_ONESHOT (0 << 13)
+#define ADC_CCR_DMACFG_CIRCULAR (1 << 13)
+
+#define ADC_CCR_MDMA_MASK (3 << 14)
+#define ADC_CCR_MDMA_DISABLED (0 << 14)
+#define ADC_CCR_MDMA_WORD (2 << 14)
+#define ADC_CCR_MDMA_HWORD (3 << 14)
+
+#define ADC_CCR_CKMODE_MASK (3 << 16)
+#define ADC_CCR_CKMODE_ADCCK (0 << 16)
+#define ADC_CCR_CKMODE_AHB_DIV1 (1 << 16)
+#define ADC_CCR_CKMODE_AHB_DIV2 (2 << 16)
+#define ADC_CCR_CKMODE_AHB_DIV4 (3 << 16)
+
+#if !defined(STM32F3XX)
+#define ADC_CCR_PRESC_MASK (15 << 18)
+#define ADC_CCR_PRESC_NOCLOCK (0 << 18)
+#define ADC_CCR_PRESC_DIV2 (1 << 18)
+#define ADC_CCR_PRESC_DIV4 (2 << 18)
+#define ADC_CCR_PRESC_DIV6 (3 << 18)
+#define ADC_CCR_PRESC_DIV8 (4 << 18)
+#define ADC_CCR_PRESC_DIV10 (5 << 18)
+#define ADC_CCR_PRESC_DIV12 (6 << 18)
+#define ADC_CCR_PRESC_DIV16 (7 << 18)
+#define ADC_CCR_PRESC_DIV32 (8 << 18)
+#define ADC_CCR_PRESC_DIV64 (9 << 18)
+#define ADC_CCR_PRESC_DIV128 (10 << 18)
+#define ADC_CCR_PRESC_DIV256 (11 << 18)
+#endif /* !defined(STM32F3XX) */
+
+/* F3 headers do not define the following macros, L4 headers do.*/
+#if !defined(ADC_CCR_VREFEN) || defined(__DOXYGEN__)
+#define ADC_CCR_VREFEN (1 << 22)
+#endif
+
+#if !defined(ADC_CCR_TSEN) || defined(__DOXYGEN__)
+#define ADC_CCR_TSEN (1 << 23)
+#endif
+
+#if !defined(ADC_CCR_VBATEN) || defined(__DOXYGEN__)
+#define ADC_CCR_VBATEN (1 << 24)
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief Enables the ADC master/slave mode.
+ * @note In dual mode only ADCD1 and ADCD3 are available.
+ */
+#if !defined(STM32_ADC_DUAL_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_DUAL_MODE FALSE
+#endif
+
+/**
+ * @brief Makes the ADC samples type an 8bits one.
+ * @note 10 and 12 bits sampling mode must not be used when this option
+ * is enabled.
+ */
+#if !defined(STM32_ADC_COMPACT_SAMPLES) || defined(__DOXYGEN__)
+#define STM32_ADC_COMPACT_SAMPLES FALSE
+#endif
+
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief ADC2 driver enable switch.
+ * @details If set to @p TRUE the support for ADC2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC2) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC2 FALSE
+#endif
+
+/**
+ * @brief ADC3 driver enable switch.
+ * @details If set to @p TRUE the support for ADC3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC3 FALSE
+#endif
+/**
+ * @brief ADC4 driver enable switch.
+ * @details If set to @p TRUE the support for ADC4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC4) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC4 FALSE
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC2_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC4 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC4_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC1/ADC2 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC12_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC3 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC4 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC4_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC2 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC3 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC4 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC4_DMA_IRQ_PRIORITY 5
+#endif
+
+#if defined(STM32F3XX) || defined(__DOXYGEN__)
+/**
+ * @brief ADC1/ADC2 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC12_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
+#endif
+
+/**
+ * @brief ADC3/ADC4 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC34_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC34_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
+#endif
+#endif /* defined(STM32F3XX) */
+
+#if defined(STM32L4XX) || defined(STM32L4XXP) || defined(__DOXYGEN__)
+/**
+ * @brief ADC1/ADC2/ADC3 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC123_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1
+#endif
+
+/**
+ * @brief ADC1/ADC2/ADC3 clock prescaler.
+ */
+#if !defined(STM32_ADC_ADC123_PRESC) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2
+#endif
+#endif /* defined(STM32L4XX) || defined(STM32L4XXP) */
+
+#if defined(STM32G4XX) || defined(__DOXYGEN__)
+/**
+ * @brief ADC1/ADC2 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC12_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
+#endif
+
+/**
+ * @brief ADC3/ADC4/ADC5 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC345_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC345_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
+#endif
+
+/**
+ * @brief ADC1/ADC2 clock prescaler.
+ */
+#if !defined(STM32_ADC_ADC12_PRESC) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_PRESC ADC_CCR_PRESC_DIV2
+#endif
+
+/**
+ * @brief ADC3/ADC4/ADC5 clock prescaler.
+ */
+#if !defined(STM32_ADC_ADC345_PRESC) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC345_PRESC ADC_CCR_PRESC_DIV2
+#endif
+#endif /* defined(STM32G4XX) */
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Supported devices checks.*/
+#if !defined(STM32F3XX) && !defined(STM32L4XX) && !defined(STM32L4XXP) && \
+ !defined(STM32G4XX)
+#error "ADCv3 only supports F3, L4, L4+ and G4 STM32 devices"
+#endif
+
+#if defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX) || \
+ defined(__DOXYGEN__)
+#define STM32_ADCV3_OVERSAMPLING TRUE
+#else
+#define STM32_ADCV3_OVERSAMPLING FALSE
+#endif
+
+/* Registry checks.*/
+#if !defined(STM32_HAS_ADC1) || !defined(STM32_HAS_ADC2) || \
+ !defined(STM32_HAS_ADC3) || !defined(STM32_HAS_ADC4)
+#error "STM32_HAS_ADCx not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER)) || \
+ (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_HANDLER)) || \
+ (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_HANDLER)) || \
+ (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_HANDLER))
+#error "STM32_ADCx_HANDLER not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER)) || \
+ (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_NUMBER)) || \
+ (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_NUMBER)) || \
+ (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_NUMBER))
+#error "STM32_ADCx_NUMBER not defined in registry"
+#endif
+
+#if !STM32_DMA_SUPPORTS_DMAMUX
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_DMA_MSK)) || \
+ (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_DMA_MSK)) || \
+ (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_DMA_MSK)) || \
+ (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_DMA_MSK))
+#error "STM32_ADCx_DMA_MSK not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_DMA_CHN)) || \
+ (STM32_ADC_USE_ADC2 && !defined(STM32_ADC2_DMA_CHN)) || \
+ (STM32_ADC_USE_ADC3 && !defined(STM32_ADC3_DMA_CHN)) || \
+ (STM32_ADC_USE_ADC4 && !defined(STM32_ADC4_DMA_CHN))
+#error "STM32_ADCx_DMA_CHN not defined in registry"
+#endif
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* Units checks.*/
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_ADC2 && !STM32_HAS_ADC2
+#error "ADC2 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
+#error "ADC3 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_ADC4 && !STM32_HAS_ADC4
+#error "ADC4 not present in the selected device"
+#endif
+
+/* Units checks related to dual mode.*/
+#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC1 && !STM32_HAS_ADC2
+#error "ADC2 not present in the selected device, required for dual mode"
+#endif
+
+#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC3 && !STM32_HAS_ADC4
+#error "ADC4 not present in the selected device, required for dual mode"
+#endif
+
+#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC2
+#error "ADC2 cannot be used in dual mode"
+#endif
+
+#if STM32_ADC_DUAL_MODE && STM32_ADC_USE_ADC4
+#error "ADC4 cannot be used in dual mode"
+#endif
+
+/* At least one ADC must be assigned.*/
+#if !STM32_ADC_USE_ADC1 && !STM32_ADC_USE_ADC2 && \
+ !STM32_ADC_USE_ADC3 && !STM32_ADC_USE_ADC4
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+/* ISR arrangements checks.*/
+#if STM32_HAS_ADC1 && STM32_HAS_ADC2
+#if STM32_ADC1_NUMBER != STM32_ADC2_NUMBER
+#error "ADCv3 driver expects STM32_ADC1_NUMBER == STM32_ADC2_NUMBER from registry"
+#endif
+#endif
+
+/* ADC IRQ priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC2"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC3"
+#endif
+
+#if STM32_ADC_USE_ADC4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC4"
+#endif
+
+/* DMA IRQ priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1 DMA"
+#endif
+
+#if STM32_ADC_USE_ADC2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC2_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC2 DMA"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC3 DMA"
+#endif
+
+#if STM32_ADC_USE_ADC4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC4_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC4 DMA"
+#endif
+
+/* DMA priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC2"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC3"
+#endif
+
+#if STM32_ADC_USE_ADC4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC4"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_ADC_USE_ADC1 && !defined(STM32_ADC_ADC1_DMA_STREAM)
+#error "ADC1 DMA stream not defined"
+#endif
+
+#if STM32_ADC_USE_ADC2 && !defined(STM32_ADC_ADC2_DMA_STREAM)
+#error "ADC2 DMA stream not defined"
+#endif
+
+#if STM32_ADC_USE_ADC3 && !defined(STM32_ADC_ADC3_DMA_STREAM)
+#error "ADC3 DMA stream not defined"
+#endif
+
+#if STM32_ADC_USE_ADC4 && !defined(STM32_ADC_ADC4_DMA_STREAM)
+#error "ADC4 DMA stream not defined"
+#endif
+
+#if STM32_DMA_SUPPORTS_DMAMUX
+
+#else /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_MSK)
+#error "invalid DMA stream associated to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC2_DMA_STREAM, STM32_ADC2_DMA_MSK)
+#error "invalid DMA stream associated to ADC2"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC3_DMA_STREAM, STM32_ADC3_DMA_MSK)
+#error "invalid DMA stream associated to ADC3"
+#endif
+
+#if STM32_ADC_USE_ADC4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_ADC_ADC4_DMA_STREAM, STM32_ADC4_DMA_MSK)
+#error "invalid DMA stream associated to ADC4"
+#endif
+
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* ADC clock prescaler checks.*/
+#if defined(STM32F3XX)
+#endif /* defined(STM32F3XX) */
+
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+#if STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV2
+#define ADC123_PRESC_VALUE 2
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV4
+#define ADC123_PRESC_VALUE 4
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV6
+#define ADC123_PRESC_VALUE 6
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV8
+#define ADC123_PRESC_VALUE 8
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV10
+#define ADC123_PRESC_VALUE 10
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV12
+#define ADC123_PRESC_VALUE 12
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV16
+#define ADC123_PRESC_VALUE 16
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV32
+#define ADC123_PRESC_VALUE 32
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV64
+#define ADC123_PRESC_VALUE 64
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV128
+#define ADC123_PRESC_VALUE 128
+#elif STM32_ADC_ADC123_PRESC == ADC_CCR_PRESC_DIV256
+#define ADC123_PRESC_VALUE 256
+#error "invalid clock divider selected for STM32_ADC_ADC12_PRESC"
+#endif
+#endif /* defined(STM32L4XX) || defined(STM32L4XXP) */
+
+#if defined(STM32G4XX)
+#if STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV2
+#define ADC12_PRESC_VALUE 2
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV4
+#define ADC12_PRESC_VALUE 4
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV6
+#define ADC12_PRESC_VALUE 6
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV8
+#define ADC12_PRESC_VALUE 8
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV10
+#define ADC12_PRESC_VALUE 10
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV12
+#define ADC12_PRESC_VALUE 12
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV16
+#define ADC12_PRESC_VALUE 16
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV32
+#define ADC12_PRESC_VALUE 32
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV64
+#define ADC12_PRESC_VALUE 64
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV128
+#define ADC12_PRESC_VALUE 128
+#elif STM32_ADC_ADC12_PRESC == ADC_CCR_PRESC_DIV256
+#define ADC12_PRESC_VALUE 256
+#error "invalid clock divider selected for STM32_ADC_ADC12_PRESC"
+#endif
+
+#if STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV2
+#define ADC345_PRESC_VALUE 2
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV4
+#define ADC345_PRESC_VALUE 4
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV6
+#define ADC345_PRESC_VALUE 6
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV8
+#define ADC345_PRESC_VALUE 8
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV10
+#define ADC345_PRESC_VALUE 10
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV12
+#define ADC345_PRESC_VALUE 12
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV16
+#define ADC345_PRESC_VALUE 16
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV32
+#define ADC345_PRESC_VALUE 32
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV64
+#define ADC345_PRESC_VALUE 64
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV128
+#define ADC345_PRESC_VALUE 128
+#elif STM32_ADC_ADC345_PRESC == ADC_CCR_PRESC_DIV256
+#define ADC345_PRESC_VALUE 256
+#error "invalid clock divider selected for STM32_ADC_ADC345_PRESC"
+#endif
+#endif /* defined(STM32G4XX) */
+
+/* ADC clock source checks.*/
+#if defined(STM32F3XX)
+#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC12_CLOCK STM32_ADC12CLK
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC12_CLOCK (STM32_HCLK / 1)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC12_CLOCK (STM32_HCLK / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC12_CLOCK (STM32_HCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
+#endif
+
+#if STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC34_CLOCK STM32_ADC34CLK
+#elif STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC34_CLOCK (STM32_HCLK / 1)
+#elif STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC34_CLOCK (STM32_HCLK / 2)
+#elif STM32_ADC_ADC34_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC34_CLOCK (STM32_HCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC34_CLOCK_MODE"
+#endif
+
+#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+
+#if STM32_ADC34_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC34_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+#endif /* defined(STM32F3XX) */
+
+#if defined(STM32L4XX) || defined(STM32L4XXP)
+#if STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC123_CLOCK (STM32_ADCCLK / ADC123_PRESC_VALUE)
+#elif STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC123_CLOCK (STM32_ADCCLK / 1)
+#elif STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC123_CLOCK (STM32_ADCCLK / 2)
+#elif STM32_ADC_ADC123_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC123_CLOCK (STM32_ADCCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC123_CLOCK_MODE"
+#endif
+
+#if STM32_ADC123_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC123_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+#endif /* defined(STM32L4XX) || defined(STM32L4XXP) */
+
+#if defined(STM32G4XX)
+#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC12_CLOCK (STM32_ADC12CLK / ADC12_PRESC_VALUE)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC12_CLOCK (STM32_HCLK / 1)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC12_CLOCK (STM32_HCLK / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC12_CLOCK (STM32_HCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
+#endif
+
+#if STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC345_CLOCK (STM32_ADC345CLK / ADC345_PRESC_VALUE)
+#elif STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC345_CLOCK (STM32_HCLK / 1)
+#elif STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC345_CLOCK (STM32_HCLK / 2)
+#elif STM32_ADC_ADC345_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC345_CLOCK (STM32_HCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC345_CLOCK_MODE"
+#endif
+
+#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+
+#if STM32_ADC345_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC345_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+#endif /* defined(STM32G4XX) */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+#if !STM32_ADC_COMPACT_SAMPLES || defined(__DOXYGEN__)
+typedef uint16_t adcsample_t;
+#else
+typedef uint8_t adcsample_t;
+#endif
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
+ ADC_ERR_AWD1 = 2, /**< Watchdog 1 triggered. */
+ ADC_ERR_AWD2 = 3, /**< Watchdog 2 triggered. */
+ ADC_ERR_AWD3 = 4 /**< Watchdog 3 triggered. */
+} adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
+#define adc_lld_driver_fields \
+ /* Pointer to the master ADCx registers block.*/ \
+ ADC_TypeDef *adcm; \
+ /* Pointer to the slave ADCx registers block.*/ \
+ ADC_TypeDef *adcs; \
+ /* Pointer to the common ADCx_y registers block.*/ \
+ ADC_Common_TypeDef *adcc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+#else
+#define adc_lld_driver_fields \
+ /* Pointer to the master ADCx registers block.*/ \
+ ADC_TypeDef *adcm; \
+ /* Pointer to the slave ADCx registers block.*/ \
+ ADC_Common_TypeDef *adcc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+#endif
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* ADC DIFSEL register initialization data.*/ \
+ uint32_t difsel
+
+/**
+ * @brief Low level fields of the ADC group configuration structure.
+ */
+#if (STM32_ADCV3_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
+#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
+#define adc_lld_configuration_group_fields \
+ /* ADC CFGR register initialization data. \
+ NOTE: The bits DMAEN and DMACFG are enforced internally \
+ to the driver, keep them to zero. \
+ NOTE: The bits @p ADC_CFGR_CONT or @p ADC_CFGR_DISCEN must be \
+ specified in continuous mode or if the buffer depth is \
+ greater than one.*/ \
+ uint32_t cfgr; \
+ /* ADC CFGR2 register initialization data.*/ \
+ uint32_t cfgr2; \
+ /* ADC TR1 register initialization data.*/ \
+ uint32_t tr1; \
+ /* ADC TR2 register initialization data.*/ \
+ uint32_t tr2; \
+ /* ADC TR3 register initialization data.*/ \
+ uint32_t tr3; \
+ /* ADC AWD2CR register initialization data.*/ \
+ uint32_t awd2cr; \
+ /* ADC AWD3CR register initialization data.*/ \
+ uint32_t awd3cr; \
+ /* ADC CCR register initialization data. \
+ NOTE: Put this field to zero if not using oversampling.*/ \
+ uint32_t ccr; \
+ /* ADC SMPRx registers initialization data.*/ \
+ uint32_t smpr[2]; \
+ /* ADC SQRx register initialization data.*/ \
+ uint32_t sqr[4]; \
+ /* Slave ADC SMPRx registers initialization data. \
+ NOTE: This field is only present in dual mode.*/ \
+ uint32_t ssmpr[2]; \
+ /* Slave ADC SQRx register initialization data. \
+ NOTE: This field is only present in dual mode.*/ \
+ uint32_t ssqr[4]
+#else /* STM32_ADC_DUAL_MODE == FALSE */
+#define adc_lld_configuration_group_fields \
+ uint32_t cfgr; \
+ uint32_t cfgr2; \
+ uint32_t tr1; \
+ uint32_t tr2; \
+ uint32_t tr3; \
+ uint32_t awd2cr; \
+ uint32_t awd3cr; \
+ uint32_t smpr[2]; \
+ uint32_t sqr[4]
+#endif /* STM32_ADC_DUAL_MODE == FALSE */
+
+#else /* STM32_ADCV3_OVERSAMPLING == FALSE */
+#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
+#define adc_lld_configuration_group_fields \
+ uint32_t cfgr; \
+ uint32_t tr1; \
+ uint32_t tr2; \
+ uint32_t tr3; \
+ uint32_t awd2cr; \
+ uint32_t awd3cr; \
+ uint32_t ccr; \
+ uint32_t smpr[2]; \
+ uint32_t sqr[4]; \
+ uint32_t ssmpr[2]; \
+ uint32_t ssqr[4]
+#else /* STM32_ADC_DUAL_MODE == FALSE */
+#define adc_lld_configuration_group_fields \
+ uint32_t cfgr; \
+ uint32_t tr1; \
+ uint32_t tr2; \
+ uint32_t tr3; \
+ uint32_t awd2cr; \
+ uint32_t awd3cr; \
+ uint32_t smpr[2]; \
+ uint32_t sqr[4]
+#endif /* STM32_ADC_DUAL_MODE == FALSE */
+#endif /* STM32_ADCV3_OVERSAMPLING == FALSE */
+
+/**
+ * @name Threshold registers initializers
+ * @{
+ */
+#define ADC_TR(low, high) (((uint32_t)(high) << 16) | (uint32_t)(low))
+#define ADC_TR_DISABLED ADC_TR(0U, 0x0FFFU)
+#define ADC_AWDCR_ENABLE(n) (1U << (n))
+/** @} */
+
+/**
+ * @name Sequences building helper macros
+ * @{
+ */
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
+#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 0)
+
+#define ADC_SQR1_SQ1_N(n) ((n) << 6) /**< @brief 1st channel in seq. */
+#define ADC_SQR1_SQ2_N(n) ((n) << 12) /**< @brief 2nd channel in seq. */
+#define ADC_SQR1_SQ3_N(n) ((n) << 18) /**< @brief 3rd channel in seq. */
+#define ADC_SQR1_SQ4_N(n) ((n) << 24) /**< @brief 4th channel in seq. */
+
+#define ADC_SQR2_SQ5_N(n) ((n) << 0) /**< @brief 5th channel in seq. */
+#define ADC_SQR2_SQ6_N(n) ((n) << 6) /**< @brief 6th channel in seq. */
+#define ADC_SQR2_SQ7_N(n) ((n) << 12) /**< @brief 7th channel in seq. */
+#define ADC_SQR2_SQ8_N(n) ((n) << 18) /**< @brief 8th channel in seq. */
+#define ADC_SQR2_SQ9_N(n) ((n) << 24) /**< @brief 9th channel in seq. */
+
+#define ADC_SQR3_SQ10_N(n) ((n) << 0) /**< @brief 10th channel in seq.*/
+#define ADC_SQR3_SQ11_N(n) ((n) << 6) /**< @brief 11th channel in seq.*/
+#define ADC_SQR3_SQ12_N(n) ((n) << 12) /**< @brief 12th channel in seq.*/
+#define ADC_SQR3_SQ13_N(n) ((n) << 18) /**< @brief 13th channel in seq.*/
+#define ADC_SQR3_SQ14_N(n) ((n) << 24) /**< @brief 14th channel in seq.*/
+
+#define ADC_SQR4_SQ15_N(n) ((n) << 0) /**< @brief 15th channel in seq.*/
+#define ADC_SQR4_SQ16_N(n) ((n) << 6) /**< @brief 16th channel in seq.*/
+/** @} */
+
+/**
+ * @name Sampling rate settings helper macros
+ * @{
+ */
+#define ADC_SMPR1_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
+#define ADC_SMPR1_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
+#define ADC_SMPR1_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
+#define ADC_SMPR1_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
+#define ADC_SMPR1_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
+#define ADC_SMPR1_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
+#define ADC_SMPR1_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
+#define ADC_SMPR1_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
+#define ADC_SMPR1_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
+#define ADC_SMPR1_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
+
+#define ADC_SMPR2_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
+#define ADC_SMPR2_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
+#define ADC_SMPR2_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
+#define ADC_SMPR2_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
+#define ADC_SMPR2_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
+#define ADC_SMPR2_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
+#define ADC_SMPR2_SMP_AN16(n) ((n) << 18) /**< @brief AN16 sampling time. */
+#define ADC_SMPR2_SMP_AN17(n) ((n) << 21) /**< @brief AN17 sampling time. */
+#define ADC_SMPR2_SMP_AN18(n) ((n) << 24) /**< @brief AN18 sampling time. */
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#if STM32_ADC_USE_ADC2 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD2;
+#endif
+
+#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD3;
+#endif
+
+#if STM32_ADC_USE_ADC4 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD4;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adcSTM32EnableVREF(ADCDriver *adcp);
+ void adcSTM32DisableVREF(ADCDriver *adcp);
+ void adcSTM32EnableTS(ADCDriver *adcp);
+ void adcSTM32DisableTS(ADCDriver *adcp);
+ void adcSTM32EnableVBAT(ADCDriver *adcp);
+ void adcSTM32DisableVBAT(ADCDriver *adcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv3/notes.txt b/os/hal/ports/STM32/LLD/ADCv3/notes.txt
index fbfe6c224a..24c77eb5c8 100644
--- a/os/hal/ports/STM32/LLD/ADCv3/notes.txt
+++ b/os/hal/ports/STM32/LLD/ADCv3/notes.txt
@@ -1,22 +1,22 @@
-STM32 ADCv3 driver.
-
-Driver capability:
-
-- Supports the STM32 "fast" ADC found on F3, L4, L4+ and G4 sub-families.
-
-The file registry must export:
-
-STM32_HAS_ADCx - ADCx presence flag (1..4).
-STM32_ADC1_HANDLER - IRQ vector name for ADC1.
-STM32_ADC1_NUMBER - IRQ vector number for ADC1.
-STM32_ADC2_HANDLER - IRQ vector name for ADC2.
-STM32_ADC2_NUMBER - IRQ vector number for ADC2.
-STM32_ADC3_HANDLER - IRQ vector name for ADC3.
-STM32_ADC3_NUMBER - IRQ vector number for ADC3.
-STM32_ADC4_HANDLER - IRQ vector name for ADC4.
-STM32_ADC4_NUMBER - IRQ vector number for ADC4.
-
-If there is no DMAMUX then the file registry must export also:
-
-STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels (1..4).
-STM32_ADCx_DMA_CHN - Mask of the channels mapping (1..4).
+STM32 ADCv3 driver.
+
+Driver capability:
+
+- Supports the STM32 "fast" ADC found on F3, L4, L4+ and G4 sub-families.
+
+The file registry must export:
+
+STM32_HAS_ADCx - ADCx presence flag (1..4).
+STM32_ADC1_HANDLER - IRQ vector name for ADC1.
+STM32_ADC1_NUMBER - IRQ vector number for ADC1.
+STM32_ADC2_HANDLER - IRQ vector name for ADC2.
+STM32_ADC2_NUMBER - IRQ vector number for ADC2.
+STM32_ADC3_HANDLER - IRQ vector name for ADC3.
+STM32_ADC3_NUMBER - IRQ vector number for ADC3.
+STM32_ADC4_HANDLER - IRQ vector name for ADC4.
+STM32_ADC4_NUMBER - IRQ vector number for ADC4.
+
+If there is no DMAMUX then the file registry must export also:
+
+STM32_ADCx_DMA_MSK - Mask of the compatible DMA channels (1..4).
+STM32_ADCx_DMA_CHN - Mask of the channels mapping (1..4).
diff --git a/os/hal/ports/STM32/LLD/ADCv4/driver.mk b/os/hal/ports/STM32/LLD/ADCv4/driver.mk
index 91bc8859dc..0f9cd840dd 100644
--- a/os/hal/ports/STM32/LLD/ADCv4/driver.mk
+++ b/os/hal/ports/STM32/LLD/ADCv4/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv4
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv4
diff --git a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
index a7efc91839..d58b9407b4 100644
--- a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
+++ b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.c
@@ -1,848 +1,848 @@
-/*
- 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 ADCv4/hal_adc_lld.c
- * @brief STM32 ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if STM32_ADC_DUAL_MODE == TRUE
-#define ADC12_CCR_DUAL ADC_CCR_DUAL_REG_SIMULT
-#if STM32_ADC_SAMPLES_SIZE == 8
-/* Compact type dual mode, 2x8-bit.*/
-#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
-#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_BYTE | STM32_BDMA_CR_PSIZE_BYTE)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_BYTE
-
-#else /* STM32_ADC_SAMPLES_SIZE == 16 */
-/* Large type dual mode, 2x16bit.*/
-#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
-#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_HWORD | STM32_BDMA_CR_PSIZE_HWORD)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_HWORD
-#endif /* STM32_ADC_SAMPLES_SIZE == 8 */
-
-#else /* STM32_ADC_DUAL_MODE == FALSE */
-#define ADC12_CCR_DUAL ADC_CCR_DUAL_INDEPENDENT
-#if STM32_ADC_SAMPLES_SIZE == 8
-/* Compact type single mode, 8-bit.*/
-#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE)
-#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_BYTE | STM32_BDMA_CR_PSIZE_BYTE)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
-#elif STM32_ADC_SAMPLES_SIZE == 32
-#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
-#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_WORD | STM32_BDMA_CR_PSIZE_WORD)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
-#else /* STM32_ADC_SAMPLES_SIZE == 16 */
-/* Large type single mode, 16-bit.*/
-#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
-#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_HWORD | STM32_BDMA_CR_PSIZE_HWORD)
-#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
-#endif /* STM32_ADC_SAMPLES_SIZE == 8 */
-#endif /* STM32_ADC_DUAL_MODE == FALSE */
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC12 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/** @brief ADC3 driver identifier.*/
-#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
-ADCDriver ADCD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const ADCConfig default_config = {
- .difsel = 0U
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables the ADC voltage regulator.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_vreg_on(ADCDriver *adcp) {
-
- adcp->adcm->CR = ADC_CR_ADVREGEN;
-#if STM32_ADC_DUAL_MODE
- if (&ADCD1 == adcp) {
- adcp->adcs->CR = ADC_CR_ADVREGEN;
- }
-#endif
- osalSysPolledDelayX(OSAL_US2RTC(STM32_SYS_CK, 10U));
-}
-
-/**
- * @brief Disables the ADC voltage regulator.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_vreg_off(ADCDriver *adcp) {
-
- adcp->adcm->CR = ADC_CR_DEEPPWD;
-#if STM32_ADC_DUAL_MODE
- if (&ADCD1 == adcp) {
- adcp->adcs->CR = ADC_CR_DEEPPWD;
- }
-#endif
-}
-
-/**
- * @brief Enables the ADC analog circuit.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_analog_on(ADCDriver *adcp) {
-
- adcp->adcm->ISR = ADC_ISR_ADRDY;
- adcp->adcm->CR |= ADC_CR_ADEN;
- while ((adcp->adcm->ISR & ADC_ISR_ADRDY) == 0U)
- ;
-#if STM32_ADC_DUAL_MODE
- if (&ADCD1 == adcp) {
- adcp->adcs->ISR = ADC_ISR_ADRDY;
- adcp->adcs->CR |= ADC_CR_ADEN;
- while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0U)
- ;
- }
-#endif
-}
-
-/**
- * @brief Disables the ADC analog circuit.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_analog_off(ADCDriver *adcp) {
-
- adcp->adcm->CR |= ADC_CR_ADDIS;
- while ((adcp->adcm->CR & ADC_CR_ADDIS) != 0U)
- ;
-#if STM32_ADC_DUAL_MODE
- if (&ADCD1 == adcp) {
- adcp->adcs->CR |= ADC_CR_ADDIS;
- while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0U)
- ;
- }
-#endif
-}
-
-/**
- * @brief Calibrates and ADC unit.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_calibrate(ADCDriver *adcp) {
-
- osalDbgAssert(adcp->adcm->CR == ADC_CR_ADVREGEN, "invalid register state");
-
- adcp->adcm->CR &= ~(ADC_CR_ADCALDIF | ADC_CR_ADCALLIN);
- adcp->adcm->CR |= adcp->config->calibration & (ADC_CR_ADCALDIF |
- ADC_CR_ADCALLIN);
- adcp->adcm->CR |= ADC_CR_ADCAL;
- while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0U)
- ;
-#if STM32_ADC_DUAL_MODE
- if (&ADCD1 == adcp) {
- osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state");
-
- adcp->adcs->CR &= ~(ADC_CR_ADCALDIF | ADC_CR_ADCALLIN);
- adcp->adcs->CR |= adcp->config->calibration & (ADC_CR_ADCALDIF |
- ADC_CR_ADCALLIN);
- adcp->adcs->CR |= ADC_CR_ADCAL;
- while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0U)
- ;
- }
-#endif
-}
-
-/**
- * @brief Stops an ongoing conversion, if any.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_stop_adc(ADCDriver *adcp) {
-
- if (adcp->adcm->CR & ADC_CR_ADSTART) {
- adcp->adcm->CR |= ADC_CR_ADSTP;
- while (adcp->adcm->CR & ADC_CR_ADSTP)
- ;
- }
- adcp->adcm->PCSEL = 0U;
-}
-
-#if (STM32_ADC_USE_ADC12 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief ADC DMA service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
-#if (STM32_ADC_USE_ADC3 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief ADC BDMA service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_bdma_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & STM32_BDMA_ISR_TEIF) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_BDMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_BDMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-#endif /* STM32_ADC_USE_ADC3 == TRUE */
-
-/**
- * @brief ADC IRQ service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] isr content of the ISR register
- */
-static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
-
- /* It could be a spurious interrupt caused by overflows after DMA disabling,
- just ignore it in this case.*/
- if (adcp->grpp != NULL) {
- adcerror_t emask = 0U;
-
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the state is checked too.*/
- if ((isr & ADC_ISR_OVR) && (adcp->state == ADC_ACTIVE)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- emask |= ADC_ERR_OVERFLOW;
- }
- if (isr & ADC_ISR_AWD1) {
- /* Analog watchdog 1 error.*/
- emask |= ADC_ERR_AWD1;
- }
- if (isr & ADC_ISR_AWD2) {
- /* Analog watchdog 2 error.*/
- emask |= ADC_ERR_AWD2;
- }
- if (isr & ADC_ISR_AWD3) {
- /* Analog watchdog 3 error.*/
- emask |= ADC_ERR_AWD3;
- }
- if (emask != 0U) {
- _adc_isr_error_code(adcp, emask);
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if (STM32_ADC_USE_ADC12 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief ADC1/ADC2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC12_HANDLER) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Handle ADC1 ISR first in adc_lld_serve_interrupt. */
- isr = ADC1->ISR;
- ADC1->ISR = isr;
-#if defined(STM32_ADC_ADC12_IRQ_HOOK)
- STM32_ADC_ADC12_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD1, isr);
-
- /* Handle ADC2 ISR next in adc_lld_serve_interrupt. */
-#if STM32_ADC_DUAL_MODE
- isr |= ADC2->ISR;
- ADC2->ISR = isr;
-#if defined(STM32_ADC_ADC12_IRQ_HOOK)
- STM32_ADC_ADC12_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD1, isr);
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
-#if (STM32_ADC_USE_ADC3 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief ADC3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = ADC3->ISR;
- ADC3->ISR = isr;
-#if defined(STM32_ADC_ADC3_IRQ_HOOK)
- STM32_ADC_ADC3_IRQ_HOOK
-#endif
- adc_lld_serve_interrupt(&ADCD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_ADC3 == TRUE */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC12 == TRUE
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adcc = ADC12_COMMON;
- ADCD1.adcm = ADC1;
-#if STM32_ADC_DUAL_MODE
- ADCD1.adcs = ADC2;
-#endif
- ADCD1.data.dma = NULL;
- ADCD1.dmamode = ADC12_DMA_SIZE |
- STM32_DMA_CR_PL(STM32_ADC_ADC12_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- nvicEnableVector(STM32_ADC12_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY);
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
-#if STM32_ADC_USE_ADC3 == TRUE
- /* Driver initialization.*/
- adcObjectInit(&ADCD3);
- ADCD3.adcc = ADC3_COMMON;
- ADCD3.adcm = ADC3;
- ADCD3.data.bdma = NULL;
- ADCD3.dmamode = ADC3_BDMA_SIZE |
- STM32_BDMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
- STM32_BDMA_CR_DIR_P2M |
- STM32_BDMA_CR_MINC | STM32_BDMA_CR_TCIE |
- STM32_BDMA_CR_TEIE;
- nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
-#endif /* STM32_ADC_USE_ADC3 == TRUE */
-
- /* ADC units pre-initializations.*/
-#if (STM32_HAS_ADC1 == TRUE) && (STM32_HAS_ADC2 == TRUE)
-#if STM32_ADC_USE_ADC12 == TRUE
- rccEnableADC12(true);
- rccResetADC12();
- ADC12_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_DAMDF | ADC12_CCR_DUAL;
- rccDisableADC12();
-#endif
-#if STM32_ADC_USE_ADC3 == TRUE
- rccEnableADC3(true);
- rccResetADC3();
- ADC3_COMMON->CCR = STM32_ADC_ADC3_CLOCK_MODE;
- rccDisableADC3();
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* Handling the default configuration.*/
- if (adcp->config == NULL) {
- adcp->config = &default_config;
- }
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC12 == TRUE
- if (&ADCD1 == adcp) {
- adcp->data.dma = dmaStreamAllocI(STM32_ADC_ADC12_DMA_STREAM,
- STM32_ADC_ADC12_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->data.dma != NULL, "unable to allocate stream");
- rccEnableADC12(true);
- dmaSetRequestSource(adcp->data.dma, STM32_DMAMUX1_ADC1);
-
- /* Setting DMA peripheral-side pointer.*/
-#if STM32_ADC_DUAL_MODE
- dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcc->CDR);
-#else
- dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcm->DR);
-#endif
-
- /* Differential channels setting.*/
-#if STM32_ADC_DUAL_MODE
- adcp->adcm->DIFSEL = adcp->config->difsel;
- adcp->adcs->DIFSEL = adcp->config->difsel;
-#else
- adcp->adcm->DIFSEL = adcp->config->difsel;
-#endif
- }
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
-#if STM32_ADC_USE_ADC3 == TRUE
- if (&ADCD3 == adcp) {
- adcp->data.bdma = bdmaStreamAllocI(STM32_ADC_ADC3_BDMA_STREAM,
- STM32_ADC_ADC3_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_bdma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->data.bdma != NULL, "unable to allocate stream");
- rccEnableADC3(true);
- bdmaSetRequestSource(adcp->data.bdma, STM32_DMAMUX2_ADC3_REQ);
-
- /* Setting DMA peripheral-side pointer.*/
- bdmaStreamSetPeripheral(adcp->data.bdma, &adcp->adcm->DR);
-
- /* Differential channels setting.*/
- adcp->adcm->DIFSEL = adcp->config->difsel;
- }
-#endif /* STM32_ADC_USE_ADC3 == TRUE */
-
- /* Master ADC calibration.*/
- adc_lld_vreg_on(adcp);
- adc_lld_calibrate(adcp);
-
- /* Configure the ADC boost. */
-#if STM32_ADC_USE_ADC12 == TRUE
- if (&ADCD1 == adcp) {
- adcp->adcm->CR |= STM32_ADC12_BOOST;
-#if STM32_ADC_DUAL_MODE
- adcp->adcs->CR |= STM32_ADC12_BOOST;
-#endif
- }
-#endif
-
-#if STM32_ADC_USE_ADC3 == TRUE
- if (&ADCD3 == adcp) {
- adcp->adcm->CR |= STM32_ADC3_BOOST;
- }
-#endif
-
- /* Master ADC enabled here in order to reduce conversions latencies.*/
- adc_lld_analog_on(adcp);
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock and analog part.*/
- if (adcp->state == ADC_READY) {
-
- /* Stopping the ongoing conversion, if any.*/
- adc_lld_stop_adc(adcp);
-
- /* Disabling ADC analog circuit and regulator.*/
- adc_lld_analog_off(adcp);
- adc_lld_vreg_off(adcp);
-
-#if STM32_ADC_USE_ADC12 == TRUE
- if (&ADCD1 == adcp) {
-
- /* Releasing the associated DMA channel.*/
- dmaStreamFreeI(adcp->data.dma);
- adcp->data.dma = NULL;
-
- /* Resetting CCR options except default ones.*/
- adcp->adcc->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_DAMDF | ADC12_CCR_DUAL;
- rccDisableADC12();
- }
-#endif
-
-#if STM32_ADC_USE_ADC3 == TRUE
- if (&ADCD3 == adcp) {
-
- /* Releasing the associated BDMA channel.*/
- bdmaStreamFreeI(adcp->data.bdma);
- adcp->data.bdma = NULL;
-
- /* Resetting CCR options except default ones.*/
- adcp->adcc->CCR = STM32_ADC_ADC3_CLOCK_MODE;
- rccDisableADC3();
- }
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t dmamode, cfgr = 0U;
- const ADCConversionGroup *grpp = adcp->grpp;
-
-#if STM32_ADC_USE_ADC12 == TRUE
-#if STM32_ADC_DUAL_MODE
- uint32_t ccr;
-#endif
- if (&ADCD1 == adcp) {
-#if STM32_ADC_DUAL_MODE
- ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_DAMDF_MASK);
- osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
- "odd number of channels in dual mode");
-#endif
-
- /* Calculating control registers values.*/
- dmamode = adcp->dmamode;
- if (grpp->circular) {
- dmamode |= STM32_DMA_CR_CIRC;
- cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- dmamode |= STM32_DMA_CR_HTIE;
- }
- }
- else {
- cfgr = grpp->cfgr | ADC_CFGR_DMNGT_ONESHOT;
- }
-
- /* DMA setup.*/
- dmaStreamSetMemory0(adcp->data.dma, adcp->samples);
-#if STM32_ADC_DUAL_MODE
- dmaStreamSetTransactionSize(adcp->data.dma, ((uint32_t)grpp->num_channels / 2U) *
- (uint32_t)adcp->depth);
-#else
- dmaStreamSetTransactionSize(adcp->data.dma, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
-#endif
- dmaStreamSetMode(adcp->data.dma, dmamode);
- dmaStreamEnable(adcp->data.dma);
- }
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
-#if STM32_ADC_USE_ADC3 == TRUE
- if (&ADCD3 == adcp) {
- /* Calculating control registers values.*/
- dmamode = adcp->dmamode;
- if (grpp->circular) {
- dmamode |= STM32_BDMA_CR_CIRC;
- cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- dmamode |= STM32_BDMA_CR_HTIE;
- }
- }
- else {
- cfgr = grpp->cfgr | ADC_CFGR_DMNGT_ONESHOT;
- }
-
- /* DMA setup.*/
- bdmaStreamSetMemory(adcp->data.bdma, adcp->samples);
- bdmaStreamSetTransactionSize(adcp->data.bdma, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- bdmaStreamSetMode(adcp->data.bdma, dmamode);
- bdmaStreamEnable(adcp->data.bdma);
- }
-#endif /* STM32_ADC_USE_ADC3 == TRUE */
-
- /* ADC setup, if it is defined a callback for the analog watch dog then it
- is enabled.*/
- /* clear AWD1..3 flags */
- adcp->adcm->ISR = adcp->adcm->ISR;
- /* If a callback is set enable the overflow and analog watch dog interrupts. */
- if (grpp->error_cb != NULL) {
- adcp->adcm->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
- | ADC_IER_AWD2IE
- | ADC_IER_AWD3IE;
- }
-#if STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC12 == TRUE
- /* Configuration for dual mode ADC12 */
- if (&ADCD1 == adcp) {
- /* clear AWD1..3 flags */
- adcp->adcs->ISR = adcp->adcs->ISR;
- /* If a callback is set enable the overflow and analog watch dog interrupts. */
- if (grpp->error_cb != NULL) {
- adcp->adcs->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
- | ADC_IER_AWD2IE
- | ADC_IER_AWD3IE;
- /* Configuring the CCR register with the user-specified settings
- in the conversion group configuration structure, static settings are
- preserved.*/
- adcp->adcc->CCR = (adcp->adcc->CCR &
- (ADC_CCR_CKMODE_MASK | ADC_CCR_DAMDF_MASK | ADC_CCR_DUAL_MASK)) | ccr;
-
- adcp->adcm->CFGR2 = grpp->cfgr2;
- adcp->adcm->PCSEL = grpp->pcsel;
- adcp->adcm->LTR1 = grpp->ltr1;
- adcp->adcm->HTR1 = grpp->htr1;
- adcp->adcm->LTR2 = grpp->ltr2;
- adcp->adcm->HTR2 = grpp->htr2;
- adcp->adcm->LTR3 = grpp->ltr3;
- adcp->adcm->HTR3 = grpp->htr3;
- adcp->adcm->AWD2CR = grpp->awd2cr;
- adcp->adcm->AWD3CR = grpp->awd3cr;
- adcp->adcm->SMPR1 = grpp->smpr[0];
- adcp->adcm->SMPR2 = grpp->smpr[1];
- adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
- adcp->adcm->SQR2 = grpp->sqr[1];
- adcp->adcm->SQR3 = grpp->sqr[2];
- adcp->adcm->SQR4 = grpp->sqr[3];
- adcp->adcs->CFGR2 = grpp->cfgr2;
- adcp->adcs->PCSEL = grpp->pcsel;
- adcp->adcs->LTR1 = grpp->sltr1;
- adcp->adcs->HTR1 = grpp->shtr1;
- adcp->adcs->LTR2 = grpp->sltr2;
- adcp->adcs->HTR2 = grpp->shtr2;
- adcp->adcs->LTR3 = grpp->sltr3;
- adcp->adcs->HTR3 = grpp->shtr3;
- adcp->adcs->AWD2CR = grpp->sawd2cr;
- adcp->adcs->AWD3CR = grpp->sawd3cr;
- adcp->adcs->SMPR1 = grpp->ssmpr[0];
- adcp->adcs->SMPR2 = grpp->ssmpr[1];
- adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
- adcp->adcs->SQR2 = grpp->ssqr[1];
- adcp->adcs->SQR3 = grpp->ssqr[2];
- adcp->adcs->SQR4 = grpp->ssqr[3];
-
- /* ADC configuration.*/
- adcp->adcm->CFGR = cfgr;
- adcp->adcs->CFGR = cfgr;
- }
-}
-#endif /* STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC12 == TRUE */
-
-#if STM32_ADC_DUAL_MODE == FALSE || STM32_ADC_USE_ADC3 == TRUE
- /* Configuration for ADC3 and single mode ADC1 */
-
- adcp->adcm->CFGR2 = grpp->cfgr2;
- adcp->adcm->PCSEL = grpp->pcsel;
- adcp->adcm->LTR1 = grpp->ltr1;
- adcp->adcm->HTR1 = grpp->htr1;
- adcp->adcm->LTR2 = grpp->ltr2;
- adcp->adcm->HTR2 = grpp->htr2;
- adcp->adcm->LTR3 = grpp->ltr3;
- adcp->adcm->HTR3 = grpp->htr3;
- adcp->adcm->AWD2CR = grpp->awd2cr;
- adcp->adcm->AWD3CR = grpp->awd3cr;
- adcp->adcm->SMPR1 = grpp->smpr[0];
- adcp->adcm->SMPR2 = grpp->smpr[1];
- adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
- adcp->adcm->SQR2 = grpp->sqr[1];
- adcp->adcm->SQR3 = grpp->sqr[2];
- adcp->adcm->SQR4 = grpp->sqr[3];
-
- /* ADC configuration.*/
- adcp->adcm->CFGR = cfgr;
-#endif
-
- /* Starting conversion.*/
- adcp->adcm->CR |= ADC_CR_ADSTART;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
-#if STM32_ADC_USE_ADC12 == TRUE
- if (&ADCD1 == adcp) {
- dmaStreamDisable(adcp->data.dma);
- }
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
-#if STM32_ADC_USE_ADC3 == TRUE
- if (&ADCD3 == adcp) {
- bdmaStreamDisable(adcp->data.bdma);
- }
-#endif /* STM32_ADC_USE_ADC12 == TRUE */
-
- adc_lld_stop_adc(adcp);
-}
-
-/**
- * @brief Enables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVREF(ADCDriver *adcp) {
-
- adcp->adcc->CCR |= ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Disables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVREF(ADCDriver *adcp) {
-
- adcp->adcc->CCR &= ~ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Enables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableTS(ADCDriver *adcp) {
-
- adcp->adcc->CCR |= ADC_CCR_TSEN;
-}
-
-/**
- * @brief Disables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableTS(ADCDriver *adcp) {
-
- adcp->adcc->CCR &= ~ADC_CCR_TSEN;
-}
-
-/**
- * @brief Enables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVBAT(ADCDriver *adcp) {
-
- adcp->adcc->CCR |= ADC_CCR_VBATEN;
-}
-
-/**
- * @brief Disables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVBAT(ADCDriver *adcp) {
-
- adcp->adcc->CCR &= ~ADC_CCR_VBATEN;
-}
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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 ADCv4/hal_adc_lld.c
+ * @brief STM32 ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#if STM32_ADC_DUAL_MODE == TRUE
+#define ADC12_CCR_DUAL ADC_CCR_DUAL_REG_SIMULT
+#if STM32_ADC_SAMPLES_SIZE == 8
+/* Compact type dual mode, 2x8-bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_BYTE | STM32_BDMA_CR_PSIZE_BYTE)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_BYTE
+
+#else /* STM32_ADC_SAMPLES_SIZE == 16 */
+/* Large type dual mode, 2x16bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_HWORD | STM32_BDMA_CR_PSIZE_HWORD)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_HWORD
+#endif /* STM32_ADC_SAMPLES_SIZE == 8 */
+
+#else /* STM32_ADC_DUAL_MODE == FALSE */
+#define ADC12_CCR_DUAL ADC_CCR_DUAL_INDEPENDENT
+#if STM32_ADC_SAMPLES_SIZE == 8
+/* Compact type single mode, 8-bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_PSIZE_BYTE)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_BYTE | STM32_BDMA_CR_PSIZE_BYTE)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
+#elif STM32_ADC_SAMPLES_SIZE == 32
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_WORD | STM32_BDMA_CR_PSIZE_WORD)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
+#else /* STM32_ADC_SAMPLES_SIZE == 16 */
+/* Large type single mode, 16-bit.*/
+#define ADC12_DMA_SIZE (STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD)
+#define ADC3_BDMA_SIZE (STM32_BDMA_CR_MSIZE_HWORD | STM32_BDMA_CR_PSIZE_HWORD)
+#define ADC_DMA_DAMDF ADC_CCR_DAMDF_DISABLED
+#endif /* STM32_ADC_SAMPLES_SIZE == 8 */
+#endif /* STM32_ADC_DUAL_MODE == FALSE */
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC12 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/** @brief ADC3 driver identifier.*/
+#if STM32_ADC_USE_ADC3 || defined(__DOXYGEN__)
+ADCDriver ADCD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const ADCConfig default_config = {
+ .difsel = 0U
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the ADC voltage regulator.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_vreg_on(ADCDriver *adcp) {
+
+ adcp->adcm->CR = ADC_CR_ADVREGEN;
+#if STM32_ADC_DUAL_MODE
+ if (&ADCD1 == adcp) {
+ adcp->adcs->CR = ADC_CR_ADVREGEN;
+ }
+#endif
+ osalSysPolledDelayX(OSAL_US2RTC(STM32_SYS_CK, 10U));
+}
+
+/**
+ * @brief Disables the ADC voltage regulator.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_vreg_off(ADCDriver *adcp) {
+
+ adcp->adcm->CR = ADC_CR_DEEPPWD;
+#if STM32_ADC_DUAL_MODE
+ if (&ADCD1 == adcp) {
+ adcp->adcs->CR = ADC_CR_DEEPPWD;
+ }
+#endif
+}
+
+/**
+ * @brief Enables the ADC analog circuit.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_analog_on(ADCDriver *adcp) {
+
+ adcp->adcm->ISR = ADC_ISR_ADRDY;
+ adcp->adcm->CR |= ADC_CR_ADEN;
+ while ((adcp->adcm->ISR & ADC_ISR_ADRDY) == 0U)
+ ;
+#if STM32_ADC_DUAL_MODE
+ if (&ADCD1 == adcp) {
+ adcp->adcs->ISR = ADC_ISR_ADRDY;
+ adcp->adcs->CR |= ADC_CR_ADEN;
+ while ((adcp->adcs->ISR & ADC_ISR_ADRDY) == 0U)
+ ;
+ }
+#endif
+}
+
+/**
+ * @brief Disables the ADC analog circuit.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_analog_off(ADCDriver *adcp) {
+
+ adcp->adcm->CR |= ADC_CR_ADDIS;
+ while ((adcp->adcm->CR & ADC_CR_ADDIS) != 0U)
+ ;
+#if STM32_ADC_DUAL_MODE
+ if (&ADCD1 == adcp) {
+ adcp->adcs->CR |= ADC_CR_ADDIS;
+ while ((adcp->adcs->CR & ADC_CR_ADDIS) != 0U)
+ ;
+ }
+#endif
+}
+
+/**
+ * @brief Calibrates and ADC unit.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_calibrate(ADCDriver *adcp) {
+
+ osalDbgAssert(adcp->adcm->CR == ADC_CR_ADVREGEN, "invalid register state");
+
+ adcp->adcm->CR &= ~(ADC_CR_ADCALDIF | ADC_CR_ADCALLIN);
+ adcp->adcm->CR |= adcp->config->calibration & (ADC_CR_ADCALDIF |
+ ADC_CR_ADCALLIN);
+ adcp->adcm->CR |= ADC_CR_ADCAL;
+ while ((adcp->adcm->CR & ADC_CR_ADCAL) != 0U)
+ ;
+#if STM32_ADC_DUAL_MODE
+ if (&ADCD1 == adcp) {
+ osalDbgAssert(adcp->adcs->CR == ADC_CR_ADVREGEN, "invalid register state");
+
+ adcp->adcs->CR &= ~(ADC_CR_ADCALDIF | ADC_CR_ADCALLIN);
+ adcp->adcs->CR |= adcp->config->calibration & (ADC_CR_ADCALDIF |
+ ADC_CR_ADCALLIN);
+ adcp->adcs->CR |= ADC_CR_ADCAL;
+ while ((adcp->adcs->CR & ADC_CR_ADCAL) != 0U)
+ ;
+ }
+#endif
+}
+
+/**
+ * @brief Stops an ongoing conversion, if any.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_stop_adc(ADCDriver *adcp) {
+
+ if (adcp->adcm->CR & ADC_CR_ADSTART) {
+ adcp->adcm->CR |= ADC_CR_ADSTP;
+ while (adcp->adcm->CR & ADC_CR_ADSTP)
+ ;
+ }
+ adcp->adcm->PCSEL = 0U;
+}
+
+#if (STM32_ADC_USE_ADC12 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief ADC DMA service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if (STM32_ADC_USE_ADC3 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief ADC BDMA service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_bdma_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & STM32_BDMA_ISR_TEIF) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_BDMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_BDMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
+
+/**
+ * @brief ADC IRQ service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] isr content of the ISR register
+ */
+static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (adcp->grpp != NULL) {
+ adcerror_t emask = 0U;
+
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the state is checked too.*/
+ if ((isr & ADC_ISR_OVR) && (adcp->state == ADC_ACTIVE)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ emask |= ADC_ERR_OVERFLOW;
+ }
+ if (isr & ADC_ISR_AWD1) {
+ /* Analog watchdog 1 error.*/
+ emask |= ADC_ERR_AWD1;
+ }
+ if (isr & ADC_ISR_AWD2) {
+ /* Analog watchdog 2 error.*/
+ emask |= ADC_ERR_AWD2;
+ }
+ if (isr & ADC_ISR_AWD3) {
+ /* Analog watchdog 3 error.*/
+ emask |= ADC_ERR_AWD3;
+ }
+ if (emask != 0U) {
+ _adc_isr_error_code(adcp, emask);
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if (STM32_ADC_USE_ADC12 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief ADC1/ADC2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC12_HANDLER) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Handle ADC1 ISR first in adc_lld_serve_interrupt. */
+ isr = ADC1->ISR;
+ ADC1->ISR = isr;
+#if defined(STM32_ADC_ADC12_IRQ_HOOK)
+ STM32_ADC_ADC12_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD1, isr);
+
+ /* Handle ADC2 ISR next in adc_lld_serve_interrupt. */
+#if STM32_ADC_DUAL_MODE
+ isr |= ADC2->ISR;
+ ADC2->ISR = isr;
+#if defined(STM32_ADC_ADC12_IRQ_HOOK)
+ STM32_ADC_ADC12_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD1, isr);
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if (STM32_ADC_USE_ADC3 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief ADC3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC3_HANDLER) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = ADC3->ISR;
+ ADC3->ISR = isr;
+#if defined(STM32_ADC_ADC3_IRQ_HOOK)
+ STM32_ADC_ADC3_IRQ_HOOK
+#endif
+ adc_lld_serve_interrupt(&ADCD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC12 == TRUE
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adcc = ADC12_COMMON;
+ ADCD1.adcm = ADC1;
+#if STM32_ADC_DUAL_MODE
+ ADCD1.adcs = ADC2;
+#endif
+ ADCD1.data.dma = NULL;
+ ADCD1.dmamode = ADC12_DMA_SIZE |
+ STM32_DMA_CR_PL(STM32_ADC_ADC12_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ nvicEnableVector(STM32_ADC12_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY);
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD3);
+ ADCD3.adcc = ADC3_COMMON;
+ ADCD3.adcm = ADC3;
+ ADCD3.data.bdma = NULL;
+ ADCD3.dmamode = ADC3_BDMA_SIZE |
+ STM32_BDMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) |
+ STM32_BDMA_CR_DIR_P2M |
+ STM32_BDMA_CR_MINC | STM32_BDMA_CR_TCIE |
+ STM32_BDMA_CR_TEIE;
+ nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY);
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
+
+ /* ADC units pre-initializations.*/
+#if (STM32_HAS_ADC1 == TRUE) && (STM32_HAS_ADC2 == TRUE)
+#if STM32_ADC_USE_ADC12 == TRUE
+ rccEnableADC12(true);
+ rccResetADC12();
+ ADC12_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_DAMDF | ADC12_CCR_DUAL;
+ rccDisableADC12();
+#endif
+#if STM32_ADC_USE_ADC3 == TRUE
+ rccEnableADC3(true);
+ rccResetADC3();
+ ADC3_COMMON->CCR = STM32_ADC_ADC3_CLOCK_MODE;
+ rccDisableADC3();
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* Handling the default configuration.*/
+ if (adcp->config == NULL) {
+ adcp->config = &default_config;
+ }
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC12 == TRUE
+ if (&ADCD1 == adcp) {
+ adcp->data.dma = dmaStreamAllocI(STM32_ADC_ADC12_DMA_STREAM,
+ STM32_ADC_ADC12_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->data.dma != NULL, "unable to allocate stream");
+ rccEnableADC12(true);
+ dmaSetRequestSource(adcp->data.dma, STM32_DMAMUX1_ADC1);
+
+ /* Setting DMA peripheral-side pointer.*/
+#if STM32_ADC_DUAL_MODE
+ dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcc->CDR);
+#else
+ dmaStreamSetPeripheral(adcp->data.dma, &adcp->adcm->DR);
+#endif
+
+ /* Differential channels setting.*/
+#if STM32_ADC_DUAL_MODE
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+ adcp->adcs->DIFSEL = adcp->config->difsel;
+#else
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+#endif
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ adcp->data.bdma = bdmaStreamAllocI(STM32_ADC_ADC3_BDMA_STREAM,
+ STM32_ADC_ADC3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_bdma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->data.bdma != NULL, "unable to allocate stream");
+ rccEnableADC3(true);
+ bdmaSetRequestSource(adcp->data.bdma, STM32_DMAMUX2_ADC3_REQ);
+
+ /* Setting DMA peripheral-side pointer.*/
+ bdmaStreamSetPeripheral(adcp->data.bdma, &adcp->adcm->DR);
+
+ /* Differential channels setting.*/
+ adcp->adcm->DIFSEL = adcp->config->difsel;
+ }
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
+
+ /* Master ADC calibration.*/
+ adc_lld_vreg_on(adcp);
+ adc_lld_calibrate(adcp);
+
+ /* Configure the ADC boost. */
+#if STM32_ADC_USE_ADC12 == TRUE
+ if (&ADCD1 == adcp) {
+ adcp->adcm->CR |= STM32_ADC12_BOOST;
+#if STM32_ADC_DUAL_MODE
+ adcp->adcs->CR |= STM32_ADC12_BOOST;
+#endif
+ }
+#endif
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ adcp->adcm->CR |= STM32_ADC3_BOOST;
+ }
+#endif
+
+ /* Master ADC enabled here in order to reduce conversions latencies.*/
+ adc_lld_analog_on(adcp);
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock and analog part.*/
+ if (adcp->state == ADC_READY) {
+
+ /* Stopping the ongoing conversion, if any.*/
+ adc_lld_stop_adc(adcp);
+
+ /* Disabling ADC analog circuit and regulator.*/
+ adc_lld_analog_off(adcp);
+ adc_lld_vreg_off(adcp);
+
+#if STM32_ADC_USE_ADC12 == TRUE
+ if (&ADCD1 == adcp) {
+
+ /* Releasing the associated DMA channel.*/
+ dmaStreamFreeI(adcp->data.dma);
+ adcp->data.dma = NULL;
+
+ /* Resetting CCR options except default ones.*/
+ adcp->adcc->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_DAMDF | ADC12_CCR_DUAL;
+ rccDisableADC12();
+ }
+#endif
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+
+ /* Releasing the associated BDMA channel.*/
+ bdmaStreamFreeI(adcp->data.bdma);
+ adcp->data.bdma = NULL;
+
+ /* Resetting CCR options except default ones.*/
+ adcp->adcc->CCR = STM32_ADC_ADC3_CLOCK_MODE;
+ rccDisableADC3();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t dmamode, cfgr = 0U;
+ const ADCConversionGroup *grpp = adcp->grpp;
+
+#if STM32_ADC_USE_ADC12 == TRUE
+#if STM32_ADC_DUAL_MODE
+ uint32_t ccr;
+#endif
+ if (&ADCD1 == adcp) {
+#if STM32_ADC_DUAL_MODE
+ ccr = grpp->ccr & ~(ADC_CCR_CKMODE_MASK | ADC_CCR_DAMDF_MASK);
+ osalDbgAssert(!STM32_ADC_DUAL_MODE || ((grpp->num_channels & 1) == 0),
+ "odd number of channels in dual mode");
+#endif
+
+ /* Calculating control registers values.*/
+ dmamode = adcp->dmamode;
+ if (grpp->circular) {
+ dmamode |= STM32_DMA_CR_CIRC;
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ dmamode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ else {
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_ONESHOT;
+ }
+
+ /* DMA setup.*/
+ dmaStreamSetMemory0(adcp->data.dma, adcp->samples);
+#if STM32_ADC_DUAL_MODE
+ dmaStreamSetTransactionSize(adcp->data.dma, ((uint32_t)grpp->num_channels / 2U) *
+ (uint32_t)adcp->depth);
+#else
+ dmaStreamSetTransactionSize(adcp->data.dma, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+#endif
+ dmaStreamSetMode(adcp->data.dma, dmamode);
+ dmaStreamEnable(adcp->data.dma);
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ /* Calculating control registers values.*/
+ dmamode = adcp->dmamode;
+ if (grpp->circular) {
+ dmamode |= STM32_BDMA_CR_CIRC;
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_CIRCULAR;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ dmamode |= STM32_BDMA_CR_HTIE;
+ }
+ }
+ else {
+ cfgr = grpp->cfgr | ADC_CFGR_DMNGT_ONESHOT;
+ }
+
+ /* DMA setup.*/
+ bdmaStreamSetMemory(adcp->data.bdma, adcp->samples);
+ bdmaStreamSetTransactionSize(adcp->data.bdma, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ bdmaStreamSetMode(adcp->data.bdma, dmamode);
+ bdmaStreamEnable(adcp->data.bdma);
+ }
+#endif /* STM32_ADC_USE_ADC3 == TRUE */
+
+ /* ADC setup, if it is defined a callback for the analog watch dog then it
+ is enabled.*/
+ /* clear AWD1..3 flags */
+ adcp->adcm->ISR = adcp->adcm->ISR;
+ /* If a callback is set enable the overflow and analog watch dog interrupts. */
+ if (grpp->error_cb != NULL) {
+ adcp->adcm->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
+ | ADC_IER_AWD2IE
+ | ADC_IER_AWD3IE;
+ }
+#if STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC12 == TRUE
+ /* Configuration for dual mode ADC12 */
+ if (&ADCD1 == adcp) {
+ /* clear AWD1..3 flags */
+ adcp->adcs->ISR = adcp->adcs->ISR;
+ /* If a callback is set enable the overflow and analog watch dog interrupts. */
+ if (grpp->error_cb != NULL) {
+ adcp->adcs->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
+ | ADC_IER_AWD2IE
+ | ADC_IER_AWD3IE;
+ /* Configuring the CCR register with the user-specified settings
+ in the conversion group configuration structure, static settings are
+ preserved.*/
+ adcp->adcc->CCR = (adcp->adcc->CCR &
+ (ADC_CCR_CKMODE_MASK | ADC_CCR_DAMDF_MASK | ADC_CCR_DUAL_MASK)) | ccr;
+
+ adcp->adcm->CFGR2 = grpp->cfgr2;
+ adcp->adcm->PCSEL = grpp->pcsel;
+ adcp->adcm->LTR1 = grpp->ltr1;
+ adcp->adcm->HTR1 = grpp->htr1;
+ adcp->adcm->LTR2 = grpp->ltr2;
+ adcp->adcm->HTR2 = grpp->htr2;
+ adcp->adcm->LTR3 = grpp->ltr3;
+ adcp->adcm->HTR3 = grpp->htr3;
+ adcp->adcm->AWD2CR = grpp->awd2cr;
+ adcp->adcm->AWD3CR = grpp->awd3cr;
+ adcp->adcm->SMPR1 = grpp->smpr[0];
+ adcp->adcm->SMPR2 = grpp->smpr[1];
+ adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
+ adcp->adcm->SQR2 = grpp->sqr[1];
+ adcp->adcm->SQR3 = grpp->sqr[2];
+ adcp->adcm->SQR4 = grpp->sqr[3];
+ adcp->adcs->CFGR2 = grpp->cfgr2;
+ adcp->adcs->PCSEL = grpp->pcsel;
+ adcp->adcs->LTR1 = grpp->sltr1;
+ adcp->adcs->HTR1 = grpp->shtr1;
+ adcp->adcs->LTR2 = grpp->sltr2;
+ adcp->adcs->HTR2 = grpp->shtr2;
+ adcp->adcs->LTR3 = grpp->sltr3;
+ adcp->adcs->HTR3 = grpp->shtr3;
+ adcp->adcs->AWD2CR = grpp->sawd2cr;
+ adcp->adcs->AWD3CR = grpp->sawd3cr;
+ adcp->adcs->SMPR1 = grpp->ssmpr[0];
+ adcp->adcs->SMPR2 = grpp->ssmpr[1];
+ adcp->adcs->SQR1 = grpp->ssqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels / 2);
+ adcp->adcs->SQR2 = grpp->ssqr[1];
+ adcp->adcs->SQR3 = grpp->ssqr[2];
+ adcp->adcs->SQR4 = grpp->ssqr[3];
+
+ /* ADC configuration.*/
+ adcp->adcm->CFGR = cfgr;
+ adcp->adcs->CFGR = cfgr;
+ }
+}
+#endif /* STM32_ADC_DUAL_MODE == TRUE && STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_DUAL_MODE == FALSE || STM32_ADC_USE_ADC3 == TRUE
+ /* Configuration for ADC3 and single mode ADC1 */
+
+ adcp->adcm->CFGR2 = grpp->cfgr2;
+ adcp->adcm->PCSEL = grpp->pcsel;
+ adcp->adcm->LTR1 = grpp->ltr1;
+ adcp->adcm->HTR1 = grpp->htr1;
+ adcp->adcm->LTR2 = grpp->ltr2;
+ adcp->adcm->HTR2 = grpp->htr2;
+ adcp->adcm->LTR3 = grpp->ltr3;
+ adcp->adcm->HTR3 = grpp->htr3;
+ adcp->adcm->AWD2CR = grpp->awd2cr;
+ adcp->adcm->AWD3CR = grpp->awd3cr;
+ adcp->adcm->SMPR1 = grpp->smpr[0];
+ adcp->adcm->SMPR2 = grpp->smpr[1];
+ adcp->adcm->SQR1 = grpp->sqr[0] | ADC_SQR1_NUM_CH(grpp->num_channels);
+ adcp->adcm->SQR2 = grpp->sqr[1];
+ adcp->adcm->SQR3 = grpp->sqr[2];
+ adcp->adcm->SQR4 = grpp->sqr[3];
+
+ /* ADC configuration.*/
+ adcp->adcm->CFGR = cfgr;
+#endif
+
+ /* Starting conversion.*/
+ adcp->adcm->CR |= ADC_CR_ADSTART;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+#if STM32_ADC_USE_ADC12 == TRUE
+ if (&ADCD1 == adcp) {
+ dmaStreamDisable(adcp->data.dma);
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+#if STM32_ADC_USE_ADC3 == TRUE
+ if (&ADCD3 == adcp) {
+ bdmaStreamDisable(adcp->data.bdma);
+ }
+#endif /* STM32_ADC_USE_ADC12 == TRUE */
+
+ adc_lld_stop_adc(adcp);
+}
+
+/**
+ * @brief Enables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVREF(ADCDriver *adcp) {
+
+ adcp->adcc->CCR |= ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Disables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVREF(ADCDriver *adcp) {
+
+ adcp->adcc->CCR &= ~ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Enables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableTS(ADCDriver *adcp) {
+
+ adcp->adcc->CCR |= ADC_CCR_TSEN;
+}
+
+/**
+ * @brief Disables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableTS(ADCDriver *adcp) {
+
+ adcp->adcc->CCR &= ~ADC_CCR_TSEN;
+}
+
+/**
+ * @brief Enables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVBAT(ADCDriver *adcp) {
+
+ adcp->adcc->CCR |= ADC_CCR_VBATEN;
+}
+
+/**
+ * @brief Disables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVBAT(ADCDriver *adcp) {
+
+ adcp->adcc->CCR &= ~ADC_CCR_VBATEN;
+}
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h
index 433f5fbf29..e3f35d208e 100644
--- a/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv4/hal_adc_lld.h
@@ -1,777 +1,777 @@
-/*
- 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 ADCv4/hal_adc_lld.h
- * @brief STM32 ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Possible ADC errors mask bits.
- * @{
- */
-#define ADC_ERR_DMAFAILURE 1U /**< DMA operations failure. */
-#define ADC_ERR_OVERFLOW 2U /**< ADC overflow condition. */
-#define ADC_ERR_AWD1 4U /**< Watchdog 1 triggered. */
-#define ADC_ERR_AWD2 8U /**< Watchdog 2 triggered. */
-#define ADC_ERR_AWD3 16U /**< Watchdog 3 triggered. */
-/** @} */
-
-/**
- * @name Available analog channels
- * @{
- */
-#define ADC_CHANNEL_IN0 0U /**< @brief External analog input 0. */
-#define ADC_CHANNEL_IN1 1U /**< @brief External analog input 1. */
-#define ADC_CHANNEL_IN2 2U /**< @brief External analog input 2. */
-#define ADC_CHANNEL_IN3 3U /**< @brief External analog input 3. */
-#define ADC_CHANNEL_IN4 4U /**< @brief External analog input 4. */
-#define ADC_CHANNEL_IN5 5U /**< @brief External analog input 5. */
-#define ADC_CHANNEL_IN6 6U /**< @brief External analog input 6. */
-#define ADC_CHANNEL_IN7 7U /**< @brief External analog input 7. */
-#define ADC_CHANNEL_IN8 8U /**< @brief External analog input 8. */
-#define ADC_CHANNEL_IN9 9U /**< @brief External analog input 9. */
-#define ADC_CHANNEL_IN10 10U /**< @brief External analog input 10. */
-#define ADC_CHANNEL_IN11 11U /**< @brief External analog input 11. */
-#define ADC_CHANNEL_IN12 12U /**< @brief External analog input 12. */
-#define ADC_CHANNEL_IN13 13U /**< @brief External analog input 13. */
-#define ADC_CHANNEL_IN14 14U /**< @brief External analog input 14. */
-#define ADC_CHANNEL_IN15 15U /**< @brief External analog input 15. */
-#define ADC_CHANNEL_IN16 16U /**< @brief External analog input 16. */
-#define ADC_CHANNEL_IN17 17U /**< @brief External analog input 17. */
-#define ADC_CHANNEL_IN18 18U /**< @brief External analog input 18. */
-#define ADC_CHANNEL_IN19 19U /**< @brief External analog input 19. */
-/** @} */
-
-/**
- * @name ADC channels selection masks
- * @{
- */
-#define ADC_SELMASK_IN0 (1U << ADC_CHANNEL_IN0)
-#define ADC_SELMASK_IN1 (1U << ADC_CHANNEL_IN1)
-#define ADC_SELMASK_IN2 (1U << ADC_CHANNEL_IN2)
-#define ADC_SELMASK_IN3 (1U << ADC_CHANNEL_IN3)
-#define ADC_SELMASK_IN4 (1U << ADC_CHANNEL_IN4)
-#define ADC_SELMASK_IN5 (1U << ADC_CHANNEL_IN5)
-#define ADC_SELMASK_IN6 (1U << ADC_CHANNEL_IN6)
-#define ADC_SELMASK_IN7 (1U << ADC_CHANNEL_IN7)
-#define ADC_SELMASK_IN8 (1U << ADC_CHANNEL_IN8)
-#define ADC_SELMASK_IN9 (1U << ADC_CHANNEL_IN9)
-#define ADC_SELMASK_IN10 (1U << ADC_CHANNEL_IN10)
-#define ADC_SELMASK_IN11 (1U << ADC_CHANNEL_IN11)
-#define ADC_SELMASK_IN12 (1U << ADC_CHANNEL_IN12)
-#define ADC_SELMASK_IN13 (1U << ADC_CHANNEL_IN13)
-#define ADC_SELMASK_IN14 (1U << ADC_CHANNEL_IN14)
-#define ADC_SELMASK_IN15 (1U << ADC_CHANNEL_IN15)
-#define ADC_SELMASK_IN16 (1U << ADC_CHANNEL_IN16)
-#define ADC_SELMASK_IN17 (1U << ADC_CHANNEL_IN17)
-#define ADC_SELMASK_IN18 (1U << ADC_CHANNEL_IN18)
-#define ADC_SELMASK_IN19 (1U << ADC_CHANNEL_IN19)
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#if defined(STM32H7XX)
-#define ADC_SMPR_SMP_1P5 0U /**< @brief 9 cycles conversion time */
-#define ADC_SMPR_SMP_2P5 1U /**< @brief 10 cycles conversion time. */
-#define ADC_SMPR_SMP_8P5 2U /**< @brief 16 cycles conversion time. */
-#define ADC_SMPR_SMP_16P5 3U /**< @brief 24 cycles conversion time. */
-#define ADC_SMPR_SMP_32P5 4U /**< @brief 40 cycles conversion time. */
-#define ADC_SMPR_SMP_64P5 5U /**< @brief 72 cycles conversion time. */
-#define ADC_SMPR_SMP_384P5 6U /**< @brief 392 cycles conversion time. */
-#define ADC_SMPR_SMP_810P5 7U /**< @brief 818 cycles conversion time. */
-#endif
-/** @} */
-
-/**
- * @name CFGR register configuration helpers
- * @{
- */
-#define ADC_CFGR_DMNGT_MASK (3U << 0U)
-#define ADC_CFGR_DMNGT_NODMA (0U << 0U)
-#define ADC_CFGR_DMNGT_ONESHOT (1U << 0U)
-#define ADC_CFGR_DMNGT_DFSDM (2U << 0U)
-#define ADC_CFGR_DMNGT_CIRCULAR (3U << 0U)
-
-#define ADC_CFGR_RES_MASK (7U << 2U)
-#define ADC_CFGR_RES_16BITS (0U << 2U)
-#define ADC_CFGR_RES_10BITS (3U << 2U)
-#if !defined(STM32_ENFORCE_H7_REV_XY)
-#define ADC_CFGR_RES_14BITS (5U << 2U)
-#define ADC_CFGR_RES_12BITS (6U << 2U)
-#define ADC_CFGR_RES_8BITS (7U << 2U)
-#else
-#define ADC_CFGR_RES_14BITS (1U << 2U)
-#define ADC_CFGR_RES_12BITS (2U << 2U)
-#define ADC_CFGR_RES_8BITS (4U << 2U)
-#endif
-
-#define ADC_CFGR_EXTSEL_MASK (15U << 5U)
-#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 5U)
-
-#define ADC_CFGR_EXTEN_MASK (3U << 10U)
-#define ADC_CFGR_EXTEN_DISABLED (0U << 10U)
-#define ADC_CFGR_EXTEN_RISING (1U << 10U)
-#define ADC_CFGR_EXTEN_FALLING (2U << 10U)
-#define ADC_CFGR_EXTEN_BOTH (3U << 10U)
-
-#define ADC_CFGR_CONT_MASK (1U << 13U)
-#define ADC_CFGR_CONT_DISABLED (0U << 13U)
-#define ADC_CFGR_CONT_ENABLED (1U << 13U)
-
-#define ADC_CFGR_DISCEN_MASK (1U << 16U)
-#define ADC_CFGR_DISCEN_DISABLED (0U << 16U)
-#define ADC_CFGR_DISCEN_ENABLED (1U << 16U)
-
-#define ADC_CFGR_DISCNUM_MASK (7U << 17U)
-#define ADC_CFGR_DISCNUM_VAL(n) ((n) << 17U)
-/** @} */
-
-/**
- * @name CCR register configuration helpers
- * @{
- */
-#define ADC_CCR_DUAL_MASK (31U << 0U)
-#define ADC_CCR_DUAL_FIELD(n) ((n) << 0U)
-#define ADC_CCR_DUAL_INDEPENDENT (0U << 0U) /**< @brief Independent, dual mode disabled. */
-#define ADC_CCR_DUAL_REG_SIMULT (6U << 0U) /**< @brief Regular simultaneous. */
-#define ADC_CCR_DUAL_REG_INTERL (7U << 0U) /**< @brief Regular interleaved. */
-#define ADC_CCR_DUAL_INJ_SIMULT (5U << 0U) /**< @brief Injected simultaneous. */
-#define ADC_CCR_DUAL_INJ_ALTERNATE (9U << 0U) /**< @brief Injected alternate trigger. */
-#define ADC_CCR_DUAL_REG_SIM_INJ_SIM (1U << 0U) /**< @brief Combined regular simultaneous + injected simultaneous. */
-#define ADC_CCR_DUAL_REG_SIM_INJ_ALT (2U << 0U) /**< @brief Combined regular simultaneous + injected alternate trigger. */
-#define ADC_CCR_DUAL_REG_INT_INJ_SIM (3U << 0U) /**< @brief Combined regular interleaved + injected simultaneous. */
-#define ADC_CCR_DELAY_MASK (15U << 8U)
-#define ADC_CCR_DELAY_FIELD(n) ((n) << 8U)
-#define ADC_CCR_DAMDF_MASK (3U << 14U)
-#define ADC_CCR_DAMDF_DISABLED (0U << 14U)
-#define ADC_CCR_DAMDF_HWORD (2U << 14U)
-#define ADC_CCR_DAMDF_BYTE (3U << 14U)
-#define ADC_CCR_CKMODE_MASK (3U << 16U)
-#define ADC_CCR_CKMODE_ADCCK (0U << 16U)
-#define ADC_CCR_CKMODE_AHB_DIV1 (1U << 16U)
-#define ADC_CCR_CKMODE_AHB_DIV2 (2U << 16U)
-#define ADC_CCR_CKMODE_AHB_DIV4 (3U << 16U)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief Enables the ADC1 and ADC2 master/slave mode.
- */
-#if !defined(STM32_ADC_DUAL_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_DUAL_MODE FALSE
-#endif
-
-/**
- * @brief Specifies the ADC samples width.
- * @note Must be 8, 16 or 32.
- * @note 10, 12, 14 and 16 bits sampling modes must not be used when
- * this option is set to 8.
- * @note 32 is useful when oversampling is activated.
- */
-#if !defined(STM32_ADC_SAMPLES_SIZE) || defined(__DOXYGEN__)
-#define STM32_ADC_SAMPLES_SIZE 16
-#endif
-
-/**
- * @brief ADC1/ADC2 driver enable switch.
- * @details If set to @p TRUE the support for ADC1/ADC2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC12) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC12 FALSE
-#endif
-
-/**
- * @brief ADC3 driver enable switch.
- * @details If set to @p TRUE the support for ADC3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC3 FALSE
-#endif
-
-/**
- * @brief ADC1/ADC2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC12_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC3 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC1/ADC2 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC12_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC3 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC1/ADC2 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC12_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
-#endif
-
-/**
- * @brief ADC3 clock source and mode.
- */
-#if !defined(STM32_ADC_ADC3_CLOCK_MODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC3_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Supported devices checks.*/
-#if !defined(STM32H7XX)
-#error "ADCv4 only supports H7 STM32 devices"
-#endif
-
-/* Registry checks.*/
-#if !defined(STM32_HAS_ADC1) || !defined(STM32_HAS_ADC2) || \
- !defined(STM32_HAS_ADC3)
-#error "STM32_HAS_ADCx not defined in registry"
-#endif
-
-/* Units checks.*/
-#if STM32_ADC_USE_ADC12 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-#if STM32_ADC_DUAL_MODE && !STM32_HAS_ADC2
-#error "ADC2 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
-#error "ADC3 not present in the selected device"
-#endif
-
-/* IRQ handlers checks.*/
-#if STM32_HAS_ADC1 && !defined(STM32_ADC12_HANDLER)
-#error "STM32_ADC12_HANDLER not defined in registry"
-#endif
-
-#if STM32_HAS_ADC2 && !defined(STM32_ADC12_HANDLER)
-#error "STM32_ADC12_HANDLER not defined in registry"
-#endif
-
-#if STM32_HAS_ADC3 && !defined(STM32_ADC3_HANDLER)
-#error "STM32_ADC3_HANDLER not defined in registry"
-#endif
-
-/* IRQ vector numbers checks.*/
-#if STM32_HAS_ADC1 && !defined(STM32_ADC12_NUMBER)
-#error "STM32_ADC12_NUMBER not defined in registry"
-#endif
-
-#if STM32_HAS_ADC2 && !defined(STM32_ADC12_NUMBER)
-#error "STM32_ADC12_NUMBER not defined in registry"
-#endif
-
-#if STM32_HAS_ADC3 && !defined(STM32_ADC3_NUMBER)
-#error "STM32_ADC3_NUMBER not defined in registry"
-#endif
-
-/* At least one ADC must be assigned.*/
-#if !STM32_ADC_USE_ADC12 && !STM32_ADC_USE_ADC3
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-/* Dual mode is only supported with ADC12.*/
-#if !STM32_ADC_USE_ADC12 && STM32_ADC_DUAL_MODE
-#error "STM32_ADC_DUAL_MODE only supported with ADC12"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_ADC_USE_ADC12 && !defined(STM32_ADC_ADC12_DMA_STREAM)
-#error "STM32_ADC_ADC12_DMA_STREAM not defined"
-#endif
-
-#if STM32_ADC_USE_ADC3 && !defined(STM32_ADC_ADC3_BDMA_STREAM)
-#error "STM32_ADC_ADC3_BDMA_STREAM not defined"
-#endif
-
-/* DMA channel range tests.*/
-#if STM32_ADC_USE_ADC12 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_ADC_ADC12_DMA_STREAM)
-#error "Invalid DMA channel assigned to ADC12"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !STM32_BDMA_IS_VALID_STREAM(STM32_ADC_ADC3_BDMA_STREAM)
-#error "Invalid DMA channel assigned to ADC3"
-#endif
-
-/* DMA priority tests.*/
-#if STM32_ADC_USE_ADC12 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC12_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC3"
-#endif
-
-/* ADC IRQ priority tests.*/
-#if STM32_ADC_USE_ADC12 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC3"
-#endif
-
-#if ((STM32_ADC_SAMPLES_SIZE != 8) && \
- (STM32_ADC_SAMPLES_SIZE != 16) && \
- (STM32_ADC_SAMPLES_SIZE != 32))
-#error "STM32_ADC_SAMPLES_SIZE must be 8, 16 or 32"
-#endif
-
-#if (STM32_ADC_SAMPLES_SIZE != 32) && STM32_ADC_DUAL_MODE
-#error "STM32_ADC_SAMPLES_SIZE = 32 not compatible with STM32_ADC_DUAL_MODE"
-#endif
-
-#if !defined(STM32_ENFORCE_H7_REV_XY)
-/* ADC clock source checks.*/
-#if (STM32_D1HPRE == STM32_D1HPRE_DIV1)
-#define STM32_ADC_SCLK STM32_HCLK
-#else
-#define STM32_ADC_SCLK (STM32_HCLK / 2)
-#endif
-
-#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-/* CHTODO: also check ADC_CCR_PRESC.*/
-#define STM32_ADC12_CLOCK (STM32_ADCCLK / 2)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 1 / 2)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 2 / 2)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 4 / 2)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
-#endif
-
-#if STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-/* CHTODO: also check ADC_CCR_PRESC.*/
-#define STM32_ADC3_CLOCK (STM32_ADCCLK / 2)
-#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 1 / 2)
-#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 2 / 2)
-#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 4 / 2)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC3_CLOCK_MODE"
-#endif
-
-#else /* defined(STM32_ENFORCE_H7_REV_XY) */
-
-#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC12_CLOCK STM32_ADCCLK
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC12_CLOCK (STM32_HCLK / 1)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC12_CLOCK (STM32_HCLK / 2)
-#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC12_CLOCK (STM32_HCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
-#endif
-
-#if STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
-#define STM32_ADC3_CLOCK STM32_ADCCLK
-#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
-#define STM32_ADC3_CLOCK (STM32_HCLK / 1)
-#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
-#define STM32_ADC3_CLOCK (STM32_HCLK / 2)
-#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
-#define STM32_ADC3_CLOCK (STM32_HCLK / 4)
-#else
-#error "invalid clock mode selected for STM32_ADC_ADC3_CLOCK_MODE"
-#endif
-
-#endif /* defined(STM32_ENFORCE_H7_REV_XY) */
-
-#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-
-#if STM32_ADC3_CLOCK > STM32_ADCCLK_MAX
-#error "STM32_ADC3_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
-#endif
-
-#if !defined(STM32_ENFORCE_H7_REV_XY)
-/* ADC boost checks.*/
-#if STM32_ADC12_CLOCK > 6250000
-#define STM32_ADC12_BOOST (1U << 8U)
-#elif STM32_ADC12_CLOCK > 12500000
-#define STM32_ADC12_BOOST (2U << 8U)
-#elif STM32_ADC12_CLOCK > 25000000
-#define STM32_ADC12_BOOST (3U << 8U)
-#else
-#define STM32_ADC12_BOOST (0U << 8U)
-#endif
-
-#if STM32_ADC3_CLOCK > 6250000
-#define STM32_ADC3_BOOST (1U << 8U)
-#elif STM32_ADC3_CLOCK > 12500000
-#define STM32_ADC3_BOOST (2U << 8U)
-#elif STM32_ADC3_CLOCK > 25000000
-#define STM32_ADC3_BOOST (3U << 8U)
-#else
-#define STM32_ADC3_BOOST (0U << 8U)
-#endif
-
-#else /* defined(STM32_ENFORCE_H7_REV_XY) */
-
-#if STM32_ADC12_CLOCK > 20000000
-#define STM32_ADC12_BOOST (1U << 8U)
-#else
-#define STM32_ADC12_BOOST (0U << 8U)
-#endif
-
-#if STM32_ADC3_CLOCK > 20000000
-#define STM32_ADC3_BOOST (1U << 8U)
-#else
-#define STM32_ADC3_BOOST (0U << 8U)
-#endif
-
-#endif /* defined(STM32_ENFORCE_H7_REV_XY) */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-#if STM32_ADC_USE_ADC12
-#define STM32_ADC_DMA_REQUIRED
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-#endif
-
-#if STM32_ADC_USE_ADC3
-#define STM32_ADC_BDMA_REQUIRED
-#if !defined(STM32_BDMA_REQUIRED)
-#define STM32_BDMA_REQUIRED
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-#if (STM32_ADC_SAMPLES_SIZE == 16) || defined(__DOXYGEN__)
-typedef uint16_t adcsample_t;
-#elif (STM32_ADC_SAMPLES_SIZE == 8)
-typedef uint8_t adcsample_t;
-#elif (STM32_ADC_SAMPLES_SIZE == 32)
-typedef uint32_t adcsample_t;
-#endif
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint32_t adc_channels_num_t;
-
-/**
- * @brief Type of an ADC error mask.
- */
-typedef uint32_t adcerror_t;
-
-/**
- * @brief Type of a DMA channel pointer choice.
- */
-typedef union {
-#if defined(STM32_ADC_DMA_REQUIRED) || defined(__DOXYGEN__)
- /**
- * @brief DMA stream.
- */
- const stm32_dma_stream_t *dma;
-#endif
-#if defined(STM32_ADC_BDMA_REQUIRED) || defined(__DOXYGEN__)
- /**
- * @brief BDMA stream.
- */
- const stm32_bdma_stream_t *bdma;
-#endif
-} adc_ldd_dma_reference_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
-#define adc_lld_driver_fields \
- /* Pointer to the master ADCx registers block.*/ \
- ADC_TypeDef *adcm; \
- /* Pointer to the slave ADCx registers block.*/ \
- ADC_TypeDef *adcs; \
- /* Pointer to the common ADCx_y registers block.*/ \
- ADC_Common_TypeDef *adcc; \
- /* Pointer to associated DMA channel.*/ \
- adc_ldd_dma_reference_t data; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-#else
-#define adc_lld_driver_fields \
- /* Pointer to the master ADCx registers block.*/ \
- ADC_TypeDef *adcm; \
- /* Pointer to the slave ADCx registers block.*/ \
- ADC_Common_TypeDef *adcc; \
- /* Pointer to associated DMA channel.*/ \
- adc_ldd_dma_reference_t data; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-#endif
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* ADC DIFSEL register initialization data.*/ \
- uint32_t difsel; \
- /* Calibration mode, specify ADCCALIN and/or ADCCALDIF bits in here.*/ \
- uint32_t calibration
-
-#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
-#define adc_lld_configuration_group_fields \
- /* ADC CFGR register initialization data. \
- NOTE: The bits DMAEN and DMACFG are enforced internally \
- to the driver, keep them to zero. \
- NOTE: The bits @p ADC_CFGR_CONT or @p ADC_CFGR_DISCEN must be \
- specified in continuous mode or if the buffer depth is \
- greater than one.*/ \
- uint32_t cfgr; \
- /* ADC CFGR2 register initialization data. \
- NOTE: Put this field to zero if not using oversampling.*/ \
- uint32_t cfgr2; \
- /* ADC CCR register initialization data*/ \
- uint32_t ccr; \
- /* ADC PCSEL register initialization data.*/ \
- uint32_t pcsel; \
- /* ADC LTR1 register initialization data.*/ \
- uint32_t ltr1; \
- /* ADC HTR1 register initialization data.*/ \
- uint32_t htr1; \
- /* ADC LTR2 register initialization data.*/ \
- uint32_t ltr2; \
- /* ADC HTR2 register initialization data.*/ \
- uint32_t htr2; \
- /* ADC LTR3 register initialization data.*/ \
- uint32_t ltr3; \
- /* ADC HTR3 register initialization data.*/ \
- uint32_t htr3; \
- /* ADC AWD2CR register initialization data.*/ \
- uint32_t awd2cr; \
- /* ADC AWD3CR register initialization data.*/ \
- uint32_t awd3cr; \
- /* ADC SMPRx registers initialization data.*/ \
- uint32_t smpr[2]; \
- /* ADC SQRx register initialization data.*/ \
- uint32_t sqr[4]; \
- /* Slave ADC LTR/HTRx registers initialization data. \
- NOTE: This field is only present in dual mode.*/ \
- uint32_t sltr1; \
- uint32_t shtr1; \
- uint32_t sltr2; \
- uint32_t shtr2; \
- uint32_t sltr3; \
- uint32_t shtr3; \
- /* Slave ADC AWDxCR registers initialization data. \
- NOTE: This field is only present in dual mode.*/ \
- uint32_t sawd2cr; \
- uint32_t sawd3cr; \
- /* Slave ADC SMPRx registers initialization data. \
- NOTE: This field is only present in dual mode.*/ \
- uint32_t ssmpr[2]; \
- /* Slave ADC SQRx register initialization data. \
- NOTE: This field is only present in dual mode.*/ \
- uint32_t ssqr[4]
-#else /* STM32_ADC_DUAL_MODE == FALSE */
-#define adc_lld_configuration_group_fields \
- uint32_t cfgr; \
- uint32_t cfgr2; \
- uint32_t ccr; \
- uint32_t pcsel; \
- uint32_t ltr1; \
- uint32_t htr1; \
- uint32_t ltr2; \
- uint32_t htr2; \
- uint32_t ltr3; \
- uint32_t htr3; \
- uint32_t awd2cr; \
- uint32_t awd3cr; \
- uint32_t smpr[2]; \
- uint32_t sqr[4]
-#endif /* STM32_ADC_DUAL_MODE == FALSE */
-
-/**
- * @name Sequences building helper macros
- * @{
- */
-/**
- * @brief Number of channels in a conversion sequence.
- */
-#define ADC_SQR1_NUM_CH(n) (((n) - 1U) << 0U)
-
-#define ADC_SQR1_SQ1_N(n) ((n) << 6U) /**< @brief 1st channel in seq. */
-#define ADC_SQR1_SQ2_N(n) ((n) << 12U)/**< @brief 2nd channel in seq. */
-#define ADC_SQR1_SQ3_N(n) ((n) << 18U)/**< @brief 3rd channel in seq. */
-#define ADC_SQR1_SQ4_N(n) ((n) << 24U)/**< @brief 4th channel in seq. */
-
-#define ADC_SQR2_SQ5_N(n) ((n) << 0U) /**< @brief 5th channel in seq. */
-#define ADC_SQR2_SQ6_N(n) ((n) << 6U) /**< @brief 6th channel in seq. */
-#define ADC_SQR2_SQ7_N(n) ((n) << 12U)/**< @brief 7th channel in seq. */
-#define ADC_SQR2_SQ8_N(n) ((n) << 18U)/**< @brief 8th channel in seq. */
-#define ADC_SQR2_SQ9_N(n) ((n) << 24U)/**< @brief 9th channel in seq. */
-
-#define ADC_SQR3_SQ10_N(n) ((n) << 0U) /**< @brief 10th channel in seq.*/
-#define ADC_SQR3_SQ11_N(n) ((n) << 6U) /**< @brief 11th channel in seq.*/
-#define ADC_SQR3_SQ12_N(n) ((n) << 12U)/**< @brief 12th channel in seq.*/
-#define ADC_SQR3_SQ13_N(n) ((n) << 18U)/**< @brief 13th channel in seq.*/
-#define ADC_SQR3_SQ14_N(n) ((n) << 24U)/**< @brief 14th channel in seq.*/
-
-#define ADC_SQR4_SQ15_N(n) ((n) << 0U) /**< @brief 15th channel in seq.*/
-#define ADC_SQR4_SQ16_N(n) ((n) << 6U) /**< @brief 16th channel in seq.*/
-/** @} */
-
-/**
- * @name Sampling rate settings helper macros
- * @{
- */
-#define ADC_SMPR1_SMP_AN0(n) ((n) << 0U) /**< @brief AN0 sampling time. */
-#define ADC_SMPR1_SMP_AN1(n) ((n) << 3U) /**< @brief AN1 sampling time. */
-#define ADC_SMPR1_SMP_AN2(n) ((n) << 6U) /**< @brief AN2 sampling time. */
-#define ADC_SMPR1_SMP_AN3(n) ((n) << 9U) /**< @brief AN3 sampling time. */
-#define ADC_SMPR1_SMP_AN4(n) ((n) << 12U)/**< @brief AN4 sampling time. */
-#define ADC_SMPR1_SMP_AN5(n) ((n) << 15U)/**< @brief AN5 sampling time. */
-#define ADC_SMPR1_SMP_AN6(n) ((n) << 18U)/**< @brief AN6 sampling time. */
-#define ADC_SMPR1_SMP_AN7(n) ((n) << 21U)/**< @brief AN7 sampling time. */
-#define ADC_SMPR1_SMP_AN8(n) ((n) << 24U)/**< @brief AN8 sampling time. */
-#define ADC_SMPR1_SMP_AN9(n) ((n) << 27U)/**< @brief AN9 sampling time. */
-
-#define ADC_SMPR2_SMP_AN10(n) ((n) << 0U) /**< @brief AN10 sampling time. */
-#define ADC_SMPR2_SMP_AN11(n) ((n) << 3U) /**< @brief AN11 sampling time. */
-#define ADC_SMPR2_SMP_AN12(n) ((n) << 6U) /**< @brief AN12 sampling time. */
-#define ADC_SMPR2_SMP_AN13(n) ((n) << 9U) /**< @brief AN13 sampling time. */
-#define ADC_SMPR2_SMP_AN14(n) ((n) << 12U)/**< @brief AN14 sampling time. */
-#define ADC_SMPR2_SMP_AN15(n) ((n) << 15U)/**< @brief AN15 sampling time. */
-#define ADC_SMPR2_SMP_AN16(n) ((n) << 18U)/**< @brief AN16 sampling time. */
-#define ADC_SMPR2_SMP_AN17(n) ((n) << 21U)/**< @brief AN17 sampling time. */
-#define ADC_SMPR2_SMP_AN18(n) ((n) << 24U)/**< @brief AN18 sampling time. */
-#define ADC_SMPR2_SMP_AN19(n) ((n) << 27U)/**< @brief AN19 sampling time. */
-/** @} */
-
-/**
- * @name Analog watchdog settings helper macros
- * @{
- */
-#define ADC_CFGR_AWD1_N(n) ((n) << 26U)/**< @brief AWD1 channel number */
-#define ADC_AWD23_MASK(n) (1U << (n)) /**< @brief AWD2/3 channels mask*/
-/** @} */
-
-/**
- * @name Oversampling settings helper macros
- * @{
- */
-#define ADC_CFGR2_OVSS_N(n) ((n) << 5U)/**< @brief ovsr right shift */
-#define ADC_CFGR2_OVSR_N(n) ((n) << 16U)/**< @brief oversampling ratio */
-#define ADC_CFGR2_LSHIFT_N(n) ((n) << 28U)/**< @brief ovsr left shift */
-
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC12 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adcSTM32EnableVREF(ADCDriver *adcp);
- void adcSTM32DisableVREF(ADCDriver *adcp);
- void adcSTM32EnableTS(ADCDriver *adcp);
- void adcSTM32DisableTS(ADCDriver *adcp);
- void adcSTM32EnableVBAT(ADCDriver *adcp);
- void adcSTM32DisableVBAT(ADCDriver *adcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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 ADCv4/hal_adc_lld.h
+ * @brief STM32 ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Possible ADC errors mask bits.
+ * @{
+ */
+#define ADC_ERR_DMAFAILURE 1U /**< DMA operations failure. */
+#define ADC_ERR_OVERFLOW 2U /**< ADC overflow condition. */
+#define ADC_ERR_AWD1 4U /**< Watchdog 1 triggered. */
+#define ADC_ERR_AWD2 8U /**< Watchdog 2 triggered. */
+#define ADC_ERR_AWD3 16U /**< Watchdog 3 triggered. */
+/** @} */
+
+/**
+ * @name Available analog channels
+ * @{
+ */
+#define ADC_CHANNEL_IN0 0U /**< @brief External analog input 0. */
+#define ADC_CHANNEL_IN1 1U /**< @brief External analog input 1. */
+#define ADC_CHANNEL_IN2 2U /**< @brief External analog input 2. */
+#define ADC_CHANNEL_IN3 3U /**< @brief External analog input 3. */
+#define ADC_CHANNEL_IN4 4U /**< @brief External analog input 4. */
+#define ADC_CHANNEL_IN5 5U /**< @brief External analog input 5. */
+#define ADC_CHANNEL_IN6 6U /**< @brief External analog input 6. */
+#define ADC_CHANNEL_IN7 7U /**< @brief External analog input 7. */
+#define ADC_CHANNEL_IN8 8U /**< @brief External analog input 8. */
+#define ADC_CHANNEL_IN9 9U /**< @brief External analog input 9. */
+#define ADC_CHANNEL_IN10 10U /**< @brief External analog input 10. */
+#define ADC_CHANNEL_IN11 11U /**< @brief External analog input 11. */
+#define ADC_CHANNEL_IN12 12U /**< @brief External analog input 12. */
+#define ADC_CHANNEL_IN13 13U /**< @brief External analog input 13. */
+#define ADC_CHANNEL_IN14 14U /**< @brief External analog input 14. */
+#define ADC_CHANNEL_IN15 15U /**< @brief External analog input 15. */
+#define ADC_CHANNEL_IN16 16U /**< @brief External analog input 16. */
+#define ADC_CHANNEL_IN17 17U /**< @brief External analog input 17. */
+#define ADC_CHANNEL_IN18 18U /**< @brief External analog input 18. */
+#define ADC_CHANNEL_IN19 19U /**< @brief External analog input 19. */
+/** @} */
+
+/**
+ * @name ADC channels selection masks
+ * @{
+ */
+#define ADC_SELMASK_IN0 (1U << ADC_CHANNEL_IN0)
+#define ADC_SELMASK_IN1 (1U << ADC_CHANNEL_IN1)
+#define ADC_SELMASK_IN2 (1U << ADC_CHANNEL_IN2)
+#define ADC_SELMASK_IN3 (1U << ADC_CHANNEL_IN3)
+#define ADC_SELMASK_IN4 (1U << ADC_CHANNEL_IN4)
+#define ADC_SELMASK_IN5 (1U << ADC_CHANNEL_IN5)
+#define ADC_SELMASK_IN6 (1U << ADC_CHANNEL_IN6)
+#define ADC_SELMASK_IN7 (1U << ADC_CHANNEL_IN7)
+#define ADC_SELMASK_IN8 (1U << ADC_CHANNEL_IN8)
+#define ADC_SELMASK_IN9 (1U << ADC_CHANNEL_IN9)
+#define ADC_SELMASK_IN10 (1U << ADC_CHANNEL_IN10)
+#define ADC_SELMASK_IN11 (1U << ADC_CHANNEL_IN11)
+#define ADC_SELMASK_IN12 (1U << ADC_CHANNEL_IN12)
+#define ADC_SELMASK_IN13 (1U << ADC_CHANNEL_IN13)
+#define ADC_SELMASK_IN14 (1U << ADC_CHANNEL_IN14)
+#define ADC_SELMASK_IN15 (1U << ADC_CHANNEL_IN15)
+#define ADC_SELMASK_IN16 (1U << ADC_CHANNEL_IN16)
+#define ADC_SELMASK_IN17 (1U << ADC_CHANNEL_IN17)
+#define ADC_SELMASK_IN18 (1U << ADC_CHANNEL_IN18)
+#define ADC_SELMASK_IN19 (1U << ADC_CHANNEL_IN19)
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#if defined(STM32H7XX)
+#define ADC_SMPR_SMP_1P5 0U /**< @brief 9 cycles conversion time */
+#define ADC_SMPR_SMP_2P5 1U /**< @brief 10 cycles conversion time. */
+#define ADC_SMPR_SMP_8P5 2U /**< @brief 16 cycles conversion time. */
+#define ADC_SMPR_SMP_16P5 3U /**< @brief 24 cycles conversion time. */
+#define ADC_SMPR_SMP_32P5 4U /**< @brief 40 cycles conversion time. */
+#define ADC_SMPR_SMP_64P5 5U /**< @brief 72 cycles conversion time. */
+#define ADC_SMPR_SMP_384P5 6U /**< @brief 392 cycles conversion time. */
+#define ADC_SMPR_SMP_810P5 7U /**< @brief 818 cycles conversion time. */
+#endif
+/** @} */
+
+/**
+ * @name CFGR register configuration helpers
+ * @{
+ */
+#define ADC_CFGR_DMNGT_MASK (3U << 0U)
+#define ADC_CFGR_DMNGT_NODMA (0U << 0U)
+#define ADC_CFGR_DMNGT_ONESHOT (1U << 0U)
+#define ADC_CFGR_DMNGT_DFSDM (2U << 0U)
+#define ADC_CFGR_DMNGT_CIRCULAR (3U << 0U)
+
+#define ADC_CFGR_RES_MASK (7U << 2U)
+#define ADC_CFGR_RES_16BITS (0U << 2U)
+#define ADC_CFGR_RES_10BITS (3U << 2U)
+#if !defined(STM32_ENFORCE_H7_REV_XY)
+#define ADC_CFGR_RES_14BITS (5U << 2U)
+#define ADC_CFGR_RES_12BITS (6U << 2U)
+#define ADC_CFGR_RES_8BITS (7U << 2U)
+#else
+#define ADC_CFGR_RES_14BITS (1U << 2U)
+#define ADC_CFGR_RES_12BITS (2U << 2U)
+#define ADC_CFGR_RES_8BITS (4U << 2U)
+#endif
+
+#define ADC_CFGR_EXTSEL_MASK (15U << 5U)
+#define ADC_CFGR_EXTSEL_SRC(n) ((n) << 5U)
+
+#define ADC_CFGR_EXTEN_MASK (3U << 10U)
+#define ADC_CFGR_EXTEN_DISABLED (0U << 10U)
+#define ADC_CFGR_EXTEN_RISING (1U << 10U)
+#define ADC_CFGR_EXTEN_FALLING (2U << 10U)
+#define ADC_CFGR_EXTEN_BOTH (3U << 10U)
+
+#define ADC_CFGR_CONT_MASK (1U << 13U)
+#define ADC_CFGR_CONT_DISABLED (0U << 13U)
+#define ADC_CFGR_CONT_ENABLED (1U << 13U)
+
+#define ADC_CFGR_DISCEN_MASK (1U << 16U)
+#define ADC_CFGR_DISCEN_DISABLED (0U << 16U)
+#define ADC_CFGR_DISCEN_ENABLED (1U << 16U)
+
+#define ADC_CFGR_DISCNUM_MASK (7U << 17U)
+#define ADC_CFGR_DISCNUM_VAL(n) ((n) << 17U)
+/** @} */
+
+/**
+ * @name CCR register configuration helpers
+ * @{
+ */
+#define ADC_CCR_DUAL_MASK (31U << 0U)
+#define ADC_CCR_DUAL_FIELD(n) ((n) << 0U)
+#define ADC_CCR_DUAL_INDEPENDENT (0U << 0U) /**< @brief Independent, dual mode disabled. */
+#define ADC_CCR_DUAL_REG_SIMULT (6U << 0U) /**< @brief Regular simultaneous. */
+#define ADC_CCR_DUAL_REG_INTERL (7U << 0U) /**< @brief Regular interleaved. */
+#define ADC_CCR_DUAL_INJ_SIMULT (5U << 0U) /**< @brief Injected simultaneous. */
+#define ADC_CCR_DUAL_INJ_ALTERNATE (9U << 0U) /**< @brief Injected alternate trigger. */
+#define ADC_CCR_DUAL_REG_SIM_INJ_SIM (1U << 0U) /**< @brief Combined regular simultaneous + injected simultaneous. */
+#define ADC_CCR_DUAL_REG_SIM_INJ_ALT (2U << 0U) /**< @brief Combined regular simultaneous + injected alternate trigger. */
+#define ADC_CCR_DUAL_REG_INT_INJ_SIM (3U << 0U) /**< @brief Combined regular interleaved + injected simultaneous. */
+#define ADC_CCR_DELAY_MASK (15U << 8U)
+#define ADC_CCR_DELAY_FIELD(n) ((n) << 8U)
+#define ADC_CCR_DAMDF_MASK (3U << 14U)
+#define ADC_CCR_DAMDF_DISABLED (0U << 14U)
+#define ADC_CCR_DAMDF_HWORD (2U << 14U)
+#define ADC_CCR_DAMDF_BYTE (3U << 14U)
+#define ADC_CCR_CKMODE_MASK (3U << 16U)
+#define ADC_CCR_CKMODE_ADCCK (0U << 16U)
+#define ADC_CCR_CKMODE_AHB_DIV1 (1U << 16U)
+#define ADC_CCR_CKMODE_AHB_DIV2 (2U << 16U)
+#define ADC_CCR_CKMODE_AHB_DIV4 (3U << 16U)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief Enables the ADC1 and ADC2 master/slave mode.
+ */
+#if !defined(STM32_ADC_DUAL_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_DUAL_MODE FALSE
+#endif
+
+/**
+ * @brief Specifies the ADC samples width.
+ * @note Must be 8, 16 or 32.
+ * @note 10, 12, 14 and 16 bits sampling modes must not be used when
+ * this option is set to 8.
+ * @note 32 is useful when oversampling is activated.
+ */
+#if !defined(STM32_ADC_SAMPLES_SIZE) || defined(__DOXYGEN__)
+#define STM32_ADC_SAMPLES_SIZE 16
+#endif
+
+/**
+ * @brief ADC1/ADC2 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1/ADC2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC12) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC12 FALSE
+#endif
+
+/**
+ * @brief ADC3 driver enable switch.
+ * @details If set to @p TRUE the support for ADC3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC3) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC3 FALSE
+#endif
+
+/**
+ * @brief ADC1/ADC2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC12_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC1/ADC2 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC12_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC3 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC1/ADC2 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC12_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
+#endif
+
+/**
+ * @brief ADC3 clock source and mode.
+ */
+#if !defined(STM32_ADC_ADC3_CLOCK_MODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC3_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV4
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Supported devices checks.*/
+#if !defined(STM32H7XX)
+#error "ADCv4 only supports H7 STM32 devices"
+#endif
+
+/* Registry checks.*/
+#if !defined(STM32_HAS_ADC1) || !defined(STM32_HAS_ADC2) || \
+ !defined(STM32_HAS_ADC3)
+#error "STM32_HAS_ADCx not defined in registry"
+#endif
+
+/* Units checks.*/
+#if STM32_ADC_USE_ADC12 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+#if STM32_ADC_DUAL_MODE && !STM32_HAS_ADC2
+#error "ADC2 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_ADC3 && !STM32_HAS_ADC3
+#error "ADC3 not present in the selected device"
+#endif
+
+/* IRQ handlers checks.*/
+#if STM32_HAS_ADC1 && !defined(STM32_ADC12_HANDLER)
+#error "STM32_ADC12_HANDLER not defined in registry"
+#endif
+
+#if STM32_HAS_ADC2 && !defined(STM32_ADC12_HANDLER)
+#error "STM32_ADC12_HANDLER not defined in registry"
+#endif
+
+#if STM32_HAS_ADC3 && !defined(STM32_ADC3_HANDLER)
+#error "STM32_ADC3_HANDLER not defined in registry"
+#endif
+
+/* IRQ vector numbers checks.*/
+#if STM32_HAS_ADC1 && !defined(STM32_ADC12_NUMBER)
+#error "STM32_ADC12_NUMBER not defined in registry"
+#endif
+
+#if STM32_HAS_ADC2 && !defined(STM32_ADC12_NUMBER)
+#error "STM32_ADC12_NUMBER not defined in registry"
+#endif
+
+#if STM32_HAS_ADC3 && !defined(STM32_ADC3_NUMBER)
+#error "STM32_ADC3_NUMBER not defined in registry"
+#endif
+
+/* At least one ADC must be assigned.*/
+#if !STM32_ADC_USE_ADC12 && !STM32_ADC_USE_ADC3
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+/* Dual mode is only supported with ADC12.*/
+#if !STM32_ADC_USE_ADC12 && STM32_ADC_DUAL_MODE
+#error "STM32_ADC_DUAL_MODE only supported with ADC12"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_ADC_USE_ADC12 && !defined(STM32_ADC_ADC12_DMA_STREAM)
+#error "STM32_ADC_ADC12_DMA_STREAM not defined"
+#endif
+
+#if STM32_ADC_USE_ADC3 && !defined(STM32_ADC_ADC3_BDMA_STREAM)
+#error "STM32_ADC_ADC3_BDMA_STREAM not defined"
+#endif
+
+/* DMA channel range tests.*/
+#if STM32_ADC_USE_ADC12 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_ADC_ADC12_DMA_STREAM)
+#error "Invalid DMA channel assigned to ADC12"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !STM32_BDMA_IS_VALID_STREAM(STM32_ADC_ADC3_BDMA_STREAM)
+#error "Invalid DMA channel assigned to ADC3"
+#endif
+
+/* DMA priority tests.*/
+#if STM32_ADC_USE_ADC12 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC12_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC3"
+#endif
+
+/* ADC IRQ priority tests.*/
+#if STM32_ADC_USE_ADC12 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC12_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC3"
+#endif
+
+#if ((STM32_ADC_SAMPLES_SIZE != 8) && \
+ (STM32_ADC_SAMPLES_SIZE != 16) && \
+ (STM32_ADC_SAMPLES_SIZE != 32))
+#error "STM32_ADC_SAMPLES_SIZE must be 8, 16 or 32"
+#endif
+
+#if (STM32_ADC_SAMPLES_SIZE != 32) && STM32_ADC_DUAL_MODE
+#error "STM32_ADC_SAMPLES_SIZE = 32 not compatible with STM32_ADC_DUAL_MODE"
+#endif
+
+#if !defined(STM32_ENFORCE_H7_REV_XY)
+/* ADC clock source checks.*/
+#if (STM32_D1HPRE == STM32_D1HPRE_DIV1)
+#define STM32_ADC_SCLK STM32_HCLK
+#else
+#define STM32_ADC_SCLK (STM32_HCLK / 2)
+#endif
+
+#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+/* CHTODO: also check ADC_CCR_PRESC.*/
+#define STM32_ADC12_CLOCK (STM32_ADCCLK / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 1 / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 2 / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC12_CLOCK (STM32_ADC_SCLK / 4 / 2)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
+#endif
+
+#if STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+/* CHTODO: also check ADC_CCR_PRESC.*/
+#define STM32_ADC3_CLOCK (STM32_ADCCLK / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 1 / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 2 / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC3_CLOCK (STM32_ADC_SCLK / 4 / 2)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC3_CLOCK_MODE"
+#endif
+
+#else /* defined(STM32_ENFORCE_H7_REV_XY) */
+
+#if STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC12_CLOCK STM32_ADCCLK
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC12_CLOCK (STM32_HCLK / 1)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC12_CLOCK (STM32_HCLK / 2)
+#elif STM32_ADC_ADC12_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC12_CLOCK (STM32_HCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC12_CLOCK_MODE"
+#endif
+
+#if STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_ADCCK
+#define STM32_ADC3_CLOCK STM32_ADCCLK
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV1
+#define STM32_ADC3_CLOCK (STM32_HCLK / 1)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV2
+#define STM32_ADC3_CLOCK (STM32_HCLK / 2)
+#elif STM32_ADC_ADC3_CLOCK_MODE == ADC_CCR_CKMODE_AHB_DIV4
+#define STM32_ADC3_CLOCK (STM32_HCLK / 4)
+#else
+#error "invalid clock mode selected for STM32_ADC_ADC3_CLOCK_MODE"
+#endif
+
+#endif /* defined(STM32_ENFORCE_H7_REV_XY) */
+
+#if STM32_ADC12_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC12_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+
+#if STM32_ADC3_CLOCK > STM32_ADCCLK_MAX
+#error "STM32_ADC3_CLOCK exceeding maximum frequency (STM32_ADCCLK_MAX)"
+#endif
+
+#if !defined(STM32_ENFORCE_H7_REV_XY)
+/* ADC boost checks.*/
+#if STM32_ADC12_CLOCK > 6250000
+#define STM32_ADC12_BOOST (1U << 8U)
+#elif STM32_ADC12_CLOCK > 12500000
+#define STM32_ADC12_BOOST (2U << 8U)
+#elif STM32_ADC12_CLOCK > 25000000
+#define STM32_ADC12_BOOST (3U << 8U)
+#else
+#define STM32_ADC12_BOOST (0U << 8U)
+#endif
+
+#if STM32_ADC3_CLOCK > 6250000
+#define STM32_ADC3_BOOST (1U << 8U)
+#elif STM32_ADC3_CLOCK > 12500000
+#define STM32_ADC3_BOOST (2U << 8U)
+#elif STM32_ADC3_CLOCK > 25000000
+#define STM32_ADC3_BOOST (3U << 8U)
+#else
+#define STM32_ADC3_BOOST (0U << 8U)
+#endif
+
+#else /* defined(STM32_ENFORCE_H7_REV_XY) */
+
+#if STM32_ADC12_CLOCK > 20000000
+#define STM32_ADC12_BOOST (1U << 8U)
+#else
+#define STM32_ADC12_BOOST (0U << 8U)
+#endif
+
+#if STM32_ADC3_CLOCK > 20000000
+#define STM32_ADC3_BOOST (1U << 8U)
+#else
+#define STM32_ADC3_BOOST (0U << 8U)
+#endif
+
+#endif /* defined(STM32_ENFORCE_H7_REV_XY) */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+#if STM32_ADC_USE_ADC12
+#define STM32_ADC_DMA_REQUIRED
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+#endif
+
+#if STM32_ADC_USE_ADC3
+#define STM32_ADC_BDMA_REQUIRED
+#if !defined(STM32_BDMA_REQUIRED)
+#define STM32_BDMA_REQUIRED
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+#if (STM32_ADC_SAMPLES_SIZE == 16) || defined(__DOXYGEN__)
+typedef uint16_t adcsample_t;
+#elif (STM32_ADC_SAMPLES_SIZE == 8)
+typedef uint8_t adcsample_t;
+#elif (STM32_ADC_SAMPLES_SIZE == 32)
+typedef uint32_t adcsample_t;
+#endif
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint32_t adc_channels_num_t;
+
+/**
+ * @brief Type of an ADC error mask.
+ */
+typedef uint32_t adcerror_t;
+
+/**
+ * @brief Type of a DMA channel pointer choice.
+ */
+typedef union {
+#if defined(STM32_ADC_DMA_REQUIRED) || defined(__DOXYGEN__)
+ /**
+ * @brief DMA stream.
+ */
+ const stm32_dma_stream_t *dma;
+#endif
+#if defined(STM32_ADC_BDMA_REQUIRED) || defined(__DOXYGEN__)
+ /**
+ * @brief BDMA stream.
+ */
+ const stm32_bdma_stream_t *bdma;
+#endif
+} adc_ldd_dma_reference_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
+#define adc_lld_driver_fields \
+ /* Pointer to the master ADCx registers block.*/ \
+ ADC_TypeDef *adcm; \
+ /* Pointer to the slave ADCx registers block.*/ \
+ ADC_TypeDef *adcs; \
+ /* Pointer to the common ADCx_y registers block.*/ \
+ ADC_Common_TypeDef *adcc; \
+ /* Pointer to associated DMA channel.*/ \
+ adc_ldd_dma_reference_t data; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+#else
+#define adc_lld_driver_fields \
+ /* Pointer to the master ADCx registers block.*/ \
+ ADC_TypeDef *adcm; \
+ /* Pointer to the slave ADCx registers block.*/ \
+ ADC_Common_TypeDef *adcc; \
+ /* Pointer to associated DMA channel.*/ \
+ adc_ldd_dma_reference_t data; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+#endif
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* ADC DIFSEL register initialization data.*/ \
+ uint32_t difsel; \
+ /* Calibration mode, specify ADCCALIN and/or ADCCALDIF bits in here.*/ \
+ uint32_t calibration
+
+#if (STM32_ADC_DUAL_MODE == TRUE) || defined(__DOXYGEN__)
+#define adc_lld_configuration_group_fields \
+ /* ADC CFGR register initialization data. \
+ NOTE: The bits DMAEN and DMACFG are enforced internally \
+ to the driver, keep them to zero. \
+ NOTE: The bits @p ADC_CFGR_CONT or @p ADC_CFGR_DISCEN must be \
+ specified in continuous mode or if the buffer depth is \
+ greater than one.*/ \
+ uint32_t cfgr; \
+ /* ADC CFGR2 register initialization data. \
+ NOTE: Put this field to zero if not using oversampling.*/ \
+ uint32_t cfgr2; \
+ /* ADC CCR register initialization data*/ \
+ uint32_t ccr; \
+ /* ADC PCSEL register initialization data.*/ \
+ uint32_t pcsel; \
+ /* ADC LTR1 register initialization data.*/ \
+ uint32_t ltr1; \
+ /* ADC HTR1 register initialization data.*/ \
+ uint32_t htr1; \
+ /* ADC LTR2 register initialization data.*/ \
+ uint32_t ltr2; \
+ /* ADC HTR2 register initialization data.*/ \
+ uint32_t htr2; \
+ /* ADC LTR3 register initialization data.*/ \
+ uint32_t ltr3; \
+ /* ADC HTR3 register initialization data.*/ \
+ uint32_t htr3; \
+ /* ADC AWD2CR register initialization data.*/ \
+ uint32_t awd2cr; \
+ /* ADC AWD3CR register initialization data.*/ \
+ uint32_t awd3cr; \
+ /* ADC SMPRx registers initialization data.*/ \
+ uint32_t smpr[2]; \
+ /* ADC SQRx register initialization data.*/ \
+ uint32_t sqr[4]; \
+ /* Slave ADC LTR/HTRx registers initialization data. \
+ NOTE: This field is only present in dual mode.*/ \
+ uint32_t sltr1; \
+ uint32_t shtr1; \
+ uint32_t sltr2; \
+ uint32_t shtr2; \
+ uint32_t sltr3; \
+ uint32_t shtr3; \
+ /* Slave ADC AWDxCR registers initialization data. \
+ NOTE: This field is only present in dual mode.*/ \
+ uint32_t sawd2cr; \
+ uint32_t sawd3cr; \
+ /* Slave ADC SMPRx registers initialization data. \
+ NOTE: This field is only present in dual mode.*/ \
+ uint32_t ssmpr[2]; \
+ /* Slave ADC SQRx register initialization data. \
+ NOTE: This field is only present in dual mode.*/ \
+ uint32_t ssqr[4]
+#else /* STM32_ADC_DUAL_MODE == FALSE */
+#define adc_lld_configuration_group_fields \
+ uint32_t cfgr; \
+ uint32_t cfgr2; \
+ uint32_t ccr; \
+ uint32_t pcsel; \
+ uint32_t ltr1; \
+ uint32_t htr1; \
+ uint32_t ltr2; \
+ uint32_t htr2; \
+ uint32_t ltr3; \
+ uint32_t htr3; \
+ uint32_t awd2cr; \
+ uint32_t awd3cr; \
+ uint32_t smpr[2]; \
+ uint32_t sqr[4]
+#endif /* STM32_ADC_DUAL_MODE == FALSE */
+
+/**
+ * @name Sequences building helper macros
+ * @{
+ */
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
+#define ADC_SQR1_NUM_CH(n) (((n) - 1U) << 0U)
+
+#define ADC_SQR1_SQ1_N(n) ((n) << 6U) /**< @brief 1st channel in seq. */
+#define ADC_SQR1_SQ2_N(n) ((n) << 12U)/**< @brief 2nd channel in seq. */
+#define ADC_SQR1_SQ3_N(n) ((n) << 18U)/**< @brief 3rd channel in seq. */
+#define ADC_SQR1_SQ4_N(n) ((n) << 24U)/**< @brief 4th channel in seq. */
+
+#define ADC_SQR2_SQ5_N(n) ((n) << 0U) /**< @brief 5th channel in seq. */
+#define ADC_SQR2_SQ6_N(n) ((n) << 6U) /**< @brief 6th channel in seq. */
+#define ADC_SQR2_SQ7_N(n) ((n) << 12U)/**< @brief 7th channel in seq. */
+#define ADC_SQR2_SQ8_N(n) ((n) << 18U)/**< @brief 8th channel in seq. */
+#define ADC_SQR2_SQ9_N(n) ((n) << 24U)/**< @brief 9th channel in seq. */
+
+#define ADC_SQR3_SQ10_N(n) ((n) << 0U) /**< @brief 10th channel in seq.*/
+#define ADC_SQR3_SQ11_N(n) ((n) << 6U) /**< @brief 11th channel in seq.*/
+#define ADC_SQR3_SQ12_N(n) ((n) << 12U)/**< @brief 12th channel in seq.*/
+#define ADC_SQR3_SQ13_N(n) ((n) << 18U)/**< @brief 13th channel in seq.*/
+#define ADC_SQR3_SQ14_N(n) ((n) << 24U)/**< @brief 14th channel in seq.*/
+
+#define ADC_SQR4_SQ15_N(n) ((n) << 0U) /**< @brief 15th channel in seq.*/
+#define ADC_SQR4_SQ16_N(n) ((n) << 6U) /**< @brief 16th channel in seq.*/
+/** @} */
+
+/**
+ * @name Sampling rate settings helper macros
+ * @{
+ */
+#define ADC_SMPR1_SMP_AN0(n) ((n) << 0U) /**< @brief AN0 sampling time. */
+#define ADC_SMPR1_SMP_AN1(n) ((n) << 3U) /**< @brief AN1 sampling time. */
+#define ADC_SMPR1_SMP_AN2(n) ((n) << 6U) /**< @brief AN2 sampling time. */
+#define ADC_SMPR1_SMP_AN3(n) ((n) << 9U) /**< @brief AN3 sampling time. */
+#define ADC_SMPR1_SMP_AN4(n) ((n) << 12U)/**< @brief AN4 sampling time. */
+#define ADC_SMPR1_SMP_AN5(n) ((n) << 15U)/**< @brief AN5 sampling time. */
+#define ADC_SMPR1_SMP_AN6(n) ((n) << 18U)/**< @brief AN6 sampling time. */
+#define ADC_SMPR1_SMP_AN7(n) ((n) << 21U)/**< @brief AN7 sampling time. */
+#define ADC_SMPR1_SMP_AN8(n) ((n) << 24U)/**< @brief AN8 sampling time. */
+#define ADC_SMPR1_SMP_AN9(n) ((n) << 27U)/**< @brief AN9 sampling time. */
+
+#define ADC_SMPR2_SMP_AN10(n) ((n) << 0U) /**< @brief AN10 sampling time. */
+#define ADC_SMPR2_SMP_AN11(n) ((n) << 3U) /**< @brief AN11 sampling time. */
+#define ADC_SMPR2_SMP_AN12(n) ((n) << 6U) /**< @brief AN12 sampling time. */
+#define ADC_SMPR2_SMP_AN13(n) ((n) << 9U) /**< @brief AN13 sampling time. */
+#define ADC_SMPR2_SMP_AN14(n) ((n) << 12U)/**< @brief AN14 sampling time. */
+#define ADC_SMPR2_SMP_AN15(n) ((n) << 15U)/**< @brief AN15 sampling time. */
+#define ADC_SMPR2_SMP_AN16(n) ((n) << 18U)/**< @brief AN16 sampling time. */
+#define ADC_SMPR2_SMP_AN17(n) ((n) << 21U)/**< @brief AN17 sampling time. */
+#define ADC_SMPR2_SMP_AN18(n) ((n) << 24U)/**< @brief AN18 sampling time. */
+#define ADC_SMPR2_SMP_AN19(n) ((n) << 27U)/**< @brief AN19 sampling time. */
+/** @} */
+
+/**
+ * @name Analog watchdog settings helper macros
+ * @{
+ */
+#define ADC_CFGR_AWD1_N(n) ((n) << 26U)/**< @brief AWD1 channel number */
+#define ADC_AWD23_MASK(n) (1U << (n)) /**< @brief AWD2/3 channels mask*/
+/** @} */
+
+/**
+ * @name Oversampling settings helper macros
+ * @{
+ */
+#define ADC_CFGR2_OVSS_N(n) ((n) << 5U)/**< @brief ovsr right shift */
+#define ADC_CFGR2_OVSR_N(n) ((n) << 16U)/**< @brief oversampling ratio */
+#define ADC_CFGR2_LSHIFT_N(n) ((n) << 28U)/**< @brief ovsr left shift */
+
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC12 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#if STM32_ADC_USE_ADC3 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adcSTM32EnableVREF(ADCDriver *adcp);
+ void adcSTM32DisableVREF(ADCDriver *adcp);
+ void adcSTM32EnableTS(ADCDriver *adcp);
+ void adcSTM32DisableTS(ADCDriver *adcp);
+ void adcSTM32EnableVBAT(ADCDriver *adcp);
+ void adcSTM32DisableVBAT(ADCDriver *adcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv4/notes.txt b/os/hal/ports/STM32/LLD/ADCv4/notes.txt
index d0b59b7175..6c58ab8ea0 100644
--- a/os/hal/ports/STM32/LLD/ADCv4/notes.txt
+++ b/os/hal/ports/STM32/LLD/ADCv4/notes.txt
@@ -1,13 +1,13 @@
-STM32 ADCv4 driver.
-
-Driver capability:
-
-- Supports the STM32 "fast" ADC found on H7 sub-family.
-
-The file registry must export:
-
-STM32_HAS_ADCx - ADCx presence flag (1..4).
-STM32_ADC12_HANDLER - IRQ vector name for ADC1 and ADC2.
-STM32_ADC12_NUMBER - IRQ vector number for ADC1 and ADC2.
-STM32_ADC34_HANDLER - IRQ vector name for ADC3 and ADC4.
-STM32_ADC34_NUMBER - IRQ vector number for ADC3 and ADC4.
+STM32 ADCv4 driver.
+
+Driver capability:
+
+- Supports the STM32 "fast" ADC found on H7 sub-family.
+
+The file registry must export:
+
+STM32_HAS_ADCx - ADCx presence flag (1..4).
+STM32_ADC12_HANDLER - IRQ vector name for ADC1 and ADC2.
+STM32_ADC12_NUMBER - IRQ vector number for ADC1 and ADC2.
+STM32_ADC34_HANDLER - IRQ vector name for ADC3 and ADC4.
+STM32_ADC34_NUMBER - IRQ vector number for ADC3 and ADC4.
diff --git a/os/hal/ports/STM32/LLD/ADCv5/driver.mk b/os/hal/ports/STM32/LLD/ADCv5/driver.mk
index 1774fca70d..2fab87d272 100644
--- a/os/hal/ports/STM32/LLD/ADCv5/driver.mk
+++ b/os/hal/ports/STM32/LLD/ADCv5/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv5
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv5
diff --git a/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c b/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
index 30636094e7..ad4e6e4aa3 100644
--- a/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
+++ b/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.c
@@ -1,483 +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.
-*/
-
-/**
- * @file ADCv1/hal_adc_lld.c
- * @brief STM32 ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define ADC1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief ADC voltage regulator enable.
- *
- * @param[in] adc pointer to the ADC registers block
- */
-NOINLINE static void adc_lld_vreg_on(ADC_TypeDef *adc) {
-
- osalDbgAssert(adc->CR == 0, "invalid register state");
-
-#if defined(ADC_CR_ADVREGEN)
- adc->CR = ADC_CR_ADVREGEN;
- volatile uint32_t loop = (STM32_HCLK >> 20) << 4;
- do {
- loop--;
- } while (loop > 0);
-#else
-#endif
-}
-
-/**
- * @brief Calibrates an ADC unit.
- *
- * @param[in] adc pointer to the ADC registers block
- */
-static void adc_lld_calibrate(ADC_TypeDef *adc) {
-
- adc->CR |= ADC_CR_ADCAL;
- while (adc->CR & ADC_CR_ADCAL) {
- /* Waiting for calibration end.*/
- }
- adc->CR = 0U;
-}
-
-/**
- * @brief Stops an ongoing conversion, if any.
- *
- * @param[in] adc pointer to the ADC registers block
- */
-static void adc_lld_stop_adc(ADC_TypeDef *adc) {
-
- if (adc->CR & ADC_CR_ADSTART) {
- adc->CR |= ADC_CR_ADSTP;
- while (adc->CR & ADC_CR_ADSTP)
- ;
- adc->IER = 0;
- }
-
- /* Disabling the ADC.*/
- adc->CR |= ADC_CR_ADDIS;
- while ((adc->CR & ADC_CR_ADDIS) != 0U) {
- /* Waiting for ADC to be disabled.*/
- }
-}
-
-/**
- * @brief ADC DMA service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-#if !defined(STM32_ADC1_HANDLER)
-#error "STM32_ADC1_HANDLER not defined"
-#endif
-/**
- * @brief ADC interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- adc_lld_serve_interrupt(&ADCD1);
-
-#if defined(STM32_ADC_ADC1_IRQ_HOOK)
- STM32_ADC_ADC1_IRQ_HOOK
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = ADC1;
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-
- /* The vector is initialized on driver initialization and never
- disabled.*/
- nvicEnableVector(12, STM32_ADC_ADC1_IRQ_PRIORITY);
-#endif
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
- STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
- rccEnableADC1(true);
-
- /* DMA setup.*/
- dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
- dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1);
-
- /* Clock settings.*/
- adcp->adc->CFGR2 = STM32_ADC_ADC1_CKMODE;
- }
-#endif /* STM32_ADC_USE_ADC1 */
-
- /* Regulator enabled and stabilized.*/
- adc_lld_vreg_on(ADC1);
-
- /* Calibrating ADC.*/
- adc_lld_calibrate(adcp->adc);
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock and analog part.*/
- if (adcp->state == ADC_READY) {
-
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
- /* Restoring CCR default.*/
- ADC1_COMMON->CCR = STM32_ADC_PRESC << 18;
-
- /* Regulator off.*/
- adcp->adc->CR = 0;
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp)
- rccDisableADC1();
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t mode, cfgr1, cfgr2;
- const ADCConversionGroup *grpp = adcp->grpp;
-
- /* Starting the ADC enable procedure.*/
- adcp->adc->ISR = adcp->adc->ISR;
- adcp->adc->CR = ADC_CR_ADEN;
-
- /* DMA setup.*/
- mode = adcp->dmamode;
- cfgr1 = grpp->cfgr1 | ADC_CFGR1_DMAEN;
- cfgr2 = adcp->adc->CFGR2 & STM32_ADC_CKMODE_MASK;
- if (grpp->circular) {
- mode |= STM32_DMA_CR_CIRC;
- cfgr1 |= ADC_CFGR1_DMACFG;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- mode |= STM32_DMA_CR_HTIE;
- }
- }
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
- dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- dmaStreamSetMode(adcp->dmastp, mode);
- dmaStreamEnable(adcp->dmastp);
-
- /* Ensuring that the ADC finished the enable procedure.*/
- while ((adcp->adc->ISR & ADC_ISR_ADRDY) == 0U) {
- /* Waiting for ADC to be stable.*/
- }
-
- /* ADC setup, if it is defined a callback for the analog watch dog then it
- is enabled.*/
- if (grpp->error_cb != NULL) {
- adcp->adc->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
- | ADC_IER_AWD2IE
- | ADC_IER_AWD3IE;
- adcp->adc->TR1 = grpp->tr1;
- adcp->adc->TR2 = grpp->tr2;
- adcp->adc->TR3 = grpp->tr3;
- adcp->adc->AWD2CR = grpp->awd2cr;
- adcp->adc->AWD3CR = grpp->awd3cr;
- }
- adcp->adc->SMPR = grpp->smpr;
- adcp->adc->CHSELR = grpp->chselr;
-
- /* ADC configuration and start.*/
- adcp->adc->CFGR1 = cfgr1;
- adcp->adc->CFGR2 = cfgr2 | grpp->cfgr2;
-
- /* ADC conversion start.*/
- adcp->adc->CR |= ADC_CR_ADSTART;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- dmaStreamDisable(adcp->dmastp);
- adc_lld_stop_adc(adcp->adc);
-}
-
-/**
- * @brief ISR code.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_serve_interrupt(ADCDriver *adcp) {
- uint32_t isr;
-
- isr = adcp->adc->ISR;
- adcp->adc->ISR = isr;
-
- /* It could be a spurious interrupt caused by overflows after DMA disabling,
- just ignore it in this case.*/
- if (adcp->grpp != NULL) {
- adcerror_t emask = 0U;
-
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the state is checked too.*/
- if ((isr & ADC_ISR_OVR) && (adcp->state == ADC_ACTIVE)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- emask |= ADC_ERR_OVERFLOW;
- }
- if (isr & ADC_ISR_AWD1) {
- /* Analog watchdog 1 error.*/
- emask |= ADC_ERR_AWD1;
- }
- if (isr & ADC_ISR_AWD2) {
- /* Analog watchdog 2 error.*/
- emask |= ADC_ERR_AWD2;
- }
- if (isr & ADC_ISR_AWD3) {
- /* Analog watchdog 3 error.*/
- emask |= ADC_ERR_AWD3;
- }
- if (emask != 0U) {
- _adc_isr_error_code(adcp, emask);
- }
- }
-}
-
-/**
- * @brief Enables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVREF(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC1_COMMON->CCR |= ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Disables the VREFEN bit.
- * @details The VREFEN bit is required in order to sample the VREF channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVREF(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC1_COMMON->CCR &= ~ADC_CCR_VREFEN;
-}
-
-/**
- * @brief Enables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableTS(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC1_COMMON->CCR |= ADC_CCR_TSEN;
-}
-
-/**
- * @brief Disables the TSEN bit.
- * @details The TSEN bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableTS(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC1_COMMON->CCR &= ~ADC_CCR_TSEN;
-}
-
-#if defined(ADC_CCR_VBATEN) || defined(__DOXYGEN__)
-/**
- * @brief Enables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32EnableVBAT(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC1_COMMON->CCR |= ADC_CCR_VBATEN;
-}
-
-/**
- * @brief Disables the VBATEN bit.
- * @details The VBATEN bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- * @note This function is meant to be called after @p adcStart().
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adcSTM32DisableVBAT(ADCDriver *adcp) {
-
- (void)adcp;
-
- ADC1_COMMON->CCR &= ~ADC_CCR_VBATEN;
-}
-#endif /* defined(ADC_CCR_VBATEN) */
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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 ADCv1/hal_adc_lld.c
+ * @brief STM32 ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define ADC1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_ADC_ADC1_DMA_STREAM, STM32_ADC1_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC voltage regulator enable.
+ *
+ * @param[in] adc pointer to the ADC registers block
+ */
+NOINLINE static void adc_lld_vreg_on(ADC_TypeDef *adc) {
+
+ osalDbgAssert(adc->CR == 0, "invalid register state");
+
+#if defined(ADC_CR_ADVREGEN)
+ adc->CR = ADC_CR_ADVREGEN;
+ volatile uint32_t loop = (STM32_HCLK >> 20) << 4;
+ do {
+ loop--;
+ } while (loop > 0);
+#else
+#endif
+}
+
+/**
+ * @brief Calibrates an ADC unit.
+ *
+ * @param[in] adc pointer to the ADC registers block
+ */
+static void adc_lld_calibrate(ADC_TypeDef *adc) {
+
+ adc->CR |= ADC_CR_ADCAL;
+ while (adc->CR & ADC_CR_ADCAL) {
+ /* Waiting for calibration end.*/
+ }
+ adc->CR = 0U;
+}
+
+/**
+ * @brief Stops an ongoing conversion, if any.
+ *
+ * @param[in] adc pointer to the ADC registers block
+ */
+static void adc_lld_stop_adc(ADC_TypeDef *adc) {
+
+ if (adc->CR & ADC_CR_ADSTART) {
+ adc->CR |= ADC_CR_ADSTP;
+ while (adc->CR & ADC_CR_ADSTP)
+ ;
+ adc->IER = 0;
+ }
+
+ /* Disabling the ADC.*/
+ adc->CR |= ADC_CR_ADDIS;
+ while ((adc->CR & ADC_CR_ADDIS) != 0U) {
+ /* Waiting for ADC to be disabled.*/
+ }
+}
+
+/**
+ * @brief ADC DMA service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+#if !defined(STM32_ADC1_HANDLER)
+#error "STM32_ADC1_HANDLER not defined"
+#endif
+/**
+ * @brief ADC interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_ADC1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ adc_lld_serve_interrupt(&ADCD1);
+
+#if defined(STM32_ADC_ADC1_IRQ_HOOK)
+ STM32_ADC_ADC1_IRQ_HOOK
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = ADC1;
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+
+ /* The vector is initialized on driver initialization and never
+ disabled.*/
+ nvicEnableVector(12, STM32_ADC_ADC1_IRQ_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_ADC_ADC1_DMA_STREAM,
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+ rccEnableADC1(true);
+
+ /* DMA setup.*/
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+ dmaSetRequestSource(adcp->dmastp, STM32_DMAMUX1_ADC1);
+
+ /* Clock settings.*/
+ adcp->adc->CFGR2 = STM32_ADC_ADC1_CKMODE;
+ }
+#endif /* STM32_ADC_USE_ADC1 */
+
+ /* Regulator enabled and stabilized.*/
+ adc_lld_vreg_on(ADC1);
+
+ /* Calibrating ADC.*/
+ adc_lld_calibrate(adcp->adc);
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock and analog part.*/
+ if (adcp->state == ADC_READY) {
+
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+ /* Restoring CCR default.*/
+ ADC1_COMMON->CCR = STM32_ADC_PRESC << 18;
+
+ /* Regulator off.*/
+ adcp->adc->CR = 0;
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp)
+ rccDisableADC1();
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t mode, cfgr1, cfgr2;
+ const ADCConversionGroup *grpp = adcp->grpp;
+
+ /* Starting the ADC enable procedure.*/
+ adcp->adc->ISR = adcp->adc->ISR;
+ adcp->adc->CR = ADC_CR_ADEN;
+
+ /* DMA setup.*/
+ mode = adcp->dmamode;
+ cfgr1 = grpp->cfgr1 | ADC_CFGR1_DMAEN;
+ cfgr2 = adcp->adc->CFGR2 & STM32_ADC_CKMODE_MASK;
+ if (grpp->circular) {
+ mode |= STM32_DMA_CR_CIRC;
+ cfgr1 |= ADC_CFGR1_DMACFG;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ mode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+ dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ dmaStreamSetMode(adcp->dmastp, mode);
+ dmaStreamEnable(adcp->dmastp);
+
+ /* Ensuring that the ADC finished the enable procedure.*/
+ while ((adcp->adc->ISR & ADC_ISR_ADRDY) == 0U) {
+ /* Waiting for ADC to be stable.*/
+ }
+
+ /* ADC setup, if it is defined a callback for the analog watch dog then it
+ is enabled.*/
+ if (grpp->error_cb != NULL) {
+ adcp->adc->IER = ADC_IER_OVRIE | ADC_IER_AWD1IE
+ | ADC_IER_AWD2IE
+ | ADC_IER_AWD3IE;
+ adcp->adc->TR1 = grpp->tr1;
+ adcp->adc->TR2 = grpp->tr2;
+ adcp->adc->TR3 = grpp->tr3;
+ adcp->adc->AWD2CR = grpp->awd2cr;
+ adcp->adc->AWD3CR = grpp->awd3cr;
+ }
+ adcp->adc->SMPR = grpp->smpr;
+ adcp->adc->CHSELR = grpp->chselr;
+
+ /* ADC configuration and start.*/
+ adcp->adc->CFGR1 = cfgr1;
+ adcp->adc->CFGR2 = cfgr2 | grpp->cfgr2;
+
+ /* ADC conversion start.*/
+ adcp->adc->CR |= ADC_CR_ADSTART;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ dmaStreamDisable(adcp->dmastp);
+ adc_lld_stop_adc(adcp->adc);
+}
+
+/**
+ * @brief ISR code.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_serve_interrupt(ADCDriver *adcp) {
+ uint32_t isr;
+
+ isr = adcp->adc->ISR;
+ adcp->adc->ISR = isr;
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (adcp->grpp != NULL) {
+ adcerror_t emask = 0U;
+
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the state is checked too.*/
+ if ((isr & ADC_ISR_OVR) && (adcp->state == ADC_ACTIVE)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ emask |= ADC_ERR_OVERFLOW;
+ }
+ if (isr & ADC_ISR_AWD1) {
+ /* Analog watchdog 1 error.*/
+ emask |= ADC_ERR_AWD1;
+ }
+ if (isr & ADC_ISR_AWD2) {
+ /* Analog watchdog 2 error.*/
+ emask |= ADC_ERR_AWD2;
+ }
+ if (isr & ADC_ISR_AWD3) {
+ /* Analog watchdog 3 error.*/
+ emask |= ADC_ERR_AWD3;
+ }
+ if (emask != 0U) {
+ _adc_isr_error_code(adcp, emask);
+ }
+ }
+}
+
+/**
+ * @brief Enables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVREF(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC1_COMMON->CCR |= ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Disables the VREFEN bit.
+ * @details The VREFEN bit is required in order to sample the VREF channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVREF(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC1_COMMON->CCR &= ~ADC_CCR_VREFEN;
+}
+
+/**
+ * @brief Enables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableTS(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC1_COMMON->CCR |= ADC_CCR_TSEN;
+}
+
+/**
+ * @brief Disables the TSEN bit.
+ * @details The TSEN bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableTS(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC1_COMMON->CCR &= ~ADC_CCR_TSEN;
+}
+
+#if defined(ADC_CCR_VBATEN) || defined(__DOXYGEN__)
+/**
+ * @brief Enables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32EnableVBAT(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC1_COMMON->CCR |= ADC_CCR_VBATEN;
+}
+
+/**
+ * @brief Disables the VBATEN bit.
+ * @details The VBATEN bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ * @note This function is meant to be called after @p adcStart().
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adcSTM32DisableVBAT(ADCDriver *adcp) {
+
+ (void)adcp;
+
+ ADC1_COMMON->CCR &= ~ADC_CCR_VBATEN;
+}
+#endif /* defined(ADC_CCR_VBATEN) */
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.h b/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.h
index 4df334fc75..bf470f6b9a 100644
--- a/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.h
+++ b/os/hal/ports/STM32/LLD/ADCv5/hal_adc_lld.h
@@ -1,405 +1,405 @@
-/*
- 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 ADCv1/hal_adc_lld.h
- * @brief STM32 ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Possible ADC errors mask bits.
- * @{
- */
-#define ADC_ERR_DMAFAILURE 1U /**< DMA operations failure. */
-#define ADC_ERR_OVERFLOW 2U /**< ADC overflow condition. */
-#define ADC_ERR_AWD1 4U /**< Watchdog 1 triggered. */
-#define ADC_ERR_AWD2 8U /**< Watchdog 2 triggered. */
-#define ADC_ERR_AWD3 16U /**< Watchdog 3 triggered. */
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */
-#define ADC_SMPR_SMP_3P5 1U /**< @brief 16 cycles conversion time. */
-#define ADC_SMPR_SMP_7P5 2U /**< @brief 20 cycles conversion time. */
-#define ADC_SMPR_SMP_12P5 3U /**< @brief 25 cycles conversion time. */
-#define ADC_SMPR_SMP_19P5 4U /**< @brief 31 cycles conversion time. */
-#define ADC_SMPR_SMP_39P5 5U /**< @brief 52 cycles conversion time. */
-#define ADC_SMPR_SMP_79P5 6U /**< @brief 92 cycles conversion time. */
-#define ADC_SMPR_SMP_160P5 7U /**< @brief 173 cycles conversion time. */
-/** @} */
-
-/**
- * @name CFGR1 register configuration helpers
- * @{
- */
-#define ADC_CFGR1_RES_12BIT (0U << 3U)
-#define ADC_CFGR1_RES_10BIT (1U << 3U)
-#define ADC_CFGR1_RES_8BIT (2U << 3U)
-#define ADC_CFGR1_RES_6BIT (3U << 3U)
-
-#define ADC_CFGR1_EXTSEL_MASK (15U << 6U)
-#define ADC_CFGR1_EXTSEL_SRC(n) ((n) << 6U)
-
-#define ADC_CFGR1_EXTEN_MASK (3U << 10U)
-#define ADC_CFGR1_EXTEN_DISABLED (0U << 10U)
-#define ADC_CFGR1_EXTEN_RISING (1U << 10U)
-#define ADC_CFGR1_EXTEN_FALLING (2U << 10U)
-#define ADC_CFGR1_EXTEN_BOTH (3U << 10U)
-/** @} */
-
-/**
- * @name CFGR2 register configuration helpers
- * @{
- */
-#define STM32_ADC_CKMODE_MASK (3U << 30U)
-#define STM32_ADC_CKMODE_ADCCLK (0U << 30U)
-#define STM32_ADC_CKMODE_PCLK_DIV2 (1U << 30U)
-#define STM32_ADC_CKMODE_PCLK_DIV4 (2U << 30U)
-#define STM32_ADC_CKMODE_PCLK (3U << 30U)
-
-#define ADC_CFGR2_OVSR_MASK (7U << 2U)
-#define ADC_CFGR2_OVSR_2X (0U << 2U)
-#define ADC_CFGR2_OVSR_4X (1U << 2U)
-#define ADC_CFGR2_OVSR_8X (2U << 2U)
-#define ADC_CFGR2_OVSR_16X (3U << 2U)
-#define ADC_CFGR2_OVSR_32X (4U << 2U)
-#define ADC_CFGR2_OVSR_64X (5U << 2U)
-#define ADC_CFGR2_OVSR_128X (6U << 2U)
-#define ADC_CFGR2_OVSR_256X (7U << 2U)
-
-#define ADC_CFGR2_OVSS_MASK (15 << 5U)
-#define ADC_CFGR2_OVSS_SHIFT(n) ((n) << 5U)
-/** @} */
-
-/**
- * @name CHSELR register initializers for CHSELRMOD=0
- * @{
- */
-#define ADC_CHSELR_CHSEL_N(n) (1U << (n))
-/** @} */
-
-/**
- * @name CHSELR register initializers for CHSELRMOD=1
- * @{
- */
-#define ADC_CHSELR_SQ1_N(n) ((uint32_t)(n) << 0U)
-#define ADC_CHSELR_SQ2_N(n) ((uint32_t)(n) << 4U)
-#define ADC_CHSELR_SQ3_N(n) ((uint32_t)(n) << 8U)
-#define ADC_CHSELR_SQ4_N(n) ((uint32_t)(n) << 12U)
-#define ADC_CHSELR_SQ5_N(n) ((uint32_t)(n) << 16U)
-#define ADC_CHSELR_SQ6_N(n) ((uint32_t)(n) << 20U)
-#define ADC_CHSELR_SQ7_N(n) ((uint32_t)(n) << 24U)
-#define ADC_CHSELR_SQ8_N(n) ((uint32_t)(n) << 28U)
-
-#define ADC_CHSELR_SQ1_END (15U << 0U)
-#define ADC_CHSELR_SQ2_END (15U << 4U)
-#define ADC_CHSELR_SQ3_END (15U << 8U)
-#define ADC_CHSELR_SQ4_END (15U << 12U)
-#define ADC_CHSELR_SQ5_END (15U << 16U)
-#define ADC_CHSELR_SQ6_END (15U << 20U)
-#define ADC_CHSELR_SQ7_END (15U << 24U)
-#define ADC_CHSELR_SQ8_END (15U << 28U)
-/** @} */
-
-/**
- * @name Threshold registers initializers
- * @{
- */
-#define ADC_TR(low, high) (((uint32_t)(high) << 16U) | \
- (uint32_t)(low))
-#define ADC_TR_DISABLED ADC_TR(0U, 0x0FFFU)
-#define ADC_AWDCR_ENABLE(n) (1U << (n))
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC1 clock source selection.
- */
-#if !defined(STM32_ADC_ADC1_CKMODE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_CKMODE STM32_ADC_CKMODE_ADCCLK
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_IRQ_PRIORITY 2
-#endif
-
-/**
- * @brief ADC1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
-#endif
-
-/*
- * @brief ADC prescaler setting.
- * @note This setting has effect only in asynchronous clock mode (the
- * default, @p STM32_ADC_CKMODE_ADCCLK).
- */
-#if !defined(STM32_ADC_PRESCALER_VALUE) || defined(__DOXYGEN__)
-#define STM32_ADC_PRESCALER_VALUE 2
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Supported devices checks.*/
-#if !defined(STM32G0XX) && !defined(STM32WLXX)
-#error "ADCv5 only supports G0 and WL STM32 devices"
-#endif
-
-/* Registry checks.*/
-#if !defined(STM32_HAS_ADC1)
-#error "STM32_HAS_ADC1 not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER))
-#error "STM32_ADC1_HANDLER not defined in registry"
-#endif
-
-#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER))
-#error "STM32_ADC1_NUMBER not defined in registry"
-#endif
-
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-/* Units checks.*/
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-/* At least one ADC must be assigned.*/
-#if !STM32_ADC_USE_ADC1
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-/* ADC IRQ priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-/* DMA IRQ priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1 DMA"
-#endif
-
-/* DMA priority tests.*/
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC1"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_ADC_USE_ADC1 && !defined(STM32_ADC_ADC1_DMA_STREAM)
-#error "ADC DMA stream not defined"
-#endif
-
-/* ADC clock source checks.*/
-#if STM32_ADC_PRESCALER_VALUE == 1
-#define STM32_ADC_PRESC 0U
-#elif STM32_ADC_PRESCALER_VALUE == 2
-#define STM32_ADC_PRESC 1U
-#elif STM32_ADC_PRESCALER_VALUE == 4
-#define STM32_ADC_PRESC 2U
-#elif STM32_ADC_PRESCALER_VALUE == 6
-#define STM32_ADC_PRESC 3U
-#elif STM32_ADC_PRESCALER_VALUE == 8
-#define STM32_ADC_PRESC 4U
-#elif STM32_ADC_PRESCALER_VALUE == 10
-#define STM32_ADC_PRESC 5U
-#elif STM32_ADC_PRESCALER_VALUE == 12
-#define STM32_ADC_PRESC 6U
-#elif STM32_ADC_PRESCALER_VALUE == 16
-#define STM32_ADC_PRESC 7U
-#elif STM32_ADC_PRESCALER_VALUE == 32
-#define STM32_ADC_PRESC 8U
-#elif STM32_ADC_PRESCALER_VALUE == 64
-#define STM32_ADC_PRESC 9U
-#elif STM32_ADC_PRESCALER_VALUE == 128
-#define STM32_ADC_PRESC 10U
-#elif STM32_ADC_PRESCALER_VALUE == 256
-#define STM32_ADC_PRESC 11U
-#else
-#error "Invalid value assigned to STM32_ADC_PRESCALER_VALUE"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Type of an ADC error mask.
- */
-typedef uint32_t adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* Dummy configuration, it is not needed.*/ \
- uint32_t dummy
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_configuration_group_fields \
- /* ADC CFGR1 register initialization data. \
- NOTE: The bits DMAEN and DMACFG are enforced internally \
- to the driver, keep them to zero. \
- NOTE: The bits @p ADC_CFGR1_CONT or @p ADC_CFGR1_DISCEN must be \
- specified in continuous more or if the buffer depth is \
- greater than one.*/ \
- uint32_t cfgr1; \
- /* ADC CFGR2 register initialization data. \
- NOTE: CKMODE bits must not be specified in this field and left to \
- zero.*/ \
- uint32_t cfgr2; \
- /* ADC TR1 register initialization data.*/ \
- uint32_t tr1; \
- /* ADC TR2 register initialization data.*/ \
- uint32_t tr2; \
- /* ADC TR3 register initialization data.*/ \
- uint32_t tr3; \
- /* ADC AWD2CR register initialization data.*/ \
- uint32_t awd2cr; \
- /* ADC AWD3CR register initialization data.*/ \
- uint32_t awd3cr; \
- /* ADC SMPR register initialization data.*/ \
- uint32_t smpr; \
- /* ADC CHSELR register initialization data. \
- NOTE: The number of bits at logic level one in this register must \
- be equal to the number in the @p num_channels field.*/ \
- uint32_t chselr
-
-/**
- * @brief Changes the value of the ADC CCR register.
- * @details Use this function in order to enable or disable the internal
- * analog sources. See the documentation in the STM32 Reference
- * Manual.
- * @note PRESC bits must not be specified and left to zero.
- */
-#define adcSTM32SetCCR(ccr) (ADC1_COMMON->CCR = (ccr))
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adc_lld_serve_interrupt(ADCDriver *adcp);
- void adcSTM32EnableVREF(ADCDriver *adcp);
- void adcSTM32DisableVREF(ADCDriver *adcp);
- void adcSTM32EnableTS(ADCDriver *adcp);
- void adcSTM32DisableTS(ADCDriver *adcp);
-#if defined(ADC_CCR_VBATEN)
- void adcSTM32EnableVBAT(ADCDriver *adcp);
- void adcSTM32DisableVBAT(ADCDriver *adcp);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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 ADCv1/hal_adc_lld.h
+ * @brief STM32 ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Possible ADC errors mask bits.
+ * @{
+ */
+#define ADC_ERR_DMAFAILURE 1U /**< DMA operations failure. */
+#define ADC_ERR_OVERFLOW 2U /**< ADC overflow condition. */
+#define ADC_ERR_AWD1 4U /**< Watchdog 1 triggered. */
+#define ADC_ERR_AWD2 8U /**< Watchdog 2 triggered. */
+#define ADC_ERR_AWD3 16U /**< Watchdog 3 triggered. */
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#define ADC_SMPR_SMP_1P5 0U /**< @brief 14 cycles conversion time */
+#define ADC_SMPR_SMP_3P5 1U /**< @brief 16 cycles conversion time. */
+#define ADC_SMPR_SMP_7P5 2U /**< @brief 20 cycles conversion time. */
+#define ADC_SMPR_SMP_12P5 3U /**< @brief 25 cycles conversion time. */
+#define ADC_SMPR_SMP_19P5 4U /**< @brief 31 cycles conversion time. */
+#define ADC_SMPR_SMP_39P5 5U /**< @brief 52 cycles conversion time. */
+#define ADC_SMPR_SMP_79P5 6U /**< @brief 92 cycles conversion time. */
+#define ADC_SMPR_SMP_160P5 7U /**< @brief 173 cycles conversion time. */
+/** @} */
+
+/**
+ * @name CFGR1 register configuration helpers
+ * @{
+ */
+#define ADC_CFGR1_RES_12BIT (0U << 3U)
+#define ADC_CFGR1_RES_10BIT (1U << 3U)
+#define ADC_CFGR1_RES_8BIT (2U << 3U)
+#define ADC_CFGR1_RES_6BIT (3U << 3U)
+
+#define ADC_CFGR1_EXTSEL_MASK (15U << 6U)
+#define ADC_CFGR1_EXTSEL_SRC(n) ((n) << 6U)
+
+#define ADC_CFGR1_EXTEN_MASK (3U << 10U)
+#define ADC_CFGR1_EXTEN_DISABLED (0U << 10U)
+#define ADC_CFGR1_EXTEN_RISING (1U << 10U)
+#define ADC_CFGR1_EXTEN_FALLING (2U << 10U)
+#define ADC_CFGR1_EXTEN_BOTH (3U << 10U)
+/** @} */
+
+/**
+ * @name CFGR2 register configuration helpers
+ * @{
+ */
+#define STM32_ADC_CKMODE_MASK (3U << 30U)
+#define STM32_ADC_CKMODE_ADCCLK (0U << 30U)
+#define STM32_ADC_CKMODE_PCLK_DIV2 (1U << 30U)
+#define STM32_ADC_CKMODE_PCLK_DIV4 (2U << 30U)
+#define STM32_ADC_CKMODE_PCLK (3U << 30U)
+
+#define ADC_CFGR2_OVSR_MASK (7U << 2U)
+#define ADC_CFGR2_OVSR_2X (0U << 2U)
+#define ADC_CFGR2_OVSR_4X (1U << 2U)
+#define ADC_CFGR2_OVSR_8X (2U << 2U)
+#define ADC_CFGR2_OVSR_16X (3U << 2U)
+#define ADC_CFGR2_OVSR_32X (4U << 2U)
+#define ADC_CFGR2_OVSR_64X (5U << 2U)
+#define ADC_CFGR2_OVSR_128X (6U << 2U)
+#define ADC_CFGR2_OVSR_256X (7U << 2U)
+
+#define ADC_CFGR2_OVSS_MASK (15 << 5U)
+#define ADC_CFGR2_OVSS_SHIFT(n) ((n) << 5U)
+/** @} */
+
+/**
+ * @name CHSELR register initializers for CHSELRMOD=0
+ * @{
+ */
+#define ADC_CHSELR_CHSEL_N(n) (1U << (n))
+/** @} */
+
+/**
+ * @name CHSELR register initializers for CHSELRMOD=1
+ * @{
+ */
+#define ADC_CHSELR_SQ1_N(n) ((uint32_t)(n) << 0U)
+#define ADC_CHSELR_SQ2_N(n) ((uint32_t)(n) << 4U)
+#define ADC_CHSELR_SQ3_N(n) ((uint32_t)(n) << 8U)
+#define ADC_CHSELR_SQ4_N(n) ((uint32_t)(n) << 12U)
+#define ADC_CHSELR_SQ5_N(n) ((uint32_t)(n) << 16U)
+#define ADC_CHSELR_SQ6_N(n) ((uint32_t)(n) << 20U)
+#define ADC_CHSELR_SQ7_N(n) ((uint32_t)(n) << 24U)
+#define ADC_CHSELR_SQ8_N(n) ((uint32_t)(n) << 28U)
+
+#define ADC_CHSELR_SQ1_END (15U << 0U)
+#define ADC_CHSELR_SQ2_END (15U << 4U)
+#define ADC_CHSELR_SQ3_END (15U << 8U)
+#define ADC_CHSELR_SQ4_END (15U << 12U)
+#define ADC_CHSELR_SQ5_END (15U << 16U)
+#define ADC_CHSELR_SQ6_END (15U << 20U)
+#define ADC_CHSELR_SQ7_END (15U << 24U)
+#define ADC_CHSELR_SQ8_END (15U << 28U)
+/** @} */
+
+/**
+ * @name Threshold registers initializers
+ * @{
+ */
+#define ADC_TR(low, high) (((uint32_t)(high) << 16U) | \
+ (uint32_t)(low))
+#define ADC_TR_DISABLED ADC_TR(0U, 0x0FFFU)
+#define ADC_AWDCR_ENABLE(n) (1U << (n))
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief ADC1 clock source selection.
+ */
+#if !defined(STM32_ADC_ADC1_CKMODE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_CKMODE STM32_ADC_CKMODE_ADCCLK
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_IRQ_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
+#endif
+
+/*
+ * @brief ADC prescaler setting.
+ * @note This setting has effect only in asynchronous clock mode (the
+ * default, @p STM32_ADC_CKMODE_ADCCLK).
+ */
+#if !defined(STM32_ADC_PRESCALER_VALUE) || defined(__DOXYGEN__)
+#define STM32_ADC_PRESCALER_VALUE 2
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Supported devices checks.*/
+#if !defined(STM32G0XX) && !defined(STM32WLXX)
+#error "ADCv5 only supports G0 and WL STM32 devices"
+#endif
+
+/* Registry checks.*/
+#if !defined(STM32_HAS_ADC1)
+#error "STM32_HAS_ADC1 not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_HANDLER))
+#error "STM32_ADC1_HANDLER not defined in registry"
+#endif
+
+#if (STM32_ADC_USE_ADC1 && !defined(STM32_ADC1_NUMBER))
+#error "STM32_ADC1_NUMBER not defined in registry"
+#endif
+
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+/* Units checks.*/
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+/* At least one ADC must be assigned.*/
+#if !STM32_ADC_USE_ADC1
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+/* ADC IRQ priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1"
+#endif
+
+/* DMA IRQ priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1 DMA"
+#endif
+
+/* DMA priority tests.*/
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC1"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_ADC_USE_ADC1 && !defined(STM32_ADC_ADC1_DMA_STREAM)
+#error "ADC DMA stream not defined"
+#endif
+
+/* ADC clock source checks.*/
+#if STM32_ADC_PRESCALER_VALUE == 1
+#define STM32_ADC_PRESC 0U
+#elif STM32_ADC_PRESCALER_VALUE == 2
+#define STM32_ADC_PRESC 1U
+#elif STM32_ADC_PRESCALER_VALUE == 4
+#define STM32_ADC_PRESC 2U
+#elif STM32_ADC_PRESCALER_VALUE == 6
+#define STM32_ADC_PRESC 3U
+#elif STM32_ADC_PRESCALER_VALUE == 8
+#define STM32_ADC_PRESC 4U
+#elif STM32_ADC_PRESCALER_VALUE == 10
+#define STM32_ADC_PRESC 5U
+#elif STM32_ADC_PRESCALER_VALUE == 12
+#define STM32_ADC_PRESC 6U
+#elif STM32_ADC_PRESCALER_VALUE == 16
+#define STM32_ADC_PRESC 7U
+#elif STM32_ADC_PRESCALER_VALUE == 32
+#define STM32_ADC_PRESC 8U
+#elif STM32_ADC_PRESCALER_VALUE == 64
+#define STM32_ADC_PRESC 9U
+#elif STM32_ADC_PRESCALER_VALUE == 128
+#define STM32_ADC_PRESC 10U
+#elif STM32_ADC_PRESCALER_VALUE == 256
+#define STM32_ADC_PRESC 11U
+#else
+#error "Invalid value assigned to STM32_ADC_PRESCALER_VALUE"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint16_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Type of an ADC error mask.
+ */
+typedef uint32_t adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* Dummy configuration, it is not needed.*/ \
+ uint32_t dummy
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_configuration_group_fields \
+ /* ADC CFGR1 register initialization data. \
+ NOTE: The bits DMAEN and DMACFG are enforced internally \
+ to the driver, keep them to zero. \
+ NOTE: The bits @p ADC_CFGR1_CONT or @p ADC_CFGR1_DISCEN must be \
+ specified in continuous more or if the buffer depth is \
+ greater than one.*/ \
+ uint32_t cfgr1; \
+ /* ADC CFGR2 register initialization data. \
+ NOTE: CKMODE bits must not be specified in this field and left to \
+ zero.*/ \
+ uint32_t cfgr2; \
+ /* ADC TR1 register initialization data.*/ \
+ uint32_t tr1; \
+ /* ADC TR2 register initialization data.*/ \
+ uint32_t tr2; \
+ /* ADC TR3 register initialization data.*/ \
+ uint32_t tr3; \
+ /* ADC AWD2CR register initialization data.*/ \
+ uint32_t awd2cr; \
+ /* ADC AWD3CR register initialization data.*/ \
+ uint32_t awd3cr; \
+ /* ADC SMPR register initialization data.*/ \
+ uint32_t smpr; \
+ /* ADC CHSELR register initialization data. \
+ NOTE: The number of bits at logic level one in this register must \
+ be equal to the number in the @p num_channels field.*/ \
+ uint32_t chselr
+
+/**
+ * @brief Changes the value of the ADC CCR register.
+ * @details Use this function in order to enable or disable the internal
+ * analog sources. See the documentation in the STM32 Reference
+ * Manual.
+ * @note PRESC bits must not be specified and left to zero.
+ */
+#define adcSTM32SetCCR(ccr) (ADC1_COMMON->CCR = (ccr))
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adc_lld_serve_interrupt(ADCDriver *adcp);
+ void adcSTM32EnableVREF(ADCDriver *adcp);
+ void adcSTM32DisableVREF(ADCDriver *adcp);
+ void adcSTM32EnableTS(ADCDriver *adcp);
+ void adcSTM32DisableTS(ADCDriver *adcp);
+#if defined(ADC_CCR_VBATEN)
+ void adcSTM32EnableVBAT(ADCDriver *adcp);
+ void adcSTM32DisableVBAT(ADCDriver *adcp);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv5/notes.txt b/os/hal/ports/STM32/LLD/ADCv5/notes.txt
index 48ede4c0a5..71fe7490da 100644
--- a/os/hal/ports/STM32/LLD/ADCv5/notes.txt
+++ b/os/hal/ports/STM32/LLD/ADCv5/notes.txt
@@ -1,16 +1,16 @@
-STM32 ADCv5 driver.
-
-Driver capability:
-
-- Supports the STM32 "simple" ADC, the one found on small devices (G0).
-
-The file registry must export:
-
-STM32_HAS_ADC1 - ADC1 presence flag.
-STM32_ADC_SUPPORTS_PRESCALER - Support of CCR PRESC field.
-STM32_ADC_SUPPORTS_OVERSAMPLING - Support of oversampling-related fields.
-STM32_ADC1_IRQ_SHARED_WITH_EXTI - TRUE if the IRQ is shared with EXTI.
-STM32_ADC1_HANDLER - IRQ vector name.
-STM32_ADC1_NUMBER - IRQ vector number.
-STM32_ADC1_DMA_MSK - Mask of the compatible DMA channels.
-STM32_ADC1_DMA_CHN - Mask of the channels mapping.
+STM32 ADCv5 driver.
+
+Driver capability:
+
+- Supports the STM32 "simple" ADC, the one found on small devices (G0).
+
+The file registry must export:
+
+STM32_HAS_ADC1 - ADC1 presence flag.
+STM32_ADC_SUPPORTS_PRESCALER - Support of CCR PRESC field.
+STM32_ADC_SUPPORTS_OVERSAMPLING - Support of oversampling-related fields.
+STM32_ADC1_IRQ_SHARED_WITH_EXTI - TRUE if the IRQ is shared with EXTI.
+STM32_ADC1_HANDLER - IRQ vector name.
+STM32_ADC1_NUMBER - IRQ vector number.
+STM32_ADC1_DMA_MSK - Mask of the compatible DMA channels.
+STM32_ADC1_DMA_CHN - Mask of the channels mapping.
diff --git a/os/hal/ports/STM32/LLD/BDMAv1/driver.mk b/os/hal/ports/STM32/LLD/BDMAv1/driver.mk
index 1146b41467..71ee1cabfb 100644
--- a/os/hal/ports/STM32/LLD/BDMAv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/BDMAv1/driver.mk
@@ -1,2 +1,2 @@
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/BDMAv1
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/BDMAv1
diff --git a/os/hal/ports/STM32/LLD/BDMAv1/notes.txt b/os/hal/ports/STM32/LLD/BDMAv1/notes.txt
index e7fe3ad1fc..5c1497d13f 100644
--- a/os/hal/ports/STM32/LLD/BDMAv1/notes.txt
+++ b/os/hal/ports/STM32/LLD/BDMAv1/notes.txt
@@ -1,11 +1,11 @@
-STM32 BDMAv1 driver.
-
-Driver capability:
-
-- The driver supports the "basic" DMA controller.
-
-The file registry must export:
-
-STM32_BDMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
- is not exported then the ISR is not declared.
-STM32_BDMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
+STM32 BDMAv1 driver.
+
+Driver capability:
+
+- The driver supports the "basic" DMA controller.
+
+The file registry must export:
+
+STM32_BDMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
+ is not exported then the ISR is not declared.
+STM32_BDMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
diff --git a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c
index 4ca2e417bb..411a55b30f 100644
--- a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c
+++ b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.c
@@ -1,455 +1,455 @@
-/*
- 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 BDMAv1/stm32_bdma.c
- * @brief BDMA helper driver code.
- *
- * @addtogroup STM32_BDMA
- * @details BDMA sharing helper driver. In the STM32 the BDMA streams are a
- * shared resource, this driver allows to allocate and free BDMA
- * streams at runtime in order to allow all the other device
- * drivers to coordinate the access to the resource.
- * @note The BDMA ISR handlers are all declared into this module because
- * sharing, the various device drivers can associate a callback to
- * ISRs when allocating streams.
- * @{
- */
-
-#include "hal.h"
-
-/* The following macro is only defined if some driver requiring BDMA services
- has been enabled.*/
-#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/**
- * @brief Mask of the BDMA streams in @p bdma_allocated_mask.
- */
-#define STM32_BDMA_STREAMS_MASK 0x000000FFU
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief BDMA streams descriptors.
- * @details This table keeps the association between an unique stream
- * identifier and the involved physical registers.
- * @note Don't use this array directly, use the appropriate wrapper macros
- * instead: @p STM32_BDMA1_STREAM1, @p STM32_BDMA1_STREAM2 etc.
- */
-const stm32_bdma_stream_t _stm32_bdma_streams[STM32_BDMA_STREAMS] = {
- {BDMA, BDMA_Channel0, 0, DMAMUX2_Channel0, 0, STM32_BDMA1_CH0_NUMBER},
- {BDMA, BDMA_Channel1, 4, DMAMUX2_Channel1, 1, STM32_BDMA1_CH1_NUMBER},
- {BDMA, BDMA_Channel2, 8, DMAMUX2_Channel2, 2, STM32_BDMA1_CH2_NUMBER},
- {BDMA, BDMA_Channel3, 12, DMAMUX2_Channel3, 3, STM32_BDMA1_CH3_NUMBER},
- {BDMA, BDMA_Channel4, 16, DMAMUX2_Channel4, 4, STM32_BDMA1_CH4_NUMBER},
- {BDMA, BDMA_Channel5, 20, DMAMUX2_Channel5, 5, STM32_BDMA1_CH5_NUMBER},
- {BDMA, BDMA_Channel6, 24, DMAMUX2_Channel6, 6, STM32_BDMA1_CH6_NUMBER},
- {BDMA, BDMA_Channel7, 28, DMAMUX2_Channel7, 7, STM32_BDMA1_CH7_NUMBER}
-};
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief BDMA ISR redirector type.
- */
-typedef struct {
- stm32_bdmaisr_t func; /**< @brief BDMA callback function. */
- void *param; /**< @brief BDMA callback parameter.*/
-} bdma_isr_redir_t;
-
-/**
- * @brief BDMA driver base structure.
- */
-static struct {
- /**
- * @brief Mask of the allocated streams.
- */
- uint32_t allocated_mask;
- /**
- * @brief DMA IRQ redirectors.
- */
- struct {
- /**
- * @brief DMA callback function.
- */
- stm32_bdmaisr_t func;
- /**
- * @brief DMA callback parameter.
- */
- void *param;
- } streams[STM32_BDMA_STREAMS];
-} bdma;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/**
- * @brief BDMA1 stream 0 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH0_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 0U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 0U;
- if (bdma.streams[0].func)
- bdma.streams[0].func(bdma.streams[0].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 1 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH1_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 4U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 4U;
- if (bdma.streams[1].func)
- bdma.streams[1].func(bdma.streams[1].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 2 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH2_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 8U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 8U;
- if (bdma.streams[2].func)
- bdma.streams[2].func(bdma.streams[2].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 3 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH3_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 12U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 12U;
- if (bdma.streams[3].func)
- bdma.streams[3].func(bdma.streams[3].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 4 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH4_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 16U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 16U;
- if (bdma.streams[4].func)
- bdma.streams[4].func(bdma.streams[4].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 5 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH5_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 20U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 20U;
- if (bdma.streams[5].func)
- bdma.streams[5].func(bdma.streams[5].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 6 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH6_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 24U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 24U;
- if (bdma.streams[6].func)
- bdma.streams[6].func(bdma.streams[6].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief BDMA1 stream 7 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_BDMA1_CH7_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (BDMA->ISR >> 28U) & STM32_BDMA_ISR_MASK;
- BDMA->IFCR = flags << 28U;
- if (bdma.streams[7].func)
- bdma.streams[7].func(bdma.streams[7].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 BDMA helper initialization.
- *
- * @init
- */
-void bdmaInit(void) {
- unsigned i;
-
- bdma.allocated_mask = 0U;
- for (i = 0; i < STM32_BDMA_STREAMS; i++) {
- _stm32_bdma_streams[i].channel->CCR = 0U;
- bdma.streams[i].func = NULL;
- bdma.streams[i].param = NULL;
- }
- BDMA->IFCR = 0xFFFFFFFFU;
-}
-
-/**
- * @brief Allocates a BDMA stream.
- * @details The stream is allocated and, if required, the BDMA clock enabled.
- * The function also enables the IRQ vector associated to the stream
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific stream or:
- * - @p STM32_BDMA_STREAM_ID_ANY for any stream.
- * .
- * @param[in] priority IRQ priority for the BDMA stream
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_bdma_stream_t
- * structure.
- * @retval NULL if a/the stream is not available.
- *
- * @iclass
- */
-const stm32_bdma_stream_t *bdmaStreamAllocI(uint32_t id,
- uint32_t priority,
- stm32_bdmaisr_t func,
- void *param) {
- uint32_t i, startid, endid;
-
- osalDbgCheckClassI();
-
- if (id < STM32_BDMA_STREAMS) {
- startid = id;
- endid = id;
- }
- else if (id == STM32_BDMA_STREAM_ID_ANY) {
- startid = 0U;
- endid = STM32_BDMA_STREAMS - 1U;
- }
- else {
- osalDbgCheck(false);
- return NULL;
- }
-
- for (i = startid; i <= endid; i++) {
- uint32_t mask = (1U << i);
- if ((bdma.allocated_mask & mask) == 0U) {
- const stm32_bdma_stream_t *stp = STM32_BDMA_STREAM(i);
-
- /* Installs the DMA handler.*/
- bdma.streams[i].func = func;
- bdma.streams[i].param = param;
- bdma.allocated_mask |= mask;
-
- /* Enabling DMA clocks required by the current streams set.*/
- if ((STM32_BDMA_STREAMS_MASK & mask) != 0U) {
- rccEnableBDMA1(true);
- }
-
-#if defined(rccEnableDMAMUX)
- /* Enabling DMAMUX if present.*/
- if (bdma.allocated_mask != 0U) {
- rccEnableDMAMUX(true);
- }
-#endif
-
- /* Enables the associated IRQ vector if not already enabled and if a
- callback is defined.*/
- if (func != NULL) {
- nvicEnableVector(stp->vector, priority);
- }
-
- /* Putting the stream in a known state.*/
- bdmaStreamDisable(stp);
- stp->channel->CCR = STM32_BDMA_CR_RESET_VALUE;
-
- return stp;
- }
- }
-
- return NULL;
-}
-
-/**
- * @brief Allocates a BDMA stream.
- * @details The stream is allocated and, if required, the BDMA clock enabled.
- * The function also enables the IRQ vector associated to the stream
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific stream or:
- * - @p STM32_BDMA_STREAM_ID_ANY for any stream.
- * .
- * @param[in] priority IRQ priority for the BDMA stream
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_bdma_stream_t
- * structure.
- * @retval NULL if a/the stream is not available.
- *
- * @api
- */
-const stm32_bdma_stream_t *bdmaStreamAlloc(uint32_t id,
- uint32_t priority,
- stm32_bdmaisr_t func,
- void *param) {
- const stm32_bdma_stream_t *stp;
-
- osalSysLock();
- stp = bdmaStreamAllocI(id, priority, func, param);
- osalSysUnlock();
-
- return stp;
-}
-
-/**
- * @brief Releases a BDMA stream.
- * @details The stream is freed and, if required, the BDMA clock disabled.
- * Trying to release a unallocated stream is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- *
- * @iclass
- */
-void bdmaStreamFreeI(const stm32_bdma_stream_t *stp) {
-
- osalDbgCheck(stp != NULL);
-
- /* Check if the streams is not taken.*/
- osalDbgAssert((bdma.allocated_mask & (1U << stp->selfindex)) != 0U,
- "not allocated");
-
- /* Disables the associated IRQ vector.*/
- nvicDisableVector(stp->vector);
-
- /* Marks the stream as not allocated.*/
- bdma.allocated_mask &= ~(1U << stp->selfindex);
-
- /* Clearing associated handler and parameter.*/
- bdma.streams->func = NULL;
- bdma.streams->param = NULL;
-
- /* Shutting down clocks that are no more required, if any.*/
- if ((bdma.allocated_mask & STM32_BDMA_STREAMS_MASK) == 0U) {
- rccDisableBDMA1();
- }
-}
-
-/**
- * @brief Releases a BDMA stream.
- * @details The stream is freed and, if required, the BDMA clock disabled.
- * Trying to release a unallocated stream is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- *
- * @api
- */
-void bdmaStreamFree(const stm32_bdma_stream_t *stp) {
-
- osalSysLock();
- bdmaStreamFreeI(stp);
- osalSysUnlock();
-}
-
-/**
- * @brief Associates a peripheral request to a BDMA stream.
- * @note This function can be invoked in both ISR or thread context.
- *
- * @param[in] stp pointer to a @p stm32_bdma_stream_t structure
- * @param[in] per peripheral identifier
- *
- * @special
- */
-void bdmaSetRequestSource(const stm32_bdma_stream_t *stp, uint32_t per) {
-
- osalDbgCheck(per < 256U);
-
- stp->mux->CCR = per;
-}
-
-#endif /* STM32_BDMA_REQUIRED */
-
-/** @} */
+/*
+ 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 BDMAv1/stm32_bdma.c
+ * @brief BDMA helper driver code.
+ *
+ * @addtogroup STM32_BDMA
+ * @details BDMA sharing helper driver. In the STM32 the BDMA streams are a
+ * shared resource, this driver allows to allocate and free BDMA
+ * streams at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The BDMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * ISRs when allocating streams.
+ * @{
+ */
+
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring BDMA services
+ has been enabled.*/
+#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/**
+ * @brief Mask of the BDMA streams in @p bdma_allocated_mask.
+ */
+#define STM32_BDMA_STREAMS_MASK 0x000000FFU
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief BDMA streams descriptors.
+ * @details This table keeps the association between an unique stream
+ * identifier and the involved physical registers.
+ * @note Don't use this array directly, use the appropriate wrapper macros
+ * instead: @p STM32_BDMA1_STREAM1, @p STM32_BDMA1_STREAM2 etc.
+ */
+const stm32_bdma_stream_t _stm32_bdma_streams[STM32_BDMA_STREAMS] = {
+ {BDMA, BDMA_Channel0, 0, DMAMUX2_Channel0, 0, STM32_BDMA1_CH0_NUMBER},
+ {BDMA, BDMA_Channel1, 4, DMAMUX2_Channel1, 1, STM32_BDMA1_CH1_NUMBER},
+ {BDMA, BDMA_Channel2, 8, DMAMUX2_Channel2, 2, STM32_BDMA1_CH2_NUMBER},
+ {BDMA, BDMA_Channel3, 12, DMAMUX2_Channel3, 3, STM32_BDMA1_CH3_NUMBER},
+ {BDMA, BDMA_Channel4, 16, DMAMUX2_Channel4, 4, STM32_BDMA1_CH4_NUMBER},
+ {BDMA, BDMA_Channel5, 20, DMAMUX2_Channel5, 5, STM32_BDMA1_CH5_NUMBER},
+ {BDMA, BDMA_Channel6, 24, DMAMUX2_Channel6, 6, STM32_BDMA1_CH6_NUMBER},
+ {BDMA, BDMA_Channel7, 28, DMAMUX2_Channel7, 7, STM32_BDMA1_CH7_NUMBER}
+};
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief BDMA ISR redirector type.
+ */
+typedef struct {
+ stm32_bdmaisr_t func; /**< @brief BDMA callback function. */
+ void *param; /**< @brief BDMA callback parameter.*/
+} bdma_isr_redir_t;
+
+/**
+ * @brief BDMA driver base structure.
+ */
+static struct {
+ /**
+ * @brief Mask of the allocated streams.
+ */
+ uint32_t allocated_mask;
+ /**
+ * @brief DMA IRQ redirectors.
+ */
+ struct {
+ /**
+ * @brief DMA callback function.
+ */
+ stm32_bdmaisr_t func;
+ /**
+ * @brief DMA callback parameter.
+ */
+ void *param;
+ } streams[STM32_BDMA_STREAMS];
+} bdma;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief BDMA1 stream 0 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH0_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 0U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 0U;
+ if (bdma.streams[0].func)
+ bdma.streams[0].func(bdma.streams[0].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 1 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH1_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 4U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 4U;
+ if (bdma.streams[1].func)
+ bdma.streams[1].func(bdma.streams[1].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 2 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH2_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 8U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 8U;
+ if (bdma.streams[2].func)
+ bdma.streams[2].func(bdma.streams[2].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 3 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH3_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 12U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 12U;
+ if (bdma.streams[3].func)
+ bdma.streams[3].func(bdma.streams[3].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 4 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH4_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 16U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 16U;
+ if (bdma.streams[4].func)
+ bdma.streams[4].func(bdma.streams[4].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 5 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH5_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 20U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 20U;
+ if (bdma.streams[5].func)
+ bdma.streams[5].func(bdma.streams[5].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 6 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH6_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 24U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 24U;
+ if (bdma.streams[6].func)
+ bdma.streams[6].func(bdma.streams[6].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief BDMA1 stream 7 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_BDMA1_CH7_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (BDMA->ISR >> 28U) & STM32_BDMA_ISR_MASK;
+ BDMA->IFCR = flags << 28U;
+ if (bdma.streams[7].func)
+ bdma.streams[7].func(bdma.streams[7].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 BDMA helper initialization.
+ *
+ * @init
+ */
+void bdmaInit(void) {
+ unsigned i;
+
+ bdma.allocated_mask = 0U;
+ for (i = 0; i < STM32_BDMA_STREAMS; i++) {
+ _stm32_bdma_streams[i].channel->CCR = 0U;
+ bdma.streams[i].func = NULL;
+ bdma.streams[i].param = NULL;
+ }
+ BDMA->IFCR = 0xFFFFFFFFU;
+}
+
+/**
+ * @brief Allocates a BDMA stream.
+ * @details The stream is allocated and, if required, the BDMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific stream or:
+ * - @p STM32_BDMA_STREAM_ID_ANY for any stream.
+ * .
+ * @param[in] priority IRQ priority for the BDMA stream
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_bdma_stream_t
+ * structure.
+ * @retval NULL if a/the stream is not available.
+ *
+ * @iclass
+ */
+const stm32_bdma_stream_t *bdmaStreamAllocI(uint32_t id,
+ uint32_t priority,
+ stm32_bdmaisr_t func,
+ void *param) {
+ uint32_t i, startid, endid;
+
+ osalDbgCheckClassI();
+
+ if (id < STM32_BDMA_STREAMS) {
+ startid = id;
+ endid = id;
+ }
+ else if (id == STM32_BDMA_STREAM_ID_ANY) {
+ startid = 0U;
+ endid = STM32_BDMA_STREAMS - 1U;
+ }
+ else {
+ osalDbgCheck(false);
+ return NULL;
+ }
+
+ for (i = startid; i <= endid; i++) {
+ uint32_t mask = (1U << i);
+ if ((bdma.allocated_mask & mask) == 0U) {
+ const stm32_bdma_stream_t *stp = STM32_BDMA_STREAM(i);
+
+ /* Installs the DMA handler.*/
+ bdma.streams[i].func = func;
+ bdma.streams[i].param = param;
+ bdma.allocated_mask |= mask;
+
+ /* Enabling DMA clocks required by the current streams set.*/
+ if ((STM32_BDMA_STREAMS_MASK & mask) != 0U) {
+ rccEnableBDMA1(true);
+ }
+
+#if defined(rccEnableDMAMUX)
+ /* Enabling DMAMUX if present.*/
+ if (bdma.allocated_mask != 0U) {
+ rccEnableDMAMUX(true);
+ }
+#endif
+
+ /* Enables the associated IRQ vector if not already enabled and if a
+ callback is defined.*/
+ if (func != NULL) {
+ nvicEnableVector(stp->vector, priority);
+ }
+
+ /* Putting the stream in a known state.*/
+ bdmaStreamDisable(stp);
+ stp->channel->CCR = STM32_BDMA_CR_RESET_VALUE;
+
+ return stp;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Allocates a BDMA stream.
+ * @details The stream is allocated and, if required, the BDMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific stream or:
+ * - @p STM32_BDMA_STREAM_ID_ANY for any stream.
+ * .
+ * @param[in] priority IRQ priority for the BDMA stream
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_bdma_stream_t
+ * structure.
+ * @retval NULL if a/the stream is not available.
+ *
+ * @api
+ */
+const stm32_bdma_stream_t *bdmaStreamAlloc(uint32_t id,
+ uint32_t priority,
+ stm32_bdmaisr_t func,
+ void *param) {
+ const stm32_bdma_stream_t *stp;
+
+ osalSysLock();
+ stp = bdmaStreamAllocI(id, priority, func, param);
+ osalSysUnlock();
+
+ return stp;
+}
+
+/**
+ * @brief Releases a BDMA stream.
+ * @details The stream is freed and, if required, the BDMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ *
+ * @iclass
+ */
+void bdmaStreamFreeI(const stm32_bdma_stream_t *stp) {
+
+ osalDbgCheck(stp != NULL);
+
+ /* Check if the streams is not taken.*/
+ osalDbgAssert((bdma.allocated_mask & (1U << stp->selfindex)) != 0U,
+ "not allocated");
+
+ /* Disables the associated IRQ vector.*/
+ nvicDisableVector(stp->vector);
+
+ /* Marks the stream as not allocated.*/
+ bdma.allocated_mask &= ~(1U << stp->selfindex);
+
+ /* Clearing associated handler and parameter.*/
+ bdma.streams->func = NULL;
+ bdma.streams->param = NULL;
+
+ /* Shutting down clocks that are no more required, if any.*/
+ if ((bdma.allocated_mask & STM32_BDMA_STREAMS_MASK) == 0U) {
+ rccDisableBDMA1();
+ }
+}
+
+/**
+ * @brief Releases a BDMA stream.
+ * @details The stream is freed and, if required, the BDMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ *
+ * @api
+ */
+void bdmaStreamFree(const stm32_bdma_stream_t *stp) {
+
+ osalSysLock();
+ bdmaStreamFreeI(stp);
+ osalSysUnlock();
+}
+
+/**
+ * @brief Associates a peripheral request to a BDMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] stp pointer to a @p stm32_bdma_stream_t structure
+ * @param[in] per peripheral identifier
+ *
+ * @special
+ */
+void bdmaSetRequestSource(const stm32_bdma_stream_t *stp, uint32_t per) {
+
+ osalDbgCheck(per < 256U);
+
+ stp->mux->CCR = per;
+}
+
+#endif /* STM32_BDMA_REQUIRED */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h
index 6ed63f11c0..3e13f2772e 100644
--- a/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h
+++ b/os/hal/ports/STM32/LLD/BDMAv1/stm32_bdma.h
@@ -1,441 +1,441 @@
-/*
- 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 BDMAv1/stm32_bdma.h
- * @brief BDMA helper driver header.
- * @note This driver uses the new naming convention used for the STM32F2xx
- * so the "BDMA channels" are referred as "BDMA streams".
- *
- * @addtogroup STM32_BDMA
- * @{
- */
-
-#ifndef STM32_BDMA_H
-#define STM32_BDMA_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Total number of BDMA streams.
- * @details This is the total number of streams among all the BDMA units.
- */
-#define STM32_BDMA_STREAMS 8U
-
-/**
- * @brief Mask of the ISR bits passed to the BDMA callback functions.
- */
-#define STM32_BDMA_ISR_MASK 0x0EU
-
-/**
- * @brief Checks if a BDMA priority is within the valid range.
- *
- * @param[in] prio BDMA priority
- * @retval The check result.
- * @retval false invalid BDMA priority.
- * @retval true correct BDMA priority.
- */
-#define STM32_BDMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
-
-/**
- * @brief Checks if a BDMA stream id is within the valid range.
- *
- * @param[in] id BDMA stream id
- * @retval The check result.
- * @retval false invalid DMA stream.
- * @retval true correct DMA stream.
- */
-#define STM32_BDMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) <= STM32_BDMA_STREAMS))
-
-/**
- * @name Special stream identifiers
- * @{
- */
-#define STM32_BDMA_STREAM_ID_ANY STM32_BDMA_STREAMS
-/** @} */
-
-/**
- * @name BDMA streams identifiers
- * @{
- */
-/**
- * @brief Returns a pointer to a stm32_dma_stream_t structure.
- *
- * @param[in] id the stream numeric identifier
- * @return A pointer to the stm32_bdma_stream_t constant structure
- * associated to the BDMA stream.
- */
-#define STM32_BDMA_STREAM(id) (&_stm32_bdma_streams[id])
-
-#define STM32_BDMA1_STREAM0 STM32_BDMA_STREAM(0)
-#define STM32_BDMA1_STREAM1 STM32_BDMA_STREAM(1)
-#define STM32_BDMA1_STREAM2 STM32_BDMA_STREAM(2)
-#define STM32_BDMA1_STREAM3 STM32_BDMA_STREAM(3)
-#define STM32_BDMA1_STREAM4 STM32_BDMA_STREAM(4)
-#define STM32_BDMA1_STREAM5 STM32_BDMA_STREAM(5)
-#define STM32_BDMA1_STREAM6 STM32_BDMA_STREAM(6)
-#define STM32_BDMA1_STREAM7 STM32_BDMA_STREAM(7)
-/** @} */
-
-/**
- * @name CR register constants
- * @{
- */
-#define STM32_BDMA_CR_RESET_VALUE 0x00000000U
-#define STM32_BDMA_CR_EN BDMA_CCR_EN_Msk
-#define STM32_BDMA_CR_TCIE BDMA_CCR_TCIE
-#define STM32_BDMA_CR_HTIE BDMA_CCR_HTIE
-#define STM32_BDMA_CR_TEIE BDMA_CCR_TEIE
-#define STM32_BDMA_CR_DIR_MASK (BDMA_CCR_DIR | BDMA_CCR_MEM2MEM)
-#define STM32_BDMA_CR_DIR_P2M 0U
-#define STM32_BDMA_CR_DIR_M2P BDMA_CCR_DIR
-#define STM32_BDMA_CR_DIR_M2M BDMA_CCR_MEM2MEM
-#define STM32_BDMA_CR_CIRC BDMA_CCR_CIRC
-#define STM32_BDMA_CR_PINC BDMA_CCR_PINC
-#define STM32_BDMA_CR_MINC BDMA_CCR_MINC
-#define STM32_BDMA_CR_PSIZE_MASK BDMA_CCR_PSIZE_Msk
-#define STM32_BDMA_CR_PSIZE_BYTE 0U
-#define STM32_BDMA_CR_PSIZE_HWORD BDMA_CCR_PSIZE_0
-#define STM32_BDMA_CR_PSIZE_WORD BDMA_CCR_PSIZE_1
-#define STM32_BDMA_CR_MSIZE_MASK BDMA_CCR_MSIZE_Msk
-#define STM32_BDMA_CR_MSIZE_BYTE 0U
-#define STM32_BDMA_CR_MSIZE_HWORD BDMA_CCR_MSIZE_0
-#define STM32_BDMA_CR_MSIZE_WORD BDMA_CCR_MSIZE_1
-#define STM32_BDMA_CR_SIZE_MASK (STM32_BDMA_CR_PSIZE_MASK | \
- STM32_BDMA_CR_MSIZE_MASK)
-#define STM32_BDMA_CR_PL_MASK BDMA_CCR_PL_Msk
-#define STM32_BDMA_CR_PL(n) ((n) << 12U)
-#if !defined(STM32_ENFORCE_H7_REV_XY)
-#define STM32_BDMA_CR_DBM BDMA_CCR_DBM
-#define STM32_BDMA_CR_CM BDMA_CCR_CT
-#endif
-/** @} */
-
-/**
- * @name Status flags passed to the ISR callbacks
- * @{
- */
-#define STM32_BDMA_ISR_TEIF BDMA_ISR_TEIF0
-#define STM32_BDMA_ISR_HTIF BDMA_ISR_HTIF0
-#define STM32_BDMA_ISR_TCIF BDMA_ISR_TCIF0
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_BDMA1)
-#error "STM32_HAS_BDMA1 missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH0_HANDLER)
-#error "STM32_BDMA1_CH0_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH1_HANDLER)
-#error "STM32_BDMA1_CH1_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH2_HANDLER)
-#error "STM32_BDMA1_CH2_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH3_HANDLER)
-#error "STM32_BDMA1_CH3_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH4_HANDLER)
-#error "STM32_BDMA1_CH4_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH5_HANDLER)
-#error "STM32_BDMA1_CH5_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH6_HANDLER)
-#error "STM32_BDMA1_CH6_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH7_HANDLER)
-#error "STM32_BDMA1_CH7_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH0_NUMBER)
-#error "STM32_BDMA1_CH0_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH1_NUMBER)
-#error "STM32_BDMA1_CH1_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH2_NUMBER)
-#error "STM32_BDMA1_CH2_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH3_NUMBER)
-#error "STM32_BDMA1_CH3_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH4_NUMBER)
-#error "STM32_BDMA1_CH4_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH5_NUMBER)
-#error "STM32_BDMA1_CH5_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH6_NUMBER)
-#error "STM32_BDMA1_CH6_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_BDMA1_CH7_NUMBER)
-#error "STM32_BDMA1_CH7_NUMBER missing in registry"
-#endif
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 BDMA ISR function type.
- *
- * @param[in] p parameter for the registered function
- * @param[in] flags pre-shifted content of the ISR register, the bits
- * are aligned to bit zero
- */
-typedef void (*stm32_bdmaisr_t)(void *p, uint32_t flags);
-
-/**
- * @brief STM32 BDMA stream descriptor structure.
- */
-typedef struct {
- BDMA_TypeDef *bdma; /**< @brief Associated BDMA. */
- BDMA_Channel_TypeDef *channel; /**< @brief Associated BDMA channel.*/
- uint8_t shift; /**< @brief Bit offset in ISR and
- IFCR registers. */
- DMAMUX_Channel_TypeDef *mux; /**< @brief Associated BDMA stream. */
- uint8_t selfindex; /**< @brief Index to self in array. */
- uint8_t vector; /**< @brief Associated IRQ vector. */
-} stm32_bdma_stream_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @name Macro Functions
- * @{
- */
-/**
- * @brief Associates a peripheral data register to a BDMA stream.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- * @param[in] addr value to be written in the CPAR register
- *
- * @special
- */
-#define bdmaStreamSetPeripheral(stp, addr) { \
- (stp)->channel->CPAR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Associates a memory destination to a BDMA stream.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- * @param[in] addr value to be written in the CMAR register
- *
- * @special
- */
-#define bdmaStreamSetMemory(stp, addr) { \
- (stp)->channel->CM0AR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Sets the number of transfers to be performed.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- * @param[in] size value to be written in the CNDTR register
- *
- * @special
- */
-#define bdmaStreamSetTransactionSize(stp, size) { \
- (stp)->channel->CNDTR = (uint32_t)(size); \
-}
-
-/**
- * @brief Returns the number of transfers to be performed.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- * @return The number of transfers to be performed.
- *
- * @special
- */
-#define bdmaStreamGetTransactionSize(stp) ((size_t)((stp)->channel->CNDTR))
-
-/**
- * @brief Programs the stream mode settings.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- * @param[in] mode value to be written in the CCR register
- *
- * @special
- */
-#define bdmaStreamSetMode(stp, mode) { \
- (stp)->channel->CCR = (uint32_t)(mode); \
-}
-
-/**
- * @brief BDMA stream enable.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- *
- * @special
- */
-#define bdmaStreamEnable(stp) { \
- (stp)->channel->CCR |= STM32_BDMA_CR_EN; \
-}
-
-/**
- * @brief BDMA stream disable.
- * @details The function disables the specified stream and then clears any
- * pending interrupt.
- * @note This function can be invoked in both ISR or thread context.
- * @note Interrupts enabling flags are set to zero after this call, see
- * bug 3607518.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- *
- * @special
- */
-#define bdmaStreamDisable(stp) { \
- (stp)->channel->CCR &= ~(STM32_BDMA_CR_TCIE | STM32_BDMA_CR_HTIE | \
- STM32_BDMA_CR_TEIE | STM32_BDMA_CR_EN); \
- bdmaStreamClearInterrupt(stp); \
-}
-
-/**
- * @brief BDMA stream interrupt sources clear.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- *
- * @special
- */
-#define bdmaStreamClearInterrupt(stp) { \
- (stp)->bdma->IFCR = STM32_BDMA_ISR_MASK << (stp)->shift; \
-}
-
-/**
- * @brief Starts a memory to memory operation using the specified stream.
- * @note The default transfer data mode is "byte to byte" but it can be
- * changed by specifying extra options in the @p mode parameter.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- * @param[in] mode value to be written in the CCR register, this value
- * is implicitly ORed with:
- * - @p STM32_BDMA_CR_MINC
- * - @p STM32_BDMA_CR_PINC
- * - @p STM32_BDMA_CR_DIR_M2M
- * - @p STM32_BDMA_CR_EN
- * .
- * @param[in] src source address
- * @param[in] dst destination address
- * @param[in] n number of data units to copy
- */
-#define bdmaStartMemCopy(stp, mode, src, dst, n) { \
- bdmaStreamSetPeripheral(stp, src); \
- bdmaStreamSetMemory0(stp, dst); \
- bdmaStreamSetTransactionSize(stp, n); \
- bdmaStreamSetMode(stp, (mode) | \
- STM32_BDMA_CR_MINC | STM32_BDMA_CR_PINC | \
- STM32_BDMA_CR_DIR_M2M | STM32_BDMA_CR_EN); \
-}
-
-/**
- * @brief Polled wait for BDMA transfer end.
- * @pre The stream must have been allocated using @p bdmaStreamAllocate().
- * @post After use the stream can be released using @p bdmaStreamRelease().
- *
- * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
- */
-#define bdmaWaitCompletion(stp) { \
- while ((stp)->channel->CNDTR > 0U) \
- ; \
- bdmaStreamDisable(stp); \
-}
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern const stm32_bdma_stream_t _stm32_bdma_streams[STM32_BDMA_STREAMS];
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void bdmaInit(void);
- const stm32_bdma_stream_t *bdmaStreamAllocI(uint32_t id,
- uint32_t priority,
- stm32_bdmaisr_t func,
- void *param);
- const stm32_bdma_stream_t *bdmaStreamAlloc(uint32_t id,
- uint32_t priority,
- stm32_bdmaisr_t func,
- void *param);
- void bdmaStreamFreeI(const stm32_bdma_stream_t *stp);
- void bdmaStreamFree(const stm32_bdma_stream_t *stp);
- void bdmaSetRequestSource(const stm32_bdma_stream_t *stp, uint32_t per);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_BDMA_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 BDMAv1/stm32_bdma.h
+ * @brief BDMA helper driver header.
+ * @note This driver uses the new naming convention used for the STM32F2xx
+ * so the "BDMA channels" are referred as "BDMA streams".
+ *
+ * @addtogroup STM32_BDMA
+ * @{
+ */
+
+#ifndef STM32_BDMA_H
+#define STM32_BDMA_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Total number of BDMA streams.
+ * @details This is the total number of streams among all the BDMA units.
+ */
+#define STM32_BDMA_STREAMS 8U
+
+/**
+ * @brief Mask of the ISR bits passed to the BDMA callback functions.
+ */
+#define STM32_BDMA_ISR_MASK 0x0EU
+
+/**
+ * @brief Checks if a BDMA priority is within the valid range.
+ *
+ * @param[in] prio BDMA priority
+ * @retval The check result.
+ * @retval false invalid BDMA priority.
+ * @retval true correct BDMA priority.
+ */
+#define STM32_BDMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
+
+/**
+ * @brief Checks if a BDMA stream id is within the valid range.
+ *
+ * @param[in] id BDMA stream id
+ * @retval The check result.
+ * @retval false invalid DMA stream.
+ * @retval true correct DMA stream.
+ */
+#define STM32_BDMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) <= STM32_BDMA_STREAMS))
+
+/**
+ * @name Special stream identifiers
+ * @{
+ */
+#define STM32_BDMA_STREAM_ID_ANY STM32_BDMA_STREAMS
+/** @} */
+
+/**
+ * @name BDMA streams identifiers
+ * @{
+ */
+/**
+ * @brief Returns a pointer to a stm32_dma_stream_t structure.
+ *
+ * @param[in] id the stream numeric identifier
+ * @return A pointer to the stm32_bdma_stream_t constant structure
+ * associated to the BDMA stream.
+ */
+#define STM32_BDMA_STREAM(id) (&_stm32_bdma_streams[id])
+
+#define STM32_BDMA1_STREAM0 STM32_BDMA_STREAM(0)
+#define STM32_BDMA1_STREAM1 STM32_BDMA_STREAM(1)
+#define STM32_BDMA1_STREAM2 STM32_BDMA_STREAM(2)
+#define STM32_BDMA1_STREAM3 STM32_BDMA_STREAM(3)
+#define STM32_BDMA1_STREAM4 STM32_BDMA_STREAM(4)
+#define STM32_BDMA1_STREAM5 STM32_BDMA_STREAM(5)
+#define STM32_BDMA1_STREAM6 STM32_BDMA_STREAM(6)
+#define STM32_BDMA1_STREAM7 STM32_BDMA_STREAM(7)
+/** @} */
+
+/**
+ * @name CR register constants
+ * @{
+ */
+#define STM32_BDMA_CR_RESET_VALUE 0x00000000U
+#define STM32_BDMA_CR_EN BDMA_CCR_EN_Msk
+#define STM32_BDMA_CR_TCIE BDMA_CCR_TCIE
+#define STM32_BDMA_CR_HTIE BDMA_CCR_HTIE
+#define STM32_BDMA_CR_TEIE BDMA_CCR_TEIE
+#define STM32_BDMA_CR_DIR_MASK (BDMA_CCR_DIR | BDMA_CCR_MEM2MEM)
+#define STM32_BDMA_CR_DIR_P2M 0U
+#define STM32_BDMA_CR_DIR_M2P BDMA_CCR_DIR
+#define STM32_BDMA_CR_DIR_M2M BDMA_CCR_MEM2MEM
+#define STM32_BDMA_CR_CIRC BDMA_CCR_CIRC
+#define STM32_BDMA_CR_PINC BDMA_CCR_PINC
+#define STM32_BDMA_CR_MINC BDMA_CCR_MINC
+#define STM32_BDMA_CR_PSIZE_MASK BDMA_CCR_PSIZE_Msk
+#define STM32_BDMA_CR_PSIZE_BYTE 0U
+#define STM32_BDMA_CR_PSIZE_HWORD BDMA_CCR_PSIZE_0
+#define STM32_BDMA_CR_PSIZE_WORD BDMA_CCR_PSIZE_1
+#define STM32_BDMA_CR_MSIZE_MASK BDMA_CCR_MSIZE_Msk
+#define STM32_BDMA_CR_MSIZE_BYTE 0U
+#define STM32_BDMA_CR_MSIZE_HWORD BDMA_CCR_MSIZE_0
+#define STM32_BDMA_CR_MSIZE_WORD BDMA_CCR_MSIZE_1
+#define STM32_BDMA_CR_SIZE_MASK (STM32_BDMA_CR_PSIZE_MASK | \
+ STM32_BDMA_CR_MSIZE_MASK)
+#define STM32_BDMA_CR_PL_MASK BDMA_CCR_PL_Msk
+#define STM32_BDMA_CR_PL(n) ((n) << 12U)
+#if !defined(STM32_ENFORCE_H7_REV_XY)
+#define STM32_BDMA_CR_DBM BDMA_CCR_DBM
+#define STM32_BDMA_CR_CM BDMA_CCR_CT
+#endif
+/** @} */
+
+/**
+ * @name Status flags passed to the ISR callbacks
+ * @{
+ */
+#define STM32_BDMA_ISR_TEIF BDMA_ISR_TEIF0
+#define STM32_BDMA_ISR_HTIF BDMA_ISR_HTIF0
+#define STM32_BDMA_ISR_TCIF BDMA_ISR_TCIF0
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_BDMA1)
+#error "STM32_HAS_BDMA1 missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH0_HANDLER)
+#error "STM32_BDMA1_CH0_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH1_HANDLER)
+#error "STM32_BDMA1_CH1_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH2_HANDLER)
+#error "STM32_BDMA1_CH2_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH3_HANDLER)
+#error "STM32_BDMA1_CH3_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH4_HANDLER)
+#error "STM32_BDMA1_CH4_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH5_HANDLER)
+#error "STM32_BDMA1_CH5_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH6_HANDLER)
+#error "STM32_BDMA1_CH6_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH7_HANDLER)
+#error "STM32_BDMA1_CH7_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH0_NUMBER)
+#error "STM32_BDMA1_CH0_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH1_NUMBER)
+#error "STM32_BDMA1_CH1_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH2_NUMBER)
+#error "STM32_BDMA1_CH2_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH3_NUMBER)
+#error "STM32_BDMA1_CH3_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH4_NUMBER)
+#error "STM32_BDMA1_CH4_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH5_NUMBER)
+#error "STM32_BDMA1_CH5_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH6_NUMBER)
+#error "STM32_BDMA1_CH6_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_BDMA1_CH7_NUMBER)
+#error "STM32_BDMA1_CH7_NUMBER missing in registry"
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 BDMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the ISR register, the bits
+ * are aligned to bit zero
+ */
+typedef void (*stm32_bdmaisr_t)(void *p, uint32_t flags);
+
+/**
+ * @brief STM32 BDMA stream descriptor structure.
+ */
+typedef struct {
+ BDMA_TypeDef *bdma; /**< @brief Associated BDMA. */
+ BDMA_Channel_TypeDef *channel; /**< @brief Associated BDMA channel.*/
+ uint8_t shift; /**< @brief Bit offset in ISR and
+ IFCR registers. */
+ DMAMUX_Channel_TypeDef *mux; /**< @brief Associated BDMA stream. */
+ uint8_t selfindex; /**< @brief Index to self in array. */
+ uint8_t vector; /**< @brief Associated IRQ vector. */
+} stm32_bdma_stream_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Associates a peripheral data register to a BDMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ * @param[in] addr value to be written in the CPAR register
+ *
+ * @special
+ */
+#define bdmaStreamSetPeripheral(stp, addr) { \
+ (stp)->channel->CPAR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Associates a memory destination to a BDMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ * @param[in] addr value to be written in the CMAR register
+ *
+ * @special
+ */
+#define bdmaStreamSetMemory(stp, addr) { \
+ (stp)->channel->CM0AR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Sets the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ * @param[in] size value to be written in the CNDTR register
+ *
+ * @special
+ */
+#define bdmaStreamSetTransactionSize(stp, size) { \
+ (stp)->channel->CNDTR = (uint32_t)(size); \
+}
+
+/**
+ * @brief Returns the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ * @return The number of transfers to be performed.
+ *
+ * @special
+ */
+#define bdmaStreamGetTransactionSize(stp) ((size_t)((stp)->channel->CNDTR))
+
+/**
+ * @brief Programs the stream mode settings.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ * @param[in] mode value to be written in the CCR register
+ *
+ * @special
+ */
+#define bdmaStreamSetMode(stp, mode) { \
+ (stp)->channel->CCR = (uint32_t)(mode); \
+}
+
+/**
+ * @brief BDMA stream enable.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ *
+ * @special
+ */
+#define bdmaStreamEnable(stp) { \
+ (stp)->channel->CCR |= STM32_BDMA_CR_EN; \
+}
+
+/**
+ * @brief BDMA stream disable.
+ * @details The function disables the specified stream and then clears any
+ * pending interrupt.
+ * @note This function can be invoked in both ISR or thread context.
+ * @note Interrupts enabling flags are set to zero after this call, see
+ * bug 3607518.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ *
+ * @special
+ */
+#define bdmaStreamDisable(stp) { \
+ (stp)->channel->CCR &= ~(STM32_BDMA_CR_TCIE | STM32_BDMA_CR_HTIE | \
+ STM32_BDMA_CR_TEIE | STM32_BDMA_CR_EN); \
+ bdmaStreamClearInterrupt(stp); \
+}
+
+/**
+ * @brief BDMA stream interrupt sources clear.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ *
+ * @special
+ */
+#define bdmaStreamClearInterrupt(stp) { \
+ (stp)->bdma->IFCR = STM32_BDMA_ISR_MASK << (stp)->shift; \
+}
+
+/**
+ * @brief Starts a memory to memory operation using the specified stream.
+ * @note The default transfer data mode is "byte to byte" but it can be
+ * changed by specifying extra options in the @p mode parameter.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ * @param[in] mode value to be written in the CCR register, this value
+ * is implicitly ORed with:
+ * - @p STM32_BDMA_CR_MINC
+ * - @p STM32_BDMA_CR_PINC
+ * - @p STM32_BDMA_CR_DIR_M2M
+ * - @p STM32_BDMA_CR_EN
+ * .
+ * @param[in] src source address
+ * @param[in] dst destination address
+ * @param[in] n number of data units to copy
+ */
+#define bdmaStartMemCopy(stp, mode, src, dst, n) { \
+ bdmaStreamSetPeripheral(stp, src); \
+ bdmaStreamSetMemory0(stp, dst); \
+ bdmaStreamSetTransactionSize(stp, n); \
+ bdmaStreamSetMode(stp, (mode) | \
+ STM32_BDMA_CR_MINC | STM32_BDMA_CR_PINC | \
+ STM32_BDMA_CR_DIR_M2M | STM32_BDMA_CR_EN); \
+}
+
+/**
+ * @brief Polled wait for BDMA transfer end.
+ * @pre The stream must have been allocated using @p bdmaStreamAllocate().
+ * @post After use the stream can be released using @p bdmaStreamRelease().
+ *
+ * @param[in] stp pointer to an @p stm32_bdma_stream_t structure
+ */
+#define bdmaWaitCompletion(stp) { \
+ while ((stp)->channel->CNDTR > 0U) \
+ ; \
+ bdmaStreamDisable(stp); \
+}
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern const stm32_bdma_stream_t _stm32_bdma_streams[STM32_BDMA_STREAMS];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void bdmaInit(void);
+ const stm32_bdma_stream_t *bdmaStreamAllocI(uint32_t id,
+ uint32_t priority,
+ stm32_bdmaisr_t func,
+ void *param);
+ const stm32_bdma_stream_t *bdmaStreamAlloc(uint32_t id,
+ uint32_t priority,
+ stm32_bdmaisr_t func,
+ void *param);
+ void bdmaStreamFreeI(const stm32_bdma_stream_t *stp);
+ void bdmaStreamFree(const stm32_bdma_stream_t *stp);
+ void bdmaSetRequestSource(const stm32_bdma_stream_t *stp, uint32_t per);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_BDMA_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/CANv1/driver.mk b/os/hal/ports/STM32/LLD/CANv1/driver.mk
index 608a9273f2..6db597adb8 100644
--- a/os/hal/ports/STM32/LLD/CANv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/CANv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1
diff --git a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
index 5e24fa1d4d..e76fa42af3 100644
--- a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
+++ b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.c
@@ -1,1049 +1,1049 @@
-/*
- 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 CANv1/hal_can_lld.c
- * @brief STM32 CAN subsystem low level driver source.
- *
- * @addtogroup CAN
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_CAN || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*
- * Addressing differences in the headers, they seem unable to agree on names.
- */
-#if STM32_CAN_USE_CAN1
-#if !defined(CAN1)
-#define CAN1 CAN
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief CAN1 driver identifier.*/
-#if STM32_CAN_USE_CAN1 || defined(__DOXYGEN__)
-CANDriver CAND1;
-#endif
-
-/** @brief CAN2 driver identifier.*/
-#if STM32_CAN_USE_CAN2 || defined(__DOXYGEN__)
-CANDriver CAND2;
-#endif
-
-/** @brief CAN3 driver identifier.*/
-#if STM32_CAN_USE_CAN3 || defined(__DOXYGEN__)
-CANDriver CAND3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-/**
- * @brief Programs the filters of CAN 1 and CAN 2.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] can2sb number of the first filter assigned to CAN2
- * @param[in] num number of entries in the filters array, if zero then
- * a default filter is programmed
- * @param[in] cfp pointer to the filters array, can be @p NULL if
- * (num == 0)
- *
- * @notapi
- */
-static void can_lld_set_filters(CANDriver* canp,
- uint32_t can2sb,
- uint32_t num,
- const CANFilter *cfp) {
-
-#if STM32_CAN_USE_CAN2
- if (canp == &CAND2) {
- /* Set handle to CAN1, because CAN1 manages the filters of CAN2.*/
- canp = &CAND1;
- }
-#endif
-
- /* Temporarily enabling CAN clock.*/
-#if STM32_CAN_USE_CAN1
- if (canp == &CAND1) {
- rccEnableCAN1(true);
- /* Filters initialization.*/
- canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
- canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | (can2sb << 8) | CAN_FMR_FINIT;
- }
-#endif
-
-#if STM32_CAN_USE_CAN3
- if (canp == &CAND3) {
- rccEnableCAN3(true);
- /* Filters initialization.*/
- canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
- }
-#endif
-
- if (num > 0) {
- uint32_t i, fmask;
-
- /* All filters cleared.*/
- canp->can->FA1R = 0;
- canp->can->FM1R = 0;
- canp->can->FS1R = 0;
- canp->can->FFA1R = 0;
-
-#if STM32_CAN_USE_CAN1
- if (canp == &CAND1) {
- for (i = 0; i < STM32_CAN_MAX_FILTERS; i++) {
- canp->can->sFilterRegister[i].FR1 = 0;
- canp->can->sFilterRegister[i].FR2 = 0;
- }
- }
-#endif
-
-#if STM32_CAN_USE_CAN3
- if (canp == &CAND3) {
- for (i = 0; i < STM32_CAN3_MAX_FILTERS; i++) {
- canp->can->sFilterRegister[i].FR1 = 0;
- canp->can->sFilterRegister[i].FR2 = 0;
- }
- }
-#endif
-
- /* Scanning the filters array.*/
- for (i = 0; i < num; i++) {
- fmask = 1 << cfp->filter;
- if (cfp->mode)
- canp->can->FM1R |= fmask;
- if (cfp->scale)
- canp->can->FS1R |= fmask;
- if (cfp->assignment)
- canp->can->FFA1R |= fmask;
- canp->can->sFilterRegister[cfp->filter].FR1 = cfp->register1;
- canp->can->sFilterRegister[cfp->filter].FR2 = cfp->register2;
- canp->can->FA1R |= fmask;
- cfp++;
- }
- }
- else {
- /* Setting up a single default filter that enables everything for both
- CANs.*/
- canp->can->sFilterRegister[0].FR1 = 0;
- canp->can->sFilterRegister[0].FR2 = 0;
-#if STM32_CAN_USE_CAN2
- if (canp == &CAND1) {
- canp->can->sFilterRegister[can2sb].FR1 = 0;
- canp->can->sFilterRegister[can2sb].FR2 = 0;
- }
-#endif
- canp->can->FM1R = 0;
- canp->can->FFA1R = 0;
- canp->can->FS1R = 1;
- canp->can->FA1R = 1;
-#if STM32_CAN_USE_CAN2
- if (canp == &CAND1) {
- canp->can->FS1R |= 1 << can2sb;
- canp->can->FA1R |= 1 << can2sb;
- }
-#endif
- }
- canp->can->FMR &= ~CAN_FMR_FINIT;
-
- /* Clock disabled, it will be enabled again in can_lld_start().*/
- /* Temporarily enabling CAN clock.*/
-#if STM32_CAN_USE_CAN1
- if (canp == &CAND1) {
- rccDisableCAN1();
- }
-#endif
-#if STM32_CAN_USE_CAN3
- if (canp == &CAND3) {
- rccDisableCAN3();
- }
-#endif
-}
-
-/**
- * @brief Common TX ISR handler.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-static void can_lld_tx_handler(CANDriver *canp) {
- uint32_t tsr;
- eventflags_t flags;
-
- /* Clearing IRQ sources.*/
- tsr = canp->can->TSR;
- canp->can->TSR = tsr;
-
- /* Flags to be signaled through the TX event source.*/
- flags = 0U;
-
- /* Checking mailbox 0.*/
- if ((tsr & CAN_TSR_RQCP0) != 0U) {
- if ((tsr & (CAN_TSR_ALST0 | CAN_TSR_TERR0)) != 0U) {
- flags |= CAN_MAILBOX_TO_MASK(1U) << 16U;
- }
- else {
- flags |= CAN_MAILBOX_TO_MASK(1U);
- }
- }
-
- /* Checking mailbox 1.*/
- if ((tsr & CAN_TSR_RQCP1) != 0U) {
- if ((tsr & (CAN_TSR_ALST1 | CAN_TSR_TERR1)) != 0U) {
- flags |= CAN_MAILBOX_TO_MASK(2U) << 16U;
- }
- else {
- flags |= CAN_MAILBOX_TO_MASK(2U);
- }
- }
-
- /* Checking mailbox 2.*/
- if ((tsr & CAN_TSR_RQCP2) != 0U) {
- if ((tsr & (CAN_TSR_ALST2 | CAN_TSR_TERR2)) != 0U) {
- flags |= CAN_MAILBOX_TO_MASK(3U) << 16U;
- }
- else {
- flags |= CAN_MAILBOX_TO_MASK(3U);
- }
- }
-
- /* Signaling flags and waking up threads waiting for a transmission slot.*/
- _can_tx_empty_isr(canp, flags);
-}
-
-/**
- * @brief Common RX0 ISR handler.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-static void can_lld_rx0_handler(CANDriver *canp) {
- uint32_t rf0r;
-
- rf0r = canp->can->RF0R;
- if ((rf0r & CAN_RF0R_FMP0) > 0) {
- /* No more receive events until the queue 0 has been emptied.*/
- canp->can->IER &= ~CAN_IER_FMPIE0;
- _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(1U));
- }
- if ((rf0r & CAN_RF0R_FOVR0) > 0) {
- /* Overflow events handling.*/
- canp->can->RF0R = CAN_RF0R_FOVR0;
- _can_error_isr(canp, CAN_OVERFLOW_ERROR);
- }
-}
-
-/**
- * @brief Common RX1 ISR handler.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-static void can_lld_rx1_handler(CANDriver *canp) {
- uint32_t rf1r;
-
- rf1r = canp->can->RF1R;
- if ((rf1r & CAN_RF1R_FMP1) > 0) {
- /* No more receive events until the queue 0 has been emptied.*/
- canp->can->IER &= ~CAN_IER_FMPIE1;
- _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(2U));
- }
- if ((rf1r & CAN_RF1R_FOVR1) > 0) {
- /* Overflow events handling.*/
- canp->can->RF1R = CAN_RF1R_FOVR1;
- _can_error_isr(canp, CAN_OVERFLOW_ERROR);
- }
-}
-
-/**
- * @brief Common SCE ISR handler.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-static void can_lld_sce_handler(CANDriver *canp) {
- uint32_t msr;
-
- /* Clearing IRQ sources.*/
- msr = canp->can->MSR;
- canp->can->MSR = msr;
-
- /* Wakeup event.*/
-#if CAN_USE_SLEEP_MODE
- if (msr & CAN_MSR_WKUI) {
- canp->state = CAN_READY;
- canp->can->MCR &= ~CAN_MCR_SLEEP;
- _can_wakeup_isr(canp);
- }
-#endif /* CAN_USE_SLEEP_MODE */
- /* Error event.*/
- if (msr & CAN_MSR_ERRI) {
- eventflags_t flags;
- uint32_t esr = canp->can->ESR;
-
-#if STM32_CAN_REPORT_ALL_ERRORS
- flags = (eventflags_t)(esr & 7);
- if ((esr & CAN_ESR_LEC) > 0)
- flags |= CAN_FRAMING_ERROR;
-#else
- flags = 0;
-#endif
-
- /* The content of the ESR register is copied unchanged in the upper
- half word of the listener flags mask.*/
- _can_error_isr(canp, flags | (eventflags_t)(esr << 16U));
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_CAN_USE_CAN1 || defined(__DOXYGEN__)
-#if defined(STM32_CAN1_UNIFIED_HANDLER)
-/**
- * @brief CAN1 unified interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN1_UNIFIED_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_tx_handler(&CAND1);
- can_lld_rx0_handler(&CAND1);
- can_lld_rx1_handler(&CAND1);
- can_lld_sce_handler(&CAND1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#else /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
-
-#if !defined(STM32_CAN1_TX_HANDLER)
-#error "STM32_CAN1_TX_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN1_RX0_HANDLER)
-#error "STM32_CAN1_RX0_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN1_RX1_HANDLER)
-#error "STM32_CAN1_RX1_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN1_SCE_HANDLER)
-#error "STM32_CAN1_SCE_HANDLER not defined"
-#endif
-
-/**
- * @brief CAN1 TX interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN1_TX_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_tx_handler(&CAND1);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN1 RX0 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN1_RX0_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_rx0_handler(&CAND1);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN1 RX1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN1_RX1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_rx1_handler(&CAND1);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN1 SCE interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN1_SCE_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_sce_handler(&CAND1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
-#endif /* STM32_CAN_USE_CAN1 */
-
-#if STM32_CAN_USE_CAN2 || defined(__DOXYGEN__)
-#if defined(STM32_CAN2_UNIFIED_HANDLER)
-/**
- * @brief CAN1 unified interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN2_UNIFIED_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_tx_handler(&CAND2);
- can_lld_rx0_handler(&CAND2);
- can_lld_rx1_handler(&CAND2);
- can_lld_sce_handler(&CAND2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#else /* !defined(STM32_CAN2_UNIFIED_HANDLER) */
-
-#if !defined(STM32_CAN1_TX_HANDLER)
-#error "STM32_CAN1_TX_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN1_RX0_HANDLER)
-#error "STM32_CAN1_RX0_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN1_RX1_HANDLER)
-#error "STM32_CAN1_RX1_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN1_SCE_HANDLER)
-#error "STM32_CAN1_SCE_HANDLER not defined"
-#endif
-
-/**
- * @brief CAN2 TX interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN2_TX_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_tx_handler(&CAND2);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN2 RX0 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN2_RX0_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_rx0_handler(&CAND2);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN2 RX1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN2_RX1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_rx1_handler(&CAND2);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN2 SCE interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN2_SCE_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_sce_handler(&CAND2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_CAN2_UNIFIED_HANDLER) */
-#endif /* STM32_CAN_USE_CAN2 */
-
-#if STM32_CAN_USE_CAN3 || defined(__DOXYGEN__)
-#if defined(STM32_CAN3_UNIFIED_HANDLER)
-/**
- * @brief CAN1 unified interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN3_UNIFIED_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_tx_handler(&CAND3);
- can_lld_rx0_handler(&CAND3);
- can_lld_rx1_handler(&CAND3);
- can_lld_sce_handler(&CAND3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#else /* !defined(STM32_CAN3_UNIFIED_HANDLER) */
-
-#if !defined(STM32_CAN3_TX_HANDLER)
-#error "STM32_CAN3_TX_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN3_RX0_HANDLER)
-#error "STM32_CAN3_RX0_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN3_RX1_HANDLER)
-#error "STM32_CAN3_RX1_HANDLER not defined"
-#endif
-#if !defined(STM32_CAN3_SCE_HANDLER)
-#error "STM32_CAN3_SCE_HANDLER not defined"
-#endif
-
-/**
- * @brief CAN3 TX interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN3_TX_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_tx_handler(&CAND3);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN3 RX0 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN3_RX0_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_rx0_handler(&CAND3);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN1 RX3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN3_RX1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_rx1_handler(&CAND3);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief CAN1 SCE interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_CAN3_SCE_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- can_lld_sce_handler(&CAND3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
-#endif /* STM32_CAN_USE_CAN1 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level CAN driver initialization.
- *
- * @notapi
- */
-void can_lld_init(void) {
-
-#if STM32_CAN_USE_CAN1
- /* Driver initialization.*/
- canObjectInit(&CAND1);
- CAND1.can = CAN1;
-#if defined(STM32_CAN1_UNIFIED_NUMBER)
- nvicEnableVector(STM32_CAN1_UNIFIED_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
-#else
- nvicEnableVector(STM32_CAN1_TX_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN1_RX0_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN1_RX1_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN1_SCE_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_CAN_USE_CAN2
- /* Driver initialization.*/
- canObjectInit(&CAND2);
- CAND2.can = CAN2;
-#if defined(STM32_CAN2_UNIFIED_NUMBER)
- nvicEnableVector(STM32_CAN2_UNIFIED_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
-#else
- nvicEnableVector(STM32_CAN2_TX_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN2_RX0_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN2_RX1_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN2_SCE_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_CAN_USE_CAN3
- /* Driver initialization.*/
- canObjectInit(&CAND3);
- CAND3.can = CAN3;
-#if defined(STM32_CAN3_UNIFIED_NUMBER)
- nvicEnableVector(STM32_CAN3_UNIFIED_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
-#else
- nvicEnableVector(STM32_CAN3_TX_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN3_RX0_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN3_RX1_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
- nvicEnableVector(STM32_CAN3_SCE_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
-#endif
-#endif
-
- /* Filters initialization.*/
-#if STM32_CAN_USE_CAN1
-#if STM32_HAS_CAN2
- can_lld_set_filters(&CAND1, STM32_CAN_MAX_FILTERS / 2, 0, NULL);
-#else
- can_lld_set_filters(&CAND1, STM32_CAN_MAX_FILTERS, 0, NULL);
-#endif
-#endif
-
-#if STM32_HAS_CAN3
-#if STM32_CAN_USE_CAN3
- can_lld_set_filters(&CAND3, STM32_CAN3_MAX_FILTERS, 0, NULL);
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the CAN peripheral.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_start(CANDriver *canp) {
-
- /* Clock activation.*/
-#if STM32_CAN_USE_CAN1
- if (&CAND1 == canp) {
- rccEnableCAN1(true);
- }
-#endif
-
-#if STM32_CAN_USE_CAN2
- if (&CAND2 == canp) {
- rccEnableCAN1(true); /* CAN 2 requires CAN1, so enabling it first.*/
- rccEnableCAN2(true);
- }
-#endif
-
-#if STM32_CAN_USE_CAN3
- if (&CAND3 == canp) {
- rccEnableCAN3(true);
- }
-#endif
-
- /* Configuring CAN. */
- canp->can->MCR = CAN_MCR_INRQ;
- while ((canp->can->MSR & CAN_MSR_INAK) == 0)
- osalThreadSleepS(1);
- canp->can->BTR = canp->config->btr;
- canp->can->MCR = canp->config->mcr;
-
- /* Interrupt sources initialization.*/
-#if STM32_CAN_REPORT_ALL_ERRORS
- canp->can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
- CAN_IER_WKUIE | CAN_IER_ERRIE | CAN_IER_LECIE |
- CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
- CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
-#else
- canp->can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
- CAN_IER_WKUIE | CAN_IER_ERRIE |
- CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
- CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
-#endif
-}
-
-/**
- * @brief Deactivates the CAN peripheral.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_stop(CANDriver *canp) {
-
- /* If in ready state then disables the CAN peripheral.*/
- if (canp->state == CAN_READY) {
-#if STM32_CAN_USE_CAN1
- if (&CAND1 == canp) {
- CAN1->MCR = 0x00010002; /* Register reset value. */
- CAN1->IER = 0x00000000; /* All sources disabled. */
-#if STM32_CAN_USE_CAN2
- /* If CAND2 is stopped then CAN1 clock is stopped here.*/
- if (CAND2.state == CAN_STOP)
-#endif
- {
- rccDisableCAN1();
- }
- }
-#endif
-
-#if STM32_CAN_USE_CAN2
- if (&CAND2 == canp) {
- CAN2->MCR = 0x00010002; /* Register reset value. */
- CAN2->IER = 0x00000000; /* All sources disabled. */
-#if STM32_CAN_USE_CAN1
- /* If CAND1 is stopped then CAN1 clock is stopped here.*/
- if (CAND1.state == CAN_STOP)
-#endif
- {
- rccDisableCAN1();
- }
- rccDisableCAN2();
- }
-#endif
-
-#if STM32_CAN_USE_CAN3
- if (&CAND3 == canp) {
- CAN3->MCR = 0x00010002; /* Register reset value. */
- CAN3->IER = 0x00000000; /* All sources disabled. */
- rccDisableCAN3();
- }
-#endif
- }
-}
-
-/**
- * @brief Determines whether a frame can be transmitted.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- *
- * @return The queue space availability.
- * @retval false no space in the transmit queue.
- * @retval true transmit slot available.
- *
- * @notapi
- */
-bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
-
- switch (mailbox) {
- case CAN_ANY_MAILBOX:
- return (canp->can->TSR & CAN_TSR_TME) != 0;
- case 1:
- return (canp->can->TSR & CAN_TSR_TME0) != 0;
- case 2:
- return (canp->can->TSR & CAN_TSR_TME1) != 0;
- case 3:
- return (canp->can->TSR & CAN_TSR_TME2) != 0;
- default:
- return false;
- }
-}
-
-/**
- * @brief Inserts a frame into the transmit queue.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] ctfp pointer to the CAN frame to be transmitted
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- *
- * @notapi
- */
-void can_lld_transmit(CANDriver *canp,
- canmbx_t mailbox,
- const CANTxFrame *ctfp) {
- uint32_t tir;
- CAN_TxMailBox_TypeDef *tmbp;
-
- /* Pointer to a free transmission mailbox.*/
- switch (mailbox) {
- case CAN_ANY_MAILBOX:
- if ((DBGMCU->IDCODE >> 16) == 0x1001) {
- /* real STM32 */
- tmbp = &canp->can->sTxMailBox[(canp->can->TSR & CAN_TSR_CODE) >> 24];
- } else {
- int n;
- /* GD32 */
- if ((canp->can->TSR & CAN_TSR_TME0) == CAN_TSR_TME0)
- n = 0;
- else if ((canp->can->TSR & CAN_TSR_TME1) == CAN_TSR_TME1)
- n = 1;
- else if ((canp->can->TSR & CAN_TSR_TME2) == CAN_TSR_TME2)
- n = 2;
- else {
- /* silence? */
- return;
- }
- tmbp = &canp->can->sTxMailBox[n];
- }
- break;
- case 1:
- tmbp = &canp->can->sTxMailBox[0];
- break;
- case 2:
- tmbp = &canp->can->sTxMailBox[1];
- break;
- case 3:
- tmbp = &canp->can->sTxMailBox[2];
- break;
- default:
- return;
- }
-
- /* Preparing the message.*/
- if (ctfp->IDE)
- tir = ((uint32_t)ctfp->EID << 3) | ((uint32_t)ctfp->RTR << 1) |
- CAN_TI0R_IDE;
- else
- tir = ((uint32_t)ctfp->SID << 21) | ((uint32_t)ctfp->RTR << 1);
- tmbp->TDTR = ctfp->DLC;
- tmbp->TDLR = ctfp->data32[0];
- tmbp->TDHR = ctfp->data32[1];
- tmbp->TIR = tir | CAN_TI0R_TXRQ;
-}
-
-/**
- * @brief Determines whether a frame has been received.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- *
- * @return The queue space availability.
- * @retval false no space in the transmit queue.
- * @retval true transmit slot available.
- *
- * @notapi
- */
-bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
-
- switch (mailbox) {
- case CAN_ANY_MAILBOX:
- return ((canp->can->RF0R & CAN_RF0R_FMP0) != 0 ||
- (canp->can->RF1R & CAN_RF1R_FMP1) != 0);
- case 1:
- return (canp->can->RF0R & CAN_RF0R_FMP0) != 0;
- case 2:
- return (canp->can->RF1R & CAN_RF1R_FMP1) != 0;
- default:
- return false;
- }
-}
-
-/**
- * @brief Receives a frame from the input queue.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- * @param[out] crfp pointer to the buffer where the CAN frame is copied
- *
- * @notapi
- */
-void can_lld_receive(CANDriver *canp,
- canmbx_t mailbox,
- CANRxFrame *crfp) {
- uint32_t rir, rdtr;
-
- if (mailbox == CAN_ANY_MAILBOX) {
- if ((canp->can->RF0R & CAN_RF0R_FMP0) != 0)
- mailbox = 1;
- else if ((canp->can->RF1R & CAN_RF1R_FMP1) != 0)
- mailbox = 2;
- else {
- /* Should not happen, do nothing.*/
- return;
- }
- }
- switch (mailbox) {
- case 1:
- /* Fetches the message.*/
- rir = canp->can->sFIFOMailBox[0].RIR;
- rdtr = canp->can->sFIFOMailBox[0].RDTR;
- crfp->data32[0] = canp->can->sFIFOMailBox[0].RDLR;
- crfp->data32[1] = canp->can->sFIFOMailBox[0].RDHR;
-
- /* Releases the mailbox.*/
- canp->can->RF0R = CAN_RF0R_RFOM0;
-
- /* If the queue is empty re-enables the interrupt in order to generate
- events again.*/
- if ((canp->can->RF0R & CAN_RF0R_FMP0) == 0)
- canp->can->IER |= CAN_IER_FMPIE0;
- break;
- case 2:
- /* Fetches the message.*/
- rir = canp->can->sFIFOMailBox[1].RIR;
- rdtr = canp->can->sFIFOMailBox[1].RDTR;
- crfp->data32[0] = canp->can->sFIFOMailBox[1].RDLR;
- crfp->data32[1] = canp->can->sFIFOMailBox[1].RDHR;
-
- /* Releases the mailbox.*/
- canp->can->RF1R = CAN_RF1R_RFOM1;
-
- /* If the queue is empty re-enables the interrupt in order to generate
- events again.*/
- if ((canp->can->RF1R & CAN_RF1R_FMP1) == 0)
- canp->can->IER |= CAN_IER_FMPIE1;
- break;
- default:
- /* Should not happen, do nothing.*/
- return;
- }
-
- /* Decodes the various fields in the RX frame.*/
- crfp->RTR = (rir & CAN_RI0R_RTR) >> 1;
- crfp->IDE = (rir & CAN_RI0R_IDE) >> 2;
- if (crfp->IDE)
- crfp->EID = rir >> 3;
- else
- crfp->SID = rir >> 21;
- crfp->DLC = rdtr & CAN_RDT0R_DLC;
- crfp->FMI = (uint8_t)(rdtr >> 8);
- crfp->TIME = (uint16_t)(rdtr >> 16);
-}
-
-/**
- * @brief Tries to abort an ongoing transmission.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number
- *
- * @notapi
- */
-void can_lld_abort(CANDriver *canp,
- canmbx_t mailbox) {
-
- canp->can->TSR = 128U << ((mailbox - 1U) * 8U);
-}
-
-#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
-/**
- * @brief Enters the sleep mode.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_sleep(CANDriver *canp) {
-
- canp->can->MCR |= CAN_MCR_SLEEP;
-}
-
-/**
- * @brief Enforces leaving the sleep mode.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_wakeup(CANDriver *canp) {
-
- canp->can->MCR &= ~CAN_MCR_SLEEP;
-}
-#endif /* CAN_USE_SLEEP_MODE */
-
-/**
- * @brief Programs the filters.
- * @note This is an STM32-specific API.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] can2sb number of the first filter assigned to CAN2
- * @param[in] num number of entries in the filters array, if zero then
- * a default filter is programmed
- * @param[in] cfp pointer to the filters array, can be @p NULL if
- * (num == 0)
- *
- * @api
- */
-void canSTM32SetFilters(CANDriver *canp, uint32_t can2sb,
- uint32_t num, const CANFilter *cfp) {
-
-#if STM32_CAN_USE_CAN2
- osalDbgCheck((can2sb <= STM32_CAN_MAX_FILTERS) &&
- (num <= STM32_CAN_MAX_FILTERS));
-#endif
-
-#if STM32_CAN_USE_CAN1
- osalDbgAssert(CAND1.state == CAN_STOP, "invalid state");
-#endif
-#if STM32_CAN_USE_CAN2
- osalDbgAssert(CAND2.state == CAN_STOP, "invalid state");
-#endif
-#if STM32_CAN_USE_CAN3
- osalDbgAssert(CAND3.state == CAN_STOP, "invalid state");
-#endif
-
-#if STM32_CAN_USE_CAN1
- if (canp == &CAND1) {
- can_lld_set_filters(canp, can2sb, num, cfp);
- }
-#endif
-#if STM32_CAN_USE_CAN3
- if (canp == &CAND3) {
- can_lld_set_filters(canp, can2sb, num, cfp);
- }
-#endif
-}
-
-#endif /* HAL_USE_CAN */
-
-/** @} */
+/*
+ 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 CANv1/hal_can_lld.c
+ * @brief STM32 CAN subsystem low level driver source.
+ *
+ * @addtogroup CAN
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_CAN || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*
+ * Addressing differences in the headers, they seem unable to agree on names.
+ */
+#if STM32_CAN_USE_CAN1
+#if !defined(CAN1)
+#define CAN1 CAN
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief CAN1 driver identifier.*/
+#if STM32_CAN_USE_CAN1 || defined(__DOXYGEN__)
+CANDriver CAND1;
+#endif
+
+/** @brief CAN2 driver identifier.*/
+#if STM32_CAN_USE_CAN2 || defined(__DOXYGEN__)
+CANDriver CAND2;
+#endif
+
+/** @brief CAN3 driver identifier.*/
+#if STM32_CAN_USE_CAN3 || defined(__DOXYGEN__)
+CANDriver CAND3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+/**
+ * @brief Programs the filters of CAN 1 and CAN 2.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] can2sb number of the first filter assigned to CAN2
+ * @param[in] num number of entries in the filters array, if zero then
+ * a default filter is programmed
+ * @param[in] cfp pointer to the filters array, can be @p NULL if
+ * (num == 0)
+ *
+ * @notapi
+ */
+static void can_lld_set_filters(CANDriver* canp,
+ uint32_t can2sb,
+ uint32_t num,
+ const CANFilter *cfp) {
+
+#if STM32_CAN_USE_CAN2
+ if (canp == &CAND2) {
+ /* Set handle to CAN1, because CAN1 manages the filters of CAN2.*/
+ canp = &CAND1;
+ }
+#endif
+
+ /* Temporarily enabling CAN clock.*/
+#if STM32_CAN_USE_CAN1
+ if (canp == &CAND1) {
+ rccEnableCAN1(true);
+ /* Filters initialization.*/
+ canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
+ canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | (can2sb << 8) | CAN_FMR_FINIT;
+ }
+#endif
+
+#if STM32_CAN_USE_CAN3
+ if (canp == &CAND3) {
+ rccEnableCAN3(true);
+ /* Filters initialization.*/
+ canp->can->FMR = (canp->can->FMR & 0xFFFF0000) | CAN_FMR_FINIT;
+ }
+#endif
+
+ if (num > 0) {
+ uint32_t i, fmask;
+
+ /* All filters cleared.*/
+ canp->can->FA1R = 0;
+ canp->can->FM1R = 0;
+ canp->can->FS1R = 0;
+ canp->can->FFA1R = 0;
+
+#if STM32_CAN_USE_CAN1
+ if (canp == &CAND1) {
+ for (i = 0; i < STM32_CAN_MAX_FILTERS; i++) {
+ canp->can->sFilterRegister[i].FR1 = 0;
+ canp->can->sFilterRegister[i].FR2 = 0;
+ }
+ }
+#endif
+
+#if STM32_CAN_USE_CAN3
+ if (canp == &CAND3) {
+ for (i = 0; i < STM32_CAN3_MAX_FILTERS; i++) {
+ canp->can->sFilterRegister[i].FR1 = 0;
+ canp->can->sFilterRegister[i].FR2 = 0;
+ }
+ }
+#endif
+
+ /* Scanning the filters array.*/
+ for (i = 0; i < num; i++) {
+ fmask = 1 << cfp->filter;
+ if (cfp->mode)
+ canp->can->FM1R |= fmask;
+ if (cfp->scale)
+ canp->can->FS1R |= fmask;
+ if (cfp->assignment)
+ canp->can->FFA1R |= fmask;
+ canp->can->sFilterRegister[cfp->filter].FR1 = cfp->register1;
+ canp->can->sFilterRegister[cfp->filter].FR2 = cfp->register2;
+ canp->can->FA1R |= fmask;
+ cfp++;
+ }
+ }
+ else {
+ /* Setting up a single default filter that enables everything for both
+ CANs.*/
+ canp->can->sFilterRegister[0].FR1 = 0;
+ canp->can->sFilterRegister[0].FR2 = 0;
+#if STM32_CAN_USE_CAN2
+ if (canp == &CAND1) {
+ canp->can->sFilterRegister[can2sb].FR1 = 0;
+ canp->can->sFilterRegister[can2sb].FR2 = 0;
+ }
+#endif
+ canp->can->FM1R = 0;
+ canp->can->FFA1R = 0;
+ canp->can->FS1R = 1;
+ canp->can->FA1R = 1;
+#if STM32_CAN_USE_CAN2
+ if (canp == &CAND1) {
+ canp->can->FS1R |= 1 << can2sb;
+ canp->can->FA1R |= 1 << can2sb;
+ }
+#endif
+ }
+ canp->can->FMR &= ~CAN_FMR_FINIT;
+
+ /* Clock disabled, it will be enabled again in can_lld_start().*/
+ /* Temporarily enabling CAN clock.*/
+#if STM32_CAN_USE_CAN1
+ if (canp == &CAND1) {
+ rccDisableCAN1();
+ }
+#endif
+#if STM32_CAN_USE_CAN3
+ if (canp == &CAND3) {
+ rccDisableCAN3();
+ }
+#endif
+}
+
+/**
+ * @brief Common TX ISR handler.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+static void can_lld_tx_handler(CANDriver *canp) {
+ uint32_t tsr;
+ eventflags_t flags;
+
+ /* Clearing IRQ sources.*/
+ tsr = canp->can->TSR;
+ canp->can->TSR = tsr;
+
+ /* Flags to be signaled through the TX event source.*/
+ flags = 0U;
+
+ /* Checking mailbox 0.*/
+ if ((tsr & CAN_TSR_RQCP0) != 0U) {
+ if ((tsr & (CAN_TSR_ALST0 | CAN_TSR_TERR0)) != 0U) {
+ flags |= CAN_MAILBOX_TO_MASK(1U) << 16U;
+ }
+ else {
+ flags |= CAN_MAILBOX_TO_MASK(1U);
+ }
+ }
+
+ /* Checking mailbox 1.*/
+ if ((tsr & CAN_TSR_RQCP1) != 0U) {
+ if ((tsr & (CAN_TSR_ALST1 | CAN_TSR_TERR1)) != 0U) {
+ flags |= CAN_MAILBOX_TO_MASK(2U) << 16U;
+ }
+ else {
+ flags |= CAN_MAILBOX_TO_MASK(2U);
+ }
+ }
+
+ /* Checking mailbox 2.*/
+ if ((tsr & CAN_TSR_RQCP2) != 0U) {
+ if ((tsr & (CAN_TSR_ALST2 | CAN_TSR_TERR2)) != 0U) {
+ flags |= CAN_MAILBOX_TO_MASK(3U) << 16U;
+ }
+ else {
+ flags |= CAN_MAILBOX_TO_MASK(3U);
+ }
+ }
+
+ /* Signaling flags and waking up threads waiting for a transmission slot.*/
+ _can_tx_empty_isr(canp, flags);
+}
+
+/**
+ * @brief Common RX0 ISR handler.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+static void can_lld_rx0_handler(CANDriver *canp) {
+ uint32_t rf0r;
+
+ rf0r = canp->can->RF0R;
+ if ((rf0r & CAN_RF0R_FMP0) > 0) {
+ /* No more receive events until the queue 0 has been emptied.*/
+ canp->can->IER &= ~CAN_IER_FMPIE0;
+ _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(1U));
+ }
+ if ((rf0r & CAN_RF0R_FOVR0) > 0) {
+ /* Overflow events handling.*/
+ canp->can->RF0R = CAN_RF0R_FOVR0;
+ _can_error_isr(canp, CAN_OVERFLOW_ERROR);
+ }
+}
+
+/**
+ * @brief Common RX1 ISR handler.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+static void can_lld_rx1_handler(CANDriver *canp) {
+ uint32_t rf1r;
+
+ rf1r = canp->can->RF1R;
+ if ((rf1r & CAN_RF1R_FMP1) > 0) {
+ /* No more receive events until the queue 0 has been emptied.*/
+ canp->can->IER &= ~CAN_IER_FMPIE1;
+ _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(2U));
+ }
+ if ((rf1r & CAN_RF1R_FOVR1) > 0) {
+ /* Overflow events handling.*/
+ canp->can->RF1R = CAN_RF1R_FOVR1;
+ _can_error_isr(canp, CAN_OVERFLOW_ERROR);
+ }
+}
+
+/**
+ * @brief Common SCE ISR handler.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+static void can_lld_sce_handler(CANDriver *canp) {
+ uint32_t msr;
+
+ /* Clearing IRQ sources.*/
+ msr = canp->can->MSR;
+ canp->can->MSR = msr;
+
+ /* Wakeup event.*/
+#if CAN_USE_SLEEP_MODE
+ if (msr & CAN_MSR_WKUI) {
+ canp->state = CAN_READY;
+ canp->can->MCR &= ~CAN_MCR_SLEEP;
+ _can_wakeup_isr(canp);
+ }
+#endif /* CAN_USE_SLEEP_MODE */
+ /* Error event.*/
+ if (msr & CAN_MSR_ERRI) {
+ eventflags_t flags;
+ uint32_t esr = canp->can->ESR;
+
+#if STM32_CAN_REPORT_ALL_ERRORS
+ flags = (eventflags_t)(esr & 7);
+ if ((esr & CAN_ESR_LEC) > 0)
+ flags |= CAN_FRAMING_ERROR;
+#else
+ flags = 0;
+#endif
+
+ /* The content of the ESR register is copied unchanged in the upper
+ half word of the listener flags mask.*/
+ _can_error_isr(canp, flags | (eventflags_t)(esr << 16U));
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_CAN_USE_CAN1 || defined(__DOXYGEN__)
+#if defined(STM32_CAN1_UNIFIED_HANDLER)
+/**
+ * @brief CAN1 unified interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN1_UNIFIED_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND1);
+ can_lld_rx0_handler(&CAND1);
+ can_lld_rx1_handler(&CAND1);
+ can_lld_sce_handler(&CAND1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
+
+#if !defined(STM32_CAN1_TX_HANDLER)
+#error "STM32_CAN1_TX_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN1_RX0_HANDLER)
+#error "STM32_CAN1_RX0_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN1_RX1_HANDLER)
+#error "STM32_CAN1_RX1_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN1_SCE_HANDLER)
+#error "STM32_CAN1_SCE_HANDLER not defined"
+#endif
+
+/**
+ * @brief CAN1 TX interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN1_TX_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 RX0 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN1_RX0_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx0_handler(&CAND1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 RX1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN1_RX1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx1_handler(&CAND1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 SCE interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN1_SCE_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_sce_handler(&CAND1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
+#endif /* STM32_CAN_USE_CAN1 */
+
+#if STM32_CAN_USE_CAN2 || defined(__DOXYGEN__)
+#if defined(STM32_CAN2_UNIFIED_HANDLER)
+/**
+ * @brief CAN1 unified interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN2_UNIFIED_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND2);
+ can_lld_rx0_handler(&CAND2);
+ can_lld_rx1_handler(&CAND2);
+ can_lld_sce_handler(&CAND2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /* !defined(STM32_CAN2_UNIFIED_HANDLER) */
+
+#if !defined(STM32_CAN1_TX_HANDLER)
+#error "STM32_CAN1_TX_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN1_RX0_HANDLER)
+#error "STM32_CAN1_RX0_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN1_RX1_HANDLER)
+#error "STM32_CAN1_RX1_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN1_SCE_HANDLER)
+#error "STM32_CAN1_SCE_HANDLER not defined"
+#endif
+
+/**
+ * @brief CAN2 TX interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN2_TX_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN2 RX0 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN2_RX0_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx0_handler(&CAND2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN2 RX1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN2_RX1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx1_handler(&CAND2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN2 SCE interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN2_SCE_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_sce_handler(&CAND2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_CAN2_UNIFIED_HANDLER) */
+#endif /* STM32_CAN_USE_CAN2 */
+
+#if STM32_CAN_USE_CAN3 || defined(__DOXYGEN__)
+#if defined(STM32_CAN3_UNIFIED_HANDLER)
+/**
+ * @brief CAN1 unified interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_UNIFIED_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND3);
+ can_lld_rx0_handler(&CAND3);
+ can_lld_rx1_handler(&CAND3);
+ can_lld_sce_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /* !defined(STM32_CAN3_UNIFIED_HANDLER) */
+
+#if !defined(STM32_CAN3_TX_HANDLER)
+#error "STM32_CAN3_TX_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN3_RX0_HANDLER)
+#error "STM32_CAN3_RX0_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN3_RX1_HANDLER)
+#error "STM32_CAN3_RX1_HANDLER not defined"
+#endif
+#if !defined(STM32_CAN3_SCE_HANDLER)
+#error "STM32_CAN3_SCE_HANDLER not defined"
+#endif
+
+/**
+ * @brief CAN3 TX interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_TX_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_tx_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN3 RX0 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_RX0_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx0_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 RX3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_RX1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_rx1_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief CAN1 SCE interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_CAN3_SCE_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ can_lld_sce_handler(&CAND3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_CAN1_UNIFIED_HANDLER) */
+#endif /* STM32_CAN_USE_CAN1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level CAN driver initialization.
+ *
+ * @notapi
+ */
+void can_lld_init(void) {
+
+#if STM32_CAN_USE_CAN1
+ /* Driver initialization.*/
+ canObjectInit(&CAND1);
+ CAND1.can = CAN1;
+#if defined(STM32_CAN1_UNIFIED_NUMBER)
+ nvicEnableVector(STM32_CAN1_UNIFIED_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+#else
+ nvicEnableVector(STM32_CAN1_TX_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN1_RX0_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN1_RX1_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN1_SCE_NUMBER, STM32_CAN_CAN1_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_CAN_USE_CAN2
+ /* Driver initialization.*/
+ canObjectInit(&CAND2);
+ CAND2.can = CAN2;
+#if defined(STM32_CAN2_UNIFIED_NUMBER)
+ nvicEnableVector(STM32_CAN2_UNIFIED_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+#else
+ nvicEnableVector(STM32_CAN2_TX_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN2_RX0_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN2_RX1_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN2_SCE_NUMBER, STM32_CAN_CAN2_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_CAN_USE_CAN3
+ /* Driver initialization.*/
+ canObjectInit(&CAND3);
+ CAND3.can = CAN3;
+#if defined(STM32_CAN3_UNIFIED_NUMBER)
+ nvicEnableVector(STM32_CAN3_UNIFIED_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+#else
+ nvicEnableVector(STM32_CAN3_TX_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN3_RX0_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN3_RX1_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_CAN3_SCE_NUMBER, STM32_CAN_CAN3_IRQ_PRIORITY);
+#endif
+#endif
+
+ /* Filters initialization.*/
+#if STM32_CAN_USE_CAN1
+#if STM32_HAS_CAN2
+ can_lld_set_filters(&CAND1, STM32_CAN_MAX_FILTERS / 2, 0, NULL);
+#else
+ can_lld_set_filters(&CAND1, STM32_CAN_MAX_FILTERS, 0, NULL);
+#endif
+#endif
+
+#if STM32_HAS_CAN3
+#if STM32_CAN_USE_CAN3
+ can_lld_set_filters(&CAND3, STM32_CAN3_MAX_FILTERS, 0, NULL);
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the CAN peripheral.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_start(CANDriver *canp) {
+
+ /* Clock activation.*/
+#if STM32_CAN_USE_CAN1
+ if (&CAND1 == canp) {
+ rccEnableCAN1(true);
+ }
+#endif
+
+#if STM32_CAN_USE_CAN2
+ if (&CAND2 == canp) {
+ rccEnableCAN1(true); /* CAN 2 requires CAN1, so enabling it first.*/
+ rccEnableCAN2(true);
+ }
+#endif
+
+#if STM32_CAN_USE_CAN3
+ if (&CAND3 == canp) {
+ rccEnableCAN3(true);
+ }
+#endif
+
+ /* Configuring CAN. */
+ canp->can->MCR = CAN_MCR_INRQ;
+ while ((canp->can->MSR & CAN_MSR_INAK) == 0)
+ osalThreadSleepS(1);
+ canp->can->BTR = canp->config->btr;
+ canp->can->MCR = canp->config->mcr;
+
+ /* Interrupt sources initialization.*/
+#if STM32_CAN_REPORT_ALL_ERRORS
+ canp->can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
+ CAN_IER_WKUIE | CAN_IER_ERRIE | CAN_IER_LECIE |
+ CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
+ CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
+#else
+ canp->can->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 |
+ CAN_IER_WKUIE | CAN_IER_ERRIE |
+ CAN_IER_BOFIE | CAN_IER_EPVIE | CAN_IER_EWGIE |
+ CAN_IER_FOVIE0 | CAN_IER_FOVIE1;
+#endif
+}
+
+/**
+ * @brief Deactivates the CAN peripheral.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_stop(CANDriver *canp) {
+
+ /* If in ready state then disables the CAN peripheral.*/
+ if (canp->state == CAN_READY) {
+#if STM32_CAN_USE_CAN1
+ if (&CAND1 == canp) {
+ CAN1->MCR = 0x00010002; /* Register reset value. */
+ CAN1->IER = 0x00000000; /* All sources disabled. */
+#if STM32_CAN_USE_CAN2
+ /* If CAND2 is stopped then CAN1 clock is stopped here.*/
+ if (CAND2.state == CAN_STOP)
+#endif
+ {
+ rccDisableCAN1();
+ }
+ }
+#endif
+
+#if STM32_CAN_USE_CAN2
+ if (&CAND2 == canp) {
+ CAN2->MCR = 0x00010002; /* Register reset value. */
+ CAN2->IER = 0x00000000; /* All sources disabled. */
+#if STM32_CAN_USE_CAN1
+ /* If CAND1 is stopped then CAN1 clock is stopped here.*/
+ if (CAND1.state == CAN_STOP)
+#endif
+ {
+ rccDisableCAN1();
+ }
+ rccDisableCAN2();
+ }
+#endif
+
+#if STM32_CAN_USE_CAN3
+ if (&CAND3 == canp) {
+ CAN3->MCR = 0x00010002; /* Register reset value. */
+ CAN3->IER = 0x00000000; /* All sources disabled. */
+ rccDisableCAN3();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Determines whether a frame can be transmitted.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ *
+ * @return The queue space availability.
+ * @retval false no space in the transmit queue.
+ * @retval true transmit slot available.
+ *
+ * @notapi
+ */
+bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
+
+ switch (mailbox) {
+ case CAN_ANY_MAILBOX:
+ return (canp->can->TSR & CAN_TSR_TME) != 0;
+ case 1:
+ return (canp->can->TSR & CAN_TSR_TME0) != 0;
+ case 2:
+ return (canp->can->TSR & CAN_TSR_TME1) != 0;
+ case 3:
+ return (canp->can->TSR & CAN_TSR_TME2) != 0;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Inserts a frame into the transmit queue.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] ctfp pointer to the CAN frame to be transmitted
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ *
+ * @notapi
+ */
+void can_lld_transmit(CANDriver *canp,
+ canmbx_t mailbox,
+ const CANTxFrame *ctfp) {
+ uint32_t tir;
+ CAN_TxMailBox_TypeDef *tmbp;
+
+ /* Pointer to a free transmission mailbox.*/
+ switch (mailbox) {
+ case CAN_ANY_MAILBOX:
+ if ((DBGMCU->IDCODE >> 16) == 0x1001) {
+ /* real STM32 */
+ tmbp = &canp->can->sTxMailBox[(canp->can->TSR & CAN_TSR_CODE) >> 24];
+ } else {
+ int n;
+ /* GD32 */
+ if ((canp->can->TSR & CAN_TSR_TME0) == CAN_TSR_TME0)
+ n = 0;
+ else if ((canp->can->TSR & CAN_TSR_TME1) == CAN_TSR_TME1)
+ n = 1;
+ else if ((canp->can->TSR & CAN_TSR_TME2) == CAN_TSR_TME2)
+ n = 2;
+ else {
+ /* silence? */
+ return;
+ }
+ tmbp = &canp->can->sTxMailBox[n];
+ }
+ break;
+ case 1:
+ tmbp = &canp->can->sTxMailBox[0];
+ break;
+ case 2:
+ tmbp = &canp->can->sTxMailBox[1];
+ break;
+ case 3:
+ tmbp = &canp->can->sTxMailBox[2];
+ break;
+ default:
+ return;
+ }
+
+ /* Preparing the message.*/
+ if (ctfp->IDE)
+ tir = ((uint32_t)ctfp->EID << 3) | ((uint32_t)ctfp->RTR << 1) |
+ CAN_TI0R_IDE;
+ else
+ tir = ((uint32_t)ctfp->SID << 21) | ((uint32_t)ctfp->RTR << 1);
+ tmbp->TDTR = ctfp->DLC;
+ tmbp->TDLR = ctfp->data32[0];
+ tmbp->TDHR = ctfp->data32[1];
+ tmbp->TIR = tir | CAN_TI0R_TXRQ;
+}
+
+/**
+ * @brief Determines whether a frame has been received.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ *
+ * @return The queue space availability.
+ * @retval false no space in the transmit queue.
+ * @retval true transmit slot available.
+ *
+ * @notapi
+ */
+bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
+
+ switch (mailbox) {
+ case CAN_ANY_MAILBOX:
+ return ((canp->can->RF0R & CAN_RF0R_FMP0) != 0 ||
+ (canp->can->RF1R & CAN_RF1R_FMP1) != 0);
+ case 1:
+ return (canp->can->RF0R & CAN_RF0R_FMP0) != 0;
+ case 2:
+ return (canp->can->RF1R & CAN_RF1R_FMP1) != 0;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Receives a frame from the input queue.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ * @param[out] crfp pointer to the buffer where the CAN frame is copied
+ *
+ * @notapi
+ */
+void can_lld_receive(CANDriver *canp,
+ canmbx_t mailbox,
+ CANRxFrame *crfp) {
+ uint32_t rir, rdtr;
+
+ if (mailbox == CAN_ANY_MAILBOX) {
+ if ((canp->can->RF0R & CAN_RF0R_FMP0) != 0)
+ mailbox = 1;
+ else if ((canp->can->RF1R & CAN_RF1R_FMP1) != 0)
+ mailbox = 2;
+ else {
+ /* Should not happen, do nothing.*/
+ return;
+ }
+ }
+ switch (mailbox) {
+ case 1:
+ /* Fetches the message.*/
+ rir = canp->can->sFIFOMailBox[0].RIR;
+ rdtr = canp->can->sFIFOMailBox[0].RDTR;
+ crfp->data32[0] = canp->can->sFIFOMailBox[0].RDLR;
+ crfp->data32[1] = canp->can->sFIFOMailBox[0].RDHR;
+
+ /* Releases the mailbox.*/
+ canp->can->RF0R = CAN_RF0R_RFOM0;
+
+ /* If the queue is empty re-enables the interrupt in order to generate
+ events again.*/
+ if ((canp->can->RF0R & CAN_RF0R_FMP0) == 0)
+ canp->can->IER |= CAN_IER_FMPIE0;
+ break;
+ case 2:
+ /* Fetches the message.*/
+ rir = canp->can->sFIFOMailBox[1].RIR;
+ rdtr = canp->can->sFIFOMailBox[1].RDTR;
+ crfp->data32[0] = canp->can->sFIFOMailBox[1].RDLR;
+ crfp->data32[1] = canp->can->sFIFOMailBox[1].RDHR;
+
+ /* Releases the mailbox.*/
+ canp->can->RF1R = CAN_RF1R_RFOM1;
+
+ /* If the queue is empty re-enables the interrupt in order to generate
+ events again.*/
+ if ((canp->can->RF1R & CAN_RF1R_FMP1) == 0)
+ canp->can->IER |= CAN_IER_FMPIE1;
+ break;
+ default:
+ /* Should not happen, do nothing.*/
+ return;
+ }
+
+ /* Decodes the various fields in the RX frame.*/
+ crfp->RTR = (rir & CAN_RI0R_RTR) >> 1;
+ crfp->IDE = (rir & CAN_RI0R_IDE) >> 2;
+ if (crfp->IDE)
+ crfp->EID = rir >> 3;
+ else
+ crfp->SID = rir >> 21;
+ crfp->DLC = rdtr & CAN_RDT0R_DLC;
+ crfp->FMI = (uint8_t)(rdtr >> 8);
+ crfp->TIME = (uint16_t)(rdtr >> 16);
+}
+
+/**
+ * @brief Tries to abort an ongoing transmission.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number
+ *
+ * @notapi
+ */
+void can_lld_abort(CANDriver *canp,
+ canmbx_t mailbox) {
+
+ canp->can->TSR = 128U << ((mailbox - 1U) * 8U);
+}
+
+#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
+/**
+ * @brief Enters the sleep mode.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_sleep(CANDriver *canp) {
+
+ canp->can->MCR |= CAN_MCR_SLEEP;
+}
+
+/**
+ * @brief Enforces leaving the sleep mode.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_wakeup(CANDriver *canp) {
+
+ canp->can->MCR &= ~CAN_MCR_SLEEP;
+}
+#endif /* CAN_USE_SLEEP_MODE */
+
+/**
+ * @brief Programs the filters.
+ * @note This is an STM32-specific API.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] can2sb number of the first filter assigned to CAN2
+ * @param[in] num number of entries in the filters array, if zero then
+ * a default filter is programmed
+ * @param[in] cfp pointer to the filters array, can be @p NULL if
+ * (num == 0)
+ *
+ * @api
+ */
+void canSTM32SetFilters(CANDriver *canp, uint32_t can2sb,
+ uint32_t num, const CANFilter *cfp) {
+
+#if STM32_CAN_USE_CAN2
+ osalDbgCheck((can2sb <= STM32_CAN_MAX_FILTERS) &&
+ (num <= STM32_CAN_MAX_FILTERS));
+#endif
+
+#if STM32_CAN_USE_CAN1
+ osalDbgAssert(CAND1.state == CAN_STOP, "invalid state");
+#endif
+#if STM32_CAN_USE_CAN2
+ osalDbgAssert(CAND2.state == CAN_STOP, "invalid state");
+#endif
+#if STM32_CAN_USE_CAN3
+ osalDbgAssert(CAND3.state == CAN_STOP, "invalid state");
+#endif
+
+#if STM32_CAN_USE_CAN1
+ if (canp == &CAND1) {
+ can_lld_set_filters(canp, can2sb, num, cfp);
+ }
+#endif
+#if STM32_CAN_USE_CAN3
+ if (canp == &CAND3) {
+ can_lld_set_filters(canp, can2sb, num, cfp);
+ }
+#endif
+}
+
+#endif /* HAL_USE_CAN */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
index e4eb6f6d2c..3235a228e7 100644
--- a/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
+++ b/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h
@@ -1,471 +1,471 @@
-/*
- 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 CANv1/hal_can_lld.h
- * @brief STM32 CAN subsystem low level driver header.
- *
- * @addtogroup CAN
- * @{
- */
-
-#ifndef HAL_CAN_LLD_H
-#define HAL_CAN_LLD_H
-
-#if HAL_USE_CAN || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*
- * The following macros from the ST header file are replaced with better
- * equivalents.
- */
-#undef CAN_BTR_BRP
-#undef CAN_BTR_TS1
-#undef CAN_BTR_TS2
-#undef CAN_BTR_SJW
-
-/**
- * @brief This switch defines whether the driver implementation supports
- * a low power switch mode with automatic an wakeup feature.
- */
-#define CAN_SUPPORTS_SLEEP TRUE
-
-/**
- * @brief This implementation supports three transmit mailboxes.
- */
-#define CAN_TX_MAILBOXES 3
-
-/**
- * @brief This implementation supports two receive mailboxes.
- */
-#define CAN_RX_MAILBOXES 2
-
-/**
- * @name CAN registers helper macros
- * @{
- */
-#define CAN_BTR_BRP(n) (n) /**< @brief BRP field macro.*/
-#define CAN_BTR_TS1(n) ((n) << 16) /**< @brief TS1 field macro.*/
-#define CAN_BTR_TS2(n) ((n) << 20) /**< @brief TS2 field macro.*/
-#define CAN_BTR_SJW(n) ((n) << 24) /**< @brief SJW field macro.*/
-
-#define CAN_IDE_STD 0 /**< @brief Standard id. */
-#define CAN_IDE_EXT 1 /**< @brief Extended id. */
-
-#define CAN_RTR_DATA 0 /**< @brief Data frame. */
-#define CAN_RTR_REMOTE 1 /**< @brief Remote frame. */
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief CAN pedantic errors report.
- * @details Use of this option is IRQ-intensive.
- */
-#if !defined(STM32_CAN_REPORT_ALL_ERRORS) || defined(__DOXYGEN__)
-#define STM32_CAN_REPORT_ALL_ERRORS FALSE
-#endif
-
-/**
- * @brief CAN1 driver enable switch.
- * @details If set to @p TRUE the support for CAN1 is included.
- */
-#if !defined(STM32_CAN_USE_CAN1) || defined(__DOXYGEN__)
-#define STM32_CAN_USE_CAN1 FALSE
-#endif
-
-/**
- * @brief CAN2 driver enable switch.
- * @details If set to @p TRUE the support for CAN2 is included.
- */
-#if !defined(STM32_CAN_USE_CAN2) || defined(__DOXYGEN__)
-#define STM32_CAN_USE_CAN2 FALSE
-#endif
-
-/**
- * @brief CAN3 driver enable switch.
- * @details If set to @p TRUE the support for CAN3 is included.
- */
-#if !defined(STM32_CAN_USE_CAN3) || defined(__DOXYGEN__)
-#define STM32_CAN_USE_CAN3 FALSE
-#endif
-
-/**
- * @brief CAN1 interrupt priority level setting.
- */
-#if !defined(STM32_CAN_CAN1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CAN_CAN1_IRQ_PRIORITY 11
-#endif
-/** @} */
-
-/**
- * @brief CAN2 interrupt priority level setting.
- */
-#if !defined(STM32_CAN_CAN2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CAN_CAN2_IRQ_PRIORITY 11
-#endif
-/** @} */
-
-/**
- * @brief CAN3 interrupt priority level setting.
- */
-#if !defined(STM32_CAN_CAN3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CAN_CAN3_IRQ_PRIORITY 11
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_CAN1)
-#error "STM32_HAS_CAN1 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_CAN2)
-#error "STM32_HAS_CAN2 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_CAN3)
-#error "STM32_HAS_CAN3 not defined in registry"
-#endif
-
-#if (STM32_HAS_CAN1 | STM32_HAS_CAN2) && !defined(STM32_CAN_MAX_FILTERS)
-#error "STM32_CAN_MAX_FILTERS not defined in registry"
-#endif
-
-#if STM32_HAS_CAN3 && !defined(STM32_CAN3_MAX_FILTERS)
-#error "STM32_CAN3_MAX_FILTERS not defined in registry"
-#endif
-
-#if STM32_CAN_USE_CAN1 && !STM32_HAS_CAN1
-#error "CAN1 not present in the selected device"
-#endif
-
-#if STM32_CAN_USE_CAN2 && !STM32_HAS_CAN2
-#error "CAN2 not present in the selected device"
-#endif
-
-#if STM32_CAN_USE_CAN3 && !STM32_HAS_CAN3
-#error "CAN2 not present in the selected device"
-#endif
-
-#if !STM32_CAN_USE_CAN1 && !STM32_CAN_USE_CAN2 && !STM32_CAN_USE_CAN3
-#error "CAN driver activated but no CAN peripheral assigned"
-#endif
-
-#if !STM32_CAN_USE_CAN1 && STM32_CAN_USE_CAN2
-#error "CAN2 requires CAN1, it cannot operate independently"
-#endif
-
-#if CAN_USE_SLEEP_MODE && !CAN_SUPPORTS_SLEEP
-#error "CAN sleep mode not supported in this architecture"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a structure representing an CAN driver.
- */
-typedef struct CANDriver CANDriver;
-
-/**
- * @brief Type of a transmission mailbox index.
- */
-typedef uint32_t canmbx_t;
-
-#if (CAN_ENFORCE_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a CAN notification callback.
- *
- * @param[in] canp pointer to the @p CANDriver object triggering the
- * callback
- * @param[in] flags flags associated to the mailbox callback
- */
-typedef void (*can_callback_t)(CANDriver *canp, uint32_t flags);
-#endif
-
-/**
- * @brief CAN transmission frame.
- * @note Accessing the frame data as word16 or word32 is not portable because
- * machine data endianness, it can be still useful for a quick filling.
- */
-typedef struct {
- struct {
- uint8_t DLC:4; /**< @brief Data length. */
- uint8_t RTR:1; /**< @brief Frame type. */
- uint8_t IDE:1; /**< @brief Identifier type. */
- };
- union {
- struct {
- uint32_t SID:11; /**< @brief Standard identifier.*/
- };
- struct {
- uint32_t EID:29; /**< @brief Extended identifier.*/
- };
- };
- union {
- uint8_t data8[8]; /**< @brief Frame data. */
- uint16_t data16[4]; /**< @brief Frame data. */
- uint32_t data32[2]; /**< @brief Frame data. */
- uint64_t data64[1]; /**< @brief Frame data. */
- };
-} CANTxFrame;
-
-/**
- * @brief CAN received frame.
- * @note Accessing the frame data as word16 or word32 is not portable because
- * machine data endianness, it can be still useful for a quick filling.
- */
-typedef struct {
- struct {
- uint8_t FMI; /**< @brief Filter id. */
- uint16_t TIME; /**< @brief Time stamp. */
- };
- struct {
- uint8_t DLC:4; /**< @brief Data length. */
- uint8_t RTR:1; /**< @brief Frame type. */
- uint8_t IDE:1; /**< @brief Identifier type. */
- };
- union {
- struct {
- uint32_t SID:11; /**< @brief Standard identifier.*/
- };
- struct {
- uint32_t EID:29; /**< @brief Extended identifier.*/
- };
- };
- union {
- uint8_t data8[8]; /**< @brief Frame data. */
- uint16_t data16[4]; /**< @brief Frame data. */
- uint32_t data32[2]; /**< @brief Frame data. */
- uint64_t data64[1]; /**< @brief Frame data. */
- };
-} CANRxFrame;
-
-/**
- * @brief CAN filter.
- * @note Refer to the STM32 reference manual for info about filters.
- */
-typedef struct {
- /**
- * @brief Number of the filter bank to be programmed.
- */
- uint32_t filter:16;
- /**
- * @brief Filter mode.
- * @note This bit represent the CAN_FM1R register bit associated to this
- * filter (0=mask mode, 1=list mode).
- */
- uint32_t mode:1;
- /**
- * @brief Filter scale.
- * @note This bit represent the CAN_FS1R register bit associated to this
- * filter (0=16 bits mode, 1=32 bits mode).
- */
- uint32_t scale:1;
- /**
- * @brief Filter mode.
- * @note This bit represent the CAN_FFA1R register bit associated to this
- * filter, must be set to zero in this version of the driver.
- */
- uint32_t assignment:1;
- /**
- * @brief Filter register 1 (identifier).
- */
- uint32_t register1;
- /**
- * @brief Filter register 2 (mask/identifier depending on mode=0/1).
- */
- uint32_t register2;
-} CANFilter;
-
-/**
- * @brief Driver configuration structure.
- */
-typedef struct {
- /**
- * @brief CAN MCR register initialization data.
- * @note Some bits in this register are enforced by the driver regardless
- * their status in this field.
- */
- uint32_t mcr;
- /**
- * @brief CAN BTR register initialization data.
- * @note Some bits in this register are enforced by the driver regardless
- * their status in this field.
- */
- uint32_t btr;
-} CANConfig;
-
-/**
- * @brief Structure representing an CAN driver.
- */
-struct CANDriver {
- /**
- * @brief Driver state.
- */
- canstate_t state;
- /**
- * @brief Current configuration data.
- */
- const CANConfig *config;
- /**
- * @brief Transmission threads queue.
- */
- threads_queue_t txqueue;
- /**
- * @brief Receive threads queue.
- */
- threads_queue_t rxqueue;
-#if (CAN_ENFORCE_USE_CALLBACKS == FALSE) || defined(__DOXYGEN__)
- /**
- * @brief One or more frames become available.
- * @note After broadcasting this event it will not be broadcasted again
- * until the received frames queue has been completely emptied. It
- * is not broadcasted for each received frame. It is
- * responsibility of the application to empty the queue by
- * repeatedly invoking @p canReceive() when listening to this event.
- * This behavior minimizes the interrupt served by the system
- * because CAN traffic.
- * @note The flags associated to the listeners will indicate which
- * receive mailboxes become non-empty.
- */
- event_source_t rxfull_event;
- /**
- * @brief One or more transmission mailbox become available.
- * @note The flags associated to the listeners will indicate which
- * transmit mailboxes become empty.
- * @note The upper 16 bits are transmission error flags associated
- * to the transmit mailboxes.
- */
- event_source_t txempty_event;
- /**
- * @brief A CAN bus error happened.
- * @note The flags associated to the listeners will indicate that
- * receive error(s) have occurred.
- * @note In this implementation the upper 16 bits are filled with the
- * unprocessed content of the ESR register.
- */
- event_source_t error_event;
-#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
- /**
- * @brief Entering sleep state event.
- */
- event_source_t sleep_event;
- /**
- * @brief Exiting sleep state event.
- */
- event_source_t wakeup_event;
-#endif /* CAN_USE_SLEEP_MODE */
-#else /* CAN_ENFORCE_USE_CALLBACKS == TRUE */
- /**
- * @brief One or more frames become available.
- * @note After calling this function it will not be called again
- * until the received frames queue has been completely emptied. It
- * is not called for each received frame. It is
- * responsibility of the application to empty the queue by
- * repeatedly invoking @p chTryReceiveI().
- * This behavior minimizes the interrupt served by the system
- * because CAN traffic.
- */
- can_callback_t rxfull_cb;
- /**
- * @brief One or more transmission mailbox become available.
- * @note The flags associated to the callback will indicate which
- * transmit mailboxes become empty.
- */
- can_callback_t txempty_cb;
- /**
- * @brief A CAN bus error happened.
- */
- can_callback_t error_cb;
-#if (CAN_USE_SLEEP_MODE == TRUE) || defined (__DOXYGEN__)
- /**
- * @brief Exiting sleep state.
- */
- can_callback_t wakeup_cb;
-#endif
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the CAN registers.
- */
- CAN_TypeDef *can;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_CAN_USE_CAN1 && !defined(__DOXYGEN__)
-extern CANDriver CAND1;
-#endif
-
-#if STM32_CAN_USE_CAN2 && !defined(__DOXYGEN__)
-extern CANDriver CAND2;
-#endif
-
-#if STM32_CAN_USE_CAN3 && !defined(__DOXYGEN__)
-extern CANDriver CAND3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void can_lld_init(void);
- void can_lld_start(CANDriver *canp);
- void can_lld_stop(CANDriver *canp);
- bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox);
- void can_lld_transmit(CANDriver *canp,
- canmbx_t mailbox,
- const CANTxFrame *crfp);
- bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox);
- void can_lld_receive(CANDriver *canp,
- canmbx_t mailbox,
- CANRxFrame *ctfp);
- void can_lld_abort(CANDriver *canp,
- canmbx_t mailbox);
-#if CAN_USE_SLEEP_MODE
- void can_lld_sleep(CANDriver *canp);
- void can_lld_wakeup(CANDriver *canp);
-#endif /* CAN_USE_SLEEP_MODE */
- void canSTM32SetFilters(CANDriver *canp, uint32_t can2sb,
- uint32_t num, const CANFilter *cfp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_CAN */
-
-#endif /* HAL_CAN_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 CANv1/hal_can_lld.h
+ * @brief STM32 CAN subsystem low level driver header.
+ *
+ * @addtogroup CAN
+ * @{
+ */
+
+#ifndef HAL_CAN_LLD_H
+#define HAL_CAN_LLD_H
+
+#if HAL_USE_CAN || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*
+ * The following macros from the ST header file are replaced with better
+ * equivalents.
+ */
+#undef CAN_BTR_BRP
+#undef CAN_BTR_TS1
+#undef CAN_BTR_TS2
+#undef CAN_BTR_SJW
+
+/**
+ * @brief This switch defines whether the driver implementation supports
+ * a low power switch mode with automatic an wakeup feature.
+ */
+#define CAN_SUPPORTS_SLEEP TRUE
+
+/**
+ * @brief This implementation supports three transmit mailboxes.
+ */
+#define CAN_TX_MAILBOXES 3
+
+/**
+ * @brief This implementation supports two receive mailboxes.
+ */
+#define CAN_RX_MAILBOXES 2
+
+/**
+ * @name CAN registers helper macros
+ * @{
+ */
+#define CAN_BTR_BRP(n) (n) /**< @brief BRP field macro.*/
+#define CAN_BTR_TS1(n) ((n) << 16) /**< @brief TS1 field macro.*/
+#define CAN_BTR_TS2(n) ((n) << 20) /**< @brief TS2 field macro.*/
+#define CAN_BTR_SJW(n) ((n) << 24) /**< @brief SJW field macro.*/
+
+#define CAN_IDE_STD 0 /**< @brief Standard id. */
+#define CAN_IDE_EXT 1 /**< @brief Extended id. */
+
+#define CAN_RTR_DATA 0 /**< @brief Data frame. */
+#define CAN_RTR_REMOTE 1 /**< @brief Remote frame. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief CAN pedantic errors report.
+ * @details Use of this option is IRQ-intensive.
+ */
+#if !defined(STM32_CAN_REPORT_ALL_ERRORS) || defined(__DOXYGEN__)
+#define STM32_CAN_REPORT_ALL_ERRORS FALSE
+#endif
+
+/**
+ * @brief CAN1 driver enable switch.
+ * @details If set to @p TRUE the support for CAN1 is included.
+ */
+#if !defined(STM32_CAN_USE_CAN1) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_CAN1 FALSE
+#endif
+
+/**
+ * @brief CAN2 driver enable switch.
+ * @details If set to @p TRUE the support for CAN2 is included.
+ */
+#if !defined(STM32_CAN_USE_CAN2) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_CAN2 FALSE
+#endif
+
+/**
+ * @brief CAN3 driver enable switch.
+ * @details If set to @p TRUE the support for CAN3 is included.
+ */
+#if !defined(STM32_CAN_USE_CAN3) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_CAN3 FALSE
+#endif
+
+/**
+ * @brief CAN1 interrupt priority level setting.
+ */
+#if !defined(STM32_CAN_CAN1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CAN_CAN1_IRQ_PRIORITY 11
+#endif
+/** @} */
+
+/**
+ * @brief CAN2 interrupt priority level setting.
+ */
+#if !defined(STM32_CAN_CAN2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CAN_CAN2_IRQ_PRIORITY 11
+#endif
+/** @} */
+
+/**
+ * @brief CAN3 interrupt priority level setting.
+ */
+#if !defined(STM32_CAN_CAN3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CAN_CAN3_IRQ_PRIORITY 11
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_CAN1)
+#error "STM32_HAS_CAN1 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_CAN2)
+#error "STM32_HAS_CAN2 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_CAN3)
+#error "STM32_HAS_CAN3 not defined in registry"
+#endif
+
+#if (STM32_HAS_CAN1 | STM32_HAS_CAN2) && !defined(STM32_CAN_MAX_FILTERS)
+#error "STM32_CAN_MAX_FILTERS not defined in registry"
+#endif
+
+#if STM32_HAS_CAN3 && !defined(STM32_CAN3_MAX_FILTERS)
+#error "STM32_CAN3_MAX_FILTERS not defined in registry"
+#endif
+
+#if STM32_CAN_USE_CAN1 && !STM32_HAS_CAN1
+#error "CAN1 not present in the selected device"
+#endif
+
+#if STM32_CAN_USE_CAN2 && !STM32_HAS_CAN2
+#error "CAN2 not present in the selected device"
+#endif
+
+#if STM32_CAN_USE_CAN3 && !STM32_HAS_CAN3
+#error "CAN2 not present in the selected device"
+#endif
+
+#if !STM32_CAN_USE_CAN1 && !STM32_CAN_USE_CAN2 && !STM32_CAN_USE_CAN3
+#error "CAN driver activated but no CAN peripheral assigned"
+#endif
+
+#if !STM32_CAN_USE_CAN1 && STM32_CAN_USE_CAN2
+#error "CAN2 requires CAN1, it cannot operate independently"
+#endif
+
+#if CAN_USE_SLEEP_MODE && !CAN_SUPPORTS_SLEEP
+#error "CAN sleep mode not supported in this architecture"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a structure representing an CAN driver.
+ */
+typedef struct CANDriver CANDriver;
+
+/**
+ * @brief Type of a transmission mailbox index.
+ */
+typedef uint32_t canmbx_t;
+
+#if (CAN_ENFORCE_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a CAN notification callback.
+ *
+ * @param[in] canp pointer to the @p CANDriver object triggering the
+ * callback
+ * @param[in] flags flags associated to the mailbox callback
+ */
+typedef void (*can_callback_t)(CANDriver *canp, uint32_t flags);
+#endif
+
+/**
+ * @brief CAN transmission frame.
+ * @note Accessing the frame data as word16 or word32 is not portable because
+ * machine data endianness, it can be still useful for a quick filling.
+ */
+typedef struct {
+ struct {
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
+ };
+ union {
+ struct {
+ uint32_t SID:11; /**< @brief Standard identifier.*/
+ };
+ struct {
+ uint32_t EID:29; /**< @brief Extended identifier.*/
+ };
+ };
+ union {
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
+ uint64_t data64[1]; /**< @brief Frame data. */
+ };
+} CANTxFrame;
+
+/**
+ * @brief CAN received frame.
+ * @note Accessing the frame data as word16 or word32 is not portable because
+ * machine data endianness, it can be still useful for a quick filling.
+ */
+typedef struct {
+ struct {
+ uint8_t FMI; /**< @brief Filter id. */
+ uint16_t TIME; /**< @brief Time stamp. */
+ };
+ struct {
+ uint8_t DLC:4; /**< @brief Data length. */
+ uint8_t RTR:1; /**< @brief Frame type. */
+ uint8_t IDE:1; /**< @brief Identifier type. */
+ };
+ union {
+ struct {
+ uint32_t SID:11; /**< @brief Standard identifier.*/
+ };
+ struct {
+ uint32_t EID:29; /**< @brief Extended identifier.*/
+ };
+ };
+ union {
+ uint8_t data8[8]; /**< @brief Frame data. */
+ uint16_t data16[4]; /**< @brief Frame data. */
+ uint32_t data32[2]; /**< @brief Frame data. */
+ uint64_t data64[1]; /**< @brief Frame data. */
+ };
+} CANRxFrame;
+
+/**
+ * @brief CAN filter.
+ * @note Refer to the STM32 reference manual for info about filters.
+ */
+typedef struct {
+ /**
+ * @brief Number of the filter bank to be programmed.
+ */
+ uint32_t filter:16;
+ /**
+ * @brief Filter mode.
+ * @note This bit represent the CAN_FM1R register bit associated to this
+ * filter (0=mask mode, 1=list mode).
+ */
+ uint32_t mode:1;
+ /**
+ * @brief Filter scale.
+ * @note This bit represent the CAN_FS1R register bit associated to this
+ * filter (0=16 bits mode, 1=32 bits mode).
+ */
+ uint32_t scale:1;
+ /**
+ * @brief Filter mode.
+ * @note This bit represent the CAN_FFA1R register bit associated to this
+ * filter, must be set to zero in this version of the driver.
+ */
+ uint32_t assignment:1;
+ /**
+ * @brief Filter register 1 (identifier).
+ */
+ uint32_t register1;
+ /**
+ * @brief Filter register 2 (mask/identifier depending on mode=0/1).
+ */
+ uint32_t register2;
+} CANFilter;
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief CAN MCR register initialization data.
+ * @note Some bits in this register are enforced by the driver regardless
+ * their status in this field.
+ */
+ uint32_t mcr;
+ /**
+ * @brief CAN BTR register initialization data.
+ * @note Some bits in this register are enforced by the driver regardless
+ * their status in this field.
+ */
+ uint32_t btr;
+} CANConfig;
+
+/**
+ * @brief Structure representing an CAN driver.
+ */
+struct CANDriver {
+ /**
+ * @brief Driver state.
+ */
+ canstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const CANConfig *config;
+ /**
+ * @brief Transmission threads queue.
+ */
+ threads_queue_t txqueue;
+ /**
+ * @brief Receive threads queue.
+ */
+ threads_queue_t rxqueue;
+#if (CAN_ENFORCE_USE_CALLBACKS == FALSE) || defined(__DOXYGEN__)
+ /**
+ * @brief One or more frames become available.
+ * @note After broadcasting this event it will not be broadcasted again
+ * until the received frames queue has been completely emptied. It
+ * is not broadcasted for each received frame. It is
+ * responsibility of the application to empty the queue by
+ * repeatedly invoking @p canReceive() when listening to this event.
+ * This behavior minimizes the interrupt served by the system
+ * because CAN traffic.
+ * @note The flags associated to the listeners will indicate which
+ * receive mailboxes become non-empty.
+ */
+ event_source_t rxfull_event;
+ /**
+ * @brief One or more transmission mailbox become available.
+ * @note The flags associated to the listeners will indicate which
+ * transmit mailboxes become empty.
+ * @note The upper 16 bits are transmission error flags associated
+ * to the transmit mailboxes.
+ */
+ event_source_t txempty_event;
+ /**
+ * @brief A CAN bus error happened.
+ * @note The flags associated to the listeners will indicate that
+ * receive error(s) have occurred.
+ * @note In this implementation the upper 16 bits are filled with the
+ * unprocessed content of the ESR register.
+ */
+ event_source_t error_event;
+#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
+ /**
+ * @brief Entering sleep state event.
+ */
+ event_source_t sleep_event;
+ /**
+ * @brief Exiting sleep state event.
+ */
+ event_source_t wakeup_event;
+#endif /* CAN_USE_SLEEP_MODE */
+#else /* CAN_ENFORCE_USE_CALLBACKS == TRUE */
+ /**
+ * @brief One or more frames become available.
+ * @note After calling this function it will not be called again
+ * until the received frames queue has been completely emptied. It
+ * is not called for each received frame. It is
+ * responsibility of the application to empty the queue by
+ * repeatedly invoking @p chTryReceiveI().
+ * This behavior minimizes the interrupt served by the system
+ * because CAN traffic.
+ */
+ can_callback_t rxfull_cb;
+ /**
+ * @brief One or more transmission mailbox become available.
+ * @note The flags associated to the callback will indicate which
+ * transmit mailboxes become empty.
+ */
+ can_callback_t txempty_cb;
+ /**
+ * @brief A CAN bus error happened.
+ */
+ can_callback_t error_cb;
+#if (CAN_USE_SLEEP_MODE == TRUE) || defined (__DOXYGEN__)
+ /**
+ * @brief Exiting sleep state.
+ */
+ can_callback_t wakeup_cb;
+#endif
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the CAN registers.
+ */
+ CAN_TypeDef *can;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_CAN_USE_CAN1 && !defined(__DOXYGEN__)
+extern CANDriver CAND1;
+#endif
+
+#if STM32_CAN_USE_CAN2 && !defined(__DOXYGEN__)
+extern CANDriver CAND2;
+#endif
+
+#if STM32_CAN_USE_CAN3 && !defined(__DOXYGEN__)
+extern CANDriver CAND3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void can_lld_init(void);
+ void can_lld_start(CANDriver *canp);
+ void can_lld_stop(CANDriver *canp);
+ bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox);
+ void can_lld_transmit(CANDriver *canp,
+ canmbx_t mailbox,
+ const CANTxFrame *crfp);
+ bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox);
+ void can_lld_receive(CANDriver *canp,
+ canmbx_t mailbox,
+ CANRxFrame *ctfp);
+ void can_lld_abort(CANDriver *canp,
+ canmbx_t mailbox);
+#if CAN_USE_SLEEP_MODE
+ void can_lld_sleep(CANDriver *canp);
+ void can_lld_wakeup(CANDriver *canp);
+#endif /* CAN_USE_SLEEP_MODE */
+ void canSTM32SetFilters(CANDriver *canp, uint32_t can2sb,
+ uint32_t num, const CANFilter *cfp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_CAN */
+
+#endif /* HAL_CAN_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/CRYPv1/driver.mk b/os/hal/ports/STM32/LLD/CRYPv1/driver.mk
index 43936d3e30..8774b92077 100644
--- a/os/hal/ports/STM32/LLD/CRYPv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/CRYPv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_CRY TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_CRY TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/CRYPv1
diff --git a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
index 1d83e199bb..dab504d72d 100644
--- a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
+++ b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c
@@ -1,1901 +1,1901 @@
-/*
- 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 CRYPv1/hal_crypto_lld.c
- * @brief STM32 cryptographic subsystem low level driver source.
- *
- * @addtogroup CRYPTO
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define CRYP1_IN_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_CRY_CRYP1_IN_DMA_STREAM, \
- STM32_CRYP1_IN_DMA_CHN)
-
-#define CRYP1_OUT_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_CRY_CRYP1_OUT_DMA_STREAM, \
- STM32_CRYP1_OUT_DMA_CHN)
-
-#define HASH1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_CRY_HASH1_DMA_STREAM, \
- STM32_HASH1_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief CRY1 driver identifier.*/
-#if (STM32_CRY_ENABLED1 == TRUE) || defined(__DOXYGEN__)
-CRYDriver CRYD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#if (STM32_CRY_USE_CRYP1 == TRUE) || defined (__DOXYGEN__)
-/**
- * @brief Setting AES key for encryption.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] algomode algorithm mode field of CR register
- */
-static inline void cryp_set_key_encrypt(CRYDriver *cryp, uint32_t algomode) {
- uint32_t cr;
-
- /* Loading key data.*/
- CRYP->K0LR = cryp->cryp_k[0];
- CRYP->K0RR = cryp->cryp_k[1];
- CRYP->K1LR = cryp->cryp_k[2];
- CRYP->K1RR = cryp->cryp_k[3];
- CRYP->K2LR = cryp->cryp_k[4];
- CRYP->K2RR = cryp->cryp_k[5];
- CRYP->K3LR = cryp->cryp_k[6];
- CRYP->K3RR = cryp->cryp_k[7];
-
- /* Setting up then starting operation.*/
- cr = CRYP->CR;
- cr &= ~(CRYP_CR_KEYSIZE_Msk | CRYP_CR_ALGOMODE_Msk | CRYP_CR_ALGODIR_Msk);
- cr |= cryp->cryp_ksize | algomode | CRYP_CR_CRYPEN;
- CRYP->CR = cr;
-
- cryp->cryp_ktype = cryp_key_aes_encrypt;
-}
-
-/**
- * @brief Setting AES key for decryption.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] algomode algorithm field of CR register
- */
-static inline void cryp_set_key_decrypt(CRYDriver *cryp, uint32_t algomode) {
- uint32_t cr;
-
- /* Loading key data then doing transformation for decrypt.*/
- cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_KEY);
- while ((CRYP->CR & CRYP_CR_CRYPEN) != 0U) {
- }
-
- /* Setting up then starting operation.*/
- cr = CRYP->CR;
- cr &= ~(CRYP_CR_KEYSIZE_Msk | CRYP_CR_ALGOMODE_Msk | CRYP_CR_ALGODIR_Msk);
- cr |= cryp->cryp_ksize | algomode | CRYP_CR_ALGODIR | CRYP_CR_CRYPEN;
- CRYP->CR = cr;
-
- cryp->cryp_ktype = cryp_key_aes_decrypt;
-}
-
-/**
- * @brief Setting IV.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] iv 128 bits initial vector
- */
-static inline void cryp_set_iv(CRYDriver *cryp, const uint8_t *iv) {
-
- (void)cryp;
-
- CRYP->IV0LR = __REV(__UNALIGNED_UINT32_READ(&iv[0]));
- CRYP->IV0RR = __REV(__UNALIGNED_UINT32_READ(&iv[4]));
- CRYP->IV1LR = __REV(__UNALIGNED_UINT32_READ(&iv[8]));
- CRYP->IV1RR = __REV(__UNALIGNED_UINT32_READ(&iv[12]));
-}
-
-/**
- * @brief Performs a CRYP operation using DMA.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] size size of both buffers, this number must be a
- * multiple of 16
- * @param[in] in input buffer
- * @param[out] out output buffer
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- */
-static cryerror_t cryp_do_transfer(CRYDriver *cryp,
- size_t size,
- const uint8_t *in,
- uint8_t *out) {
- uint32_t szw;
-
- szw = (uint32_t)(size / sizeof (uint32_t));
-#if STM32_CRY_CRYP_SIZE_THRESHOLD > 1
- if (size >= STM32_CRY_CRYP_SIZE_THRESHOLD)
-#endif
-#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
- {
- /* DMA limitation.*/
- osalDbgCheck(size < 0x10000U * 4U);
-
- osalSysLock();
-
- /* Preparing DMAs.*/
- dmaStreamSetTransactionSize(cryp->cryp_dma_in, szw);
- dmaStreamSetTransactionSize(cryp->cryp_dma_out, szw);
- dmaStreamSetMemory0(cryp->cryp_dma_in, in);
- dmaStreamSetMemory0(cryp->cryp_dma_out, out);
- dmaStreamEnable(cryp->cryp_dma_in);
- dmaStreamEnable(cryp->cryp_dma_out);
-
- (void) osalThreadSuspendS(&cryp->cryp_tr);
-
- osalSysUnlock();
- }
-#endif
-#if STM32_CRY_CRYP_SIZE_THRESHOLD > 1
- else
-#endif
-#if STM32_CRY_CRYP_SIZE_THRESHOLD != 1
- {
- uint32_t nr, nw;
-
- nr = 0U;
- nw = 0U;
- while (nw < szw) {
-
- if ((CRYP->SR & CRYP_SR_OFNE) != 0U) {
- __UNALIGNED_UINT32_WRITE(out, CRYP->DOUT);
- out += 4;
- nw++;
- continue; /* Priority to output FIFO.*/
- }
-
- if ((nr < szw) && ((CRYP->SR & CRYP_SR_IFNF) != 0U)) {
- CRYP->DR = __UNALIGNED_UINT32_READ(in);
- in += 4;
- nr++;
- }
- }
- }
-#endif
-
- /* Disabling unit.*/
- CRYP->CR &= ~CRYP_CR_CRYPEN;
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief CRYP-IN DMA ISR.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void cry_lld_serve_cryp_in_interrupt(CRYDriver *cryp, uint32_t flags) {
-
- (void)cryp;
-
- /* DMA errors handling.*/
-#if defined(STM32_CRY_CRYP_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
- STM32_CRY_CRYP_DMA_ERROR_HOOK(cryp);
- }
-#endif
-}
-
-/**
- * @brief CRYP-OUT DMA ISR.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void cry_lld_serve_cryp_out_interrupt(CRYDriver *cryp, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_CRY_CRYP_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
- STM32_CRY_CRYP_DMA_ERROR_HOOK(cryp);
- }
-#endif
-
- /* End buffer interrupt.*/
- if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
-
- /* Clearing flags of the other stream too.*/
- dmaStreamClearInterrupt(cryp->cryp_dma_in);
-
- /* Resuming waiting thread.*/
- osalSysLockFromISR();
- osalThreadResumeI(&cryp->cryp_tr, MSG_OK);
- osalSysUnlockFromISR();
- }
-}
-#endif
-
-#if (STM32_CRY_USE_HASH1 == TRUE) || defined (__DOXYGEN__)
-#if (STM32_CRY_HASH_SIZE_THRESHOLD != 0) || defined (__DOXYGEN__)
-/**
- * @brief HASH DMA ISR.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void cry_lld_serve_hash_interrupt(CRYDriver *cryp, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_HASH_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
- STM32_CRY_HASH_DMA_ERROR_HOOK(cryp);
- }
-#endif
-
- /* End buffer interrupt.*/
- if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
-
- /* Resuming waiting thread.*/
- osalSysLockFromISR();
- osalThreadResumeI(&cryp->hash_tr, MSG_OK);
- osalSysUnlockFromISR();
- }
-}
-#endif
-#endif
-
-/**
- * @brief Pushes a series of words into the hash engine.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] n the number of words to be pushed
- * @param[in] p pointer to the words buffer
- */
-static void cry_lld_hash_push(CRYDriver *cryp, uint32_t n, const uint32_t *p) {
-
- (void)cryp; /* Not touched in some cases, needs this.*/
-
- /* Data is processed in 32kB blocks because DMA size limitations.*/
- while (n > 0U) {
- uint32_t chunk = n > 0x8000U ? 0x8000U : n;
- n -= chunk;
-
-#if STM32_CRY_HASH_SIZE_THRESHOLD > 1
- if (chunk >= STM32_CRY_HASH_SIZE_THRESHOLD)
-#endif
-#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
- {
- /* Setting up transfer.*/
- dmaStreamSetTransactionSize(cryp->hash_dma, chunk);
- dmaStreamSetPeripheral(cryp->hash_dma, p);
- p += chunk;
-
- osalSysLock();
-
- /* Enabling DMA channel then HASH engine.*/
- dmaStreamEnable(cryp->hash_dma);
-
- /* Waiting for DMA operation completion.*/
- osalThreadSuspendS(&cryp->hash_tr);
-
- osalSysUnlock();
- }
-#endif
-#if STM32_CRY_HASH_SIZE_THRESHOLD > 1
- else
-#endif
-#if STM32_CRY_HASH_SIZE_THRESHOLD != 1
- {
- /* Small chunk, just pushing data without touching DMA.*/
- do {
- HASH->DIN = *p++;
- chunk--;
- } while (chunk > 0U);
- }
-#endif
- }
-
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level crypto driver initialization.
- *
- * @notapi
- */
-void cry_lld_init(void) {
-
-#if STM32_CRY_ENABLED1
- cryObjectInit(&CRYD1);
-
-#if STM32_CRY_USE_CRYP1
-#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
- CRYD1.cryp_tr = NULL;
- CRYD1.cryp_dma_in = NULL;
- CRYD1.cryp_dma_out = NULL;
-#endif
-#endif
-
-#if STM32_CRY_USE_HASH1
-#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
- CRYD1.hash_tr = NULL;
- CRYD1.hash_dma = NULL;
-#endif /* STM32_CRY_HASH_SIZE_THRESHOLD != 0 */
-#endif /* STM32_CRY_USE_HASH1 */
-
-#endif /* STM32_CRY_ENABLED1 */
-}
-
-/**
- * @brief Configures and activates the crypto peripheral.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- *
- * @notapi
- */
-void cry_lld_start(CRYDriver *cryp) {
-
- if (cryp->state == CRY_STOP) {
-
-#if STM32_CRY_ENABLED1
- if (&CRYD1 == cryp) {
-#if STM32_CRY_USE_CRYP1 == TRUE
-#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
- /* Allocating DMA channels.*/
- cryp->cryp_dma_in = dmaStreamAllocI(STM32_CRY_CRYP1_IN_DMA_STREAM,
- STM32_CRY_CRYP1_IRQ_PRIORITY,
- (stm32_dmaisr_t)cry_lld_serve_cryp_in_interrupt,
- (void *)cryp);
- osalDbgAssert(cryp->cryp_dma_in != NULL, "unable to allocate stream");
- cryp->cryp_dma_out = dmaStreamAllocI(STM32_CRY_CRYP1_OUT_DMA_STREAM,
- STM32_CRY_CRYP1_IRQ_PRIORITY,
- (stm32_dmaisr_t)cry_lld_serve_cryp_out_interrupt,
- (void *)cryp);
- osalDbgAssert(cryp->cryp_dma_out != NULL, "unable to allocate stream");
-
- /* Preparing the DMA channels.*/
- dmaStreamSetMode(cryp->cryp_dma_in,
- STM32_DMA_CR_CHSEL(CRYP1_IN_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_CRY_CRYP1_IN_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE);
- dmaStreamSetMode(cryp->cryp_dma_out,
- STM32_DMA_CR_CHSEL(CRYP1_OUT_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_CRY_CRYP1_OUT_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
- STM32_DMA_CR_TCIE);
- dmaStreamSetPeripheral(cryp->cryp_dma_in, &CRYP->DR);
- dmaStreamSetPeripheral(cryp->cryp_dma_out, &CRYP->DOUT);
- dmaStreamSetFIFO(cryp->cryp_dma_in, STM32_DMA_FCR_DMDIS);
- dmaStreamSetFIFO(cryp->cryp_dma_out, STM32_DMA_FCR_DMDIS);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(cryp->cryp_dma_in, STM32_DMAMUX1_CRYP_IN);
- dmaSetRequestSource(cryp->cryp_dma_out, STM32_DMAMUX1_CRYP_OUT);
-#endif
-#endif /* STM32_CRY_CRYP_SIZE_THRESHOLD != 0 */
- rccEnableCRYP(true);
-#endif /* STM32_CRY_USE_CRYP1 == TRUE */
-
-#if STM32_CRY_USE_HASH1 == TRUE
-#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
- cryp->hash_dma = dmaStreamAllocI(STM32_CRY_HASH1_DMA_STREAM,
- STM32_CRY_HASH1_IRQ_PRIORITY,
- (stm32_dmaisr_t)cry_lld_serve_hash_interrupt,
- (void *)cryp);
- osalDbgAssert(cryp->hash_dma != NULL, "unable to allocate stream");
-
- /* Preparing the DMA channel.*/
- dmaStreamSetMode(cryp->hash_dma,
- STM32_DMA_CR_CHSEL(HASH1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_CRY_HASH1_DMA_PRIORITY) |
- STM32_DMA_CR_PINC | STM32_DMA_CR_DIR_M2M |
- STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
- STM32_DMA_CR_TCIE);
- dmaStreamSetMemory0(cryp->hash_dma, &HASH->DIN);
- dmaStreamSetFIFO(cryp->hash_dma, STM32_DMA_FCR_DMDIS);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(cryp->hash_dma, STM32_DMAMUX1_HASH_IN);
-#endif
-#endif /* STM32_CRY_HASH_SIZE_THRESHOLD != 0 */
- rccEnableHASH(true);
-#endif /* STM32_CRY_USE_HASH1 == TRUE */
- }
-#endif
- }
-
- /* Resetting trasient key data.*/
- cryp->cryp_ktype = cryp_key_none;
- cryp->cryp_ksize = 0U;
- cryp->cryp_k[0] = 0U;
- cryp->cryp_k[1] = 0U;
- cryp->cryp_k[2] = 0U;
- cryp->cryp_k[3] = 0U;
- cryp->cryp_k[4] = 0U;
- cryp->cryp_k[5] = 0U;
- cryp->cryp_k[6] = 0U;
- cryp->cryp_k[7] = 0U;
-
-#if STM32_CRY_USE_CRYP1
- /* CRYP setup.*/
- CRYP->CR = CRYP_CR_DATATYPE_1;
- CRYP->DMACR = CRYP_DMACR_DIEN | CRYP_DMACR_DOEN;
-#endif
-
-#if STM32_CRY_USE_HASH1
- /* HASH setup and enable.*/
-#endif
-}
-
-/**
- * @brief Deactivates the crypto peripheral.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- *
- * @notapi
- */
-void cry_lld_stop(CRYDriver *cryp) {
-
- if (cryp->state == CRY_READY) {
-
- /* Resetting CRYP.*/
- CRYP->CR = 0U;
- CRYP->DMACR = 0U;
-
-#if STM32_CRY_ENABLED1
- if (&CRYD1 == cryp) {
-#if STM32_CRY_USE_CRYP1
-#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
- dmaStreamFreeI(cryp->cryp_dma_in);
- dmaStreamFreeI(cryp->cryp_dma_out);
- cryp->cryp_dma_in = NULL;
- cryp->cryp_dma_out = NULL;
-#endif
- rccDisableCRYP();
-#endif
-
-#if STM32_CRY_USE_HASH1
-#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
- dmaStreamFreeI(cryp->hash_dma);
- cryp->hash_dma = NULL;
-#endif
- rccDisableHASH();
-#endif
- }
-#endif
- }
-}
-
-#if (CRY_LLD_SUPPORTS_AES == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Initializes the AES transient key.
- * @note It is the underlying implementation to decide which key sizes are
- * allowable.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] size key size in bytes
- * @param[in] keyp pointer to the key data
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the algorithm is unsupported.
- * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid for
- * the specified algorithm.
- *
- * @notapi
- */
-cryerror_t cry_lld_aes_loadkey(CRYDriver *cryp,
- size_t size,
- const uint8_t *keyp) {
-
- /* Fetching key data.*/
- if (size == (size_t)32) {
- cryp->cryp_ksize = CRYP_CR_KEYSIZE_1;
- cryp->cryp_k[0] = __REV(__UNALIGNED_UINT32_READ(&keyp[0]));
- cryp->cryp_k[1] = __REV(__UNALIGNED_UINT32_READ(&keyp[4]));
- cryp->cryp_k[2] = __REV(__UNALIGNED_UINT32_READ(&keyp[8]));
- cryp->cryp_k[3] = __REV(__UNALIGNED_UINT32_READ(&keyp[12]));
- cryp->cryp_k[4] = __REV(__UNALIGNED_UINT32_READ(&keyp[16]));
- cryp->cryp_k[5] = __REV(__UNALIGNED_UINT32_READ(&keyp[20]));
- cryp->cryp_k[6] = __REV(__UNALIGNED_UINT32_READ(&keyp[24]));
- cryp->cryp_k[7] = __REV(__UNALIGNED_UINT32_READ(&keyp[28]));
- }
- else if (size == (size_t)24) {
- cryp->cryp_ksize = CRYP_CR_KEYSIZE_0;
- cryp->cryp_k[0] = 0U;
- cryp->cryp_k[1] = 0U;
- cryp->cryp_k[2] = __REV(__UNALIGNED_UINT32_READ(&keyp[8]));
- cryp->cryp_k[3] = __REV(__UNALIGNED_UINT32_READ(&keyp[12]));
- cryp->cryp_k[4] = __REV(__UNALIGNED_UINT32_READ(&keyp[16]));
- cryp->cryp_k[5] = __REV(__UNALIGNED_UINT32_READ(&keyp[20]));
- cryp->cryp_k[6] = __REV(__UNALIGNED_UINT32_READ(&keyp[24]));
- cryp->cryp_k[7] = __REV(__UNALIGNED_UINT32_READ(&keyp[28]));
- }
- else if (size == (size_t)16) {
- cryp->cryp_ksize = 0U;
- cryp->cryp_k[0] = 0U;
- cryp->cryp_k[1] = 0U;
- cryp->cryp_k[2] = 0U;
- cryp->cryp_k[3] = 0U;
- cryp->cryp_k[4] = __REV(__UNALIGNED_UINT32_READ(&keyp[16]));
- cryp->cryp_k[5] = __REV(__UNALIGNED_UINT32_READ(&keyp[20]));
- cryp->cryp_k[6] = __REV(__UNALIGNED_UINT32_READ(&keyp[24]));
- cryp->cryp_k[7] = __REV(__UNALIGNED_UINT32_READ(&keyp[28]));
- }
- else {
- return CRY_ERR_INV_KEY_SIZE;
- }
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief Encryption of a single block using AES.
- * @note The implementation of this function must guarantee that it can
- * be called from any context.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out) {
- unsigned i;
-
- /* Only key zero is supported.*/
- if (key_id != 0U) {
- return CRY_ERR_INV_KEY_ID;
- }
-
- /* Setting the stored key.*/
- if (cryp->cryp_ktype != cryp_key_aes_encrypt) {
- cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
- }
-
- /* Pushing the AES block in the FIFO, it is assumed to be empty.*/
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[0]);
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[4]);
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[8]);
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[12]);
-
- /* Reading the result.*/
- for (i = 0U; i < 4; i++, out += 4) {
- while ((CRYP->SR & CRYP_SR_OFNE) == 0U) {
- }
- __UNALIGNED_UINT32_WRITE(out, CRYP->DOUT);
- }
-
- /* Disabling unit.*/
- CRYP->CR &= ~CRYP_CR_CRYPEN;
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief Decryption of a single block using AES.
- * @note The implementation of this function must guarantee that it can
- * be called from any context.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] in buffer containing the input ciphertext
- * @param[out] out buffer for the output plaintext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out) {
- unsigned i;
-
- /* Only key zero is supported.*/
- if (key_id != 0U) {
- return CRY_ERR_INV_KEY_ID;
- }
-
- /* Setting the stored key.*/
- if (cryp->cryp_ktype != cryp_key_aes_decrypt) {
- cryp_set_key_decrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
- }
-
- /* Pushing the AES block in the FIFO, it is assumed to be empty.*/
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[0]);
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[4]);
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[8]);
- CRYP->DR = __UNALIGNED_UINT32_READ(&in[12]);
-
- /* Reading the result.*/
- for (i = 0U; i < 4; i++, out += 4) {
- while ((CRYP->SR & CRYP_SR_OFNE) == 0U) {
- }
- __UNALIGNED_UINT32_WRITE(out, CRYP->DOUT);
- }
-
- /* Disabling unit.*/
- CRYP->CR &= ~CRYP_CR_CRYPEN;
-
- return CRY_NOERROR;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using AES-ECB.
- * @note The function operates on data buffers whose length is a multiple
- * of an AES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers, this number must be a
- * multiple of 16
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out) {
-
- /* Only key zero is supported.*/
- if (key_id != 0U) {
- return CRY_ERR_INV_KEY_ID;
- }
-
- /* Setting the stored key.*/
- if (cryp->cryp_ktype != cryp_key_aes_encrypt) {
- cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
- }
-
- return cryp_do_transfer(cryp, size, in, out);
-}
-
-/**
- * @brief Decryption operation using AES-ECB.
- * @note The function operates on data buffers whose length is a multiple
- * of an AES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers, this number must be a
- * multiple of 16
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out) {
-
- /* Only key zero is supported.*/
- if (key_id != 0U) {
- return CRY_ERR_INV_KEY_ID;
- }
-
- /* Setting the stored key.*/
- if (cryp->cryp_ktype != cryp_key_aes_decrypt) {
- cryp_set_key_decrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
- }
-
- return cryp_do_transfer(cryp, size, in, out);
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using AES-CBC.
- * @note The function operates on data buffers whose length is a multiple
- * of an AES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers, this number must be a
- * multiple of 16
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @param[in] iv 128 bits initial vector
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- /* Only key zero is supported.*/
- if (key_id != 0U) {
- return CRY_ERR_INV_KEY_ID;
- }
-
- /* Setting the stored key and IV.*/
- cryp_set_iv(cryp, iv);
- if (cryp->cryp_ktype != cryp_key_aes_encrypt) {
- cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_CBC);
- }
-
- return cryp_do_transfer(cryp, size, in, out);
-}
-
-/**
- * @brief Decryption operation using AES-CBC.
- * @note The function operates on data buffers whose length is a multiple
- * of an AES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers, this number must be a
- * multiple of 16
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @param[in] iv 128 bits initial vector
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- /* Only key zero is supported.*/
- if (key_id != 0U) {
- return CRY_ERR_INV_KEY_ID;
- }
-
- /* Setting the stored key and IV.*/
- cryp_set_iv(cryp, iv);
- if (cryp->cryp_ktype != cryp_key_aes_decrypt) {
- cryp_set_key_decrypt(cryp, CRYP_CR_ALGOMODE_AES_CBC);
- }
-
- return cryp_do_transfer(cryp, size, in, out);
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using AES-CFB.
- * @note This is a stream cipher, there are no size restrictions.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @param[in] iv 128 bits initial vector
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Decryption operation using AES-CFB.
- * @note This is a stream cipher, there are no size restrictions.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @param[in] iv 128 bits initial vector
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using AES-CTR.
- * @note This is a stream cipher, there are no size restrictions.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @param[in] iv 128 bits initial vector + counter, it contains
- * a 96 bits IV and a 32 bits counter
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Decryption operation using AES-CTR.
- * @note This is a stream cipher, there are no size restrictions.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of both buffers
- * @param[in] in buffer containing the input ciphertext
- * @param[out] out buffer for the output plaintext
- * @param[in] iv 128 bits initial vector + counter, it contains
- * a 96 bits IV and a 32 bits counter
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_AES_GCM == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using AES-GCM.
- * @note This is a stream cipher, there are no size restrictions.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] auth_size size of the data buffer to be authenticated
- * @param[in] auth_in buffer containing the data to be authenticated
- * @param[in] text_size size of the text buffer
- * @param[in] text_in buffer containing the input plaintext
- * @param[out] text_out buffer for the output ciphertext
- * @param[in] iv 128 bits input vector
- * @param[in] tag_size size of the authentication tag, this number
- * must be between 1 and 16
- * @param[out] tag_out buffer for the generated authentication tag
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp,
- crykey_t key_id,
- size_t auth_size,
- const uint8_t *auth_in,
- size_t text_size,
- const uint8_t *text_in,
- uint8_t *text_out,
- const uint8_t *iv,
- size_t tag_size,
- uint8_t *tag_out) {
-
- (void)cryp;
- (void)key_id;
- (void)auth_size;
- (void)auth_in;
- (void)text_size;
- (void)text_in;
- (void)text_out;
- (void)iv;
- (void)tag_size;
- (void)tag_out;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Decryption operation using AES-GCM.
- * @note This is a stream cipher, there are no size restrictions.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] auth_size size of the data buffer to be authenticated
- * @param[in] auth_in buffer containing the data to be authenticated
- * @param[in] text_size size of the text buffer
- * @param[in] text_in buffer containing the input plaintext
- * @param[out] text_out buffer for the output ciphertext
- * @param[in] iv 128 bits input vector
- * @param[in] tag_size size of the authentication tag, this number
- * must be between 1 and 16
- * @param[in] tag_in buffer for the generated authentication tag
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_AUTH_FAILED authentication failed
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp,
- crykey_t key_id,
- size_t auth_size,
- const uint8_t *auth_in,
- size_t text_size,
- const uint8_t *text_in,
- uint8_t *text_out,
- const uint8_t *iv,
- size_t tag_size,
- const uint8_t *tag_in) {
-
- (void)cryp;
- (void)key_id;
- (void)auth_size;
- (void)auth_in;
- (void)text_size;
- (void)text_in;
- (void)text_out;
- (void)iv;
- (void)tag_size;
- (void)tag_in;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_DES == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Initializes the DES transient key.
- * @note It is the underlying implementation to decide which key sizes are
- * allowable.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] size key size in bytes
- * @param[in] keyp pointer to the key data
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the algorithm is unsupported.
- * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid for
- * the specified algorithm.
- *
- * @notapi
- */
-cryerror_t cry_lld_des_loadkey(CRYDriver *cryp,
- size_t size,
- const uint8_t *keyp) {
-
- (void)cryp;
- (void)size;
- (void)keyp;
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief Encryption of a single block using (T)DES.
- * @note The implementation of this function must guarantee that it can
- * be called from any context.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out) {
-
- (void)cryp;
- (void)key_id;
- (void)in;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Decryption of a single block using (T)DES.
- * @note The implementation of this function must guarantee that it can
- * be called from any context.
- *
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] in buffer containing the input ciphertext
- * @param[out] out buffer for the output plaintext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out) {
-
- (void)cryp;
- (void)key_id;
- (void)in;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_DES_ECB == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using (T)DES-ECB.
- * @note The function operates on data buffers whose length is a multiple
- * of an DES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of the plaintext buffer, this number must
- * be a multiple of 8
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Decryption operation using (T)DES-ECB.
- * @note The function operates on data buffers whose length is a multiple
- * of an DES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of the plaintext buffer, this number must
- * be a multiple of 8
- * @param[in] in buffer containing the input ciphertext
- * @param[out] out buffer for the output plaintext
- * @return T he operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_DES_CBC == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Encryption operation using (T)DES-CBC.
- * @note The function operates on data buffers whose length is a multiple
- * of an DES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of the plaintext buffer, this number must
- * be a multiple of 8
- * @param[in] in buffer containing the input plaintext
- * @param[out] out buffer for the output ciphertext
- * @param[in] iv 64 bits input vector
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Decryption operation using (T)DES-CBC.
- * @note The function operates on data buffers whose length is a multiple
- * of an DES block, this means that padding must be done by the
- * caller.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] key_id the key to be used for the operation, zero is
- * the transient key, other values are keys stored
- * in an unspecified way
- * @param[in] size size of the plaintext buffer, this number must
- * be a multiple of 8
- * @param[in] in buffer containing the input ciphertext
- * @param[out] out buffer for the output plaintext
- * @param[in] iv 64 bits input vector
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
- * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
- * or refers to an empty key slot.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv) {
-
- (void)cryp;
- (void)key_id;
- (void)size;
- (void)in;
- (void)out;
- (void)iv;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Hash initialization using SHA1.
- * @note Use of this algorithm is not recommended because proven weak.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[out] sha1ctxp pointer to a SHA1 context to be initialized
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA1_init(CRYDriver *cryp, SHA1Context *sha1ctxp) {
-
- (void)cryp;
- (void)sha1ctxp;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash update using SHA1.
- * @note Use of this algorithm is not recommended because proven weak.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] sha1ctxp pointer to a SHA1 context
- * @param[in] size size of input buffer
- * @param[in] in buffer containing the input text
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA1_update(CRYDriver *cryp, SHA1Context *sha1ctxp,
- size_t size, const uint8_t *in) {
-
- (void)cryp;
- (void)sha1ctxp;
- (void)size;
- (void)in;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash finalization using SHA1.
- * @note Use of this algorithm is not recommended because proven weak.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] sha1ctxp pointer to a SHA1 context
- * @param[out] out 160 bits output buffer
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA1_final(CRYDriver *cryp, SHA1Context *sha1ctxp,
- uint8_t *out) {
-
- (void)cryp;
- (void)sha1ctxp;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Hash initialization using SHA256.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[out] sha256ctxp pointer to a SHA256 context to be initialized
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp) {
-
- (void)cryp;
-
- /* Initializing context structure.*/
- sha256ctxp->last_data = 0U;
- sha256ctxp->last_size = 0U;
-
- /* Initializing operation.*/
- HASH->CR = /*HASH_CR_MDMAT |*/ HASH_CR_ALGO_1 | HASH_CR_ALGO_0 |
- HASH_CR_DATATYPE_1 | HASH_CR_INIT;
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief Hash update using SHA256.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] sha256ctxp pointer to a SHA256 context
- * @param[in] size size of input buffer
- * @param[in] in buffer containing the input text
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp,
- size_t size, const uint8_t *in) {
- const uint32_t *wp = (const uint32_t *)(const void *)in;
-
- /* This HW is unable to hash blocks that are not a multiple of 4 bytes
- except for the last block in the stream which is handled in the
- "final" function.*/
- if (sha256ctxp->last_size != 0U) {
- return CRY_ERR_OP_FAILURE;
- }
-
- /* Any unaligned data is deferred to the "final" function.*/
- sha256ctxp->last_size = 8U * (size % sizeof (uint32_t));
- if (sha256ctxp->last_size > 0U) {
- sha256ctxp->last_data = wp[size / sizeof (uint32_t)];
- }
-
- /* Pushing data.*/
- cry_lld_hash_push(cryp, (uint32_t)(size / sizeof (uint32_t)), wp);
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief Hash finalization using SHA256.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] sha256ctxp pointer to a SHA256 context
- * @param[out] out 256 bits output buffer
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA256_final(CRYDriver *cryp, SHA256Context *sha256ctxp,
- uint8_t *out) {
- uint32_t digest[8];
-
- (void)cryp;
-
- if (sha256ctxp->last_size > 0U) {
- HASH->DIN = sha256ctxp->last_data;
- }
-
- /* Triggering final calculation and wait for result.*/
- HASH->SR = 0U;
- HASH->STR = sha256ctxp->last_size;
- HASH->STR = sha256ctxp->last_size | HASH_STR_DCAL;
- while ((HASH->SR & HASH_SR_DCIS) == 0U) {
- }
-
- /* Reading digest.*/
- digest[0] = HASH_DIGEST->HR[0];
- digest[1] = HASH_DIGEST->HR[1];
- digest[2] = HASH_DIGEST->HR[2];
- digest[3] = HASH_DIGEST->HR[3];
- digest[4] = HASH_DIGEST->HR[4];
- digest[5] = HASH_DIGEST->HR[5];
- digest[6] = HASH_DIGEST->HR[6];
- digest[7] = HASH_DIGEST->HR[7];
- memcpy((void *)out, (const void *)digest, sizeof digest);
-
- return CRY_NOERROR;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Hash initialization using SHA512.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[out] sha512ctxp pointer to a SHA512 context to be initialized
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA512_init(CRYDriver *cryp, SHA512Context *sha512ctxp) {
-
- (void)cryp;
- (void)sha512ctxp;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash update using SHA512.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] sha512ctxp pointer to a SHA512 context
- * @param[in] size size of input buffer
- * @param[in] in buffer containing the input text
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA512_update(CRYDriver *cryp, SHA512Context *sha512ctxp,
- size_t size, const uint8_t *in) {
-
- (void)cryp;
- (void)sha512ctxp;
- (void)size;
- (void)in;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash finalization using SHA512.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] sha512ctxp pointer to a SHA512 context
- * @param[out] out 512 bits output buffer
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_SHA512_final(CRYDriver *cryp, SHA512Context *sha512ctxp,
- uint8_t *out) {
-
- (void)cryp;
- (void)sha512ctxp;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Initializes the HMAC transient key.
- * @note It is the underlying implementation to decide which key sizes are
- * allowable.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] size key size in bytes
- * @param[in] keyp pointer to the key data
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the algorithm is unsupported.
- * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid for
- * the specified algorithm.
- *
- * @notapi
- */
-cryerror_t cry_lld_hmac_loadkey(CRYDriver *cryp,
- size_t size,
- const uint8_t *keyp) {
-
- (void)cryp;
- (void)size;
- (void)keyp;
-
- return CRY_NOERROR;
-}
-
-/**
- * @brief Hash initialization using HMAC_SHA256.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[out] hmacsha256ctxp pointer to a HMAC_SHA256 context to be
- * initialized
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_HMACSHA256_init(CRYDriver *cryp,
- HMACSHA256Context *hmacsha256ctxp) {
-
- (void)cryp;
- (void)hmacsha256ctxp;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash update using HMAC.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] hmacsha256ctxp pointer to a HMAC_SHA256 context
- * @param[in] size size of input buffer
- * @param[in] in buffer containing the input text
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_HMACSHA256_update(CRYDriver *cryp,
- HMACSHA256Context *hmacsha256ctxp,
- size_t size,
- const uint8_t *in) {
-
- (void)cryp;
- (void)hmacsha256ctxp;
- (void)size;
- (void)in;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash finalization using HMAC.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] hmacsha256ctxp pointer to a HMAC_SHA256 context
- * @param[out] out 256 bits output buffer
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_HMACSHA256_final(CRYDriver *cryp,
- HMACSHA256Context *hmacsha256ctxp,
- uint8_t *out) {
-
- (void)cryp;
- (void)hmacsha256ctxp;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Hash initialization using HMAC_SHA512.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[out] hmacsha512ctxp pointer to a HMAC_SHA512 context to be
- * initialized
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_HMACSHA512_init(CRYDriver *cryp,
- HMACSHA512Context *hmacsha512ctxp) {
-
- (void)cryp;
- (void)hmacsha512ctxp;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash update using HMAC.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] hmacsha512ctxp pointer to a HMAC_SHA512 context
- * @param[in] size size of input buffer
- * @param[in] in buffer containing the input text
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_HMACSHA512_update(CRYDriver *cryp,
- HMACSHA512Context *hmacsha512ctxp,
- size_t size,
- const uint8_t *in) {
-
- (void)cryp;
- (void)hmacsha512ctxp;
- (void)size;
- (void)in;
-
- return CRY_ERR_INV_ALGO;
-}
-
-/**
- * @brief Hash finalization using HMAC.
- *
- * @param[in] cryp pointer to the @p CRYDriver object
- * @param[in] hmacsha512ctxp pointer to a HMAC_SHA512 context
- * @param[out] out 512 bits output buffer
- * @return The operation status.
- * @retval CRY_NOERROR if the operation succeeded.
- * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
- * device instance.
- * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
- * dependent.
- *
- * @notapi
- */
-cryerror_t cry_lld_HMACSHA512_final(CRYDriver *cryp,
- HMACSHA512Context *hmacsha512ctxp,
- uint8_t *out) {
-
- (void)cryp;
- (void)hmacsha512ctxp;
- (void)out;
-
- return CRY_ERR_INV_ALGO;
-}
-#endif
-
-#endif /* HAL_USE_CRY == 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 CRYPv1/hal_crypto_lld.c
+ * @brief STM32 cryptographic subsystem low level driver source.
+ *
+ * @addtogroup CRYPTO
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define CRYP1_IN_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_CRY_CRYP1_IN_DMA_STREAM, \
+ STM32_CRYP1_IN_DMA_CHN)
+
+#define CRYP1_OUT_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_CRY_CRYP1_OUT_DMA_STREAM, \
+ STM32_CRYP1_OUT_DMA_CHN)
+
+#define HASH1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_CRY_HASH1_DMA_STREAM, \
+ STM32_HASH1_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief CRY1 driver identifier.*/
+#if (STM32_CRY_ENABLED1 == TRUE) || defined(__DOXYGEN__)
+CRYDriver CRYD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#if (STM32_CRY_USE_CRYP1 == TRUE) || defined (__DOXYGEN__)
+/**
+ * @brief Setting AES key for encryption.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] algomode algorithm mode field of CR register
+ */
+static inline void cryp_set_key_encrypt(CRYDriver *cryp, uint32_t algomode) {
+ uint32_t cr;
+
+ /* Loading key data.*/
+ CRYP->K0LR = cryp->cryp_k[0];
+ CRYP->K0RR = cryp->cryp_k[1];
+ CRYP->K1LR = cryp->cryp_k[2];
+ CRYP->K1RR = cryp->cryp_k[3];
+ CRYP->K2LR = cryp->cryp_k[4];
+ CRYP->K2RR = cryp->cryp_k[5];
+ CRYP->K3LR = cryp->cryp_k[6];
+ CRYP->K3RR = cryp->cryp_k[7];
+
+ /* Setting up then starting operation.*/
+ cr = CRYP->CR;
+ cr &= ~(CRYP_CR_KEYSIZE_Msk | CRYP_CR_ALGOMODE_Msk | CRYP_CR_ALGODIR_Msk);
+ cr |= cryp->cryp_ksize | algomode | CRYP_CR_CRYPEN;
+ CRYP->CR = cr;
+
+ cryp->cryp_ktype = cryp_key_aes_encrypt;
+}
+
+/**
+ * @brief Setting AES key for decryption.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] algomode algorithm field of CR register
+ */
+static inline void cryp_set_key_decrypt(CRYDriver *cryp, uint32_t algomode) {
+ uint32_t cr;
+
+ /* Loading key data then doing transformation for decrypt.*/
+ cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_KEY);
+ while ((CRYP->CR & CRYP_CR_CRYPEN) != 0U) {
+ }
+
+ /* Setting up then starting operation.*/
+ cr = CRYP->CR;
+ cr &= ~(CRYP_CR_KEYSIZE_Msk | CRYP_CR_ALGOMODE_Msk | CRYP_CR_ALGODIR_Msk);
+ cr |= cryp->cryp_ksize | algomode | CRYP_CR_ALGODIR | CRYP_CR_CRYPEN;
+ CRYP->CR = cr;
+
+ cryp->cryp_ktype = cryp_key_aes_decrypt;
+}
+
+/**
+ * @brief Setting IV.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] iv 128 bits initial vector
+ */
+static inline void cryp_set_iv(CRYDriver *cryp, const uint8_t *iv) {
+
+ (void)cryp;
+
+ CRYP->IV0LR = __REV(__UNALIGNED_UINT32_READ(&iv[0]));
+ CRYP->IV0RR = __REV(__UNALIGNED_UINT32_READ(&iv[4]));
+ CRYP->IV1LR = __REV(__UNALIGNED_UINT32_READ(&iv[8]));
+ CRYP->IV1RR = __REV(__UNALIGNED_UINT32_READ(&iv[12]));
+}
+
+/**
+ * @brief Performs a CRYP operation using DMA.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] size size of both buffers, this number must be a
+ * multiple of 16
+ * @param[in] in input buffer
+ * @param[out] out output buffer
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ */
+static cryerror_t cryp_do_transfer(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out) {
+ uint32_t szw;
+
+ szw = (uint32_t)(size / sizeof (uint32_t));
+#if STM32_CRY_CRYP_SIZE_THRESHOLD > 1
+ if (size >= STM32_CRY_CRYP_SIZE_THRESHOLD)
+#endif
+#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
+ {
+ /* DMA limitation.*/
+ osalDbgCheck(size < 0x10000U * 4U);
+
+ osalSysLock();
+
+ /* Preparing DMAs.*/
+ dmaStreamSetTransactionSize(cryp->cryp_dma_in, szw);
+ dmaStreamSetTransactionSize(cryp->cryp_dma_out, szw);
+ dmaStreamSetMemory0(cryp->cryp_dma_in, in);
+ dmaStreamSetMemory0(cryp->cryp_dma_out, out);
+ dmaStreamEnable(cryp->cryp_dma_in);
+ dmaStreamEnable(cryp->cryp_dma_out);
+
+ (void) osalThreadSuspendS(&cryp->cryp_tr);
+
+ osalSysUnlock();
+ }
+#endif
+#if STM32_CRY_CRYP_SIZE_THRESHOLD > 1
+ else
+#endif
+#if STM32_CRY_CRYP_SIZE_THRESHOLD != 1
+ {
+ uint32_t nr, nw;
+
+ nr = 0U;
+ nw = 0U;
+ while (nw < szw) {
+
+ if ((CRYP->SR & CRYP_SR_OFNE) != 0U) {
+ __UNALIGNED_UINT32_WRITE(out, CRYP->DOUT);
+ out += 4;
+ nw++;
+ continue; /* Priority to output FIFO.*/
+ }
+
+ if ((nr < szw) && ((CRYP->SR & CRYP_SR_IFNF) != 0U)) {
+ CRYP->DR = __UNALIGNED_UINT32_READ(in);
+ in += 4;
+ nr++;
+ }
+ }
+ }
+#endif
+
+ /* Disabling unit.*/
+ CRYP->CR &= ~CRYP_CR_CRYPEN;
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief CRYP-IN DMA ISR.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void cry_lld_serve_cryp_in_interrupt(CRYDriver *cryp, uint32_t flags) {
+
+ (void)cryp;
+
+ /* DMA errors handling.*/
+#if defined(STM32_CRY_CRYP_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
+ STM32_CRY_CRYP_DMA_ERROR_HOOK(cryp);
+ }
+#endif
+}
+
+/**
+ * @brief CRYP-OUT DMA ISR.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void cry_lld_serve_cryp_out_interrupt(CRYDriver *cryp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_CRY_CRYP_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
+ STM32_CRY_CRYP_DMA_ERROR_HOOK(cryp);
+ }
+#endif
+
+ /* End buffer interrupt.*/
+ if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
+
+ /* Clearing flags of the other stream too.*/
+ dmaStreamClearInterrupt(cryp->cryp_dma_in);
+
+ /* Resuming waiting thread.*/
+ osalSysLockFromISR();
+ osalThreadResumeI(&cryp->cryp_tr, MSG_OK);
+ osalSysUnlockFromISR();
+ }
+}
+#endif
+
+#if (STM32_CRY_USE_HASH1 == TRUE) || defined (__DOXYGEN__)
+#if (STM32_CRY_HASH_SIZE_THRESHOLD != 0) || defined (__DOXYGEN__)
+/**
+ * @brief HASH DMA ISR.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void cry_lld_serve_hash_interrupt(CRYDriver *cryp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_HASH_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
+ STM32_CRY_HASH_DMA_ERROR_HOOK(cryp);
+ }
+#endif
+
+ /* End buffer interrupt.*/
+ if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
+
+ /* Resuming waiting thread.*/
+ osalSysLockFromISR();
+ osalThreadResumeI(&cryp->hash_tr, MSG_OK);
+ osalSysUnlockFromISR();
+ }
+}
+#endif
+#endif
+
+/**
+ * @brief Pushes a series of words into the hash engine.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] n the number of words to be pushed
+ * @param[in] p pointer to the words buffer
+ */
+static void cry_lld_hash_push(CRYDriver *cryp, uint32_t n, const uint32_t *p) {
+
+ (void)cryp; /* Not touched in some cases, needs this.*/
+
+ /* Data is processed in 32kB blocks because DMA size limitations.*/
+ while (n > 0U) {
+ uint32_t chunk = n > 0x8000U ? 0x8000U : n;
+ n -= chunk;
+
+#if STM32_CRY_HASH_SIZE_THRESHOLD > 1
+ if (chunk >= STM32_CRY_HASH_SIZE_THRESHOLD)
+#endif
+#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
+ {
+ /* Setting up transfer.*/
+ dmaStreamSetTransactionSize(cryp->hash_dma, chunk);
+ dmaStreamSetPeripheral(cryp->hash_dma, p);
+ p += chunk;
+
+ osalSysLock();
+
+ /* Enabling DMA channel then HASH engine.*/
+ dmaStreamEnable(cryp->hash_dma);
+
+ /* Waiting for DMA operation completion.*/
+ osalThreadSuspendS(&cryp->hash_tr);
+
+ osalSysUnlock();
+ }
+#endif
+#if STM32_CRY_HASH_SIZE_THRESHOLD > 1
+ else
+#endif
+#if STM32_CRY_HASH_SIZE_THRESHOLD != 1
+ {
+ /* Small chunk, just pushing data without touching DMA.*/
+ do {
+ HASH->DIN = *p++;
+ chunk--;
+ } while (chunk > 0U);
+ }
+#endif
+ }
+
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level crypto driver initialization.
+ *
+ * @notapi
+ */
+void cry_lld_init(void) {
+
+#if STM32_CRY_ENABLED1
+ cryObjectInit(&CRYD1);
+
+#if STM32_CRY_USE_CRYP1
+#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
+ CRYD1.cryp_tr = NULL;
+ CRYD1.cryp_dma_in = NULL;
+ CRYD1.cryp_dma_out = NULL;
+#endif
+#endif
+
+#if STM32_CRY_USE_HASH1
+#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
+ CRYD1.hash_tr = NULL;
+ CRYD1.hash_dma = NULL;
+#endif /* STM32_CRY_HASH_SIZE_THRESHOLD != 0 */
+#endif /* STM32_CRY_USE_HASH1 */
+
+#endif /* STM32_CRY_ENABLED1 */
+}
+
+/**
+ * @brief Configures and activates the crypto peripheral.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ *
+ * @notapi
+ */
+void cry_lld_start(CRYDriver *cryp) {
+
+ if (cryp->state == CRY_STOP) {
+
+#if STM32_CRY_ENABLED1
+ if (&CRYD1 == cryp) {
+#if STM32_CRY_USE_CRYP1 == TRUE
+#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
+ /* Allocating DMA channels.*/
+ cryp->cryp_dma_in = dmaStreamAllocI(STM32_CRY_CRYP1_IN_DMA_STREAM,
+ STM32_CRY_CRYP1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)cry_lld_serve_cryp_in_interrupt,
+ (void *)cryp);
+ osalDbgAssert(cryp->cryp_dma_in != NULL, "unable to allocate stream");
+ cryp->cryp_dma_out = dmaStreamAllocI(STM32_CRY_CRYP1_OUT_DMA_STREAM,
+ STM32_CRY_CRYP1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)cry_lld_serve_cryp_out_interrupt,
+ (void *)cryp);
+ osalDbgAssert(cryp->cryp_dma_out != NULL, "unable to allocate stream");
+
+ /* Preparing the DMA channels.*/
+ dmaStreamSetMode(cryp->cryp_dma_in,
+ STM32_DMA_CR_CHSEL(CRYP1_IN_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_CRY_CRYP1_IN_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE);
+ dmaStreamSetMode(cryp->cryp_dma_out,
+ STM32_DMA_CR_CHSEL(CRYP1_OUT_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_CRY_CRYP1_OUT_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
+ STM32_DMA_CR_TCIE);
+ dmaStreamSetPeripheral(cryp->cryp_dma_in, &CRYP->DR);
+ dmaStreamSetPeripheral(cryp->cryp_dma_out, &CRYP->DOUT);
+ dmaStreamSetFIFO(cryp->cryp_dma_in, STM32_DMA_FCR_DMDIS);
+ dmaStreamSetFIFO(cryp->cryp_dma_out, STM32_DMA_FCR_DMDIS);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(cryp->cryp_dma_in, STM32_DMAMUX1_CRYP_IN);
+ dmaSetRequestSource(cryp->cryp_dma_out, STM32_DMAMUX1_CRYP_OUT);
+#endif
+#endif /* STM32_CRY_CRYP_SIZE_THRESHOLD != 0 */
+ rccEnableCRYP(true);
+#endif /* STM32_CRY_USE_CRYP1 == TRUE */
+
+#if STM32_CRY_USE_HASH1 == TRUE
+#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
+ cryp->hash_dma = dmaStreamAllocI(STM32_CRY_HASH1_DMA_STREAM,
+ STM32_CRY_HASH1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)cry_lld_serve_hash_interrupt,
+ (void *)cryp);
+ osalDbgAssert(cryp->hash_dma != NULL, "unable to allocate stream");
+
+ /* Preparing the DMA channel.*/
+ dmaStreamSetMode(cryp->hash_dma,
+ STM32_DMA_CR_CHSEL(HASH1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_CRY_HASH1_DMA_PRIORITY) |
+ STM32_DMA_CR_PINC | STM32_DMA_CR_DIR_M2M |
+ STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
+ STM32_DMA_CR_TCIE);
+ dmaStreamSetMemory0(cryp->hash_dma, &HASH->DIN);
+ dmaStreamSetFIFO(cryp->hash_dma, STM32_DMA_FCR_DMDIS);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(cryp->hash_dma, STM32_DMAMUX1_HASH_IN);
+#endif
+#endif /* STM32_CRY_HASH_SIZE_THRESHOLD != 0 */
+ rccEnableHASH(true);
+#endif /* STM32_CRY_USE_HASH1 == TRUE */
+ }
+#endif
+ }
+
+ /* Resetting trasient key data.*/
+ cryp->cryp_ktype = cryp_key_none;
+ cryp->cryp_ksize = 0U;
+ cryp->cryp_k[0] = 0U;
+ cryp->cryp_k[1] = 0U;
+ cryp->cryp_k[2] = 0U;
+ cryp->cryp_k[3] = 0U;
+ cryp->cryp_k[4] = 0U;
+ cryp->cryp_k[5] = 0U;
+ cryp->cryp_k[6] = 0U;
+ cryp->cryp_k[7] = 0U;
+
+#if STM32_CRY_USE_CRYP1
+ /* CRYP setup.*/
+ CRYP->CR = CRYP_CR_DATATYPE_1;
+ CRYP->DMACR = CRYP_DMACR_DIEN | CRYP_DMACR_DOEN;
+#endif
+
+#if STM32_CRY_USE_HASH1
+ /* HASH setup and enable.*/
+#endif
+}
+
+/**
+ * @brief Deactivates the crypto peripheral.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ *
+ * @notapi
+ */
+void cry_lld_stop(CRYDriver *cryp) {
+
+ if (cryp->state == CRY_READY) {
+
+ /* Resetting CRYP.*/
+ CRYP->CR = 0U;
+ CRYP->DMACR = 0U;
+
+#if STM32_CRY_ENABLED1
+ if (&CRYD1 == cryp) {
+#if STM32_CRY_USE_CRYP1
+#if STM32_CRY_CRYP_SIZE_THRESHOLD != 0
+ dmaStreamFreeI(cryp->cryp_dma_in);
+ dmaStreamFreeI(cryp->cryp_dma_out);
+ cryp->cryp_dma_in = NULL;
+ cryp->cryp_dma_out = NULL;
+#endif
+ rccDisableCRYP();
+#endif
+
+#if STM32_CRY_USE_HASH1
+#if STM32_CRY_HASH_SIZE_THRESHOLD != 0
+ dmaStreamFreeI(cryp->hash_dma);
+ cryp->hash_dma = NULL;
+#endif
+ rccDisableHASH();
+#endif
+ }
+#endif
+ }
+}
+
+#if (CRY_LLD_SUPPORTS_AES == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Initializes the AES transient key.
+ * @note It is the underlying implementation to decide which key sizes are
+ * allowable.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] size key size in bytes
+ * @param[in] keyp pointer to the key data
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the algorithm is unsupported.
+ * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid for
+ * the specified algorithm.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_aes_loadkey(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *keyp) {
+
+ /* Fetching key data.*/
+ if (size == (size_t)32) {
+ cryp->cryp_ksize = CRYP_CR_KEYSIZE_1;
+ cryp->cryp_k[0] = __REV(__UNALIGNED_UINT32_READ(&keyp[0]));
+ cryp->cryp_k[1] = __REV(__UNALIGNED_UINT32_READ(&keyp[4]));
+ cryp->cryp_k[2] = __REV(__UNALIGNED_UINT32_READ(&keyp[8]));
+ cryp->cryp_k[3] = __REV(__UNALIGNED_UINT32_READ(&keyp[12]));
+ cryp->cryp_k[4] = __REV(__UNALIGNED_UINT32_READ(&keyp[16]));
+ cryp->cryp_k[5] = __REV(__UNALIGNED_UINT32_READ(&keyp[20]));
+ cryp->cryp_k[6] = __REV(__UNALIGNED_UINT32_READ(&keyp[24]));
+ cryp->cryp_k[7] = __REV(__UNALIGNED_UINT32_READ(&keyp[28]));
+ }
+ else if (size == (size_t)24) {
+ cryp->cryp_ksize = CRYP_CR_KEYSIZE_0;
+ cryp->cryp_k[0] = 0U;
+ cryp->cryp_k[1] = 0U;
+ cryp->cryp_k[2] = __REV(__UNALIGNED_UINT32_READ(&keyp[8]));
+ cryp->cryp_k[3] = __REV(__UNALIGNED_UINT32_READ(&keyp[12]));
+ cryp->cryp_k[4] = __REV(__UNALIGNED_UINT32_READ(&keyp[16]));
+ cryp->cryp_k[5] = __REV(__UNALIGNED_UINT32_READ(&keyp[20]));
+ cryp->cryp_k[6] = __REV(__UNALIGNED_UINT32_READ(&keyp[24]));
+ cryp->cryp_k[7] = __REV(__UNALIGNED_UINT32_READ(&keyp[28]));
+ }
+ else if (size == (size_t)16) {
+ cryp->cryp_ksize = 0U;
+ cryp->cryp_k[0] = 0U;
+ cryp->cryp_k[1] = 0U;
+ cryp->cryp_k[2] = 0U;
+ cryp->cryp_k[3] = 0U;
+ cryp->cryp_k[4] = __REV(__UNALIGNED_UINT32_READ(&keyp[16]));
+ cryp->cryp_k[5] = __REV(__UNALIGNED_UINT32_READ(&keyp[20]));
+ cryp->cryp_k[6] = __REV(__UNALIGNED_UINT32_READ(&keyp[24]));
+ cryp->cryp_k[7] = __REV(__UNALIGNED_UINT32_READ(&keyp[28]));
+ }
+ else {
+ return CRY_ERR_INV_KEY_SIZE;
+ }
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief Encryption of a single block using AES.
+ * @note The implementation of this function must guarantee that it can
+ * be called from any context.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out) {
+ unsigned i;
+
+ /* Only key zero is supported.*/
+ if (key_id != 0U) {
+ return CRY_ERR_INV_KEY_ID;
+ }
+
+ /* Setting the stored key.*/
+ if (cryp->cryp_ktype != cryp_key_aes_encrypt) {
+ cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
+ }
+
+ /* Pushing the AES block in the FIFO, it is assumed to be empty.*/
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[0]);
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[4]);
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[8]);
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[12]);
+
+ /* Reading the result.*/
+ for (i = 0U; i < 4; i++, out += 4) {
+ while ((CRYP->SR & CRYP_SR_OFNE) == 0U) {
+ }
+ __UNALIGNED_UINT32_WRITE(out, CRYP->DOUT);
+ }
+
+ /* Disabling unit.*/
+ CRYP->CR &= ~CRYP_CR_CRYPEN;
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief Decryption of a single block using AES.
+ * @note The implementation of this function must guarantee that it can
+ * be called from any context.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] in buffer containing the input ciphertext
+ * @param[out] out buffer for the output plaintext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out) {
+ unsigned i;
+
+ /* Only key zero is supported.*/
+ if (key_id != 0U) {
+ return CRY_ERR_INV_KEY_ID;
+ }
+
+ /* Setting the stored key.*/
+ if (cryp->cryp_ktype != cryp_key_aes_decrypt) {
+ cryp_set_key_decrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
+ }
+
+ /* Pushing the AES block in the FIFO, it is assumed to be empty.*/
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[0]);
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[4]);
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[8]);
+ CRYP->DR = __UNALIGNED_UINT32_READ(&in[12]);
+
+ /* Reading the result.*/
+ for (i = 0U; i < 4; i++, out += 4) {
+ while ((CRYP->SR & CRYP_SR_OFNE) == 0U) {
+ }
+ __UNALIGNED_UINT32_WRITE(out, CRYP->DOUT);
+ }
+
+ /* Disabling unit.*/
+ CRYP->CR &= ~CRYP_CR_CRYPEN;
+
+ return CRY_NOERROR;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using AES-ECB.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an AES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers, this number must be a
+ * multiple of 16
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out) {
+
+ /* Only key zero is supported.*/
+ if (key_id != 0U) {
+ return CRY_ERR_INV_KEY_ID;
+ }
+
+ /* Setting the stored key.*/
+ if (cryp->cryp_ktype != cryp_key_aes_encrypt) {
+ cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
+ }
+
+ return cryp_do_transfer(cryp, size, in, out);
+}
+
+/**
+ * @brief Decryption operation using AES-ECB.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an AES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers, this number must be a
+ * multiple of 16
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out) {
+
+ /* Only key zero is supported.*/
+ if (key_id != 0U) {
+ return CRY_ERR_INV_KEY_ID;
+ }
+
+ /* Setting the stored key.*/
+ if (cryp->cryp_ktype != cryp_key_aes_decrypt) {
+ cryp_set_key_decrypt(cryp, CRYP_CR_ALGOMODE_AES_ECB);
+ }
+
+ return cryp_do_transfer(cryp, size, in, out);
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using AES-CBC.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an AES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers, this number must be a
+ * multiple of 16
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @param[in] iv 128 bits initial vector
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ /* Only key zero is supported.*/
+ if (key_id != 0U) {
+ return CRY_ERR_INV_KEY_ID;
+ }
+
+ /* Setting the stored key and IV.*/
+ cryp_set_iv(cryp, iv);
+ if (cryp->cryp_ktype != cryp_key_aes_encrypt) {
+ cryp_set_key_encrypt(cryp, CRYP_CR_ALGOMODE_AES_CBC);
+ }
+
+ return cryp_do_transfer(cryp, size, in, out);
+}
+
+/**
+ * @brief Decryption operation using AES-CBC.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an AES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers, this number must be a
+ * multiple of 16
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @param[in] iv 128 bits initial vector
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ /* Only key zero is supported.*/
+ if (key_id != 0U) {
+ return CRY_ERR_INV_KEY_ID;
+ }
+
+ /* Setting the stored key and IV.*/
+ cryp_set_iv(cryp, iv);
+ if (cryp->cryp_ktype != cryp_key_aes_decrypt) {
+ cryp_set_key_decrypt(cryp, CRYP_CR_ALGOMODE_AES_CBC);
+ }
+
+ return cryp_do_transfer(cryp, size, in, out);
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using AES-CFB.
+ * @note This is a stream cipher, there are no size restrictions.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @param[in] iv 128 bits initial vector
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+ (void)iv;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Decryption operation using AES-CFB.
+ * @note This is a stream cipher, there are no size restrictions.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @param[in] iv 128 bits initial vector
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+ (void)iv;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using AES-CTR.
+ * @note This is a stream cipher, there are no size restrictions.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @param[in] iv 128 bits initial vector + counter, it contains
+ * a 96 bits IV and a 32 bits counter
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+ (void)iv;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Decryption operation using AES-CTR.
+ * @note This is a stream cipher, there are no size restrictions.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of both buffers
+ * @param[in] in buffer containing the input ciphertext
+ * @param[out] out buffer for the output plaintext
+ * @param[in] iv 128 bits initial vector + counter, it contains
+ * a 96 bits IV and a 32 bits counter
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+ (void)iv;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_AES_GCM == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using AES-GCM.
+ * @note This is a stream cipher, there are no size restrictions.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] auth_size size of the data buffer to be authenticated
+ * @param[in] auth_in buffer containing the data to be authenticated
+ * @param[in] text_size size of the text buffer
+ * @param[in] text_in buffer containing the input plaintext
+ * @param[out] text_out buffer for the output ciphertext
+ * @param[in] iv 128 bits input vector
+ * @param[in] tag_size size of the authentication tag, this number
+ * must be between 1 and 16
+ * @param[out] tag_out buffer for the generated authentication tag
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t auth_size,
+ const uint8_t *auth_in,
+ size_t text_size,
+ const uint8_t *text_in,
+ uint8_t *text_out,
+ const uint8_t *iv,
+ size_t tag_size,
+ uint8_t *tag_out) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)auth_size;
+ (void)auth_in;
+ (void)text_size;
+ (void)text_in;
+ (void)text_out;
+ (void)iv;
+ (void)tag_size;
+ (void)tag_out;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Decryption operation using AES-GCM.
+ * @note This is a stream cipher, there are no size restrictions.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] auth_size size of the data buffer to be authenticated
+ * @param[in] auth_in buffer containing the data to be authenticated
+ * @param[in] text_size size of the text buffer
+ * @param[in] text_in buffer containing the input plaintext
+ * @param[out] text_out buffer for the output ciphertext
+ * @param[in] iv 128 bits input vector
+ * @param[in] tag_size size of the authentication tag, this number
+ * must be between 1 and 16
+ * @param[in] tag_in buffer for the generated authentication tag
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_AUTH_FAILED authentication failed
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t auth_size,
+ const uint8_t *auth_in,
+ size_t text_size,
+ const uint8_t *text_in,
+ uint8_t *text_out,
+ const uint8_t *iv,
+ size_t tag_size,
+ const uint8_t *tag_in) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)auth_size;
+ (void)auth_in;
+ (void)text_size;
+ (void)text_in;
+ (void)text_out;
+ (void)iv;
+ (void)tag_size;
+ (void)tag_in;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_DES == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Initializes the DES transient key.
+ * @note It is the underlying implementation to decide which key sizes are
+ * allowable.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] size key size in bytes
+ * @param[in] keyp pointer to the key data
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the algorithm is unsupported.
+ * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid for
+ * the specified algorithm.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_des_loadkey(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *keyp) {
+
+ (void)cryp;
+ (void)size;
+ (void)keyp;
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief Encryption of a single block using (T)DES.
+ * @note The implementation of this function must guarantee that it can
+ * be called from any context.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)in;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Decryption of a single block using (T)DES.
+ * @note The implementation of this function must guarantee that it can
+ * be called from any context.
+ *
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] in buffer containing the input ciphertext
+ * @param[out] out buffer for the output plaintext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)in;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_DES_ECB == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using (T)DES-ECB.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an DES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of the plaintext buffer, this number must
+ * be a multiple of 8
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Decryption operation using (T)DES-ECB.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an DES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of the plaintext buffer, this number must
+ * be a multiple of 8
+ * @param[in] in buffer containing the input ciphertext
+ * @param[out] out buffer for the output plaintext
+ * @return T he operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_DES_CBC == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Encryption operation using (T)DES-CBC.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an DES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of the plaintext buffer, this number must
+ * be a multiple of 8
+ * @param[in] in buffer containing the input plaintext
+ * @param[out] out buffer for the output ciphertext
+ * @param[in] iv 64 bits input vector
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+ (void)iv;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Decryption operation using (T)DES-CBC.
+ * @note The function operates on data buffers whose length is a multiple
+ * of an DES block, this means that padding must be done by the
+ * caller.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] key_id the key to be used for the operation, zero is
+ * the transient key, other values are keys stored
+ * in an unspecified way
+ * @param[in] size size of the plaintext buffer, this number must
+ * be a multiple of 8
+ * @param[in] in buffer containing the input ciphertext
+ * @param[out] out buffer for the output plaintext
+ * @param[in] iv 64 bits input vector
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_INV_KEY_TYPE the selected key is invalid for this operation.
+ * @retval CRY_ERR_INV_KEY_ID if the specified key identifier is invalid
+ * or refers to an empty key slot.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv) {
+
+ (void)cryp;
+ (void)key_id;
+ (void)size;
+ (void)in;
+ (void)out;
+ (void)iv;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Hash initialization using SHA1.
+ * @note Use of this algorithm is not recommended because proven weak.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[out] sha1ctxp pointer to a SHA1 context to be initialized
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA1_init(CRYDriver *cryp, SHA1Context *sha1ctxp) {
+
+ (void)cryp;
+ (void)sha1ctxp;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash update using SHA1.
+ * @note Use of this algorithm is not recommended because proven weak.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] sha1ctxp pointer to a SHA1 context
+ * @param[in] size size of input buffer
+ * @param[in] in buffer containing the input text
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA1_update(CRYDriver *cryp, SHA1Context *sha1ctxp,
+ size_t size, const uint8_t *in) {
+
+ (void)cryp;
+ (void)sha1ctxp;
+ (void)size;
+ (void)in;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash finalization using SHA1.
+ * @note Use of this algorithm is not recommended because proven weak.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] sha1ctxp pointer to a SHA1 context
+ * @param[out] out 160 bits output buffer
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA1_final(CRYDriver *cryp, SHA1Context *sha1ctxp,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)sha1ctxp;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Hash initialization using SHA256.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[out] sha256ctxp pointer to a SHA256 context to be initialized
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp) {
+
+ (void)cryp;
+
+ /* Initializing context structure.*/
+ sha256ctxp->last_data = 0U;
+ sha256ctxp->last_size = 0U;
+
+ /* Initializing operation.*/
+ HASH->CR = /*HASH_CR_MDMAT |*/ HASH_CR_ALGO_1 | HASH_CR_ALGO_0 |
+ HASH_CR_DATATYPE_1 | HASH_CR_INIT;
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief Hash update using SHA256.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] sha256ctxp pointer to a SHA256 context
+ * @param[in] size size of input buffer
+ * @param[in] in buffer containing the input text
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp,
+ size_t size, const uint8_t *in) {
+ const uint32_t *wp = (const uint32_t *)(const void *)in;
+
+ /* This HW is unable to hash blocks that are not a multiple of 4 bytes
+ except for the last block in the stream which is handled in the
+ "final" function.*/
+ if (sha256ctxp->last_size != 0U) {
+ return CRY_ERR_OP_FAILURE;
+ }
+
+ /* Any unaligned data is deferred to the "final" function.*/
+ sha256ctxp->last_size = 8U * (size % sizeof (uint32_t));
+ if (sha256ctxp->last_size > 0U) {
+ sha256ctxp->last_data = wp[size / sizeof (uint32_t)];
+ }
+
+ /* Pushing data.*/
+ cry_lld_hash_push(cryp, (uint32_t)(size / sizeof (uint32_t)), wp);
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief Hash finalization using SHA256.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] sha256ctxp pointer to a SHA256 context
+ * @param[out] out 256 bits output buffer
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA256_final(CRYDriver *cryp, SHA256Context *sha256ctxp,
+ uint8_t *out) {
+ uint32_t digest[8];
+
+ (void)cryp;
+
+ if (sha256ctxp->last_size > 0U) {
+ HASH->DIN = sha256ctxp->last_data;
+ }
+
+ /* Triggering final calculation and wait for result.*/
+ HASH->SR = 0U;
+ HASH->STR = sha256ctxp->last_size;
+ HASH->STR = sha256ctxp->last_size | HASH_STR_DCAL;
+ while ((HASH->SR & HASH_SR_DCIS) == 0U) {
+ }
+
+ /* Reading digest.*/
+ digest[0] = HASH_DIGEST->HR[0];
+ digest[1] = HASH_DIGEST->HR[1];
+ digest[2] = HASH_DIGEST->HR[2];
+ digest[3] = HASH_DIGEST->HR[3];
+ digest[4] = HASH_DIGEST->HR[4];
+ digest[5] = HASH_DIGEST->HR[5];
+ digest[6] = HASH_DIGEST->HR[6];
+ digest[7] = HASH_DIGEST->HR[7];
+ memcpy((void *)out, (const void *)digest, sizeof digest);
+
+ return CRY_NOERROR;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Hash initialization using SHA512.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[out] sha512ctxp pointer to a SHA512 context to be initialized
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA512_init(CRYDriver *cryp, SHA512Context *sha512ctxp) {
+
+ (void)cryp;
+ (void)sha512ctxp;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash update using SHA512.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] sha512ctxp pointer to a SHA512 context
+ * @param[in] size size of input buffer
+ * @param[in] in buffer containing the input text
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA512_update(CRYDriver *cryp, SHA512Context *sha512ctxp,
+ size_t size, const uint8_t *in) {
+
+ (void)cryp;
+ (void)sha512ctxp;
+ (void)size;
+ (void)in;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash finalization using SHA512.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] sha512ctxp pointer to a SHA512 context
+ * @param[out] out 512 bits output buffer
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_SHA512_final(CRYDriver *cryp, SHA512Context *sha512ctxp,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)sha512ctxp;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Initializes the HMAC transient key.
+ * @note It is the underlying implementation to decide which key sizes are
+ * allowable.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] size key size in bytes
+ * @param[in] keyp pointer to the key data
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the algorithm is unsupported.
+ * @retval CRY_ERR_INV_KEY_SIZE if the specified key size is invalid for
+ * the specified algorithm.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_hmac_loadkey(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *keyp) {
+
+ (void)cryp;
+ (void)size;
+ (void)keyp;
+
+ return CRY_NOERROR;
+}
+
+/**
+ * @brief Hash initialization using HMAC_SHA256.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[out] hmacsha256ctxp pointer to a HMAC_SHA256 context to be
+ * initialized
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_HMACSHA256_init(CRYDriver *cryp,
+ HMACSHA256Context *hmacsha256ctxp) {
+
+ (void)cryp;
+ (void)hmacsha256ctxp;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash update using HMAC.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] hmacsha256ctxp pointer to a HMAC_SHA256 context
+ * @param[in] size size of input buffer
+ * @param[in] in buffer containing the input text
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_HMACSHA256_update(CRYDriver *cryp,
+ HMACSHA256Context *hmacsha256ctxp,
+ size_t size,
+ const uint8_t *in) {
+
+ (void)cryp;
+ (void)hmacsha256ctxp;
+ (void)size;
+ (void)in;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash finalization using HMAC.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] hmacsha256ctxp pointer to a HMAC_SHA256 context
+ * @param[out] out 256 bits output buffer
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_HMACSHA256_final(CRYDriver *cryp,
+ HMACSHA256Context *hmacsha256ctxp,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)hmacsha256ctxp;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Hash initialization using HMAC_SHA512.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[out] hmacsha512ctxp pointer to a HMAC_SHA512 context to be
+ * initialized
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_HMACSHA512_init(CRYDriver *cryp,
+ HMACSHA512Context *hmacsha512ctxp) {
+
+ (void)cryp;
+ (void)hmacsha512ctxp;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash update using HMAC.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] hmacsha512ctxp pointer to a HMAC_SHA512 context
+ * @param[in] size size of input buffer
+ * @param[in] in buffer containing the input text
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_HMACSHA512_update(CRYDriver *cryp,
+ HMACSHA512Context *hmacsha512ctxp,
+ size_t size,
+ const uint8_t *in) {
+
+ (void)cryp;
+ (void)hmacsha512ctxp;
+ (void)size;
+ (void)in;
+
+ return CRY_ERR_INV_ALGO;
+}
+
+/**
+ * @brief Hash finalization using HMAC.
+ *
+ * @param[in] cryp pointer to the @p CRYDriver object
+ * @param[in] hmacsha512ctxp pointer to a HMAC_SHA512 context
+ * @param[out] out 512 bits output buffer
+ * @return The operation status.
+ * @retval CRY_NOERROR if the operation succeeded.
+ * @retval CRY_ERR_INV_ALGO if the operation is unsupported on this
+ * device instance.
+ * @retval CRY_ERR_OP_FAILURE if the operation failed, implementation
+ * dependent.
+ *
+ * @notapi
+ */
+cryerror_t cry_lld_HMACSHA512_final(CRYDriver *cryp,
+ HMACSHA512Context *hmacsha512ctxp,
+ uint8_t *out) {
+
+ (void)cryp;
+ (void)hmacsha512ctxp;
+ (void)out;
+
+ return CRY_ERR_INV_ALGO;
+}
+#endif
+
+#endif /* HAL_USE_CRY == TRUE */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h
index 257d39624a..523ef03c8e 100644
--- a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h
+++ b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h
@@ -1,618 +1,618 @@
-/*
- 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 CRYPv1/hal_cry_lld.h
- * @brief STM32 cryptographic subsystem low level driver header.
- *
- * @addtogroup CRYPTO
- * @{
- */
-
-#ifndef HAL_CRYPTO_LLD_H
-#define HAL_CRYPTO_LLD_H
-
-#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name STM32 configuration options
- * @{
- */
-/**
- * @brief CRYP1 driver enable switch.
- * @details If set to @p TRUE the support for CRYP1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_CRY_USE_CRYP1) || defined(__DOXYGEN__)
-#define STM32_CRY_USE_CRYP1 FALSE
-#endif
-
-/**
- * @brief HASH1 driver enable switch.
- * @details If set to @p TRUE the support for HASH1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_CRY_USE_HASH1) || defined(__DOXYGEN__)
-#define STM32_CRY_USE_HASH1 FALSE
-#endif
-
-/**
- * @brief CRYP1 interrupt priority level setting.
- */
-#if !defined(STM32_CRY_CRYP1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CRY_CRYP1_IRQ_PRIORITY 9
-#endif
-
-/**
- * @brief HASH1 interrupt priority level setting.
- */
-#if !defined(STM32_CRY_HASH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CRY_HASH1_IRQ_PRIORITY 9
-#endif
-
-/**
- * @brief HASH1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_CRY_CRYP1_OUT_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CRY_CRYP1_OUT_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief HASH1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_CRY_HASH1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_CRY_HASH1_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief Minimum message size (in words) for DMA use.
- * @note If set to zero then DMA is never used.
- * @note If set to one then DMA is always used.
- */
-#if !defined(STM32_CRY_HASH_SIZE_THRESHOLD) || defined(__DOXYGEN__)
-#define STM32_CRY_HASH_SIZE_THRESHOLD 1024
-#endif
-
-/**
- * @brief Minimum text size (in bytes) for DMA use.
- * @note If set to zero then DMA is never used.
- * @note If set to one then DMA is always used.
- */
-#if !defined(STM32_CRY_CRYP_SIZE_THRESHOLD) || defined(__DOXYGEN__)
-#define STM32_CRY_CRYP_SIZE_THRESHOLD 1024
-#endif
-
-/**
- * @brief Hash DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_CRY_HASH_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_CRY_HASH_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure")
-#endif
-
-/**
- * @brief CRYP DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_CRY_CRYP_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_CRY_CRYP_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if (STM32_CRY_USE_CRYP1 == TRUE) || (STM32_CRY_USE_HASH1 == TRUE) || \
- defined (__DOXYGEN__)
-#define STM32_CRY_ENABLED1 TRUE
-#else
-#define STM32_CRY_ENABLED1 FALSE
-#endif
-
-#if !defined (STM32_HAS_CRYP1)
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-#if !defined (STM32_HAS_HASH1)
-#define STM32_HAS_HASH1 FALSE
-#endif
-
-#if STM32_CRY_USE_CRYP1 && !STM32_HAS_CRYP1
-#error "CRYP1 not present in the selected device"
-#endif
-
-#if STM32_CRY_USE_HASH1 && !STM32_HAS_HASH1
-#error "HASH1 not present in the selected device"
-#endif
-
-#if !STM32_CRY_ENABLED1
-#error "CRY driver activated but no CRYP nor HASH peripheral assigned"
-#endif
-
-#if STM32_CRY_USE_HASH1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_CRY_HASH1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to HASH1"
-#endif
-
-#if STM32_CRY_USE_CRYP1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_CRY_CRYP1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to CRYP1"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if !defined(STM32_CRY_HASH1_DMA_STREAM)
-#error "HASH1 DMA streams not defined"
-#endif
-
-/* Sanity checks on DMA streams settings in mcuconf.h.*/
-#if STM32_CRY_USE_HASH1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_CRY_HASH1_DMA_STREAM)
-#error "Invalid DMA stream assigned to HASH1"
-#endif
-
-/* Devices without DMAMUX require an additional check.*/
-#if !STM32_DMA_SUPPORTS_DMAMUX
-#if STM32_CRY_USE_CRYP1 && \
- !STM32_DMA_IS_VALID_ID(STM32_CRY_CRYP1_IN_DMA_STREAM, \
- STM32_CRYP1_IN_DMA_MSK)
-#error "invalid DMA stream associated to CRYP1_IN"
-#endif
-
-#if STM32_CRY_USE_CRYP1 && \
- !STM32_DMA_IS_VALID_ID(STM32_CRY_CRYP1_OUT_DMA_STREAM, \
- STM32_CRYP1_OUT_DMA_MSK)
-#error "invalid DMA stream associated to CRYP1_OUT"
-#endif
-
-#if STM32_CRY_USE_HASH1 && \
- !STM32_DMA_IS_VALID_ID(STM32_CRY_HASH1_DMA_STREAM, STM32_HASH1_DMA_MSK)
-#error "invalid DMA stream associated to HASH1"
-#endif
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* DMA priority check.*/
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_CRY_CRYP1_IN_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to CRYP1_IN"
-#endif
-
-/* DMA priority check.*/
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_CRY_CRYP1_OUT_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to CRYP1_OUT"
-#endif
-
-/* DMA priority check.*/
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_CRY_HASH1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to HASH1"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-#if STM32_CRY_HASH_SIZE_THRESHOLD < 0
-#error "invalid STM32_CRY_HASH_SIZE_THRESHOLD value"
-#endif
-
-/**
- * @name Driver capability switches
- * @{
- */
-#if STM32_CRY_USE_CRYP1 || defined (__DOXYGEN__)
-#define CRY_LLD_SUPPORTS_AES TRUE
-#define CRY_LLD_SUPPORTS_AES_ECB TRUE
-#define CRY_LLD_SUPPORTS_AES_CBC TRUE
-#define CRY_LLD_SUPPORTS_AES_CFB FALSE
-#define CRY_LLD_SUPPORTS_AES_CTR TRUE
-#define CRY_LLD_SUPPORTS_AES_GCM TRUE
-#define CRY_LLD_SUPPORTS_DES TRUE
-#define CRY_LLD_SUPPORTS_DES_ECB TRUE
-#define CRY_LLD_SUPPORTS_DES_CBC TRUE
-#else
-#define CRY_LLD_SUPPORTS_AES FALSE
-#define CRY_LLD_SUPPORTS_AES_ECB FALSE
-#define CRY_LLD_SUPPORTS_AES_CBC FALSE
-#define CRY_LLD_SUPPORTS_AES_CFB FALSE
-#define CRY_LLD_SUPPORTS_AES_CTR FALSE
-#define CRY_LLD_SUPPORTS_AES_GCM FALSE
-#define CRY_LLD_SUPPORTS_DES FALSE
-#define CRY_LLD_SUPPORTS_DES_ECB FALSE
-#define CRY_LLD_SUPPORTS_DES_CBC FALSE
-#endif
-#if STM32_CRY_USE_HASH1 || defined (__DOXYGEN__)
-#define CRY_LLD_SUPPORTS_SHA1 FALSE
-#define CRY_LLD_SUPPORTS_SHA256 TRUE
-#define CRY_LLD_SUPPORTS_SHA512 FALSE
-#define CRY_LLD_SUPPORTS_HMAC_SHA256 TRUE
-#define CRY_LLD_SUPPORTS_HMAC_SHA512 FALSE
-#else
-#define CRY_LLD_SUPPORTS_SHA1 FALSE
-#define CRY_LLD_SUPPORTS_SHA256 FALSE
-#define CRY_LLD_SUPPORTS_SHA512 FALSE
-#define CRY_LLD_SUPPORTS_HMAC_SHA256 FALSE
-#define CRY_LLD_SUPPORTS_HMAC_SHA512 FALSE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief CRY key identifier type.
- */
-typedef uint32_t crykey_t;
-
-/**
- * @brief Type of a structure representing an CRY driver.
- */
-typedef struct CRYDriver CRYDriver;
-
-/**
- * @brief Type of key stored in CRYP.
- */
-typedef enum {
- cryp_key_none = 0,
- cryp_key_des = 1,
- cryp_key_tdes = 2,
- cryp_key_aes_encrypt = 3,
- cryp_key_aes_decrypt = 4
-} cryp_ktype_t;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- uint32_t dummy;
-} CRYConfig;
-
-/**
- * @brief Structure representing an CRY driver.
- */
-struct CRYDriver {
- /**
- * @brief Driver state.
- */
- crystate_t state;
- /**
- * @brief Current configuration data.
- */
- const CRYConfig *config;
-#if defined(CRY_DRIVER_EXT_FIELDS)
- CRY_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
-#if (STM32_CRY_USE_CRYP1 == TRUE) || defined (__DOXYGEN__)
- /**
- * @brief Type of the key currently stored in CRYP.
- */
- cryp_ktype_t cryp_ktype;
- /**
- * @brief Key size setup value for CR register.
- */
- uint32_t cryp_ksize;
- /**
- * @brief Transient key data.
- */
- uint32_t cryp_k[8];
-#if (STM32_CRY_CRYP_SIZE_THRESHOLD != 0) || defined (__DOXYGEN__)
- /**
- * @brief Thread reference for CRYP operations.
- */
- thread_reference_t cryp_tr;
- /**
- * @brief CRYP IN DMA stream.
- */
- const stm32_dma_stream_t *cryp_dma_in;
- /**
- * @brief CRYP OUT DMA stream.
- */
- const stm32_dma_stream_t *cryp_dma_out;
-#endif /* STM32_CRY_CRYP_SIZE_THRESHOLD != 0 */
-#endif /* STM32_CRY_USE_CRYP1 == TRUE */
-#if (STM32_CRY_USE_HASH1 == TRUE) || defined (__DOXYGEN__)
-#if (STM32_CRY_HASH_SIZE_THRESHOLD != 0) || defined (__DOXYGEN__)
- /**
- * @brief Thread reference for hash operations.
- */
- thread_reference_t hash_tr;
- /**
- * @brief Hash DMA stream.
- */
- const stm32_dma_stream_t *hash_dma;
-#endif /* STM32_CRY_HASH_SIZE_THRESHOLD != 0 */
-#endif /* STM32_CRY_USE_HASH1 == TRUE */
-};
-
-#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a SHA1 context.
- */
-typedef struct {
- uint32_t dummy;
-} SHA1Context;
-#endif
-
-#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a SHA256 context.
- */
-typedef struct {
- /**
- * @brief Last data to be hashed on finalization.
- */
- uint32_t last_data;
- /**
- * @brief Size, in bits, of the last data.
- */
- uint32_t last_size;
-} SHA256Context;
-#endif
-
-#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a SHA512 context.
- */
-typedef struct {
- uint32_t dummy;
-} SHA512Context;
-#endif
-
-#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a HMAC_SHA256 context.
- */
-typedef struct {
- uint32_t dummy;
-} HMACSHA256Context;
-#endif
-
-#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a HMAC_SHA512 context.
- */
-typedef struct {
- uint32_t dummy;
-} HMACSHA512Context;
-#endif
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if (STM32_CRY_ENABLED1 == TRUE) && !defined(__DOXYGEN__)
-extern CRYDriver CRYD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void cry_lld_init(void);
- void cry_lld_start(CRYDriver *cryp);
- void cry_lld_stop(CRYDriver *cryp);
-#if (CRY_LLD_SUPPORTS_AES == TRUE) || \
- (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || \
- (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || \
- (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || \
- (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || \
- (CRY_LLD_SUPPORTS_AES_GCM == TRUE) || \
- defined(__DOXYGEN__)
- cryerror_t cry_lld_aes_loadkey(CRYDriver *cryp,
- size_t size,
- const uint8_t *keyp);
-#endif
-#if (CRY_LLD_SUPPORTS_AES == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out);
- cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out);
- cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
- cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
-#endif
-#if (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
- cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
-#endif
-#if (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
- cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
-#endif
-#if (CRY_LLD_SUPPORTS_AES_GCM == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp,
- crykey_t key_id,
- size_t auth_size,
- const uint8_t *auth_in,
- size_t text_size,
- const uint8_t *text_in,
- uint8_t *text_out,
- const uint8_t *iv,
- size_t tag_size,
- uint8_t *tag_out);
- cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp,
- crykey_t key_id,
- size_t auth_size,
- const uint8_t *auth_in,
- size_t text_size,
- const uint8_t *text_in,
- uint8_t *text_out,
- const uint8_t *iv,
- size_t tag_size,
- const uint8_t *tag_in);
-#endif
-#if (CRY_LLD_SUPPORTS_DES == TRUE) || \
- (CRY_LLD_SUPPORTS_DES_ECB == TRUE) || \
- (CRY_LLD_SUPPORTS_DES_CBC == TRUE) || \
- defined(__DOXYGEN__)
- cryerror_t cry_lld_des_loadkey(CRYDriver *cryp,
- size_t size,
- const uint8_t *keyp);
-#endif
-#if (CRY_LLD_SUPPORTS_DES == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out);
- cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp,
- crykey_t key_id,
- const uint8_t *in,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_DES_ECB == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out);
- cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_DES_CBC == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
- cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp,
- crykey_t key_id,
- size_t size,
- const uint8_t *in,
- uint8_t *out,
- const uint8_t *iv);
-#endif
-#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_SHA1_init(CRYDriver *cryp, SHA1Context *sha1ctxp);
- cryerror_t cry_lld_SHA1_update(CRYDriver *cryp, SHA1Context *sha1ctxp,
- size_t size, const uint8_t *in);
- cryerror_t cry_lld_SHA1_final(CRYDriver *cryp, SHA1Context *sha1ctxp,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp);
- cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp,
- size_t size, const uint8_t *in);
- cryerror_t cry_lld_SHA256_final(CRYDriver *cryp, SHA256Context *sha256ctxp,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_SHA512_init(CRYDriver *cryp, SHA512Context *sha512ctxp);
- cryerror_t cry_lld_SHA512_update(CRYDriver *cryp, SHA512Context *sha512ctxp,
- size_t size, const uint8_t *in);
- cryerror_t cry_lld_SHA512_final(CRYDriver *cryp, SHA512Context *sha512ctxp,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || \
- (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || \
- defined(__DOXYGEN__)
- cryerror_t cry_lld_hmac_loadkey(CRYDriver *cryp,
- size_t size,
- const uint8_t *keyp);
-#endif
-#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_HMACSHA256_init(CRYDriver *cryp,
- HMACSHA256Context *hmacsha256ctxp);
- cryerror_t cry_lld_HMACSHA256_update(CRYDriver *cryp,
- HMACSHA256Context *hmacsha256ctxp,
- size_t size, const uint8_t *in);
- cryerror_t cry_lld_HMACSHA256_final(CRYDriver *cryp,
- HMACSHA256Context *hmacsha256ctxp,
- uint8_t *out);
-#endif
-#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__)
- cryerror_t cry_lld_HMACSHA512_init(CRYDriver *cryp,
- HMACSHA512Context *hmacsha512ctxp);
- cryerror_t cry_lld_HMACSHA512_update(CRYDriver *cryp,
- HMACSHA512Context *hmacsha512ctxp,
- size_t size, const uint8_t *in);
- cryerror_t cry_lld_HMACSHA512_final(CRYDriver *cryp,
- HMACSHA512Context *hmacsha512ctxp,
- uint8_t *out);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_CRY == TRUE */
-
-#endif /* HAL_CRYPTO_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 CRYPv1/hal_cry_lld.h
+ * @brief STM32 cryptographic subsystem low level driver header.
+ *
+ * @addtogroup CRYPTO
+ * @{
+ */
+
+#ifndef HAL_CRYPTO_LLD_H
+#define HAL_CRYPTO_LLD_H
+
+#if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name STM32 configuration options
+ * @{
+ */
+/**
+ * @brief CRYP1 driver enable switch.
+ * @details If set to @p TRUE the support for CRYP1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_CRY_USE_CRYP1) || defined(__DOXYGEN__)
+#define STM32_CRY_USE_CRYP1 FALSE
+#endif
+
+/**
+ * @brief HASH1 driver enable switch.
+ * @details If set to @p TRUE the support for HASH1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_CRY_USE_HASH1) || defined(__DOXYGEN__)
+#define STM32_CRY_USE_HASH1 FALSE
+#endif
+
+/**
+ * @brief CRYP1 interrupt priority level setting.
+ */
+#if !defined(STM32_CRY_CRYP1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CRY_CRYP1_IRQ_PRIORITY 9
+#endif
+
+/**
+ * @brief HASH1 interrupt priority level setting.
+ */
+#if !defined(STM32_CRY_HASH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CRY_HASH1_IRQ_PRIORITY 9
+#endif
+
+/**
+ * @brief HASH1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_CRY_CRYP1_OUT_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CRY_CRYP1_OUT_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief HASH1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_CRY_HASH1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_CRY_HASH1_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief Minimum message size (in words) for DMA use.
+ * @note If set to zero then DMA is never used.
+ * @note If set to one then DMA is always used.
+ */
+#if !defined(STM32_CRY_HASH_SIZE_THRESHOLD) || defined(__DOXYGEN__)
+#define STM32_CRY_HASH_SIZE_THRESHOLD 1024
+#endif
+
+/**
+ * @brief Minimum text size (in bytes) for DMA use.
+ * @note If set to zero then DMA is never used.
+ * @note If set to one then DMA is always used.
+ */
+#if !defined(STM32_CRY_CRYP_SIZE_THRESHOLD) || defined(__DOXYGEN__)
+#define STM32_CRY_CRYP_SIZE_THRESHOLD 1024
+#endif
+
+/**
+ * @brief Hash DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_CRY_HASH_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_CRY_HASH_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure")
+#endif
+
+/**
+ * @brief CRYP DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_CRY_CRYP_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_CRY_CRYP_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if (STM32_CRY_USE_CRYP1 == TRUE) || (STM32_CRY_USE_HASH1 == TRUE) || \
+ defined (__DOXYGEN__)
+#define STM32_CRY_ENABLED1 TRUE
+#else
+#define STM32_CRY_ENABLED1 FALSE
+#endif
+
+#if !defined (STM32_HAS_CRYP1)
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+#if !defined (STM32_HAS_HASH1)
+#define STM32_HAS_HASH1 FALSE
+#endif
+
+#if STM32_CRY_USE_CRYP1 && !STM32_HAS_CRYP1
+#error "CRYP1 not present in the selected device"
+#endif
+
+#if STM32_CRY_USE_HASH1 && !STM32_HAS_HASH1
+#error "HASH1 not present in the selected device"
+#endif
+
+#if !STM32_CRY_ENABLED1
+#error "CRY driver activated but no CRYP nor HASH peripheral assigned"
+#endif
+
+#if STM32_CRY_USE_HASH1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_CRY_HASH1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to HASH1"
+#endif
+
+#if STM32_CRY_USE_CRYP1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_CRY_CRYP1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to CRYP1"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if !defined(STM32_CRY_HASH1_DMA_STREAM)
+#error "HASH1 DMA streams not defined"
+#endif
+
+/* Sanity checks on DMA streams settings in mcuconf.h.*/
+#if STM32_CRY_USE_HASH1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_CRY_HASH1_DMA_STREAM)
+#error "Invalid DMA stream assigned to HASH1"
+#endif
+
+/* Devices without DMAMUX require an additional check.*/
+#if !STM32_DMA_SUPPORTS_DMAMUX
+#if STM32_CRY_USE_CRYP1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_CRY_CRYP1_IN_DMA_STREAM, \
+ STM32_CRYP1_IN_DMA_MSK)
+#error "invalid DMA stream associated to CRYP1_IN"
+#endif
+
+#if STM32_CRY_USE_CRYP1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_CRY_CRYP1_OUT_DMA_STREAM, \
+ STM32_CRYP1_OUT_DMA_MSK)
+#error "invalid DMA stream associated to CRYP1_OUT"
+#endif
+
+#if STM32_CRY_USE_HASH1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_CRY_HASH1_DMA_STREAM, STM32_HASH1_DMA_MSK)
+#error "invalid DMA stream associated to HASH1"
+#endif
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* DMA priority check.*/
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_CRY_CRYP1_IN_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to CRYP1_IN"
+#endif
+
+/* DMA priority check.*/
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_CRY_CRYP1_OUT_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to CRYP1_OUT"
+#endif
+
+/* DMA priority check.*/
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_CRY_HASH1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to HASH1"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+#if STM32_CRY_HASH_SIZE_THRESHOLD < 0
+#error "invalid STM32_CRY_HASH_SIZE_THRESHOLD value"
+#endif
+
+/**
+ * @name Driver capability switches
+ * @{
+ */
+#if STM32_CRY_USE_CRYP1 || defined (__DOXYGEN__)
+#define CRY_LLD_SUPPORTS_AES TRUE
+#define CRY_LLD_SUPPORTS_AES_ECB TRUE
+#define CRY_LLD_SUPPORTS_AES_CBC TRUE
+#define CRY_LLD_SUPPORTS_AES_CFB FALSE
+#define CRY_LLD_SUPPORTS_AES_CTR TRUE
+#define CRY_LLD_SUPPORTS_AES_GCM TRUE
+#define CRY_LLD_SUPPORTS_DES TRUE
+#define CRY_LLD_SUPPORTS_DES_ECB TRUE
+#define CRY_LLD_SUPPORTS_DES_CBC TRUE
+#else
+#define CRY_LLD_SUPPORTS_AES FALSE
+#define CRY_LLD_SUPPORTS_AES_ECB FALSE
+#define CRY_LLD_SUPPORTS_AES_CBC FALSE
+#define CRY_LLD_SUPPORTS_AES_CFB FALSE
+#define CRY_LLD_SUPPORTS_AES_CTR FALSE
+#define CRY_LLD_SUPPORTS_AES_GCM FALSE
+#define CRY_LLD_SUPPORTS_DES FALSE
+#define CRY_LLD_SUPPORTS_DES_ECB FALSE
+#define CRY_LLD_SUPPORTS_DES_CBC FALSE
+#endif
+#if STM32_CRY_USE_HASH1 || defined (__DOXYGEN__)
+#define CRY_LLD_SUPPORTS_SHA1 FALSE
+#define CRY_LLD_SUPPORTS_SHA256 TRUE
+#define CRY_LLD_SUPPORTS_SHA512 FALSE
+#define CRY_LLD_SUPPORTS_HMAC_SHA256 TRUE
+#define CRY_LLD_SUPPORTS_HMAC_SHA512 FALSE
+#else
+#define CRY_LLD_SUPPORTS_SHA1 FALSE
+#define CRY_LLD_SUPPORTS_SHA256 FALSE
+#define CRY_LLD_SUPPORTS_SHA512 FALSE
+#define CRY_LLD_SUPPORTS_HMAC_SHA256 FALSE
+#define CRY_LLD_SUPPORTS_HMAC_SHA512 FALSE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief CRY key identifier type.
+ */
+typedef uint32_t crykey_t;
+
+/**
+ * @brief Type of a structure representing an CRY driver.
+ */
+typedef struct CRYDriver CRYDriver;
+
+/**
+ * @brief Type of key stored in CRYP.
+ */
+typedef enum {
+ cryp_key_none = 0,
+ cryp_key_des = 1,
+ cryp_key_tdes = 2,
+ cryp_key_aes_encrypt = 3,
+ cryp_key_aes_decrypt = 4
+} cryp_ktype_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ uint32_t dummy;
+} CRYConfig;
+
+/**
+ * @brief Structure representing an CRY driver.
+ */
+struct CRYDriver {
+ /**
+ * @brief Driver state.
+ */
+ crystate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const CRYConfig *config;
+#if defined(CRY_DRIVER_EXT_FIELDS)
+ CRY_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+#if (STM32_CRY_USE_CRYP1 == TRUE) || defined (__DOXYGEN__)
+ /**
+ * @brief Type of the key currently stored in CRYP.
+ */
+ cryp_ktype_t cryp_ktype;
+ /**
+ * @brief Key size setup value for CR register.
+ */
+ uint32_t cryp_ksize;
+ /**
+ * @brief Transient key data.
+ */
+ uint32_t cryp_k[8];
+#if (STM32_CRY_CRYP_SIZE_THRESHOLD != 0) || defined (__DOXYGEN__)
+ /**
+ * @brief Thread reference for CRYP operations.
+ */
+ thread_reference_t cryp_tr;
+ /**
+ * @brief CRYP IN DMA stream.
+ */
+ const stm32_dma_stream_t *cryp_dma_in;
+ /**
+ * @brief CRYP OUT DMA stream.
+ */
+ const stm32_dma_stream_t *cryp_dma_out;
+#endif /* STM32_CRY_CRYP_SIZE_THRESHOLD != 0 */
+#endif /* STM32_CRY_USE_CRYP1 == TRUE */
+#if (STM32_CRY_USE_HASH1 == TRUE) || defined (__DOXYGEN__)
+#if (STM32_CRY_HASH_SIZE_THRESHOLD != 0) || defined (__DOXYGEN__)
+ /**
+ * @brief Thread reference for hash operations.
+ */
+ thread_reference_t hash_tr;
+ /**
+ * @brief Hash DMA stream.
+ */
+ const stm32_dma_stream_t *hash_dma;
+#endif /* STM32_CRY_HASH_SIZE_THRESHOLD != 0 */
+#endif /* STM32_CRY_USE_HASH1 == TRUE */
+};
+
+#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a SHA1 context.
+ */
+typedef struct {
+ uint32_t dummy;
+} SHA1Context;
+#endif
+
+#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a SHA256 context.
+ */
+typedef struct {
+ /**
+ * @brief Last data to be hashed on finalization.
+ */
+ uint32_t last_data;
+ /**
+ * @brief Size, in bits, of the last data.
+ */
+ uint32_t last_size;
+} SHA256Context;
+#endif
+
+#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a SHA512 context.
+ */
+typedef struct {
+ uint32_t dummy;
+} SHA512Context;
+#endif
+
+#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a HMAC_SHA256 context.
+ */
+typedef struct {
+ uint32_t dummy;
+} HMACSHA256Context;
+#endif
+
+#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a HMAC_SHA512 context.
+ */
+typedef struct {
+ uint32_t dummy;
+} HMACSHA512Context;
+#endif
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if (STM32_CRY_ENABLED1 == TRUE) && !defined(__DOXYGEN__)
+extern CRYDriver CRYD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void cry_lld_init(void);
+ void cry_lld_start(CRYDriver *cryp);
+ void cry_lld_stop(CRYDriver *cryp);
+#if (CRY_LLD_SUPPORTS_AES == TRUE) || \
+ (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || \
+ (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || \
+ (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || \
+ (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || \
+ (CRY_LLD_SUPPORTS_AES_GCM == TRUE) || \
+ defined(__DOXYGEN__)
+ cryerror_t cry_lld_aes_loadkey(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *keyp);
+#endif
+#if (CRY_LLD_SUPPORTS_AES == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_AES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out);
+ cryerror_t cry_lld_decrypt_AES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out);
+ cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+ cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+#endif
+#if (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+ cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+#endif
+#if (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+ cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+#endif
+#if (CRY_LLD_SUPPORTS_AES_GCM == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_AES_GCM(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t auth_size,
+ const uint8_t *auth_in,
+ size_t text_size,
+ const uint8_t *text_in,
+ uint8_t *text_out,
+ const uint8_t *iv,
+ size_t tag_size,
+ uint8_t *tag_out);
+ cryerror_t cry_lld_decrypt_AES_GCM(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t auth_size,
+ const uint8_t *auth_in,
+ size_t text_size,
+ const uint8_t *text_in,
+ uint8_t *text_out,
+ const uint8_t *iv,
+ size_t tag_size,
+ const uint8_t *tag_in);
+#endif
+#if (CRY_LLD_SUPPORTS_DES == TRUE) || \
+ (CRY_LLD_SUPPORTS_DES_ECB == TRUE) || \
+ (CRY_LLD_SUPPORTS_DES_CBC == TRUE) || \
+ defined(__DOXYGEN__)
+ cryerror_t cry_lld_des_loadkey(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *keyp);
+#endif
+#if (CRY_LLD_SUPPORTS_DES == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_DES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out);
+ cryerror_t cry_lld_decrypt_DES(CRYDriver *cryp,
+ crykey_t key_id,
+ const uint8_t *in,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_DES_ECB == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_DES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out);
+ cryerror_t cry_lld_decrypt_DES_ECB(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_DES_CBC == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_encrypt_DES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+ cryerror_t cry_lld_decrypt_DES_CBC(CRYDriver *cryp,
+ crykey_t key_id,
+ size_t size,
+ const uint8_t *in,
+ uint8_t *out,
+ const uint8_t *iv);
+#endif
+#if (CRY_LLD_SUPPORTS_SHA1 == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_SHA1_init(CRYDriver *cryp, SHA1Context *sha1ctxp);
+ cryerror_t cry_lld_SHA1_update(CRYDriver *cryp, SHA1Context *sha1ctxp,
+ size_t size, const uint8_t *in);
+ cryerror_t cry_lld_SHA1_final(CRYDriver *cryp, SHA1Context *sha1ctxp,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_SHA256 == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp);
+ cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp,
+ size_t size, const uint8_t *in);
+ cryerror_t cry_lld_SHA256_final(CRYDriver *cryp, SHA256Context *sha256ctxp,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_SHA512 == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_SHA512_init(CRYDriver *cryp, SHA512Context *sha512ctxp);
+ cryerror_t cry_lld_SHA512_update(CRYDriver *cryp, SHA512Context *sha512ctxp,
+ size_t size, const uint8_t *in);
+ cryerror_t cry_lld_SHA512_final(CRYDriver *cryp, SHA512Context *sha512ctxp,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || \
+ (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || \
+ defined(__DOXYGEN__)
+ cryerror_t cry_lld_hmac_loadkey(CRYDriver *cryp,
+ size_t size,
+ const uint8_t *keyp);
+#endif
+#if (CRY_LLD_SUPPORTS_HMAC_SHA256 == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_HMACSHA256_init(CRYDriver *cryp,
+ HMACSHA256Context *hmacsha256ctxp);
+ cryerror_t cry_lld_HMACSHA256_update(CRYDriver *cryp,
+ HMACSHA256Context *hmacsha256ctxp,
+ size_t size, const uint8_t *in);
+ cryerror_t cry_lld_HMACSHA256_final(CRYDriver *cryp,
+ HMACSHA256Context *hmacsha256ctxp,
+ uint8_t *out);
+#endif
+#if (CRY_LLD_SUPPORTS_HMAC_SHA512 == TRUE) || defined(__DOXYGEN__)
+ cryerror_t cry_lld_HMACSHA512_init(CRYDriver *cryp,
+ HMACSHA512Context *hmacsha512ctxp);
+ cryerror_t cry_lld_HMACSHA512_update(CRYDriver *cryp,
+ HMACSHA512Context *hmacsha512ctxp,
+ size_t size, const uint8_t *in);
+ cryerror_t cry_lld_HMACSHA512_final(CRYDriver *cryp,
+ HMACSHA512Context *hmacsha512ctxp,
+ uint8_t *out);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_CRY == TRUE */
+
+#endif /* HAL_CRYPTO_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DACv1/driver.mk b/os/hal/ports/STM32/LLD/DACv1/driver.mk
index da951486d6..7807214bac 100644
--- a/os/hal/ports/STM32/LLD/DACv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/DACv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_DAC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_DAC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1
diff --git a/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c b/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
index ca6ebf90cf..a5e6e14766 100644
--- a/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
+++ b/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.c
@@ -1,785 +1,785 @@
-/*
- 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 DACv1/hal_dac_lld.c
- * @brief STM32 DAC subsystem low level driver source.
- *
- * @addtogroup DAC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_DAC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* Because ST headers naming inconsistencies.*/
-#if !defined(DAC1)
-#define DAC1 DAC
-#endif
-
-#define DAC1_CH1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC1_CH1_DMA_STREAM, \
- STM32_DAC1_CH1_DMA_CHN)
-
-#define DAC1_CH2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC1_CH2_DMA_STREAM, \
- STM32_DAC1_CH2_DMA_CHN)
-
-#define DAC2_CH1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC2_CH1_DMA_STREAM, \
- STM32_DAC2_CH1_DMA_CHN)
-
-#define DAC2_CH2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC2_CH2_DMA_STREAM, \
- STM32_DAC2_CH2_DMA_CHN)
-
-#define DAC3_CH1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC3_CH1_DMA_STREAM, \
- STM32_DAC3_CH1_DMA_CHN)
-
-#define DAC3_CH2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC3_CH2_DMA_STREAM, \
- STM32_DAC3_CH2_DMA_CHN)
-
-#define DAC4_CH1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC4_CH1_DMA_STREAM, \
- STM32_DAC4_CH1_DMA_CHN)
-
-#define DAC4_CH2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_DAC_DAC4_CH2_DMA_STREAM, \
- STM32_DAC4_CH2_DMA_CHN)
-
-#define CHANNEL_DATA_OFFSET 3U
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief DAC1 CH1 driver identifier.*/
-#if STM32_DAC_USE_DAC1_CH1 || defined(__DOXYGEN__)
-DACDriver DACD1;
-#endif
-
-/** @brief DAC1 CH2 driver identifier.*/
-#if (STM32_DAC_USE_DAC1_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
-DACDriver DACD2;
-#endif
-
-/** @brief DAC2 CH1 driver identifier.*/
-#if STM32_DAC_USE_DAC2_CH1 || defined(__DOXYGEN__)
-DACDriver DACD3;
-#endif
-
-/** @brief DAC2 CH2 driver identifier.*/
-#if (STM32_DAC_USE_DAC2_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
-DACDriver DACD4;
-#endif
-
-/** @brief DAC3 CH1 driver identifier.*/
-#if STM32_DAC_USE_DAC3_CH1 || defined(__DOXYGEN__)
-DACDriver DACD5;
-#endif
-
-/** @brief DAC3 CH2 driver identifier.*/
-#if (STM32_DAC_USE_DAC3_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
-DACDriver DACD6;
-#endif
-
-/** @brief DAC4 CH1 driver identifier.*/
-#if STM32_DAC_USE_DAC4_CH1 || defined(__DOXYGEN__)
-DACDriver DACD7;
-#endif
-
-/** @brief DAC4 CH2 driver identifier.*/
-#if (STM32_DAC_USE_DAC4_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
-DACDriver DACD8;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-#if STM32_DAC_USE_DAC1_CH1 == TRUE
-static const dacparams_t dac1_ch1_params = {
- .dac = DAC1,
- .dataoffset = 0U,
- .regshift = 0U,
- .regmask = 0xFFFF0000U,
- .dmastream = STM32_DAC_DAC1_CH1_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC1_CH1,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC1_CH1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC1_CH1_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC1_CH1_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 == TRUE
-static const dacparams_t dac1_ch2_params = {
- .dac = DAC1,
- .dataoffset = CHANNEL_DATA_OFFSET,
- .regshift = 16U,
- .regmask = 0x0000FFFFU,
- .dmastream = STM32_DAC_DAC1_CH2_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC1_CH2,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC1_CH2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC1_CH2_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC1_CH2_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 == TRUE
-static const dacparams_t dac2_ch1_params = {
- .dac = DAC2,
- .dataoffset = 0U,
- .regshift = 0U,
- .regmask = 0xFFFF0000U,
- .dmastream = STM32_DAC_DAC2_CH1_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC2_CH1,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC2_CH1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC2_CH1_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC2_CH1_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 == TRUE
-static const dacparams_t dac2_ch2_params = {
- .dac = DAC2,
- .dataoffset = CHANNEL_DATA_OFFSET,
- .regshift = 16U,
- .regmask = 0x0000FFFFU,
- .dmastream = STM32_DAC_DAC2_CH2_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC2_CH2,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC2_CH2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC2_CH2_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC2_CH2_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 == TRUE
-static const dacparams_t dac3_ch1_params = {
- .dac = DAC3,
- .dataoffset = 0U,
- .regshift = 0U,
- .regmask = 0xFFFF0000U,
- .dmastream = STM32_DAC_DAC3_CH1_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC3_CH1,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC3_CH1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC3_CH1_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC3_CH1_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 == TRUE
-static const dacparams_t dac3_ch2_params = {
- .dac = DAC3,
- .dataoffset = CHANNEL_DATA_OFFSET,
- .regshift = 16U,
- .regmask = 0x0000FFFFU,
- .dmastream = STM32_DAC_DAC3_CH2_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC3_CH2,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC3_CH2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC3_CH2_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC3_CH2_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 == TRUE
-static const dacparams_t dac4_ch1_params = {
- .dac = DAC4,
- .dataoffset = 0U,
- .regshift = 0U,
- .regmask = 0xFFFF0000U,
- .dmastream = STM32_DAC_DAC4_CH1_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC4_CH1,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC4_CH1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC4_CH1_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC4_CH1_IRQ_PRIORITY
-};
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 == TRUE
-static const dacparams_t dac4_ch2_params = {
- .dac = DAC4,
- .dataoffset = CHANNEL_DATA_OFFSET,
- .regshift = 16U,
- .regmask = 0x0000FFFFU,
- .dmastream = STM32_DAC_DAC4_CH2_DMA_STREAM,
-#if STM32_DMA_SUPPORTS_DMAMUX
- .peripheral = STM32_DMAMUX1_DAC4_CH2,
-#endif
- .dmamode = STM32_DMA_CR_CHSEL(DAC4_CH2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_DAC_DAC4_CH2_DMA_PRIORITY) |
- STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE,
- .dmairqprio = STM32_DAC_DAC4_CH2_IRQ_PRIORITY
-};
-#endif
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Shared end/half-of-tx service routine.
- *
- * @param[in] dacp pointer to the @p DACDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void dac_lld_serve_tx_interrupt(DACDriver *dacp, uint32_t flags) {
-
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA errors handling.*/
- dac_lld_stop_conversion(dacp);
- _dac_isr_error_code(dacp, DAC_ERR_DMAFAILURE);
- }
- else {
- if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _dac_isr_half_code(dacp);
- }
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _dac_isr_full_code(dacp);
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level DAC driver initialization.
- *
- * @notapi
- */
-void dac_lld_init(void) {
-
-#if STM32_DAC_USE_DAC1_CH1
- dacObjectInit(&DACD1);
- DACD1.params = &dac1_ch1_params;
- DACD1.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2
- dacObjectInit(&DACD2);
- DACD2.params = &dac1_ch2_params;
- DACD2.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1
- dacObjectInit(&DACD3);
- DACD3.params = &dac2_ch1_params;
- DACD3.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2
- dacObjectInit(&DACD4);
- DACD4.params = &dac2_ch2_params;
- DACD4.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1
- dacObjectInit(&DACD5);
- DACD5.params = &dac3_ch1_params;
- DACD5.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2
- dacObjectInit(&DACD6);
- DACD6.params = &dac3_ch2_params;
- DACD6.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1
- dacObjectInit(&DACD7);
- DACD7.params = &dac4_ch1_params;
- DACD7.dma = NULL;
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2
- dacObjectInit(&DACD8);
- DACD8.params = &dac4_ch2_params;
- DACD8.dma = NULL;
-#endif
-}
-
-/**
- * @brief Configures and activates the DAC peripheral.
- *
- * @param[in] dacp pointer to the @p DACDriver object
- *
- * @notapi
- */
-void dac_lld_start(DACDriver *dacp) {
-
- /* If the driver is in DAC_STOP state then a full initialization is
- required.*/
- if (dacp->state == DAC_STOP) {
- dacchannel_t channel = 0;
-
- /* Enabling the clock source.*/
-#if STM32_DAC_USE_DAC1_CH1
- if (&DACD1 == dacp) {
- rccEnableDAC1(true);
- }
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2
- if (&DACD2 == dacp) {
- rccEnableDAC1(true);
- channel = 1;
- }
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1
- if (&DACD3 == dacp) {
- rccEnableDAC2(true);
- }
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2
- if (&DACD4 == dacp) {
- rccEnableDAC2(true);
- channel = 1;
- }
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1
- if (&DACD5 == dacp) {
- rccEnableDAC3(true);
- }
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2
- if (&DACD6 == dacp) {
- rccEnableDAC3(true);
- channel = 1;
- }
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1
- if (&DACD7 == dacp) {
- rccEnableDAC4(true);
- }
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2
- if (&DACD8 == dacp) {
- rccEnableDAC4(true);
- channel = 1;
- }
-#endif
-
- /* Enabling DAC in SW triggering mode initially, initializing data to
- zero.*/
-#if STM32_DAC_DUAL_MODE == FALSE
- {
- uint32_t cr;
-
- cr = dacp->params->dac->CR;
- cr &= dacp->params->regmask;
- cr |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
- dacp->params->dac->CR = cr;
- dac_lld_put_channel(dacp, channel, dacp->config->init);
- }
-#else
- if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) ||
- (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) ||
- (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) {
- dacp->params->dac->CR = DAC_CR_EN2 | (dacp->config->cr << 16) | DAC_CR_EN1 | dacp->config->cr;
- dac_lld_put_channel(dacp, 1U, dacp->config->init);
- }
- else {
- dacp->params->dac->CR = DAC_CR_EN1 | dacp->config->cr;
- }
- dac_lld_put_channel(dacp, channel, dacp->config->init);
-#endif
- }
-}
-
-/**
- * @brief Deactivates the DAC peripheral.
- *
- * @param[in] dacp pointer to the @p DACDriver object
- *
- * @notapi
- */
-void dac_lld_stop(DACDriver *dacp) {
-
- /* If in ready state then disables the DAC clock.*/
- if (dacp->state == DAC_READY) {
-
- /* Disabling DAC.*/
- dacp->params->dac->CR &= dacp->params->regmask;
-
-#if STM32_DAC_USE_DAC1_CH1
- if (&DACD1 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
- rccDisableDAC1();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2
- if (&DACD2 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
- rccDisableDAC1();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1
- if (&DACD3 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
- rccDisableDAC2();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2
- if (&DACD4 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
- rccDisableDAC2();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1
- if (&DACD5 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
- rccDisableDAC3();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2
- if (&DACD6 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
- rccDisableDAC3();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1
- if (&DACD7 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
- rccDisableDAC4();
- }
- }
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2
- if (&DACD8 == dacp) {
- if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
- rccDisableDAC4();
- }
- }
-#endif
- }
-}
-
-/**
- * @brief Outputs a value directly on a DAC channel.
- *
- * @param[in] dacp pointer to the @p DACDriver object
- * @param[in] channel DAC channel number
- * @param[in] sample value to be output
- *
- * @api
- */
-void dac_lld_put_channel(DACDriver *dacp,
- dacchannel_t channel,
- dacsample_t sample) {
-
- switch (dacp->config->datamode) {
- case DAC_DHRM_12BIT_RIGHT:
-#if STM32_DAC_DUAL_MODE
- case DAC_DHRM_12BIT_RIGHT_DUAL:
-#endif
- if (channel == 0U) {
-#if STM32_DAC_DUAL_MODE
- dacp->params->dac->DHR12R1 = (uint32_t)sample;
-#else
- *(&dacp->params->dac->DHR12R1 + dacp->params->dataoffset) = (uint32_t)sample;
-#endif
- }
-#if (STM32_HAS_DAC1_CH2 || STM32_HAS_DAC2_CH2 || \
- STM32_HAS_DAC3_CH2 || STM32_HAS_DAC4_CH2)
- else {
- dacp->params->dac->DHR12R2 = (uint32_t)sample;
- }
-#endif
- break;
- case DAC_DHRM_12BIT_LEFT:
-#if STM32_DAC_DUAL_MODE
- case DAC_DHRM_12BIT_LEFT_DUAL:
-#endif
- if (channel == 0U) {
-#if STM32_DAC_DUAL_MODE
- dacp->params->dac->DHR12L1 = (uint32_t)sample;
-#else
- *(&dacp->params->dac->DHR12L1 + dacp->params->dataoffset) = (uint32_t)sample;
-#endif
- }
-#if (STM32_HAS_DAC1_CH2 || STM32_HAS_DAC2_CH2 || \
- STM32_HAS_DAC3_CH2 || STM32_HAS_DAC4_CH2)
- else {
- dacp->params->dac->DHR12L2 = (uint32_t)sample;
- }
-#endif
- break;
- case DAC_DHRM_8BIT_RIGHT:
-#if STM32_DAC_DUAL_MODE
- case DAC_DHRM_8BIT_RIGHT_DUAL:
-#endif
- if (channel == 0U) {
-#if STM32_DAC_DUAL_MODE
- dacp->params->dac->DHR8R1 = (uint32_t)sample;
-#else
- *(&dacp->params->dac->DHR8R1 + dacp->params->dataoffset) = (uint32_t)sample;
-#endif
- }
-#if (STM32_HAS_DAC1_CH2 || STM32_HAS_DAC2_CH2 || \
- STM32_HAS_DAC3_CH2 || STM32_HAS_DAC4_CH2)
- else {
- dacp->params->dac->DHR8R2 = (uint32_t)sample;
- }
-#endif
- break;
- default:
- osalDbgAssert(false, "unexpected DAC mode");
- break;
- }
-}
-
-/**
- * @brief Starts a DAC conversion.
- * @details Starts an asynchronous conversion operation.
- * @note In @p DAC_DHRM_8BIT_RIGHT mode the parameters passed to the
- * callback are wrong because two samples are packed in a single
- * dacsample_t element. This will not be corrected, do not rely
- * on those parameters.
- * @note In @p DAC_DHRM_8BIT_RIGHT_DUAL mode two samples are treated
- * as a single 16 bits sample and packed into a single dacsample_t
- * element. The num_channels must be set to one in the group
- * conversion configuration structure.
- *
- * @param[in] dacp pointer to the @p DACDriver object
- *
- * @notapi
- */
-void dac_lld_start_conversion(DACDriver *dacp) {
- uint32_t n, cr, dmamode;
-
- /* Number of DMA operations per buffer.*/
- n = dacp->depth * dacp->grpp->num_channels;
-
- /* Allocating the DMA channel.*/
- dacp->dma = dmaStreamAllocI(dacp->params->dmastream,
- dacp->params->dmairqprio,
- (stm32_dmaisr_t)dac_lld_serve_tx_interrupt,
- (void *)dacp);
- osalDbgAssert(dacp->dma != NULL, "unable to allocate stream");
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(dacp->dma, dacp->params->peripheral);
-#endif
-
- /* DMA settings depend on the chosen DAC mode.*/
- switch (dacp->config->datamode) {
- /* Sets the DAC data register */
- case DAC_DHRM_12BIT_RIGHT:
- osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
-
- dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12R1 +
- dacp->params->dataoffset);
- dmamode = dacp->params->dmamode |
-#if STM32_DMA_ADVANCED == FALSE
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_HWORD;
-#else
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
-#endif
- break;
- case DAC_DHRM_12BIT_LEFT:
- osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
-
- dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12L1 +
- dacp->params->dataoffset);
- dmamode = dacp->params->dmamode |
-#if STM32_DMA_ADVANCED == FALSE
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_HWORD;
-#else
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
-#endif
- break;
- case DAC_DHRM_8BIT_RIGHT:
- osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
-
- dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR8R1 +
- dacp->params->dataoffset);
- dmamode = dacp->params->dmamode |
-#if STM32_DMA_ADVANCED == FALSE
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_BYTE;
-#else
- STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
-#endif
-
- /* In this mode the size of the buffer is halved because two samples
- packed in a single dacsample_t element.*/
- n = (n + 1) / 2;
- break;
-#if STM32_DAC_DUAL_MODE == TRUE
- case DAC_DHRM_12BIT_RIGHT_DUAL:
- osalDbgAssert(dacp->grpp->num_channels == 2, "invalid number of channels");
-
- dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12RD);
- dmamode = dacp->params->dmamode |
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
- n /= 2;
- break;
- case DAC_DHRM_12BIT_LEFT_DUAL:
- osalDbgAssert(dacp->grpp->num_channels == 2, "invalid number of channels");
-
- dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12LD);
- dmamode = dacp->params->dmamode |
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
- n /= 2;
- break;
- case DAC_DHRM_8BIT_RIGHT_DUAL:
- osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
-
- dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR8RD);
- dmamode = dacp->params->dmamode |
-#if STM32_DMA_ADVANCED == FALSE
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_HWORD;
-#else
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
-#endif
- n /= 2;
- break;
-#endif
- default:
- osalDbgAssert(false, "unexpected DAC mode");
- return;
- }
-
- dmaStreamSetMemory0(dacp->dma, dacp->samples);
- dmaStreamSetTransactionSize(dacp->dma, n);
- dmaStreamSetMode(dacp->dma, dmamode |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
- STM32_DMA_CR_HTIE | STM32_DMA_CR_TCIE);
- dmaStreamEnable(dacp->dma);
-
- /* DAC configuration.*/
- cr = dacp->params->dac->CR;
-
-#if STM32_DAC_DUAL_MODE == FALSE
- cr &= dacp->params->regmask;
- cr |= (DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) | DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
-#else
- cr = DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) | DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr
- | (dacp->grpp->trigger << DAC_CR_TSEL2_Pos) | DAC_CR_TEN2 | DAC_CR_EN2 | (dacp->config->cr << 16);
-#endif
-
- dacp->params->dac->CR = cr;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- * @details This function stops the currently ongoing conversion and returns
- * the driver in the @p DAC_READY state. If there was no conversion
- * being processed then the function does nothing.
- *
- * @param[in] dacp pointer to the @p DACDriver object
- *
- * @iclass
- */
-void dac_lld_stop_conversion(DACDriver *dacp) {
- uint32_t cr;
-
- /* DMA channel disabled and released.*/
- dmaStreamDisable(dacp->dma);
- dmaStreamFreeI(dacp->dma);
- dacp->dma = NULL;
-
- cr = dacp->params->dac->CR;
-
-#if STM32_DAC_DUAL_MODE == FALSE
- cr &= dacp->params->regmask;
- cr |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
-#else
- if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) ||
- (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) ||
- (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) {
- cr = DAC_CR_EN2 | (dacp->config->cr << 16) |
- DAC_CR_EN1 | dacp->config->cr;
- }
- else {
- cr = DAC_CR_EN1 | dacp->config->cr;
- }
-#endif
-
- dacp->params->dac->CR = cr;
-}
-
-#endif /* HAL_USE_DAC */
-
-/** @} */
+/*
+ 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 DACv1/hal_dac_lld.c
+ * @brief STM32 DAC subsystem low level driver source.
+ *
+ * @addtogroup DAC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_DAC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* Because ST headers naming inconsistencies.*/
+#if !defined(DAC1)
+#define DAC1 DAC
+#endif
+
+#define DAC1_CH1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC1_CH1_DMA_STREAM, \
+ STM32_DAC1_CH1_DMA_CHN)
+
+#define DAC1_CH2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC1_CH2_DMA_STREAM, \
+ STM32_DAC1_CH2_DMA_CHN)
+
+#define DAC2_CH1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC2_CH1_DMA_STREAM, \
+ STM32_DAC2_CH1_DMA_CHN)
+
+#define DAC2_CH2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC2_CH2_DMA_STREAM, \
+ STM32_DAC2_CH2_DMA_CHN)
+
+#define DAC3_CH1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC3_CH1_DMA_STREAM, \
+ STM32_DAC3_CH1_DMA_CHN)
+
+#define DAC3_CH2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC3_CH2_DMA_STREAM, \
+ STM32_DAC3_CH2_DMA_CHN)
+
+#define DAC4_CH1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC4_CH1_DMA_STREAM, \
+ STM32_DAC4_CH1_DMA_CHN)
+
+#define DAC4_CH2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_DAC_DAC4_CH2_DMA_STREAM, \
+ STM32_DAC4_CH2_DMA_CHN)
+
+#define CHANNEL_DATA_OFFSET 3U
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief DAC1 CH1 driver identifier.*/
+#if STM32_DAC_USE_DAC1_CH1 || defined(__DOXYGEN__)
+DACDriver DACD1;
+#endif
+
+/** @brief DAC1 CH2 driver identifier.*/
+#if (STM32_DAC_USE_DAC1_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
+DACDriver DACD2;
+#endif
+
+/** @brief DAC2 CH1 driver identifier.*/
+#if STM32_DAC_USE_DAC2_CH1 || defined(__DOXYGEN__)
+DACDriver DACD3;
+#endif
+
+/** @brief DAC2 CH2 driver identifier.*/
+#if (STM32_DAC_USE_DAC2_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
+DACDriver DACD4;
+#endif
+
+/** @brief DAC3 CH1 driver identifier.*/
+#if STM32_DAC_USE_DAC3_CH1 || defined(__DOXYGEN__)
+DACDriver DACD5;
+#endif
+
+/** @brief DAC3 CH2 driver identifier.*/
+#if (STM32_DAC_USE_DAC3_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
+DACDriver DACD6;
+#endif
+
+/** @brief DAC4 CH1 driver identifier.*/
+#if STM32_DAC_USE_DAC4_CH1 || defined(__DOXYGEN__)
+DACDriver DACD7;
+#endif
+
+/** @brief DAC4 CH2 driver identifier.*/
+#if (STM32_DAC_USE_DAC4_CH2 && !STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
+DACDriver DACD8;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+#if STM32_DAC_USE_DAC1_CH1 == TRUE
+static const dacparams_t dac1_ch1_params = {
+ .dac = DAC1,
+ .dataoffset = 0U,
+ .regshift = 0U,
+ .regmask = 0xFFFF0000U,
+ .dmastream = STM32_DAC_DAC1_CH1_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC1_CH1,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC1_CH1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC1_CH1_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC1_CH1_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 == TRUE
+static const dacparams_t dac1_ch2_params = {
+ .dac = DAC1,
+ .dataoffset = CHANNEL_DATA_OFFSET,
+ .regshift = 16U,
+ .regmask = 0x0000FFFFU,
+ .dmastream = STM32_DAC_DAC1_CH2_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC1_CH2,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC1_CH2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC1_CH2_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC1_CH2_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 == TRUE
+static const dacparams_t dac2_ch1_params = {
+ .dac = DAC2,
+ .dataoffset = 0U,
+ .regshift = 0U,
+ .regmask = 0xFFFF0000U,
+ .dmastream = STM32_DAC_DAC2_CH1_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC2_CH1,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC2_CH1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC2_CH1_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC2_CH1_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 == TRUE
+static const dacparams_t dac2_ch2_params = {
+ .dac = DAC2,
+ .dataoffset = CHANNEL_DATA_OFFSET,
+ .regshift = 16U,
+ .regmask = 0x0000FFFFU,
+ .dmastream = STM32_DAC_DAC2_CH2_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC2_CH2,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC2_CH2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC2_CH2_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC2_CH2_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 == TRUE
+static const dacparams_t dac3_ch1_params = {
+ .dac = DAC3,
+ .dataoffset = 0U,
+ .regshift = 0U,
+ .regmask = 0xFFFF0000U,
+ .dmastream = STM32_DAC_DAC3_CH1_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC3_CH1,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC3_CH1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC3_CH1_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC3_CH1_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 == TRUE
+static const dacparams_t dac3_ch2_params = {
+ .dac = DAC3,
+ .dataoffset = CHANNEL_DATA_OFFSET,
+ .regshift = 16U,
+ .regmask = 0x0000FFFFU,
+ .dmastream = STM32_DAC_DAC3_CH2_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC3_CH2,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC3_CH2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC3_CH2_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC3_CH2_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 == TRUE
+static const dacparams_t dac4_ch1_params = {
+ .dac = DAC4,
+ .dataoffset = 0U,
+ .regshift = 0U,
+ .regmask = 0xFFFF0000U,
+ .dmastream = STM32_DAC_DAC4_CH1_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC4_CH1,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC4_CH1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC4_CH1_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC4_CH1_IRQ_PRIORITY
+};
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 == TRUE
+static const dacparams_t dac4_ch2_params = {
+ .dac = DAC4,
+ .dataoffset = CHANNEL_DATA_OFFSET,
+ .regshift = 16U,
+ .regmask = 0x0000FFFFU,
+ .dmastream = STM32_DAC_DAC4_CH2_DMA_STREAM,
+#if STM32_DMA_SUPPORTS_DMAMUX
+ .peripheral = STM32_DMAMUX1_DAC4_CH2,
+#endif
+ .dmamode = STM32_DMA_CR_CHSEL(DAC4_CH2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_DAC_DAC4_CH2_DMA_PRIORITY) |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE,
+ .dmairqprio = STM32_DAC_DAC4_CH2_IRQ_PRIORITY
+};
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared end/half-of-tx service routine.
+ *
+ * @param[in] dacp pointer to the @p DACDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void dac_lld_serve_tx_interrupt(DACDriver *dacp, uint32_t flags) {
+
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA errors handling.*/
+ dac_lld_stop_conversion(dacp);
+ _dac_isr_error_code(dacp, DAC_ERR_DMAFAILURE);
+ }
+ else {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _dac_isr_half_code(dacp);
+ }
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _dac_isr_full_code(dacp);
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level DAC driver initialization.
+ *
+ * @notapi
+ */
+void dac_lld_init(void) {
+
+#if STM32_DAC_USE_DAC1_CH1
+ dacObjectInit(&DACD1);
+ DACD1.params = &dac1_ch1_params;
+ DACD1.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2
+ dacObjectInit(&DACD2);
+ DACD2.params = &dac1_ch2_params;
+ DACD2.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1
+ dacObjectInit(&DACD3);
+ DACD3.params = &dac2_ch1_params;
+ DACD3.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2
+ dacObjectInit(&DACD4);
+ DACD4.params = &dac2_ch2_params;
+ DACD4.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1
+ dacObjectInit(&DACD5);
+ DACD5.params = &dac3_ch1_params;
+ DACD5.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2
+ dacObjectInit(&DACD6);
+ DACD6.params = &dac3_ch2_params;
+ DACD6.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1
+ dacObjectInit(&DACD7);
+ DACD7.params = &dac4_ch1_params;
+ DACD7.dma = NULL;
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2
+ dacObjectInit(&DACD8);
+ DACD8.params = &dac4_ch2_params;
+ DACD8.dma = NULL;
+#endif
+}
+
+/**
+ * @brief Configures and activates the DAC peripheral.
+ *
+ * @param[in] dacp pointer to the @p DACDriver object
+ *
+ * @notapi
+ */
+void dac_lld_start(DACDriver *dacp) {
+
+ /* If the driver is in DAC_STOP state then a full initialization is
+ required.*/
+ if (dacp->state == DAC_STOP) {
+ dacchannel_t channel = 0;
+
+ /* Enabling the clock source.*/
+#if STM32_DAC_USE_DAC1_CH1
+ if (&DACD1 == dacp) {
+ rccEnableDAC1(true);
+ }
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2
+ if (&DACD2 == dacp) {
+ rccEnableDAC1(true);
+ channel = 1;
+ }
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1
+ if (&DACD3 == dacp) {
+ rccEnableDAC2(true);
+ }
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2
+ if (&DACD4 == dacp) {
+ rccEnableDAC2(true);
+ channel = 1;
+ }
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1
+ if (&DACD5 == dacp) {
+ rccEnableDAC3(true);
+ }
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2
+ if (&DACD6 == dacp) {
+ rccEnableDAC3(true);
+ channel = 1;
+ }
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1
+ if (&DACD7 == dacp) {
+ rccEnableDAC4(true);
+ }
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2
+ if (&DACD8 == dacp) {
+ rccEnableDAC4(true);
+ channel = 1;
+ }
+#endif
+
+ /* Enabling DAC in SW triggering mode initially, initializing data to
+ zero.*/
+#if STM32_DAC_DUAL_MODE == FALSE
+ {
+ uint32_t cr;
+
+ cr = dacp->params->dac->CR;
+ cr &= dacp->params->regmask;
+ cr |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
+ dacp->params->dac->CR = cr;
+ dac_lld_put_channel(dacp, channel, dacp->config->init);
+ }
+#else
+ if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) ||
+ (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) ||
+ (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) {
+ dacp->params->dac->CR = DAC_CR_EN2 | (dacp->config->cr << 16) | DAC_CR_EN1 | dacp->config->cr;
+ dac_lld_put_channel(dacp, 1U, dacp->config->init);
+ }
+ else {
+ dacp->params->dac->CR = DAC_CR_EN1 | dacp->config->cr;
+ }
+ dac_lld_put_channel(dacp, channel, dacp->config->init);
+#endif
+ }
+}
+
+/**
+ * @brief Deactivates the DAC peripheral.
+ *
+ * @param[in] dacp pointer to the @p DACDriver object
+ *
+ * @notapi
+ */
+void dac_lld_stop(DACDriver *dacp) {
+
+ /* If in ready state then disables the DAC clock.*/
+ if (dacp->state == DAC_READY) {
+
+ /* Disabling DAC.*/
+ dacp->params->dac->CR &= dacp->params->regmask;
+
+#if STM32_DAC_USE_DAC1_CH1
+ if (&DACD1 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
+ rccDisableDAC1();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2
+ if (&DACD2 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
+ rccDisableDAC1();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1
+ if (&DACD3 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
+ rccDisableDAC2();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2
+ if (&DACD4 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
+ rccDisableDAC2();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1
+ if (&DACD5 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
+ rccDisableDAC3();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2
+ if (&DACD6 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
+ rccDisableDAC3();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1
+ if (&DACD7 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN2) == 0U) {
+ rccDisableDAC4();
+ }
+ }
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2
+ if (&DACD8 == dacp) {
+ if ((dacp->params->dac->CR & DAC_CR_EN1) == 0U) {
+ rccDisableDAC4();
+ }
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Outputs a value directly on a DAC channel.
+ *
+ * @param[in] dacp pointer to the @p DACDriver object
+ * @param[in] channel DAC channel number
+ * @param[in] sample value to be output
+ *
+ * @api
+ */
+void dac_lld_put_channel(DACDriver *dacp,
+ dacchannel_t channel,
+ dacsample_t sample) {
+
+ switch (dacp->config->datamode) {
+ case DAC_DHRM_12BIT_RIGHT:
+#if STM32_DAC_DUAL_MODE
+ case DAC_DHRM_12BIT_RIGHT_DUAL:
+#endif
+ if (channel == 0U) {
+#if STM32_DAC_DUAL_MODE
+ dacp->params->dac->DHR12R1 = (uint32_t)sample;
+#else
+ *(&dacp->params->dac->DHR12R1 + dacp->params->dataoffset) = (uint32_t)sample;
+#endif
+ }
+#if (STM32_HAS_DAC1_CH2 || STM32_HAS_DAC2_CH2 || \
+ STM32_HAS_DAC3_CH2 || STM32_HAS_DAC4_CH2)
+ else {
+ dacp->params->dac->DHR12R2 = (uint32_t)sample;
+ }
+#endif
+ break;
+ case DAC_DHRM_12BIT_LEFT:
+#if STM32_DAC_DUAL_MODE
+ case DAC_DHRM_12BIT_LEFT_DUAL:
+#endif
+ if (channel == 0U) {
+#if STM32_DAC_DUAL_MODE
+ dacp->params->dac->DHR12L1 = (uint32_t)sample;
+#else
+ *(&dacp->params->dac->DHR12L1 + dacp->params->dataoffset) = (uint32_t)sample;
+#endif
+ }
+#if (STM32_HAS_DAC1_CH2 || STM32_HAS_DAC2_CH2 || \
+ STM32_HAS_DAC3_CH2 || STM32_HAS_DAC4_CH2)
+ else {
+ dacp->params->dac->DHR12L2 = (uint32_t)sample;
+ }
+#endif
+ break;
+ case DAC_DHRM_8BIT_RIGHT:
+#if STM32_DAC_DUAL_MODE
+ case DAC_DHRM_8BIT_RIGHT_DUAL:
+#endif
+ if (channel == 0U) {
+#if STM32_DAC_DUAL_MODE
+ dacp->params->dac->DHR8R1 = (uint32_t)sample;
+#else
+ *(&dacp->params->dac->DHR8R1 + dacp->params->dataoffset) = (uint32_t)sample;
+#endif
+ }
+#if (STM32_HAS_DAC1_CH2 || STM32_HAS_DAC2_CH2 || \
+ STM32_HAS_DAC3_CH2 || STM32_HAS_DAC4_CH2)
+ else {
+ dacp->params->dac->DHR8R2 = (uint32_t)sample;
+ }
+#endif
+ break;
+ default:
+ osalDbgAssert(false, "unexpected DAC mode");
+ break;
+ }
+}
+
+/**
+ * @brief Starts a DAC conversion.
+ * @details Starts an asynchronous conversion operation.
+ * @note In @p DAC_DHRM_8BIT_RIGHT mode the parameters passed to the
+ * callback are wrong because two samples are packed in a single
+ * dacsample_t element. This will not be corrected, do not rely
+ * on those parameters.
+ * @note In @p DAC_DHRM_8BIT_RIGHT_DUAL mode two samples are treated
+ * as a single 16 bits sample and packed into a single dacsample_t
+ * element. The num_channels must be set to one in the group
+ * conversion configuration structure.
+ *
+ * @param[in] dacp pointer to the @p DACDriver object
+ *
+ * @notapi
+ */
+void dac_lld_start_conversion(DACDriver *dacp) {
+ uint32_t n, cr, dmamode;
+
+ /* Number of DMA operations per buffer.*/
+ n = dacp->depth * dacp->grpp->num_channels;
+
+ /* Allocating the DMA channel.*/
+ dacp->dma = dmaStreamAllocI(dacp->params->dmastream,
+ dacp->params->dmairqprio,
+ (stm32_dmaisr_t)dac_lld_serve_tx_interrupt,
+ (void *)dacp);
+ osalDbgAssert(dacp->dma != NULL, "unable to allocate stream");
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(dacp->dma, dacp->params->peripheral);
+#endif
+
+ /* DMA settings depend on the chosen DAC mode.*/
+ switch (dacp->config->datamode) {
+ /* Sets the DAC data register */
+ case DAC_DHRM_12BIT_RIGHT:
+ osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
+
+ dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12R1 +
+ dacp->params->dataoffset);
+ dmamode = dacp->params->dmamode |
+#if STM32_DMA_ADVANCED == FALSE
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_HWORD;
+#else
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+#endif
+ break;
+ case DAC_DHRM_12BIT_LEFT:
+ osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
+
+ dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12L1 +
+ dacp->params->dataoffset);
+ dmamode = dacp->params->dmamode |
+#if STM32_DMA_ADVANCED == FALSE
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_HWORD;
+#else
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+#endif
+ break;
+ case DAC_DHRM_8BIT_RIGHT:
+ osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
+
+ dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR8R1 +
+ dacp->params->dataoffset);
+ dmamode = dacp->params->dmamode |
+#if STM32_DMA_ADVANCED == FALSE
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_BYTE;
+#else
+ STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+#endif
+
+ /* In this mode the size of the buffer is halved because two samples
+ packed in a single dacsample_t element.*/
+ n = (n + 1) / 2;
+ break;
+#if STM32_DAC_DUAL_MODE == TRUE
+ case DAC_DHRM_12BIT_RIGHT_DUAL:
+ osalDbgAssert(dacp->grpp->num_channels == 2, "invalid number of channels");
+
+ dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12RD);
+ dmamode = dacp->params->dmamode |
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
+ n /= 2;
+ break;
+ case DAC_DHRM_12BIT_LEFT_DUAL:
+ osalDbgAssert(dacp->grpp->num_channels == 2, "invalid number of channels");
+
+ dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR12LD);
+ dmamode = dacp->params->dmamode |
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
+ n /= 2;
+ break;
+ case DAC_DHRM_8BIT_RIGHT_DUAL:
+ osalDbgAssert(dacp->grpp->num_channels == 1, "invalid number of channels");
+
+ dmaStreamSetPeripheral(dacp->dma, &dacp->params->dac->DHR8RD);
+ dmamode = dacp->params->dmamode |
+#if STM32_DMA_ADVANCED == FALSE
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_HWORD;
+#else
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+#endif
+ n /= 2;
+ break;
+#endif
+ default:
+ osalDbgAssert(false, "unexpected DAC mode");
+ return;
+ }
+
+ dmaStreamSetMemory0(dacp->dma, dacp->samples);
+ dmaStreamSetTransactionSize(dacp->dma, n);
+ dmaStreamSetMode(dacp->dma, dmamode |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE |
+ STM32_DMA_CR_HTIE | STM32_DMA_CR_TCIE);
+ dmaStreamEnable(dacp->dma);
+
+ /* DAC configuration.*/
+ cr = dacp->params->dac->CR;
+
+#if STM32_DAC_DUAL_MODE == FALSE
+ cr &= dacp->params->regmask;
+ cr |= (DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) | DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
+#else
+ cr = DAC_CR_DMAEN1 | (dacp->grpp->trigger << DAC_CR_TSEL1_Pos) | DAC_CR_TEN1 | DAC_CR_EN1 | dacp->config->cr
+ | (dacp->grpp->trigger << DAC_CR_TSEL2_Pos) | DAC_CR_TEN2 | DAC_CR_EN2 | (dacp->config->cr << 16);
+#endif
+
+ dacp->params->dac->CR = cr;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ * @details This function stops the currently ongoing conversion and returns
+ * the driver in the @p DAC_READY state. If there was no conversion
+ * being processed then the function does nothing.
+ *
+ * @param[in] dacp pointer to the @p DACDriver object
+ *
+ * @iclass
+ */
+void dac_lld_stop_conversion(DACDriver *dacp) {
+ uint32_t cr;
+
+ /* DMA channel disabled and released.*/
+ dmaStreamDisable(dacp->dma);
+ dmaStreamFreeI(dacp->dma);
+ dacp->dma = NULL;
+
+ cr = dacp->params->dac->CR;
+
+#if STM32_DAC_DUAL_MODE == FALSE
+ cr &= dacp->params->regmask;
+ cr |= (DAC_CR_EN1 | dacp->config->cr) << dacp->params->regshift;
+#else
+ if ((dacp->config->datamode == DAC_DHRM_12BIT_RIGHT_DUAL) ||
+ (dacp->config->datamode == DAC_DHRM_12BIT_LEFT_DUAL) ||
+ (dacp->config->datamode == DAC_DHRM_8BIT_RIGHT_DUAL)) {
+ cr = DAC_CR_EN2 | (dacp->config->cr << 16) |
+ DAC_CR_EN1 | dacp->config->cr;
+ }
+ else {
+ cr = DAC_CR_EN1 | dacp->config->cr;
+ }
+#endif
+
+ dacp->params->dac->CR = cr;
+}
+
+#endif /* HAL_USE_DAC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.h b/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.h
index 09550fae65..80672fa75c 100644
--- a/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.h
+++ b/os/hal/ports/STM32/LLD/DACv1/hal_dac_lld.h
@@ -1,662 +1,662 @@
-/*
- 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 DACv1/hal_dac_lld.h
- * @brief STM32 DAC subsystem low level driver header.
- *
- * @addtogroup DAC
- * @{
- */
-
-#ifndef HAL_DAC_LLD_H
-#define HAL_DAC_LLD_H
-
-#if HAL_USE_DAC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name DAC trigger modes
- * @{
- */
-#define DAC_TRG_MASK 7U
-#define DAC_TRG(n) (n)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief Enables the DAC dual mode.
- * @note In dual mode DAC second channels cannot be accessed individually.
- */
-#if !defined(STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
-#define STM32_DAC_DUAL_MODE FALSE
-#endif
-
-/**
- * @brief DAC1 CH1 driver enable switch.
- * @details If set to @p TRUE the support for DAC1 channel 1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC1_CH1) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC1_CH1 FALSE
-#endif
-
-/**
- * @brief DAC1 CH2 driver enable switch.
- * @details If set to @p TRUE the support for DAC1 channel 2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC1_CH2) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC1_CH2 FALSE
-#endif
-
-/**
- * @brief DAC2 CH1 driver enable switch.
- * @details If set to @p TRUE the support for DAC2 channel 1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC2_CH1) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC2_CH1 FALSE
-#endif
-
-/**
- * @brief DAC2 CH2 driver enable switch.
- * @details If set to @p TRUE the support for DAC2 channel 2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC2_CH2) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC2_CH2 FALSE
-#endif
-
-/**
- * @brief DAC3 CH1 driver enable switch.
- * @details If set to @p TRUE the support for DAC3 channel 1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC3_CH1) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC3_CH1 FALSE
-#endif
-
-/**
- * @brief DAC3 CH2 driver enable switch.
- * @details If set to @p TRUE the support for DAC3 channel 2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC3_CH2) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC3_CH2 FALSE
-#endif
-
-/**
- * @brief DAC4 CH1 driver enable switch.
- * @details If set to @p TRUE the support for DAC4 channel 1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC4_CH1) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC4_CH1 FALSE
-#endif
-
-/**
- * @brief DAC4 CH2 driver enable switch.
- * @details If set to @p TRUE the support for DAC4 channel 2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_DAC_USE_DAC4_CH2) || defined(__DOXYGEN__)
-#define STM32_DAC_USE_DAC4_CH2 FALSE
-#endif
-
-/**
- * @brief DAC1 CH1 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC1_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC1 CH2 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC1_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC2 CH1 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC2_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC2_CH1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC2 CH2 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC2_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC2_CH2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC3 CH1 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC3_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC3_CH1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC3 CH2 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC3_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC3_CH2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC4 CH1 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC4_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC4_CH1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC4 CH2 interrupt priority level setting.
- */
-#if !defined(STM32_DAC_DAC4_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC4_CH2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DAC1 CH1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC1_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC1 CH2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC1_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC2 CH1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC2_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC2_CH1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC2 CH2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC2_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC2_CH2_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC3 CH1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC3_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC3_CH1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC3 CH2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC3_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC3_CH2_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC4 CH1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC4_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC4_CH1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief DAC4 CH2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_DAC_DAC4_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_DAC_DAC4_CH2_DMA_PRIORITY 2
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Handling missing registry keys.*/
-#if !defined(STM32_HAS_DAC1_CH1)
-#define STM32_HAS_DAC1_CH1 FALSE
-#endif
-#if !defined(STM32_HAS_DAC1_CH2)
-#define STM32_HAS_DAC1_CH2 FALSE
-#endif
-#if !defined(STM32_HAS_DAC2_CH1)
-#define STM32_HAS_DAC2_CH1 FALSE
-#endif
-#if !defined(STM32_HAS_DAC2_CH2)
-#define STM32_HAS_DAC2_CH2 FALSE
-#endif
-#if !defined(STM32_HAS_DAC3_CH1)
-#define STM32_HAS_DAC3_CH1 FALSE
-#endif
-#if !defined(STM32_HAS_DAC3_CH2)
-#define STM32_HAS_DAC3_CH2 FALSE
-#endif
-#if !defined(STM32_HAS_DAC4_CH1)
-#define STM32_HAS_DAC4_CH1 FALSE
-#endif
-#if !defined(STM32_HAS_DAC4_CH2)
-#define STM32_HAS_DAC4_CH2 FALSE
-#endif
-
-#if STM32_DAC_USE_DAC1_CH1 && !STM32_HAS_DAC1_CH1
-#error "DAC1 CH1 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 && !STM32_HAS_DAC1_CH2
-#error "DAC1 CH2 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 && !STM32_HAS_DAC2_CH1
-#error "DAC2 CH1 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 && !STM32_HAS_DAC2_CH2
-#error "DAC2 CH2 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 && !STM32_HAS_DAC3_CH1
-#error "DAC3 CH1 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 && !STM32_HAS_DAC3_CH2
-#error "DAC3 CH2 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 && !STM32_HAS_DAC4_CH1
-#error "DAC4 CH1 not present in the selected device"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 && !STM32_HAS_DAC4_CH2
-#error "DAC4 CH2 not present in the selected device"
-#endif
-
-#if (STM32_DAC_USE_DAC1_CH2 || STM32_DAC_USE_DAC2_CH2 || \
- STM32_DAC_USE_DAC3_CH2 || STM32_DAC_USE_DAC4_CH2) && STM32_DAC_DUAL_MODE
-#error "DACx CH2 cannot be used independently in dual mode"
-#endif
-
-#if !STM32_DAC_USE_DAC1_CH1 && !STM32_DAC_USE_DAC1_CH2 && \
- !STM32_DAC_USE_DAC2_CH1 && !STM32_DAC_USE_DAC2_CH2 && \
- !STM32_DAC_USE_DAC3_CH1 && !STM32_DAC_USE_DAC3_CH2 && \
- !STM32_DAC_USE_DAC4_CH1 && !STM32_DAC_USE_DAC4_CH2
-#error "DAC driver activated but no DAC peripheral assigned"
-#endif
-
-#if STM32_DAC_USE_DAC1_CH1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC1 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC1 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC2 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC2 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC3 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC3 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC4 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to DAC4 CH2"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_DAC_USE_DAC1_CH1 && !defined(STM32_DAC_DAC1_CH1_DMA_STREAM)
-#error "DAC1 CH1 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 && !defined(STM32_DAC_DAC1_CH2_DMA_STREAM)
-#error "DAC1 CH2 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 && !defined(STM32_DAC_DAC2_CH1_DMA_STREAM)
-#error "DAC2 CH1 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 && !defined(STM32_DAC_DAC2_CH2_DMA_STREAM)
-#error "DAC2 CH2 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 && !defined(STM32_DAC_DAC3_CH1_DMA_STREAM)
-#error "DAC3 CH1 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 && !defined(STM32_DAC_DAC3_CH2_DMA_STREAM)
-#error "DAC3 CH2 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 && !defined(STM32_DAC_DAC4_CH1_DMA_STREAM)
-#error "DAC4 CH1 DMA stream not defined"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 && !defined(STM32_DAC_DAC4_CH2_DMA_STREAM)
-#error "DAC4 CH2 DMA stream not defined"
-#endif
-
-#if STM32_DMA_SUPPORTS_DMAMUX
-
-#else /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-/* Check on the validity of the assigned DMA streams.*/
-#if STM32_DAC_USE_DAC1_CH1 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC1_CH1_DMA_STREAM, STM32_DAC1_CH1_DMA_MSK)
-#error "invalid DMA stream associated to DAC1 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC1_CH2_DMA_STREAM, STM32_DAC1_CH2_DMA_MSK)
-#error "invalid DMA stream associated to DAC1 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC2_CH1_DMA_STREAM, STM32_DAC2_CH1_DMA_MSK)
-#error "invalid DMA stream associated to DAC2 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC2_CH2_DMA_STREAM, STM32_DAC2_CH2_DMA_MSK)
-#error "invalid DMA stream associated to DAC2 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC3_CH1_DMA_STREAM, STM32_DAC3_CH1_DMA_MSK)
-#error "invalid DMA stream associated to DAC1 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC3_CH2_DMA_STREAM, STM32_DAC3_CH2_DMA_MSK)
-#error "invalid DMA stream associated to DAC1 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC4_CH1_DMA_STREAM, STM32_DAC4_CH1_DMA_MSK)
-#error "invalid DMA stream associated to DAC2 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 && \
- !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC4_CH2_DMA_STREAM, STM32_DAC4_CH2_DMA_MSK)
-#error "invalid DMA stream associated to DAC2 CH2"
-#endif
-
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-#endif /* STM32_ADVANCED_DMA */
-
-#if STM32_DAC_USE_DAC1_CH1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC1 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC1 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC2 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC2 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC3 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC3 CH2"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC4 CH1"
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to DAC4 CH2"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/**
- * @brief Max DAC channels.
- */
-#if STM32_DAC_DUAL_MODE == FALSE
-#define DAC_MAX_CHANNELS 2
-#else
-#define DAC_MAX_CHANNELS 1
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a DAC channel index.
- */
-typedef uint32_t dacchannel_t;
-
-/**
- * @brief Type representing a DAC sample.
- */
-typedef uint16_t dacsample_t;
-
-/**
- * @brief DAC channel parameters type.
- */
-typedef struct {
- /**
- * @brief Pointer to the DAC registers block.
- */
- DAC_TypeDef *dac;
- /**
- * @brief DAC data registers offset.
- */
- uint32_t dataoffset;
- /**
- * @brief DAC CR register bit offset.
- */
- uint32_t regshift;
- /**
- * @brief DAC CR register mask.
- */
- uint32_t regmask;
- /**
- * @brief Associated DMA stream.
- */
- uint32_t dmastream;
- /**
- * @brief Mode bits for the DMA.
- */
- uint32_t dmamode;
- /**
- * @brief DMA channel IRQ priority.
- */
- uint32_t dmairqprio;
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief DMAMUX peripheral selector.
- */
- uint32_t peripheral;
-#endif
-} dacparams_t;
-
-/**
- * @brief Possible DAC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- DAC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- DAC_ERR_UNDERFLOW = 1 /**< DAC overflow condition. */
-} dacerror_t;
-
-/**
- * @brief Samples alignment and size mode.
- */
-typedef enum {
- DAC_DHRM_12BIT_RIGHT = 0,
- DAC_DHRM_12BIT_LEFT = 1,
- DAC_DHRM_8BIT_RIGHT = 2,
-#if STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
- DAC_DHRM_12BIT_RIGHT_DUAL = 3,
- DAC_DHRM_12BIT_LEFT_DUAL = 4,
- DAC_DHRM_8BIT_RIGHT_DUAL = 5
-#endif
-} dacdhrmode_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the DAC driver structure.
- */
-#define dac_lld_driver_fields \
- /* DAC channel parameters.*/ \
- const dacparams_t *params; \
- /* Associated DMA.*/ \
- const stm32_dma_stream_t *dma
-
-/**
- * @brief Low level fields of the DAC configuration structure.
- */
-#define dac_lld_config_fields \
- /* Initial output on DAC channels.*/ \
- dacsample_t init; \
- /* DAC data holding register mode.*/ \
- dacdhrmode_t datamode; \
- /* DAC control register lower 16 bits.*/ \
- uint32_t cr
-
-/**
- * @brief Low level fields of the DAC group configuration structure.
- */
-#define dac_lld_conversion_group_fields \
- /* DAC initialization data. This field contains the (not shifted) value \
- to be put into the TSEL field of the DAC CR register during \
- initialization. All other fields are handled internally.*/ \
- uint32_t trigger
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_DAC_USE_DAC1_CH1 && !defined(__DOXYGEN__)
-extern DACDriver DACD1;
-#endif
-
-#if STM32_DAC_USE_DAC1_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
-extern DACDriver DACD2;
-#endif
-
-#if STM32_DAC_USE_DAC2_CH1 && !defined(__DOXYGEN__)
-extern DACDriver DACD3;
-#endif
-
-#if STM32_DAC_USE_DAC2_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
-extern DACDriver DACD4;
-#endif
-
-#if STM32_DAC_USE_DAC3_CH1 && !defined(__DOXYGEN__)
-extern DACDriver DACD5;
-#endif
-
-#if STM32_DAC_USE_DAC3_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
-extern DACDriver DACD6;
-#endif
-
-#if STM32_DAC_USE_DAC4_CH1 && !defined(__DOXYGEN__)
-extern DACDriver DACD7;
-#endif
-
-#if STM32_DAC_USE_DAC4_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
-extern DACDriver DACD8;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void dac_lld_init(void);
- void dac_lld_start(DACDriver *dacp);
- void dac_lld_stop(DACDriver *dacp);
- void dac_lld_put_channel(DACDriver *dacp,
- dacchannel_t channel,
- dacsample_t sample);
- void dac_lld_start_conversion(DACDriver *dacp);
- void dac_lld_stop_conversion(DACDriver *dacp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_DAC */
-
-#endif /* HAL_DAC_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 DACv1/hal_dac_lld.h
+ * @brief STM32 DAC subsystem low level driver header.
+ *
+ * @addtogroup DAC
+ * @{
+ */
+
+#ifndef HAL_DAC_LLD_H
+#define HAL_DAC_LLD_H
+
+#if HAL_USE_DAC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name DAC trigger modes
+ * @{
+ */
+#define DAC_TRG_MASK 7U
+#define DAC_TRG(n) (n)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief Enables the DAC dual mode.
+ * @note In dual mode DAC second channels cannot be accessed individually.
+ */
+#if !defined(STM32_DAC_DUAL_MODE) || defined(__DOXYGEN__)
+#define STM32_DAC_DUAL_MODE FALSE
+#endif
+
+/**
+ * @brief DAC1 CH1 driver enable switch.
+ * @details If set to @p TRUE the support for DAC1 channel 1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC1_CH1) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC1_CH1 FALSE
+#endif
+
+/**
+ * @brief DAC1 CH2 driver enable switch.
+ * @details If set to @p TRUE the support for DAC1 channel 2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC1_CH2) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC1_CH2 FALSE
+#endif
+
+/**
+ * @brief DAC2 CH1 driver enable switch.
+ * @details If set to @p TRUE the support for DAC2 channel 1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC2_CH1) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC2_CH1 FALSE
+#endif
+
+/**
+ * @brief DAC2 CH2 driver enable switch.
+ * @details If set to @p TRUE the support for DAC2 channel 2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC2_CH2) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC2_CH2 FALSE
+#endif
+
+/**
+ * @brief DAC3 CH1 driver enable switch.
+ * @details If set to @p TRUE the support for DAC3 channel 1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC3_CH1) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC3_CH1 FALSE
+#endif
+
+/**
+ * @brief DAC3 CH2 driver enable switch.
+ * @details If set to @p TRUE the support for DAC3 channel 2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC3_CH2) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC3_CH2 FALSE
+#endif
+
+/**
+ * @brief DAC4 CH1 driver enable switch.
+ * @details If set to @p TRUE the support for DAC4 channel 1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC4_CH1) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC4_CH1 FALSE
+#endif
+
+/**
+ * @brief DAC4 CH2 driver enable switch.
+ * @details If set to @p TRUE the support for DAC4 channel 2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_DAC_USE_DAC4_CH2) || defined(__DOXYGEN__)
+#define STM32_DAC_USE_DAC4_CH2 FALSE
+#endif
+
+/**
+ * @brief DAC1 CH1 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC1_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC1 CH2 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC1_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC2 CH1 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC2_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC2_CH1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC2 CH2 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC2_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC2_CH2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC3 CH1 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC3_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC3_CH1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC3 CH2 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC3_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC3_CH2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC4 CH1 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC4_CH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC4_CH1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC4 CH2 interrupt priority level setting.
+ */
+#if !defined(STM32_DAC_DAC4_CH2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC4_CH2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DAC1 CH1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC1_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC1 CH2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC1_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC2 CH1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC2_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC2_CH1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC2 CH2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC2_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC2_CH2_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC3 CH1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC3_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC3_CH1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC3 CH2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC3_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC3_CH2_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC4 CH1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC4_CH1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC4_CH1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief DAC4 CH2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_DAC_DAC4_CH2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_DAC_DAC4_CH2_DMA_PRIORITY 2
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Handling missing registry keys.*/
+#if !defined(STM32_HAS_DAC1_CH1)
+#define STM32_HAS_DAC1_CH1 FALSE
+#endif
+#if !defined(STM32_HAS_DAC1_CH2)
+#define STM32_HAS_DAC1_CH2 FALSE
+#endif
+#if !defined(STM32_HAS_DAC2_CH1)
+#define STM32_HAS_DAC2_CH1 FALSE
+#endif
+#if !defined(STM32_HAS_DAC2_CH2)
+#define STM32_HAS_DAC2_CH2 FALSE
+#endif
+#if !defined(STM32_HAS_DAC3_CH1)
+#define STM32_HAS_DAC3_CH1 FALSE
+#endif
+#if !defined(STM32_HAS_DAC3_CH2)
+#define STM32_HAS_DAC3_CH2 FALSE
+#endif
+#if !defined(STM32_HAS_DAC4_CH1)
+#define STM32_HAS_DAC4_CH1 FALSE
+#endif
+#if !defined(STM32_HAS_DAC4_CH2)
+#define STM32_HAS_DAC4_CH2 FALSE
+#endif
+
+#if STM32_DAC_USE_DAC1_CH1 && !STM32_HAS_DAC1_CH1
+#error "DAC1 CH1 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 && !STM32_HAS_DAC1_CH2
+#error "DAC1 CH2 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 && !STM32_HAS_DAC2_CH1
+#error "DAC2 CH1 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 && !STM32_HAS_DAC2_CH2
+#error "DAC2 CH2 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 && !STM32_HAS_DAC3_CH1
+#error "DAC3 CH1 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 && !STM32_HAS_DAC3_CH2
+#error "DAC3 CH2 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 && !STM32_HAS_DAC4_CH1
+#error "DAC4 CH1 not present in the selected device"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 && !STM32_HAS_DAC4_CH2
+#error "DAC4 CH2 not present in the selected device"
+#endif
+
+#if (STM32_DAC_USE_DAC1_CH2 || STM32_DAC_USE_DAC2_CH2 || \
+ STM32_DAC_USE_DAC3_CH2 || STM32_DAC_USE_DAC4_CH2) && STM32_DAC_DUAL_MODE
+#error "DACx CH2 cannot be used independently in dual mode"
+#endif
+
+#if !STM32_DAC_USE_DAC1_CH1 && !STM32_DAC_USE_DAC1_CH2 && \
+ !STM32_DAC_USE_DAC2_CH1 && !STM32_DAC_USE_DAC2_CH2 && \
+ !STM32_DAC_USE_DAC3_CH1 && !STM32_DAC_USE_DAC3_CH2 && \
+ !STM32_DAC_USE_DAC4_CH1 && !STM32_DAC_USE_DAC4_CH2
+#error "DAC driver activated but no DAC peripheral assigned"
+#endif
+
+#if STM32_DAC_USE_DAC1_CH1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC1 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC1 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC2 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC2 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC3 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC3 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC4 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to DAC4 CH2"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_DAC_USE_DAC1_CH1 && !defined(STM32_DAC_DAC1_CH1_DMA_STREAM)
+#error "DAC1 CH1 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 && !defined(STM32_DAC_DAC1_CH2_DMA_STREAM)
+#error "DAC1 CH2 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 && !defined(STM32_DAC_DAC2_CH1_DMA_STREAM)
+#error "DAC2 CH1 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 && !defined(STM32_DAC_DAC2_CH2_DMA_STREAM)
+#error "DAC2 CH2 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 && !defined(STM32_DAC_DAC3_CH1_DMA_STREAM)
+#error "DAC3 CH1 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 && !defined(STM32_DAC_DAC3_CH2_DMA_STREAM)
+#error "DAC3 CH2 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 && !defined(STM32_DAC_DAC4_CH1_DMA_STREAM)
+#error "DAC4 CH1 DMA stream not defined"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 && !defined(STM32_DAC_DAC4_CH2_DMA_STREAM)
+#error "DAC4 CH2 DMA stream not defined"
+#endif
+
+#if STM32_DMA_SUPPORTS_DMAMUX
+
+#else /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+/* Check on the validity of the assigned DMA streams.*/
+#if STM32_DAC_USE_DAC1_CH1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC1_CH1_DMA_STREAM, STM32_DAC1_CH1_DMA_MSK)
+#error "invalid DMA stream associated to DAC1 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC1_CH2_DMA_STREAM, STM32_DAC1_CH2_DMA_MSK)
+#error "invalid DMA stream associated to DAC1 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC2_CH1_DMA_STREAM, STM32_DAC2_CH1_DMA_MSK)
+#error "invalid DMA stream associated to DAC2 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC2_CH2_DMA_STREAM, STM32_DAC2_CH2_DMA_MSK)
+#error "invalid DMA stream associated to DAC2 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC3_CH1_DMA_STREAM, STM32_DAC3_CH1_DMA_MSK)
+#error "invalid DMA stream associated to DAC1 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC3_CH2_DMA_STREAM, STM32_DAC3_CH2_DMA_MSK)
+#error "invalid DMA stream associated to DAC1 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC4_CH1_DMA_STREAM, STM32_DAC4_CH1_DMA_MSK)
+#error "invalid DMA stream associated to DAC2 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_DAC_DAC4_CH2_DMA_STREAM, STM32_DAC4_CH2_DMA_MSK)
+#error "invalid DMA stream associated to DAC2 CH2"
+#endif
+
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+#endif /* STM32_ADVANCED_DMA */
+
+#if STM32_DAC_USE_DAC1_CH1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC1 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC1_CH2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC1 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC2 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC2_CH2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC2 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC3 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC3_CH2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC3 CH2"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC4 CH1"
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_DAC_DAC4_CH2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to DAC4 CH2"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/**
+ * @brief Max DAC channels.
+ */
+#if STM32_DAC_DUAL_MODE == FALSE
+#define DAC_MAX_CHANNELS 2
+#else
+#define DAC_MAX_CHANNELS 1
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a DAC channel index.
+ */
+typedef uint32_t dacchannel_t;
+
+/**
+ * @brief Type representing a DAC sample.
+ */
+typedef uint16_t dacsample_t;
+
+/**
+ * @brief DAC channel parameters type.
+ */
+typedef struct {
+ /**
+ * @brief Pointer to the DAC registers block.
+ */
+ DAC_TypeDef *dac;
+ /**
+ * @brief DAC data registers offset.
+ */
+ uint32_t dataoffset;
+ /**
+ * @brief DAC CR register bit offset.
+ */
+ uint32_t regshift;
+ /**
+ * @brief DAC CR register mask.
+ */
+ uint32_t regmask;
+ /**
+ * @brief Associated DMA stream.
+ */
+ uint32_t dmastream;
+ /**
+ * @brief Mode bits for the DMA.
+ */
+ uint32_t dmamode;
+ /**
+ * @brief DMA channel IRQ priority.
+ */
+ uint32_t dmairqprio;
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief DMAMUX peripheral selector.
+ */
+ uint32_t peripheral;
+#endif
+} dacparams_t;
+
+/**
+ * @brief Possible DAC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ DAC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ DAC_ERR_UNDERFLOW = 1 /**< DAC overflow condition. */
+} dacerror_t;
+
+/**
+ * @brief Samples alignment and size mode.
+ */
+typedef enum {
+ DAC_DHRM_12BIT_RIGHT = 0,
+ DAC_DHRM_12BIT_LEFT = 1,
+ DAC_DHRM_8BIT_RIGHT = 2,
+#if STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
+ DAC_DHRM_12BIT_RIGHT_DUAL = 3,
+ DAC_DHRM_12BIT_LEFT_DUAL = 4,
+ DAC_DHRM_8BIT_RIGHT_DUAL = 5
+#endif
+} dacdhrmode_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the DAC driver structure.
+ */
+#define dac_lld_driver_fields \
+ /* DAC channel parameters.*/ \
+ const dacparams_t *params; \
+ /* Associated DMA.*/ \
+ const stm32_dma_stream_t *dma
+
+/**
+ * @brief Low level fields of the DAC configuration structure.
+ */
+#define dac_lld_config_fields \
+ /* Initial output on DAC channels.*/ \
+ dacsample_t init; \
+ /* DAC data holding register mode.*/ \
+ dacdhrmode_t datamode; \
+ /* DAC control register lower 16 bits.*/ \
+ uint32_t cr
+
+/**
+ * @brief Low level fields of the DAC group configuration structure.
+ */
+#define dac_lld_conversion_group_fields \
+ /* DAC initialization data. This field contains the (not shifted) value \
+ to be put into the TSEL field of the DAC CR register during \
+ initialization. All other fields are handled internally.*/ \
+ uint32_t trigger
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_DAC_USE_DAC1_CH1 && !defined(__DOXYGEN__)
+extern DACDriver DACD1;
+#endif
+
+#if STM32_DAC_USE_DAC1_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
+extern DACDriver DACD2;
+#endif
+
+#if STM32_DAC_USE_DAC2_CH1 && !defined(__DOXYGEN__)
+extern DACDriver DACD3;
+#endif
+
+#if STM32_DAC_USE_DAC2_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
+extern DACDriver DACD4;
+#endif
+
+#if STM32_DAC_USE_DAC3_CH1 && !defined(__DOXYGEN__)
+extern DACDriver DACD5;
+#endif
+
+#if STM32_DAC_USE_DAC3_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
+extern DACDriver DACD6;
+#endif
+
+#if STM32_DAC_USE_DAC4_CH1 && !defined(__DOXYGEN__)
+extern DACDriver DACD7;
+#endif
+
+#if STM32_DAC_USE_DAC4_CH2 && !STM32_DAC_DUAL_MODE && !defined(__DOXYGEN__)
+extern DACDriver DACD8;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void dac_lld_init(void);
+ void dac_lld_start(DACDriver *dacp);
+ void dac_lld_stop(DACDriver *dacp);
+ void dac_lld_put_channel(DACDriver *dacp,
+ dacchannel_t channel,
+ dacsample_t sample);
+ void dac_lld_start_conversion(DACDriver *dacp);
+ void dac_lld_stop_conversion(DACDriver *dacp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_DAC */
+
+#endif /* HAL_DAC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DMAv1/driver.mk b/os/hal/ports/STM32/LLD/DMAv1/driver.mk
index 6080cec58f..b4be3ab9da 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/DMAv1/driver.mk
@@ -1,2 +1,2 @@
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1
diff --git a/os/hal/ports/STM32/LLD/DMAv1/notes.txt b/os/hal/ports/STM32/LLD/DMAv1/notes.txt
index dc46638904..562f45fb52 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/notes.txt
+++ b/os/hal/ports/STM32/LLD/DMAv1/notes.txt
@@ -1,26 +1,26 @@
-STM32 DMAv1 driver.
-
-Driver capability:
-
-- The driver supports the STM32 traditional DMA controller in the following
- configurations: 5ch, 7ch, 7ch+5ch, 7ch+7ch.
-- Support for automatic the channel selection through the CSELR register.
-- For devices without CSELR register it is possible to select channels but
- the SYSCFG CFGR register is not configured, the user has to configure it
- before starting the DMA driver.
-- The driver supports shared ISR handlers with a quirk: the IRQ priority is
- established by the first allocated channel among the channels sharing the
- ISR.
-
-The file registry must export:
-
-STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other
- drivers use it to enable checks on DMA
- channels. Probably will be removed in the
- future.
-STM32_DMA_SUPPORTS_CSELR - TRUE if the DMA have a CSELR register.
-STM32_DMA_SUPPORTS_DMAMUX - TRUE if the DMA is riven by a DMAMUX.
-STM32_DMAn_NUM_CHANNELS - Number of channels in DMAs "n" (1..2).
-STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
- is not exported then the ISR is not declared.
-STM32_DMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
+STM32 DMAv1 driver.
+
+Driver capability:
+
+- The driver supports the STM32 traditional DMA controller in the following
+ configurations: 5ch, 7ch, 7ch+5ch, 7ch+7ch.
+- Support for automatic the channel selection through the CSELR register.
+- For devices without CSELR register it is possible to select channels but
+ the SYSCFG CFGR register is not configured, the user has to configure it
+ before starting the DMA driver.
+- The driver supports shared ISR handlers with a quirk: the IRQ priority is
+ established by the first allocated channel among the channels sharing the
+ ISR.
+
+The file registry must export:
+
+STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other
+ drivers use it to enable checks on DMA
+ channels. Probably will be removed in the
+ future.
+STM32_DMA_SUPPORTS_CSELR - TRUE if the DMA have a CSELR register.
+STM32_DMA_SUPPORTS_DMAMUX - TRUE if the DMA is riven by a DMAMUX.
+STM32_DMAn_NUM_CHANNELS - Number of channels in DMAs "n" (1..2).
+STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
+ is not exported then the ISR is not declared.
+STM32_DMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
index 955e557af1..65fa5e8bc5 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
+++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
@@ -1,816 +1,816 @@
-/*
- 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 DMAv1/stm32_dma.c
- * @brief DMA helper driver code.
- *
- * @addtogroup STM32_DMA
- * @details DMA sharing helper driver. In the STM32 the DMA streams are a
- * shared resource, this driver allows to allocate and free DMA
- * streams at runtime in order to allow all the other device
- * drivers to coordinate the access to the resource.
- * @note The DMA ISR handlers are all declared into this module because
- * sharing, the various device drivers can associate a callback to
- * ISRs when allocating streams.
- * @{
- */
-
-#include "hal.h"
-
-/* The following macro is only defined if some driver requiring DMA services
- has been enabled.*/
-#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/**
- * @brief Mask of the DMA1 streams in @p dma_streams_mask.
- */
-#define STM32_DMA1_STREAMS_MASK ((1U << STM32_DMA1_NUM_CHANNELS) - 1U)
-
-/**
- * @brief Mask of the DMA2 streams in @p dma_streams_mask.
- */
-#define STM32_DMA2_STREAMS_MASK (((1U << STM32_DMA2_NUM_CHANNELS) - \
- 1U) << STM32_DMA1_NUM_CHANNELS)
-
-#if STM32_DMA_SUPPORTS_CSELR == TRUE
-
-#if defined(DMA1_CSELR)
-#define __DMA1_CSELR &DMA1_CSELR->CSELR
-#else
-#define __DMA1_CSELR &DMA1->CSELR
-#endif
-
-#if defined(DMA2_CSELR)
-#define __DMA2_CSELR &DMA2_CSELR->CSELR
-#else
-#define __DMA2_CSELR &DMA2->CSELR
-#endif
-
-#define DMA1_CH1_VARIANT __DMA1_CSELR
-#define DMA1_CH2_VARIANT __DMA1_CSELR
-#define DMA1_CH3_VARIANT __DMA1_CSELR
-#define DMA1_CH4_VARIANT __DMA1_CSELR
-#define DMA1_CH5_VARIANT __DMA1_CSELR
-#define DMA1_CH6_VARIANT __DMA1_CSELR
-#define DMA1_CH7_VARIANT __DMA1_CSELR
-#define DMA1_CH8_VARIANT __DMA1_CSELR
-#define DMA2_CH1_VARIANT __DMA2_CSELR
-#define DMA2_CH2_VARIANT __DMA2_CSELR
-#define DMA2_CH3_VARIANT __DMA2_CSELR
-#define DMA2_CH4_VARIANT __DMA2_CSELR
-#define DMA2_CH5_VARIANT __DMA2_CSELR
-#define DMA2_CH6_VARIANT __DMA2_CSELR
-#define DMA2_CH7_VARIANT __DMA2_CSELR
-#define DMA2_CH8_VARIANT __DMA2_CSELR
-
-#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE
-
-#define DMAMUX1_CHANNEL(id) (DMAMUX1_BASE + ((id) * 4U))
-
-#define DMA1_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0))
-#define DMA1_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1))
-#define DMA1_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2))
-#define DMA1_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3))
-#define DMA1_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4))
-#define DMA1_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5))
-#define DMA1_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6))
-#define DMA1_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7))
-#define DMA2_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6 + STM32_DMA1_NUM_CHANNELS))
-#define DMA2_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7 + STM32_DMA1_NUM_CHANNELS))
-
-#else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
-
-#define DMA1_CH1_VARIANT 0
-#define DMA1_CH2_VARIANT 0
-#define DMA1_CH3_VARIANT 0
-#define DMA1_CH4_VARIANT 0
-#define DMA1_CH5_VARIANT 0
-#define DMA1_CH6_VARIANT 0
-#define DMA1_CH7_VARIANT 0
-#define DMA2_CH1_VARIANT 0
-#define DMA2_CH2_VARIANT 0
-#define DMA2_CH3_VARIANT 0
-#define DMA2_CH4_VARIANT 0
-#define DMA2_CH5_VARIANT 0
-#define DMA2_CH6_VARIANT 0
-#define DMA2_CH7_VARIANT 0
-
-#endif /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
-
-/*
- * Default ISR collision masks.
- */
-#if !defined(STM32_DMA1_CH1_CMASK)
-#define STM32_DMA1_CH1_CMASK (1U << 0U)
-#endif
-
-#if !defined(STM32_DMA1_CH2_CMASK)
-#define STM32_DMA1_CH2_CMASK (1U << 1U)
-#endif
-
-#if !defined(STM32_DMA1_CH3_CMASK)
-#define STM32_DMA1_CH3_CMASK (1U << 2U)
-#endif
-
-#if !defined(STM32_DMA1_CH4_CMASK)
-#define STM32_DMA1_CH4_CMASK (1U << 3U)
-#endif
-
-#if !defined(STM32_DMA1_CH5_CMASK)
-#define STM32_DMA1_CH5_CMASK (1U << 4U)
-#endif
-
-#if !defined(STM32_DMA1_CH6_CMASK)
-#define STM32_DMA1_CH6_CMASK (1U << 5U)
-#endif
-
-#if !defined(STM32_DMA1_CH7_CMASK)
-#define STM32_DMA1_CH7_CMASK (1U << 6U)
-#endif
-
-#if !defined(STM32_DMA1_CH8_CMASK)
-#define STM32_DMA1_CH8_CMASK (1U << 7U)
-#endif
-
-#if !defined(STM32_DMA2_CH1_CMASK)
-#define STM32_DMA2_CH1_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 0U))
-#endif
-
-#if !defined(STM32_DMA2_CH2_CMASK)
-#define STM32_DMA2_CH2_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 1U))
-#endif
-
-#if !defined(STM32_DMA2_CH3_CMASK)
-#define STM32_DMA2_CH3_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 2U))
-#endif
-
-#if !defined(STM32_DMA2_CH4_CMASK)
-#define STM32_DMA2_CH4_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 3U))
-#endif
-
-#if !defined(STM32_DMA2_CH5_CMASK)
-#define STM32_DMA2_CH5_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 4U))
-#endif
-
-#if !defined(STM32_DMA2_CH6_CMASK)
-#define STM32_DMA2_CH6_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 5U))
-#endif
-
-#if !defined(STM32_DMA2_CH7_CMASK)
-#define STM32_DMA2_CH7_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 6U))
-#endif
-
-#if !defined(STM32_DMA2_CH8_CMASK)
-#define STM32_DMA2_CH8_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 7U))
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief DMA streams descriptors.
- * @details This table keeps the association between an unique stream
- * identifier and the involved physical registers.
- * @note Don't use this array directly, use the appropriate wrapper macros
- * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
- */
-const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
-#if STM32_DMA1_NUM_CHANNELS > 0
- {DMA1, DMA1_Channel1, STM32_DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, 0, STM32_DMA1_CH1_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 1
- {DMA1, DMA1_Channel2, STM32_DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, 1, STM32_DMA1_CH2_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 2
- {DMA1, DMA1_Channel3, STM32_DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, 2, STM32_DMA1_CH3_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 3
- {DMA1, DMA1_Channel4, STM32_DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, 3, STM32_DMA1_CH4_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 4
- {DMA1, DMA1_Channel5, STM32_DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, 4, STM32_DMA1_CH5_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 5
- {DMA1, DMA1_Channel6, STM32_DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, STM32_DMA1_CH6_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 6
- {DMA1, DMA1_Channel7, STM32_DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, STM32_DMA1_CH7_NUMBER},
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 7
- {DMA1, DMA1_Channel8, STM32_DMA1_CH8_CMASK, DMA1_CH8_VARIANT, 28, 7, STM32_DMA1_CH8_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 0
- {DMA2, DMA2_Channel1, STM32_DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, 0 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH1_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 1
- {DMA2, DMA2_Channel2, STM32_DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, 1 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH2_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 2
- {DMA2, DMA2_Channel3, STM32_DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, 2 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH3_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 3
- {DMA2, DMA2_Channel4, STM32_DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, 3 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH4_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 4
- {DMA2, DMA2_Channel5, STM32_DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, 4 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH5_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 5
- {DMA2, DMA2_Channel6, STM32_DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 5 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH6_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 6
- {DMA2, DMA2_Channel7, STM32_DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 6 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH7_NUMBER},
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 7
- {DMA2, DMA2_Channel8, STM32_DMA2_CH8_CMASK, DMA2_CH8_VARIANT, 28, 7 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH8_NUMBER},
-#endif
-};
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief Global DMA-related data structures.
- */
-static struct {
- /**
- * @brief Mask of the allocated streams.
- */
- uint32_t allocated_mask;
- /**
- * @brief Mask of the enabled streams ISRs.
- */
- uint32_t isr_mask;
- /**
- * @brief DMA IRQ redirectors.
- */
- struct {
- /**
- * @brief DMA callback function.
- */
- stm32_dmaisr_t func;
- /**
- * @brief DMA callback parameter.
- */
- void *param;
- } streams[STM32_DMA_STREAMS];
-} dma;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if defined(STM32_DMA1_CH1_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 1 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH2_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 2 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH3_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 3 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH4_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 4 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH5_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 5 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH6_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 6 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH7_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 7 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA1_CH8_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA1 stream 8 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA1_STREAM8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH1_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 1 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH2_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 2 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH3_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 3 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH4_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 4 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH5_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 5 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH6_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 6 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH7_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 7 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if defined(STM32_DMA2_CH8_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief DMA2 stream 8 shared ISR.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- dmaServeInterrupt(STM32_DMA2_STREAM8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 DMA helper initialization.
- *
- * @init
- */
-void dmaInit(void) {
- int i;
-
- dma.allocated_mask = 0U;
- dma.isr_mask = 0U;
- for (i = 0; i < STM32_DMA_STREAMS; i++) {
- _stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE;
- dma.streams[i].func = NULL;
- }
- DMA1->IFCR = 0xFFFFFFFFU;
-#if STM32_DMA2_NUM_CHANNELS > 0
- DMA2->IFCR = 0xFFFFFFFFU;
-#endif
-}
-
-/**
- * @brief Allocates a DMA stream.
- * @details The stream is allocated and, if required, the DMA clock enabled.
- * The function also enables the IRQ vector associated to the stream
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific stream or:
- * - @p STM32_DMA_STREAM_ID_ANY for any stream.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
- * on DMA1.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
- * on DMA2.
- * .
- * @param[in] priority IRQ priority for the DMA stream
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_dma_stream_t
- * structure.
- * @retval NULL if a/the stream is not available.
- *
- * @iclass
- */
-const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param) {
- uint32_t i, startid, endid;
-
- osalDbgCheckClassI();
-
- if (id < STM32_DMA_STREAMS) {
- startid = id;
- endid = id;
- }
-#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
- else if (id == STM32_DMA_STREAM_ID_ANY) {
- startid = 0U;
- endid = STM32_DMA_STREAMS - 1U;
- }
- else if (id == STM32_DMA_STREAM_ID_ANY_DMA1) {
- startid = 0U;
- endid = STM32_DMA1_NUM_CHANNELS - 1U;
- }
-#if STM32_DMA2_NUM_CHANNELS > 0
- else if (id == STM32_DMA_STREAM_ID_ANY_DMA2) {
- startid = STM32_DMA1_NUM_CHANNELS;
- endid = STM32_DMA_STREAMS - 1U;
- }
-#endif
-#endif
- else {
- osalDbgCheck(false);
- return NULL;
- }
-
- for (i = startid; i <= endid; i++) {
- uint32_t mask = (1U << i);
- if ((dma.allocated_mask & mask) == 0U) {
- const stm32_dma_stream_t *dmastp = STM32_DMA_STREAM(i);
-
- /* Installs the DMA handler.*/
- dma.streams[i].func = func;
- dma.streams[i].param = param;
- dma.allocated_mask |= mask;
-
- /* Enabling DMA clocks required by the current streams set.*/
- if ((STM32_DMA1_STREAMS_MASK & mask) != 0U) {
- rccEnableDMA1(true);
- }
-#if STM32_DMA2_NUM_CHANNELS > 0
- if ((STM32_DMA2_STREAMS_MASK & mask) != 0U) {
- rccEnableDMA2(true);
- }
-#endif
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccEnableDMAMUX)
- /* Enabling DMAMUX if present.*/
- if (dma.allocated_mask != 0U) {
- rccEnableDMAMUX(true);
- }
-#endif
-
- /* Enables the associated IRQ vector if not already enabled and if a
- callback is defined.*/
- if (func != NULL) {
- if ((dma.isr_mask & dmastp->cmask) == 0U) {
- nvicEnableVector(dmastp->vector, priority);
- }
- dma.isr_mask |= mask;
- }
-
- /* Putting the stream in a known state.*/
- dmaStreamDisable(dmastp);
- dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
-
- return dmastp;
- }
- }
-
- return NULL;
-}
-
-/**
- * @brief Allocates a DMA stream.
- * @details The stream is allocated and, if required, the DMA clock enabled.
- * The function also enables the IRQ vector associated to the stream
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific stream or:
- * - @p STM32_DMA_STREAM_ID_ANY for any stream.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
- * on DMA1.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
- * on DMA2.
- * .
- * @param[in] priority IRQ priority for the DMA stream
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_dma_stream_t
- * structure.
- * @retval NULL if a/the stream is not available.
- *
- * @api
- */
-const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param) {
- const stm32_dma_stream_t *dmastp;
-
- osalSysLock();
- dmastp = dmaStreamAllocI(id, priority, func, param);
- osalSysUnlock();
-
- return dmastp;
-}
-
-/**
- * @brief Releases a DMA stream.
- * @details The stream is freed and, if required, the DMA clock disabled.
- * Trying to release a unallocated stream is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @iclass
- */
-void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) {
- uint32_t selfindex = (uint32_t)dmastp->selfindex;
-
- osalDbgCheck(dmastp != NULL);
-
- /* Check if the streams is not taken.*/
- osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U,
- "not allocated");
-
- /* Marks the stream as not allocated.*/
- dma.allocated_mask &= ~(1U << selfindex);
- dma.isr_mask &= ~(1U << selfindex);
-
- /* Disables the associated IRQ vector if it is no more in use.*/
- if ((dma.isr_mask & dmastp->cmask) == 0U) {
- nvicDisableVector(dmastp->vector);
- }
-
- /* Removes the DMA handler.*/
- dma.streams[selfindex].func = NULL;
- dma.streams[selfindex].param = NULL;
-
- /* Shutting down clocks that are no more required, if any.*/
- if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) {
- rccDisableDMA1();
- }
-#if STM32_DMA2_NUM_CHANNELS > 0
- if ((dma.allocated_mask & STM32_DMA2_STREAMS_MASK) == 0U) {
- rccDisableDMA2();
- }
-#endif
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccDisableDMAMUX)
- /* Shutting down DMAMUX if present.*/
- if (dma.allocated_mask == 0U) {
- rccDisableDMAMUX();
- }
-#endif
-}
-
-/**
- * @brief Releases a DMA stream.
- * @details The stream is freed and, if required, the DMA clock disabled.
- * Trying to release a unallocated stream is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @api
- */
-void dmaStreamFree(const stm32_dma_stream_t *dmastp) {
-
- osalSysLock();
- dmaStreamFreeI(dmastp);
- osalSysUnlock();
-}
-
-/**
- * @brief Serves a DMA IRQ.
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-void dmaServeInterrupt(const stm32_dma_stream_t *dmastp) {
- uint32_t flags;
- uint32_t selfindex = (uint32_t)dmastp->selfindex;
-
- flags = (dmastp->dma->ISR >> dmastp->shift) & STM32_DMA_ISR_MASK;
- if (flags & dmastp->channel->CCR) {
- dmastp->dma->IFCR = flags << dmastp->shift;
- if (dma.streams[selfindex].func) {
- dma.streams[selfindex].func(dma.streams[selfindex].param, flags);
- }
- }
-}
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Associates a peripheral request to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- *
- * @param[in] dmastp pointer to a @p stm32_dma_stream_t structure
- * @param[in] per peripheral identifier
- *
- * @special
- */
-void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per) {
-
- osalDbgCheck(per < 256U);
-
- dmastp->mux->CCR = per;
-}
-#endif
-
-#endif /* STM32_DMA_REQUIRED */
-
-/** @} */
+/*
+ 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 DMAv1/stm32_dma.c
+ * @brief DMA helper driver code.
+ *
+ * @addtogroup STM32_DMA
+ * @details DMA sharing helper driver. In the STM32 the DMA streams are a
+ * shared resource, this driver allows to allocate and free DMA
+ * streams at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The DMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * ISRs when allocating streams.
+ * @{
+ */
+
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring DMA services
+ has been enabled.*/
+#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/**
+ * @brief Mask of the DMA1 streams in @p dma_streams_mask.
+ */
+#define STM32_DMA1_STREAMS_MASK ((1U << STM32_DMA1_NUM_CHANNELS) - 1U)
+
+/**
+ * @brief Mask of the DMA2 streams in @p dma_streams_mask.
+ */
+#define STM32_DMA2_STREAMS_MASK (((1U << STM32_DMA2_NUM_CHANNELS) - \
+ 1U) << STM32_DMA1_NUM_CHANNELS)
+
+#if STM32_DMA_SUPPORTS_CSELR == TRUE
+
+#if defined(DMA1_CSELR)
+#define __DMA1_CSELR &DMA1_CSELR->CSELR
+#else
+#define __DMA1_CSELR &DMA1->CSELR
+#endif
+
+#if defined(DMA2_CSELR)
+#define __DMA2_CSELR &DMA2_CSELR->CSELR
+#else
+#define __DMA2_CSELR &DMA2->CSELR
+#endif
+
+#define DMA1_CH1_VARIANT __DMA1_CSELR
+#define DMA1_CH2_VARIANT __DMA1_CSELR
+#define DMA1_CH3_VARIANT __DMA1_CSELR
+#define DMA1_CH4_VARIANT __DMA1_CSELR
+#define DMA1_CH5_VARIANT __DMA1_CSELR
+#define DMA1_CH6_VARIANT __DMA1_CSELR
+#define DMA1_CH7_VARIANT __DMA1_CSELR
+#define DMA1_CH8_VARIANT __DMA1_CSELR
+#define DMA2_CH1_VARIANT __DMA2_CSELR
+#define DMA2_CH2_VARIANT __DMA2_CSELR
+#define DMA2_CH3_VARIANT __DMA2_CSELR
+#define DMA2_CH4_VARIANT __DMA2_CSELR
+#define DMA2_CH5_VARIANT __DMA2_CSELR
+#define DMA2_CH6_VARIANT __DMA2_CSELR
+#define DMA2_CH7_VARIANT __DMA2_CSELR
+#define DMA2_CH8_VARIANT __DMA2_CSELR
+
+#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE
+
+#define DMAMUX1_CHANNEL(id) (DMAMUX1_BASE + ((id) * 4U))
+
+#define DMA1_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0))
+#define DMA1_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1))
+#define DMA1_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2))
+#define DMA1_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3))
+#define DMA1_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4))
+#define DMA1_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5))
+#define DMA1_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6))
+#define DMA1_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7))
+#define DMA2_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6 + STM32_DMA1_NUM_CHANNELS))
+#define DMA2_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7 + STM32_DMA1_NUM_CHANNELS))
+
+#else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
+
+#define DMA1_CH1_VARIANT 0
+#define DMA1_CH2_VARIANT 0
+#define DMA1_CH3_VARIANT 0
+#define DMA1_CH4_VARIANT 0
+#define DMA1_CH5_VARIANT 0
+#define DMA1_CH6_VARIANT 0
+#define DMA1_CH7_VARIANT 0
+#define DMA2_CH1_VARIANT 0
+#define DMA2_CH2_VARIANT 0
+#define DMA2_CH3_VARIANT 0
+#define DMA2_CH4_VARIANT 0
+#define DMA2_CH5_VARIANT 0
+#define DMA2_CH6_VARIANT 0
+#define DMA2_CH7_VARIANT 0
+
+#endif /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
+
+/*
+ * Default ISR collision masks.
+ */
+#if !defined(STM32_DMA1_CH1_CMASK)
+#define STM32_DMA1_CH1_CMASK (1U << 0U)
+#endif
+
+#if !defined(STM32_DMA1_CH2_CMASK)
+#define STM32_DMA1_CH2_CMASK (1U << 1U)
+#endif
+
+#if !defined(STM32_DMA1_CH3_CMASK)
+#define STM32_DMA1_CH3_CMASK (1U << 2U)
+#endif
+
+#if !defined(STM32_DMA1_CH4_CMASK)
+#define STM32_DMA1_CH4_CMASK (1U << 3U)
+#endif
+
+#if !defined(STM32_DMA1_CH5_CMASK)
+#define STM32_DMA1_CH5_CMASK (1U << 4U)
+#endif
+
+#if !defined(STM32_DMA1_CH6_CMASK)
+#define STM32_DMA1_CH6_CMASK (1U << 5U)
+#endif
+
+#if !defined(STM32_DMA1_CH7_CMASK)
+#define STM32_DMA1_CH7_CMASK (1U << 6U)
+#endif
+
+#if !defined(STM32_DMA1_CH8_CMASK)
+#define STM32_DMA1_CH8_CMASK (1U << 7U)
+#endif
+
+#if !defined(STM32_DMA2_CH1_CMASK)
+#define STM32_DMA2_CH1_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 0U))
+#endif
+
+#if !defined(STM32_DMA2_CH2_CMASK)
+#define STM32_DMA2_CH2_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 1U))
+#endif
+
+#if !defined(STM32_DMA2_CH3_CMASK)
+#define STM32_DMA2_CH3_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 2U))
+#endif
+
+#if !defined(STM32_DMA2_CH4_CMASK)
+#define STM32_DMA2_CH4_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 3U))
+#endif
+
+#if !defined(STM32_DMA2_CH5_CMASK)
+#define STM32_DMA2_CH5_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 4U))
+#endif
+
+#if !defined(STM32_DMA2_CH6_CMASK)
+#define STM32_DMA2_CH6_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 5U))
+#endif
+
+#if !defined(STM32_DMA2_CH7_CMASK)
+#define STM32_DMA2_CH7_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 6U))
+#endif
+
+#if !defined(STM32_DMA2_CH8_CMASK)
+#define STM32_DMA2_CH8_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 7U))
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA streams descriptors.
+ * @details This table keeps the association between an unique stream
+ * identifier and the involved physical registers.
+ * @note Don't use this array directly, use the appropriate wrapper macros
+ * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
+ */
+const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
+#if STM32_DMA1_NUM_CHANNELS > 0
+ {DMA1, DMA1_Channel1, STM32_DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, 0, STM32_DMA1_CH1_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 1
+ {DMA1, DMA1_Channel2, STM32_DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, 1, STM32_DMA1_CH2_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 2
+ {DMA1, DMA1_Channel3, STM32_DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, 2, STM32_DMA1_CH3_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 3
+ {DMA1, DMA1_Channel4, STM32_DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, 3, STM32_DMA1_CH4_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 4
+ {DMA1, DMA1_Channel5, STM32_DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, 4, STM32_DMA1_CH5_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 5
+ {DMA1, DMA1_Channel6, STM32_DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, STM32_DMA1_CH6_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 6
+ {DMA1, DMA1_Channel7, STM32_DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, STM32_DMA1_CH7_NUMBER},
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 7
+ {DMA1, DMA1_Channel8, STM32_DMA1_CH8_CMASK, DMA1_CH8_VARIANT, 28, 7, STM32_DMA1_CH8_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 0
+ {DMA2, DMA2_Channel1, STM32_DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, 0 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH1_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 1
+ {DMA2, DMA2_Channel2, STM32_DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, 1 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH2_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 2
+ {DMA2, DMA2_Channel3, STM32_DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, 2 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH3_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 3
+ {DMA2, DMA2_Channel4, STM32_DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, 3 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH4_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 4
+ {DMA2, DMA2_Channel5, STM32_DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, 4 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH5_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 5
+ {DMA2, DMA2_Channel6, STM32_DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 5 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH6_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 6
+ {DMA2, DMA2_Channel7, STM32_DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 6 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH7_NUMBER},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 7
+ {DMA2, DMA2_Channel8, STM32_DMA2_CH8_CMASK, DMA2_CH8_VARIANT, 28, 7 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH8_NUMBER},
+#endif
+};
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Global DMA-related data structures.
+ */
+static struct {
+ /**
+ * @brief Mask of the allocated streams.
+ */
+ uint32_t allocated_mask;
+ /**
+ * @brief Mask of the enabled streams ISRs.
+ */
+ uint32_t isr_mask;
+ /**
+ * @brief DMA IRQ redirectors.
+ */
+ struct {
+ /**
+ * @brief DMA callback function.
+ */
+ stm32_dmaisr_t func;
+ /**
+ * @brief DMA callback parameter.
+ */
+ void *param;
+ } streams[STM32_DMA_STREAMS];
+} dma;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if defined(STM32_DMA1_CH1_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 1 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH2_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 2 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH3_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 3 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH4_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 4 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH5_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 5 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH6_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 6 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH7_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 7 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA1_CH8_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA1 stream 8 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA1_STREAM8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH1_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 1 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH2_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 2 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH3_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 3 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH4_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 4 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH5_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 5 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH6_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 6 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH7_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 7 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if defined(STM32_DMA2_CH8_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief DMA2 stream 8 shared ISR.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmaServeInterrupt(STM32_DMA2_STREAM8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 DMA helper initialization.
+ *
+ * @init
+ */
+void dmaInit(void) {
+ int i;
+
+ dma.allocated_mask = 0U;
+ dma.isr_mask = 0U;
+ for (i = 0; i < STM32_DMA_STREAMS; i++) {
+ _stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE;
+ dma.streams[i].func = NULL;
+ }
+ DMA1->IFCR = 0xFFFFFFFFU;
+#if STM32_DMA2_NUM_CHANNELS > 0
+ DMA2->IFCR = 0xFFFFFFFFU;
+#endif
+}
+
+/**
+ * @brief Allocates a DMA stream.
+ * @details The stream is allocated and, if required, the DMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific stream or:
+ * - @p STM32_DMA_STREAM_ID_ANY for any stream.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
+ * on DMA1.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
+ * on DMA2.
+ * .
+ * @param[in] priority IRQ priority for the DMA stream
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_dma_stream_t
+ * structure.
+ * @retval NULL if a/the stream is not available.
+ *
+ * @iclass
+ */
+const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param) {
+ uint32_t i, startid, endid;
+
+ osalDbgCheckClassI();
+
+ if (id < STM32_DMA_STREAMS) {
+ startid = id;
+ endid = id;
+ }
+#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
+ else if (id == STM32_DMA_STREAM_ID_ANY) {
+ startid = 0U;
+ endid = STM32_DMA_STREAMS - 1U;
+ }
+ else if (id == STM32_DMA_STREAM_ID_ANY_DMA1) {
+ startid = 0U;
+ endid = STM32_DMA1_NUM_CHANNELS - 1U;
+ }
+#if STM32_DMA2_NUM_CHANNELS > 0
+ else if (id == STM32_DMA_STREAM_ID_ANY_DMA2) {
+ startid = STM32_DMA1_NUM_CHANNELS;
+ endid = STM32_DMA_STREAMS - 1U;
+ }
+#endif
+#endif
+ else {
+ osalDbgCheck(false);
+ return NULL;
+ }
+
+ for (i = startid; i <= endid; i++) {
+ uint32_t mask = (1U << i);
+ if ((dma.allocated_mask & mask) == 0U) {
+ const stm32_dma_stream_t *dmastp = STM32_DMA_STREAM(i);
+
+ /* Installs the DMA handler.*/
+ dma.streams[i].func = func;
+ dma.streams[i].param = param;
+ dma.allocated_mask |= mask;
+
+ /* Enabling DMA clocks required by the current streams set.*/
+ if ((STM32_DMA1_STREAMS_MASK & mask) != 0U) {
+ rccEnableDMA1(true);
+ }
+#if STM32_DMA2_NUM_CHANNELS > 0
+ if ((STM32_DMA2_STREAMS_MASK & mask) != 0U) {
+ rccEnableDMA2(true);
+ }
+#endif
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccEnableDMAMUX)
+ /* Enabling DMAMUX if present.*/
+ if (dma.allocated_mask != 0U) {
+ rccEnableDMAMUX(true);
+ }
+#endif
+
+ /* Enables the associated IRQ vector if not already enabled and if a
+ callback is defined.*/
+ if (func != NULL) {
+ if ((dma.isr_mask & dmastp->cmask) == 0U) {
+ nvicEnableVector(dmastp->vector, priority);
+ }
+ dma.isr_mask |= mask;
+ }
+
+ /* Putting the stream in a known state.*/
+ dmaStreamDisable(dmastp);
+ dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
+
+ return dmastp;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Allocates a DMA stream.
+ * @details The stream is allocated and, if required, the DMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific stream or:
+ * - @p STM32_DMA_STREAM_ID_ANY for any stream.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
+ * on DMA1.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
+ * on DMA2.
+ * .
+ * @param[in] priority IRQ priority for the DMA stream
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_dma_stream_t
+ * structure.
+ * @retval NULL if a/the stream is not available.
+ *
+ * @api
+ */
+const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param) {
+ const stm32_dma_stream_t *dmastp;
+
+ osalSysLock();
+ dmastp = dmaStreamAllocI(id, priority, func, param);
+ osalSysUnlock();
+
+ return dmastp;
+}
+
+/**
+ * @brief Releases a DMA stream.
+ * @details The stream is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @iclass
+ */
+void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) {
+ uint32_t selfindex = (uint32_t)dmastp->selfindex;
+
+ osalDbgCheck(dmastp != NULL);
+
+ /* Check if the streams is not taken.*/
+ osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U,
+ "not allocated");
+
+ /* Marks the stream as not allocated.*/
+ dma.allocated_mask &= ~(1U << selfindex);
+ dma.isr_mask &= ~(1U << selfindex);
+
+ /* Disables the associated IRQ vector if it is no more in use.*/
+ if ((dma.isr_mask & dmastp->cmask) == 0U) {
+ nvicDisableVector(dmastp->vector);
+ }
+
+ /* Removes the DMA handler.*/
+ dma.streams[selfindex].func = NULL;
+ dma.streams[selfindex].param = NULL;
+
+ /* Shutting down clocks that are no more required, if any.*/
+ if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) {
+ rccDisableDMA1();
+ }
+#if STM32_DMA2_NUM_CHANNELS > 0
+ if ((dma.allocated_mask & STM32_DMA2_STREAMS_MASK) == 0U) {
+ rccDisableDMA2();
+ }
+#endif
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccDisableDMAMUX)
+ /* Shutting down DMAMUX if present.*/
+ if (dma.allocated_mask == 0U) {
+ rccDisableDMAMUX();
+ }
+#endif
+}
+
+/**
+ * @brief Releases a DMA stream.
+ * @details The stream is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @api
+ */
+void dmaStreamFree(const stm32_dma_stream_t *dmastp) {
+
+ osalSysLock();
+ dmaStreamFreeI(dmastp);
+ osalSysUnlock();
+}
+
+/**
+ * @brief Serves a DMA IRQ.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+void dmaServeInterrupt(const stm32_dma_stream_t *dmastp) {
+ uint32_t flags;
+ uint32_t selfindex = (uint32_t)dmastp->selfindex;
+
+ flags = (dmastp->dma->ISR >> dmastp->shift) & STM32_DMA_ISR_MASK;
+ if (flags & dmastp->channel->CCR) {
+ dmastp->dma->IFCR = flags << dmastp->shift;
+ if (dma.streams[selfindex].func) {
+ dma.streams[selfindex].func(dma.streams[selfindex].param, flags);
+ }
+ }
+}
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Associates a peripheral request to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a @p stm32_dma_stream_t structure
+ * @param[in] per peripheral identifier
+ *
+ * @special
+ */
+void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per) {
+
+ osalDbgCheck(per < 256U);
+
+ dmastp->mux->CCR = per;
+}
+#endif
+
+#endif /* STM32_DMA_REQUIRED */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
index 54b6bde846..a91f5cb5e7 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
+++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
@@ -1,554 +1,554 @@
-/*
- 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 DMAv1/stm32_dma.h
- * @brief DMA helper driver header.
- * @note This driver uses the new naming convention used for the STM32F2xx
- * so the "DMA channels" are referred as "DMA streams".
- *
- * @addtogroup STM32_DMA
- * @{
- */
-
-#ifndef STM32_DMA_H
-#define STM32_DMA_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief DMA capability.
- * @details if @p TRUE then the DMA is able of burst transfers, FIFOs,
- * scatter gather and other advanced features.
- */
-#define STM32_DMA_ADVANCED FALSE
-
-/**
- * @brief Total number of DMA streams.
- * @details This is the total number of streams among all the DMA units.
- */
-#define STM32_DMA_STREAMS (STM32_DMA1_NUM_CHANNELS + \
- STM32_DMA2_NUM_CHANNELS)
-
-/**
- * @brief Mask of the ISR bits passed to the DMA callback functions.
- */
-#define STM32_DMA_ISR_MASK 0x0E
-
-/**
- * @brief Returns the request line associated to the specified stream.
- * @note In some STM32 manuals the request line is named confusingly
- * channel.
- *
- * @param[in] id the unique numeric stream identifier
- * @param[in] c a stream/request association word, one request per
- * nibble
- * @return Returns the request associated to the stream.
- */
-#define STM32_DMA_GETCHANNEL(id, c) \
- (((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)STM32_DMA1_NUM_CHANNELS) * 4U)) & 15U)
-
-/**
- * @brief Checks if a DMA priority is within the valid range.
- * @param[in] prio DMA priority
- *
- * @retval The check result.
- * @retval false invalid DMA priority.
- * @retval true correct DMA priority.
- */
-#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__)
-/**
- * @brief Checks if a DMA stream id is within the valid range.
- *
- * @param[in] id DMA stream id
- * @retval The check result.
- * @retval false invalid DMA channel.
- * @retval true correct DMA channel.
- */
-#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) < STM32_DMA_STREAMS))
-#else /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
-#if STM32_DMA2_NUM_CHANNELS > 0
-#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) <= (STM32_DMA_STREAMS + 2)))
-#else
-#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) <= (STM32_DMA_STREAMS + 1)))
-#endif
-#endif /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
-
-/**
- * @brief Returns an unique numeric identifier for a DMA stream.
- *
- * @param[in] dma the DMA unit number
- * @param[in] stream the stream number
- * @return An unique numeric stream identifier.
- */
-#define STM32_DMA_STREAM_ID(dma, stream) \
- ((((dma) - 1) * STM32_DMA1_NUM_CHANNELS) + ((stream) - 1))
-
-/**
- * @brief Returns a DMA stream identifier mask.
- *
- *
- * @param[in] dma the DMA unit number
- * @param[in] stream the stream number
- * @return A DMA stream identifier mask.
- */
-#define STM32_DMA_STREAM_ID_MSK(dma, stream) \
- (1U << STM32_DMA_STREAM_ID(dma, stream))
-
-/**
- * @brief Checks if a DMA stream unique identifier belongs to a mask.
- *
- * @param[in] id the stream numeric identifier
- * @param[in] mask the stream numeric identifiers mask
- *
- * @retval The check result.
- * @retval false id does not belong to the mask.
- * @retval true id belongs to the mask.
- */
-#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__)
-/**
- * @name Special stream identifiers
- * @{
- */
-#define STM32_DMA_STREAM_ID_ANY STM32_DMA_STREAMS
-#define STM32_DMA_STREAM_ID_ANY_DMA1 (STM32_DMA_STREAM_ID_ANY + 1)
-#if STM32_DMA2_NUM_CHANNELS > 0
-#define STM32_DMA_STREAM_ID_ANY_DMA2 (STM32_DMA_STREAM_ID_ANY_DMA1 + 1)
-#endif
-/** @} */
-#endif
-
-/**
- * @name DMA streams identifiers
- * @{
- */
-/**
- * @brief Returns a pointer to a stm32_dma_stream_t structure.
- *
- * @param[in] id the stream numeric identifier
- * @return A pointer to the stm32_dma_stream_t constant structure
- * associated to the DMA stream.
- */
-#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id])
-
-#if STM32_DMA1_NUM_CHANNELS > 0
-#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 1
-#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 2
-#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 3
-#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 4
-#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 5
-#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 6
-#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6)
-#endif
-#if STM32_DMA1_NUM_CHANNELS > 7
-#define STM32_DMA1_STREAM8 STM32_DMA_STREAM(7)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 0
-#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 0)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 1
-#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 1)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 2
-#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 2)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 3
-#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 3)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 4
-#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 4)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 5
-#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 5)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 6
-#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 6)
-#endif
-#if STM32_DMA2_NUM_CHANNELS > 7
-#define STM32_DMA2_STREAM8 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 7)
-#endif
-/** @} */
-
-/**
- * @name CR register constants common to all DMA types
- * @{
- */
-#define STM32_DMA_CCR_RESET_VALUE 0x00000000U
-#define STM32_DMA_CR_EN DMA_CCR_EN
-#define STM32_DMA_CR_TEIE DMA_CCR_TEIE
-#define STM32_DMA_CR_HTIE DMA_CCR_HTIE
-#define STM32_DMA_CR_TCIE DMA_CCR_TCIE
-#define STM32_DMA_CR_DIR_MASK (DMA_CCR_DIR | DMA_CCR_MEM2MEM)
-#define STM32_DMA_CR_DIR_P2M 0U
-#define STM32_DMA_CR_DIR_M2P DMA_CCR_DIR
-#define STM32_DMA_CR_DIR_M2M DMA_CCR_MEM2MEM
-#define STM32_DMA_CR_CIRC DMA_CCR_CIRC
-#define STM32_DMA_CR_PINC DMA_CCR_PINC
-#define STM32_DMA_CR_MINC DMA_CCR_MINC
-#define STM32_DMA_CR_PSIZE_MASK DMA_CCR_PSIZE
-#define STM32_DMA_CR_PSIZE_BYTE 0U
-#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR_PSIZE_0
-#define STM32_DMA_CR_PSIZE_WORD DMA_CCR_PSIZE_1
-#define STM32_DMA_CR_MSIZE_MASK DMA_CCR_MSIZE
-#define STM32_DMA_CR_MSIZE_BYTE 0U
-#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR_MSIZE_0
-#define STM32_DMA_CR_MSIZE_WORD DMA_CCR_MSIZE_1
-#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
- STM32_DMA_CR_MSIZE_MASK)
-#define STM32_DMA_CR_PL_MASK DMA_CCR_PL
-#define STM32_DMA_CR_PL(n) ((n) << 12U)
-/** @} */
-
-/**
- * @name Request line selector macro
- * @{
- */
-#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__)
-#define STM32_DMA_CR_CHSEL_MASK (15U << 16U)
-#define STM32_DMA_CR_CHSEL(n) ((n) << 16U)
-#else
-#define STM32_DMA_CR_CHSEL_MASK 0U
-#define STM32_DMA_CR_CHSEL(n) 0U
-#endif
-/** @} */
-
-/**
- * @name CR register constants only found in enhanced DMA
- * @{
- */
-#define STM32_DMA_CR_DMEIE 0U /**< @brief Ignored by normal DMA. */
-/** @} */
-
-/**
- * @name Status flags passed to the ISR callbacks
- * @{
- */
-#define STM32_DMA_ISR_FEIF 0U
-#define STM32_DMA_ISR_DMEIF 0U
-#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
-#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
-#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_DMA_SUPPORTS_DMAMUX)
-#error "STM32_DMA_SUPPORTS_DMAMUX not defined in registry"
-#endif
-
-#if !defined(STM32_DMA_SUPPORTS_CSELR)
-#error "STM32_DMA_SUPPORTS_CSELR not defined in registry"
-#endif
-
-#if STM32_DMA_SUPPORTS_DMAMUX && STM32_DMA_SUPPORTS_CSELR
-#error "STM32_DMA_SUPPORTS_DMAMUX and STM32_DMA_SUPPORTS_CSELR both TRUE"
-#endif
-
-#if !defined(STM32_DMA1_NUM_CHANNELS)
-#error "STM32_DMA1_NUM_CHANNELS not defined in registry"
-#endif
-
-#if !defined(STM32_DMA2_NUM_CHANNELS)
-#error "STM32_DMA2_NUM_CHANNELS not defined in registry"
-#endif
-
-#if (STM32_DMA1_NUM_CHANNELS < 0) || (STM32_DMA1_NUM_CHANNELS > 8)
-#error "unsupported channels configuration"
-#endif
-
-#if (STM32_DMA2_NUM_CHANNELS < 0) || (STM32_DMA2_NUM_CHANNELS > 8)
-#error "unsupported channels configuration"
-#endif
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
-#include "stm32_dmamux.h"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a DMA callback.
- *
- * @param[in] p parameter for the registered function
- * @param[in] flags pre-shifted content of the ISR register, the bits
- * are aligned to bit zero
- */
-typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
-
-/**
- * @brief STM32 DMA stream descriptor structure.
- */
-typedef struct {
- DMA_TypeDef *dma; /**< @brief Associated DMA. */
- DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
- uint32_t cmask; /**< @brief Mask of streams sharing
- the same ISR. */
-#if (STM32_DMA_SUPPORTS_CSELR == TRUE) || defined(__DOXYGEN__)
- volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */
-#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE
- DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */
-#else
- uint8_t dummy; /**< @brief Filler. */
-#endif
- uint8_t shift; /**< @brief Bit offset in ISR, IFCR
- and CSELR registers. */
- uint8_t selfindex; /**< @brief Index to self in array. */
- uint8_t vector; /**< @brief Associated IRQ vector. */
-} stm32_dma_stream_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @name Macro Functions
- * @{
- */
-/**
- * @brief Associates a peripheral data register to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] addr value to be written in the CPAR register
- *
- * @special
- */
-#define dmaStreamSetPeripheral(dmastp, addr) { \
- (dmastp)->channel->CPAR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Associates a memory destination to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] addr value to be written in the CMAR register
- *
- * @special
- */
-#define dmaStreamSetMemory0(dmastp, addr) { \
- (dmastp)->channel->CMAR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Sets the number of transfers to be performed.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] size value to be written in the CNDTR register
- *
- * @special
- */
-#define dmaStreamSetTransactionSize(dmastp, size) { \
- (dmastp)->channel->CNDTR = (uint32_t)(size); \
-}
-
-/**
- * @brief Returns the number of transfers to be performed.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @return The number of transfers to be performed.
- *
- * @special
- */
-#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
-
-/**
- * @brief Programs the stream mode settings.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] mode value to be written in the CCR register
- *
- * @special
- */
-#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__)
-#define dmaStreamSetMode(dmastp, mode) { \
- uint32_t cselr = *(dmastp)->cselr; \
- cselr &= ~(0x0000000FU << (dmastp)->shift); \
- cselr |= (((uint32_t)(mode) >> 16U) << (dmastp)->shift); \
- *(dmastp)->cselr = cselr; \
- (dmastp)->channel->CCR = (uint32_t)(mode); \
-}
-#else
-#define dmaStreamSetMode(dmastp, mode) { \
- (dmastp)->channel->CCR = (uint32_t)(mode); \
-}
-#endif
-
-/**
- * @brief DMA stream enable.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-#define dmaStreamEnable(dmastp) { \
- (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
-}
-
-/**
- * @brief DMA stream disable.
- * @details The function disables the specified stream and then clears any
- * pending interrupt.
- * @note This function can be invoked in both ISR or thread context.
- * @note Interrupts enabling flags are set to zero after this call, see
- * bug 3607518.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-#define dmaStreamDisable(dmastp) { \
- (dmastp)->channel->CCR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
- STM32_DMA_CR_TEIE | STM32_DMA_CR_EN); \
- dmaStreamClearInterrupt(dmastp); \
-}
-
-/**
- * @brief DMA stream interrupt sources clear.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-#define dmaStreamClearInterrupt(dmastp) { \
- (dmastp)->dma->IFCR = STM32_DMA_ISR_MASK << (dmastp)->shift; \
-}
-
-/**
- * @brief Starts a memory to memory operation using the specified stream.
- * @note The default transfer data mode is "byte to byte" but it can be
- * changed by specifying extra options in the @p mode parameter.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] mode value to be written in the CCR register, this value
- * is implicitly ORed with:
- * - @p STM32_DMA_CR_MINC
- * - @p STM32_DMA_CR_PINC
- * - @p STM32_DMA_CR_DIR_M2M
- * - @p STM32_DMA_CR_EN
- * .
- * @param[in] src source address
- * @param[in] dst destination address
- * @param[in] n number of data units to copy
- */
-#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
- dmaStreamSetPeripheral(dmastp, src); \
- dmaStreamSetMemory0(dmastp, dst); \
- dmaStreamSetTransactionSize(dmastp, n); \
- dmaStreamSetMode(dmastp, (mode) | \
- STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
- STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \
-}
-
-/**
- * @brief Polled wait for DMA transfer end.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamRelease().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- */
-#define dmaWaitCompletion(dmastp) { \
- while ((dmastp)->channel->CNDTR > 0U) \
- ; \
- dmaStreamDisable(dmastp); \
-}
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void dmaInit(void);
- const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param);
- const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param);
- void dmaStreamFreeI(const stm32_dma_stream_t *dmastp);
- void dmaStreamFree(const stm32_dma_stream_t *dmastp);
- void dmaServeInterrupt(const stm32_dma_stream_t *dmastp);
-#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
- void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMA_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 DMAv1/stm32_dma.h
+ * @brief DMA helper driver header.
+ * @note This driver uses the new naming convention used for the STM32F2xx
+ * so the "DMA channels" are referred as "DMA streams".
+ *
+ * @addtogroup STM32_DMA
+ * @{
+ */
+
+#ifndef STM32_DMA_H
+#define STM32_DMA_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA capability.
+ * @details if @p TRUE then the DMA is able of burst transfers, FIFOs,
+ * scatter gather and other advanced features.
+ */
+#define STM32_DMA_ADVANCED FALSE
+
+/**
+ * @brief Total number of DMA streams.
+ * @details This is the total number of streams among all the DMA units.
+ */
+#define STM32_DMA_STREAMS (STM32_DMA1_NUM_CHANNELS + \
+ STM32_DMA2_NUM_CHANNELS)
+
+/**
+ * @brief Mask of the ISR bits passed to the DMA callback functions.
+ */
+#define STM32_DMA_ISR_MASK 0x0E
+
+/**
+ * @brief Returns the request line associated to the specified stream.
+ * @note In some STM32 manuals the request line is named confusingly
+ * channel.
+ *
+ * @param[in] id the unique numeric stream identifier
+ * @param[in] c a stream/request association word, one request per
+ * nibble
+ * @return Returns the request associated to the stream.
+ */
+#define STM32_DMA_GETCHANNEL(id, c) \
+ (((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)STM32_DMA1_NUM_CHANNELS) * 4U)) & 15U)
+
+/**
+ * @brief Checks if a DMA priority is within the valid range.
+ * @param[in] prio DMA priority
+ *
+ * @retval The check result.
+ * @retval false invalid DMA priority.
+ * @retval true correct DMA priority.
+ */
+#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__)
+/**
+ * @brief Checks if a DMA stream id is within the valid range.
+ *
+ * @param[in] id DMA stream id
+ * @retval The check result.
+ * @retval false invalid DMA channel.
+ * @retval true correct DMA channel.
+ */
+#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) < STM32_DMA_STREAMS))
+#else /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
+#if STM32_DMA2_NUM_CHANNELS > 0
+#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) <= (STM32_DMA_STREAMS + 2)))
+#else
+#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) <= (STM32_DMA_STREAMS + 1)))
+#endif
+#endif /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
+
+/**
+ * @brief Returns an unique numeric identifier for a DMA stream.
+ *
+ * @param[in] dma the DMA unit number
+ * @param[in] stream the stream number
+ * @return An unique numeric stream identifier.
+ */
+#define STM32_DMA_STREAM_ID(dma, stream) \
+ ((((dma) - 1) * STM32_DMA1_NUM_CHANNELS) + ((stream) - 1))
+
+/**
+ * @brief Returns a DMA stream identifier mask.
+ *
+ *
+ * @param[in] dma the DMA unit number
+ * @param[in] stream the stream number
+ * @return A DMA stream identifier mask.
+ */
+#define STM32_DMA_STREAM_ID_MSK(dma, stream) \
+ (1U << STM32_DMA_STREAM_ID(dma, stream))
+
+/**
+ * @brief Checks if a DMA stream unique identifier belongs to a mask.
+ *
+ * @param[in] id the stream numeric identifier
+ * @param[in] mask the stream numeric identifiers mask
+ *
+ * @retval The check result.
+ * @retval false id does not belong to the mask.
+ * @retval true id belongs to the mask.
+ */
+#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__)
+/**
+ * @name Special stream identifiers
+ * @{
+ */
+#define STM32_DMA_STREAM_ID_ANY STM32_DMA_STREAMS
+#define STM32_DMA_STREAM_ID_ANY_DMA1 (STM32_DMA_STREAM_ID_ANY + 1)
+#if STM32_DMA2_NUM_CHANNELS > 0
+#define STM32_DMA_STREAM_ID_ANY_DMA2 (STM32_DMA_STREAM_ID_ANY_DMA1 + 1)
+#endif
+/** @} */
+#endif
+
+/**
+ * @name DMA streams identifiers
+ * @{
+ */
+/**
+ * @brief Returns a pointer to a stm32_dma_stream_t structure.
+ *
+ * @param[in] id the stream numeric identifier
+ * @return A pointer to the stm32_dma_stream_t constant structure
+ * associated to the DMA stream.
+ */
+#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id])
+
+#if STM32_DMA1_NUM_CHANNELS > 0
+#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 1
+#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 2
+#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 3
+#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 4
+#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 5
+#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 6
+#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6)
+#endif
+#if STM32_DMA1_NUM_CHANNELS > 7
+#define STM32_DMA1_STREAM8 STM32_DMA_STREAM(7)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 0
+#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 0)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 1
+#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 1)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 2
+#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 2)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 3
+#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 3)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 4
+#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 4)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 5
+#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 5)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 6
+#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 6)
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 7
+#define STM32_DMA2_STREAM8 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 7)
+#endif
+/** @} */
+
+/**
+ * @name CR register constants common to all DMA types
+ * @{
+ */
+#define STM32_DMA_CCR_RESET_VALUE 0x00000000U
+#define STM32_DMA_CR_EN DMA_CCR_EN
+#define STM32_DMA_CR_TEIE DMA_CCR_TEIE
+#define STM32_DMA_CR_HTIE DMA_CCR_HTIE
+#define STM32_DMA_CR_TCIE DMA_CCR_TCIE
+#define STM32_DMA_CR_DIR_MASK (DMA_CCR_DIR | DMA_CCR_MEM2MEM)
+#define STM32_DMA_CR_DIR_P2M 0U
+#define STM32_DMA_CR_DIR_M2P DMA_CCR_DIR
+#define STM32_DMA_CR_DIR_M2M DMA_CCR_MEM2MEM
+#define STM32_DMA_CR_CIRC DMA_CCR_CIRC
+#define STM32_DMA_CR_PINC DMA_CCR_PINC
+#define STM32_DMA_CR_MINC DMA_CCR_MINC
+#define STM32_DMA_CR_PSIZE_MASK DMA_CCR_PSIZE
+#define STM32_DMA_CR_PSIZE_BYTE 0U
+#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR_PSIZE_0
+#define STM32_DMA_CR_PSIZE_WORD DMA_CCR_PSIZE_1
+#define STM32_DMA_CR_MSIZE_MASK DMA_CCR_MSIZE
+#define STM32_DMA_CR_MSIZE_BYTE 0U
+#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR_MSIZE_0
+#define STM32_DMA_CR_MSIZE_WORD DMA_CCR_MSIZE_1
+#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
+ STM32_DMA_CR_MSIZE_MASK)
+#define STM32_DMA_CR_PL_MASK DMA_CCR_PL
+#define STM32_DMA_CR_PL(n) ((n) << 12U)
+/** @} */
+
+/**
+ * @name Request line selector macro
+ * @{
+ */
+#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__)
+#define STM32_DMA_CR_CHSEL_MASK (15U << 16U)
+#define STM32_DMA_CR_CHSEL(n) ((n) << 16U)
+#else
+#define STM32_DMA_CR_CHSEL_MASK 0U
+#define STM32_DMA_CR_CHSEL(n) 0U
+#endif
+/** @} */
+
+/**
+ * @name CR register constants only found in enhanced DMA
+ * @{
+ */
+#define STM32_DMA_CR_DMEIE 0U /**< @brief Ignored by normal DMA. */
+/** @} */
+
+/**
+ * @name Status flags passed to the ISR callbacks
+ * @{
+ */
+#define STM32_DMA_ISR_FEIF 0U
+#define STM32_DMA_ISR_DMEIF 0U
+#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
+#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
+#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_DMA_SUPPORTS_DMAMUX)
+#error "STM32_DMA_SUPPORTS_DMAMUX not defined in registry"
+#endif
+
+#if !defined(STM32_DMA_SUPPORTS_CSELR)
+#error "STM32_DMA_SUPPORTS_CSELR not defined in registry"
+#endif
+
+#if STM32_DMA_SUPPORTS_DMAMUX && STM32_DMA_SUPPORTS_CSELR
+#error "STM32_DMA_SUPPORTS_DMAMUX and STM32_DMA_SUPPORTS_CSELR both TRUE"
+#endif
+
+#if !defined(STM32_DMA1_NUM_CHANNELS)
+#error "STM32_DMA1_NUM_CHANNELS not defined in registry"
+#endif
+
+#if !defined(STM32_DMA2_NUM_CHANNELS)
+#error "STM32_DMA2_NUM_CHANNELS not defined in registry"
+#endif
+
+#if (STM32_DMA1_NUM_CHANNELS < 0) || (STM32_DMA1_NUM_CHANNELS > 8)
+#error "unsupported channels configuration"
+#endif
+
+#if (STM32_DMA2_NUM_CHANNELS < 0) || (STM32_DMA2_NUM_CHANNELS > 8)
+#error "unsupported channels configuration"
+#endif
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
+#include "stm32_dmamux.h"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a DMA callback.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the ISR register, the bits
+ * are aligned to bit zero
+ */
+typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
+
+/**
+ * @brief STM32 DMA stream descriptor structure.
+ */
+typedef struct {
+ DMA_TypeDef *dma; /**< @brief Associated DMA. */
+ DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
+ uint32_t cmask; /**< @brief Mask of streams sharing
+ the same ISR. */
+#if (STM32_DMA_SUPPORTS_CSELR == TRUE) || defined(__DOXYGEN__)
+ volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */
+#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE
+ DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */
+#else
+ uint8_t dummy; /**< @brief Filler. */
+#endif
+ uint8_t shift; /**< @brief Bit offset in ISR, IFCR
+ and CSELR registers. */
+ uint8_t selfindex; /**< @brief Index to self in array. */
+ uint8_t vector; /**< @brief Associated IRQ vector. */
+} stm32_dma_stream_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Associates a peripheral data register to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the CPAR register
+ *
+ * @special
+ */
+#define dmaStreamSetPeripheral(dmastp, addr) { \
+ (dmastp)->channel->CPAR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Associates a memory destination to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the CMAR register
+ *
+ * @special
+ */
+#define dmaStreamSetMemory0(dmastp, addr) { \
+ (dmastp)->channel->CMAR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Sets the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] size value to be written in the CNDTR register
+ *
+ * @special
+ */
+#define dmaStreamSetTransactionSize(dmastp, size) { \
+ (dmastp)->channel->CNDTR = (uint32_t)(size); \
+}
+
+/**
+ * @brief Returns the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @return The number of transfers to be performed.
+ *
+ * @special
+ */
+#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
+
+/**
+ * @brief Programs the stream mode settings.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the CCR register
+ *
+ * @special
+ */
+#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__)
+#define dmaStreamSetMode(dmastp, mode) { \
+ uint32_t cselr = *(dmastp)->cselr; \
+ cselr &= ~(0x0000000FU << (dmastp)->shift); \
+ cselr |= (((uint32_t)(mode) >> 16U) << (dmastp)->shift); \
+ *(dmastp)->cselr = cselr; \
+ (dmastp)->channel->CCR = (uint32_t)(mode); \
+}
+#else
+#define dmaStreamSetMode(dmastp, mode) { \
+ (dmastp)->channel->CCR = (uint32_t)(mode); \
+}
+#endif
+
+/**
+ * @brief DMA stream enable.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamEnable(dmastp) { \
+ (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
+}
+
+/**
+ * @brief DMA stream disable.
+ * @details The function disables the specified stream and then clears any
+ * pending interrupt.
+ * @note This function can be invoked in both ISR or thread context.
+ * @note Interrupts enabling flags are set to zero after this call, see
+ * bug 3607518.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamDisable(dmastp) { \
+ (dmastp)->channel->CCR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_EN); \
+ dmaStreamClearInterrupt(dmastp); \
+}
+
+/**
+ * @brief DMA stream interrupt sources clear.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamClearInterrupt(dmastp) { \
+ (dmastp)->dma->IFCR = STM32_DMA_ISR_MASK << (dmastp)->shift; \
+}
+
+/**
+ * @brief Starts a memory to memory operation using the specified stream.
+ * @note The default transfer data mode is "byte to byte" but it can be
+ * changed by specifying extra options in the @p mode parameter.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the CCR register, this value
+ * is implicitly ORed with:
+ * - @p STM32_DMA_CR_MINC
+ * - @p STM32_DMA_CR_PINC
+ * - @p STM32_DMA_CR_DIR_M2M
+ * - @p STM32_DMA_CR_EN
+ * .
+ * @param[in] src source address
+ * @param[in] dst destination address
+ * @param[in] n number of data units to copy
+ */
+#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
+ dmaStreamSetPeripheral(dmastp, src); \
+ dmaStreamSetMemory0(dmastp, dst); \
+ dmaStreamSetTransactionSize(dmastp, n); \
+ dmaStreamSetMode(dmastp, (mode) | \
+ STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
+ STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \
+}
+
+/**
+ * @brief Polled wait for DMA transfer end.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamRelease().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ */
+#define dmaWaitCompletion(dmastp) { \
+ while ((dmastp)->channel->CNDTR > 0U) \
+ ; \
+ dmaStreamDisable(dmastp); \
+}
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void dmaInit(void);
+ const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param);
+ const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param);
+ void dmaStreamFreeI(const stm32_dma_stream_t *dmastp);
+ void dmaStreamFree(const stm32_dma_stream_t *dmastp);
+ void dmaServeInterrupt(const stm32_dma_stream_t *dmastp);
+#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
+ void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMA_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DMAv2/driver.mk b/os/hal/ports/STM32/LLD/DMAv2/driver.mk
index bdc468a280..0bc685374a 100644
--- a/os/hal/ports/STM32/LLD/DMAv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/DMAv2/driver.mk
@@ -1,2 +1,2 @@
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.c
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv2
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.c
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv2
diff --git a/os/hal/ports/STM32/LLD/DMAv2/notes.txt b/os/hal/ports/STM32/LLD/DMAv2/notes.txt
index 4c01d83091..aadcf2cb3a 100644
--- a/os/hal/ports/STM32/LLD/DMAv2/notes.txt
+++ b/os/hal/ports/STM32/LLD/DMAv2/notes.txt
@@ -1,18 +1,18 @@
-STM32 DMAv2 driver.
-
-Driver capability:
-
-- The driver supports the STM32 enhanced DMA controller found on F2, F4 and
- F7 sub-families.
-- Support for automatic the channel selection.
-- Support for cache flushing and invalidation.
-
-The file registry must export:
-
-STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other
- drivers use it to enable checks on DMA
- channels. Probably will be removed in the
- future.
-STM32_HAS_DMAx - Support for DMA unit "x" (1..2).
-STM32_DMAx_CHn_HANDLER - Vector name for channel "n" (0..7).
-STM32_DMAn_CHx_NUMBER - Vector number for channel "n" (0..7).
+STM32 DMAv2 driver.
+
+Driver capability:
+
+- The driver supports the STM32 enhanced DMA controller found on F2, F4 and
+ F7 sub-families.
+- Support for automatic the channel selection.
+- Support for cache flushing and invalidation.
+
+The file registry must export:
+
+STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other
+ drivers use it to enable checks on DMA
+ channels. Probably will be removed in the
+ future.
+STM32_HAS_DMAx - Support for DMA unit "x" (1..2).
+STM32_DMAx_CHn_HANDLER - Vector name for channel "n" (0..7).
+STM32_DMAn_CHx_NUMBER - Vector number for channel "n" (0..7).
diff --git a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.c
index 10b4b68fe5..eab184a20f 100644
--- a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.c
+++ b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.c
@@ -1,675 +1,675 @@
-/*
- 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 DMAv2/stm32_dma.c
- * @brief Enhanced DMA helper driver code.
- *
- * @addtogroup STM32_DMA
- * @details DMA sharing helper driver. In the STM32 the DMA streams are a
- * shared resource, this driver allows to allocate and free DMA
- * streams at runtime in order to allow all the other device
- * drivers to coordinate the access to the resource.
- * @note The DMA ISR handlers are all declared into this module because
- * sharing, the various device drivers can associate a callback to
- * ISRs when allocating streams.
- * @{
- */
-
-#include "hal.h"
-
-/* The following macro is only defined if some driver requiring DMA services
- has been enabled.*/
-#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/**
- * @brief Mask of the DMA1 streams in @p dma.allocated_mask.
- */
-#define STM32_DMA1_STREAMS_MASK 0x000000FFU
-
-/**
- * @brief Mask of the DMA2 streams in @p dma.allocated_mask.
- */
-#define STM32_DMA2_STREAMS_MASK 0x0000FF00U
-
-#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
-
-#define DMA1_CH0_VARIANT DMAMUX1_Channel0
-#define DMA1_CH1_VARIANT DMAMUX1_Channel1
-#define DMA1_CH2_VARIANT DMAMUX1_Channel2
-#define DMA1_CH3_VARIANT DMAMUX1_Channel3
-#define DMA1_CH4_VARIANT DMAMUX1_Channel4
-#define DMA1_CH5_VARIANT DMAMUX1_Channel5
-#define DMA1_CH6_VARIANT DMAMUX1_Channel6
-#define DMA1_CH7_VARIANT DMAMUX1_Channel7
-#define DMA2_CH0_VARIANT DMAMUX1_Channel8
-#define DMA2_CH1_VARIANT DMAMUX1_Channel9
-#define DMA2_CH2_VARIANT DMAMUX1_Channel10
-#define DMA2_CH3_VARIANT DMAMUX1_Channel11
-#define DMA2_CH4_VARIANT DMAMUX1_Channel12
-#define DMA2_CH5_VARIANT DMAMUX1_Channel13
-#define DMA2_CH6_VARIANT DMAMUX1_Channel14
-#define DMA2_CH7_VARIANT DMAMUX1_Channel15
-
-#else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
-
-#define DMA1_CH0_VARIANT 0
-#define DMA1_CH1_VARIANT 0
-#define DMA1_CH2_VARIANT 0
-#define DMA1_CH3_VARIANT 0
-#define DMA1_CH4_VARIANT 0
-#define DMA1_CH5_VARIANT 0
-#define DMA1_CH6_VARIANT 0
-#define DMA1_CH7_VARIANT 0
-#define DMA2_CH0_VARIANT 0
-#define DMA2_CH1_VARIANT 0
-#define DMA2_CH2_VARIANT 0
-#define DMA2_CH3_VARIANT 0
-#define DMA2_CH4_VARIANT 0
-#define DMA2_CH5_VARIANT 0
-#define DMA2_CH6_VARIANT 0
-#define DMA2_CH7_VARIANT 0
-
-#endif /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief DMA streams descriptors.
- * @details This table keeps the association between an unique stream
- * identifier and the involved physical registers.
- * @note Don't use this array directly, use the appropriate wrapper macros
- * instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
- */
-const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
- {DMA1_Stream0, &DMA1->LIFCR, DMA1_CH0_VARIANT, 0, 0, STM32_DMA1_CH0_NUMBER},
- {DMA1_Stream1, &DMA1->LIFCR, DMA1_CH1_VARIANT, 6, 1, STM32_DMA1_CH1_NUMBER},
- {DMA1_Stream2, &DMA1->LIFCR, DMA1_CH2_VARIANT, 16, 2, STM32_DMA1_CH2_NUMBER},
- {DMA1_Stream3, &DMA1->LIFCR, DMA1_CH3_VARIANT, 22, 3, STM32_DMA1_CH3_NUMBER},
- {DMA1_Stream4, &DMA1->HIFCR, DMA1_CH4_VARIANT, 0, 4, STM32_DMA1_CH4_NUMBER},
- {DMA1_Stream5, &DMA1->HIFCR, DMA1_CH5_VARIANT, 6, 5, STM32_DMA1_CH5_NUMBER},
- {DMA1_Stream6, &DMA1->HIFCR, DMA1_CH6_VARIANT, 16, 6, STM32_DMA1_CH6_NUMBER},
- {DMA1_Stream7, &DMA1->HIFCR, DMA1_CH7_VARIANT, 22, 7, STM32_DMA1_CH7_NUMBER},
- {DMA2_Stream0, &DMA2->LIFCR, DMA2_CH0_VARIANT, 0, 8, STM32_DMA2_CH0_NUMBER},
- {DMA2_Stream1, &DMA2->LIFCR, DMA2_CH1_VARIANT, 6, 9, STM32_DMA2_CH1_NUMBER},
- {DMA2_Stream2, &DMA2->LIFCR, DMA2_CH2_VARIANT, 16, 10, STM32_DMA2_CH2_NUMBER},
- {DMA2_Stream3, &DMA2->LIFCR, DMA2_CH3_VARIANT, 22, 11, STM32_DMA2_CH3_NUMBER},
- {DMA2_Stream4, &DMA2->HIFCR, DMA2_CH4_VARIANT, 0, 12, STM32_DMA2_CH4_NUMBER},
- {DMA2_Stream5, &DMA2->HIFCR, DMA2_CH5_VARIANT, 6, 13, STM32_DMA2_CH5_NUMBER},
- {DMA2_Stream6, &DMA2->HIFCR, DMA2_CH6_VARIANT, 16, 14, STM32_DMA2_CH6_NUMBER},
- {DMA2_Stream7, &DMA2->HIFCR, DMA2_CH7_VARIANT, 22, 15, STM32_DMA2_CH7_NUMBER},
-};
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief Global DMA-related data structures.
- */
-static struct {
- /**
- * @brief Mask of the allocated streams.
- */
- uint32_t allocated_mask;
- /**
- * @brief DMA IRQ redirectors.
- */
- struct {
- /**
- * @brief DMA callback function.
- */
- stm32_dmaisr_t func;
- /**
- * @brief DMA callback parameter.
- */
- void *param;
- } streams[STM32_DMA_STREAMS];
-} dma;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/**
- * @brief DMA1 stream 0 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH0_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->LISR >> 0U) & STM32_DMA_ISR_MASK;
- DMA1->LIFCR = flags << 0U;
- if (dma.streams[0].func)
- dma.streams[0].func(dma.streams[0].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 1 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->LISR >> 6U) & STM32_DMA_ISR_MASK;
- DMA1->LIFCR = flags << 6U;
- if (dma.streams[1].func)
- dma.streams[1].func(dma.streams[1].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 2 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->LISR >> 16U) & STM32_DMA_ISR_MASK;
- DMA1->LIFCR = flags << 16U;
- if (dma.streams[2].func)
- dma.streams[2].func(dma.streams[2].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 3 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->LISR >> 22U) & STM32_DMA_ISR_MASK;
- DMA1->LIFCR = flags << 22U;
- if (dma.streams[3].func)
- dma.streams[3].func(dma.streams[3].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 4 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->HISR >> 0U) & STM32_DMA_ISR_MASK;
- DMA1->HIFCR = flags << 0U;
- if (dma.streams[4].func)
- dma.streams[4].func(dma.streams[4].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 5 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->HISR >> 6U) & STM32_DMA_ISR_MASK;
- DMA1->HIFCR = flags << 6U;
- if (dma.streams[5].func)
- dma.streams[5].func(dma.streams[5].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 6 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->HISR >> 16U) & STM32_DMA_ISR_MASK;
- DMA1->HIFCR = flags << 16U;
- if (dma.streams[6].func)
- dma.streams[6].func(dma.streams[6].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA1 stream 7 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA1->HISR >> 22U) & STM32_DMA_ISR_MASK;
- DMA1->HIFCR = flags << 22U;
- if (dma.streams[7].func)
- dma.streams[7].func(dma.streams[7].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 0 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH0_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->LISR >> 0U) & STM32_DMA_ISR_MASK;
- DMA2->LIFCR = flags << 0U;
- if (dma.streams[8].func)
- dma.streams[8].func(dma.streams[8].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 1 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->LISR >> 6U) & STM32_DMA_ISR_MASK;
- DMA2->LIFCR = flags << 6U;
- if (dma.streams[9].func)
- dma.streams[9].func(dma.streams[9].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 2 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->LISR >> 16U) & STM32_DMA_ISR_MASK;
- DMA2->LIFCR = flags << 16U;
- if (dma.streams[10].func)
- dma.streams[10].func(dma.streams[10].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 3 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->LISR >> 22U) & STM32_DMA_ISR_MASK;
- DMA2->LIFCR = flags << 22U;
- if (dma.streams[11].func)
- dma.streams[11].func(dma.streams[11].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 4 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->HISR >> 0U) & STM32_DMA_ISR_MASK;
- DMA2->HIFCR = flags << 0U;
- if (dma.streams[12].func)
- dma.streams[12].func(dma.streams[12].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 5 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->HISR >> 6U) & STM32_DMA_ISR_MASK;
- DMA2->HIFCR = flags << 6U;
- if (dma.streams[13].func)
- dma.streams[13].func(dma.streams[13].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 6 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH6_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->HISR >> 16U) & STM32_DMA_ISR_MASK;
- DMA2->HIFCR = flags << 16U;
- if (dma.streams[14].func)
- dma.streams[14].func(dma.streams[14].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief DMA2 stream 7 shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_DMA2_CH7_HANDLER) {
- uint32_t flags;
-
- OSAL_IRQ_PROLOGUE();
-
- flags = (DMA2->HISR >> 22U) & STM32_DMA_ISR_MASK;
- DMA2->HIFCR = flags << 22U;
- if (dma.streams[15].func)
- dma.streams[15].func(dma.streams[15].param, flags);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 DMA helper initialization.
- *
- * @init
- */
-void dmaInit(void) {
- unsigned i;
-
- dma.allocated_mask = 0U;
- for (i = 0U; i < STM32_DMA_STREAMS; i++) {
- _stm32_dma_streams[i].stream->CR = STM32_DMA_CR_RESET_VALUE;
- dma.streams[i].func = NULL;
- }
- DMA1->LIFCR = 0xFFFFFFFFU;
- DMA1->HIFCR = 0xFFFFFFFFU;
- DMA2->LIFCR = 0xFFFFFFFFU;
- DMA2->HIFCR = 0xFFFFFFFFU;
-}
-
-/**
- * @brief Allocates a DMA stream.
- * @details The stream is allocated and, if required, the DMA clock enabled.
- * The function also enables the IRQ vector associated to the stream
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific stream or:
- * - @p STM32_DMA_STREAM_ID_ANY for any stream.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
- * on DMA1.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
- * on DMA2.
- * .
- * @param[in] priority IRQ priority for the DMA stream
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_dma_stream_t
- * structure.
- * @retval NULL if a/the stream is not available.
- *
- * @iclass
- */
-const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param) {
- uint32_t i, startid, endid;
-
- osalDbgCheckClassI();
-
- if (id < STM32_DMA_STREAMS) {
- startid = id;
- endid = id;
- }
-#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
- else if (id == STM32_DMA_STREAM_ID_ANY) {
- startid = 0U;
- endid = STM32_DMA_STREAMS - 1U;
- }
- else if (id == STM32_DMA_STREAM_ID_ANY_DMA1) {
- startid = 0U;
- endid = (STM32_DMA_STREAMS / 2U) - 1U;
- }
- else if (id == STM32_DMA_STREAM_ID_ANY_DMA2) {
- startid = (STM32_DMA_STREAMS / 2U) - 1U;
- endid = STM32_DMA_STREAMS - 1U;
- }
-#endif
- else {
- osalDbgCheck(false);
- return NULL;
- }
-
- for (i = startid; i <= endid; i++) {
- uint32_t mask = (1U << i);
- if ((dma.allocated_mask & mask) == 0U) {
- const stm32_dma_stream_t *dmastp = STM32_DMA_STREAM(i);
-
- /* Installs the DMA handler.*/
- dma.streams[i].func = func;
- dma.streams[i].param = param;
- dma.allocated_mask |= mask;
-
- /* Enabling DMA clocks required by the current streams set.*/
- if ((STM32_DMA1_STREAMS_MASK & mask) != 0U) {
- rccEnableDMA1(true);
- }
- if ((STM32_DMA2_STREAMS_MASK & mask) != 0U) {
- rccEnableDMA2(true);
- }
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccEnableDMAMUX)
- /* Enabling DMAMUX if present.*/
- if (dma.allocated_mask != 0U) {
- rccEnableDMAMUX(true);
- }
-#endif
-
- /* Putting the stream in a safe state.*/
- dmaStreamDisable(dmastp);
- dmastp->stream->CR = STM32_DMA_CR_RESET_VALUE;
- dmastp->stream->FCR = STM32_DMA_FCR_RESET_VALUE;
-
- /* Enables the associated IRQ vector if a callback is defined.*/
- if (func != NULL) {
- nvicEnableVector(dmastp->vector, priority);
- }
-
- return dmastp;
- }
- }
-
- return NULL;
-}
-
-/**
- * @brief Allocates a DMA stream.
- * @details The stream is allocated and, if required, the DMA clock enabled.
- * The function also enables the IRQ vector associated to the stream
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific stream or:
- * - @p STM32_DMA_STREAM_ID_ANY for any stream.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
- * on DMA1.
- * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
- * on DMA2.
- * .
- * @param[in] priority IRQ priority for the DMA stream
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_dma_stream_t
- * structure.
- * @retval NULL if a/the stream is not available.
- *
- * @api
- */
-const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param) {
- const stm32_dma_stream_t *dmastp;
-
- osalSysLock();
- dmastp = dmaStreamAllocI(id, priority, func, param);
- osalSysUnlock();
-
- return dmastp;
-}
-
-/**
- * @brief Releases a DMA stream.
- * @details The stream is freed and, if required, the DMA clock disabled.
- * Trying to release a unallocated stream is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @iclass
- */
-void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) {
-
- osalDbgCheck(dmastp != NULL);
-
- /* Check if the streams is not taken.*/
- osalDbgAssert((dma.allocated_mask & (1U << dmastp->selfindex)) != 0U,
- "not allocated");
-
- /* Disables the associated IRQ vector.*/
- nvicDisableVector(dmastp->vector);
-
- /* Marks the stream as not allocated.*/
- dma.allocated_mask &= ~(1U << dmastp->selfindex);
-
- /* Shutting down clocks that are no more required, if any.*/
- if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) {
- rccDisableDMA1();
- }
- if ((dma.allocated_mask & STM32_DMA2_STREAMS_MASK) == 0U) {
- rccDisableDMA2();
- }
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccDisableDMAMUX)
- /* Shutting down DMAMUX if present.*/
- if (dma.allocated_mask == 0U) {
- rccDisableDMAMUX();
- }
-#endif
-}
-
-/**
- * @brief Releases a DMA stream.
- * @details The stream is freed and, if required, the DMA clock disabled.
- * Trying to release a unallocated stream is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @api
- */
-void dmaStreamFree(const stm32_dma_stream_t *dmastp) {
-
- osalSysLock();
- dmaStreamFreeI(dmastp);
- osalSysUnlock();
-}
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Associates a peripheral request to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- *
- * @param[in] dmastp pointer to a @p stm32_dma_stream_t structure
- * @param[in] per peripheral identifier
- *
- * @special
- */
-void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per) {
-
- osalDbgCheck(per < 256U);
-
- dmastp->mux->CCR = per;
-}
-#endif
-
-#endif /* STM32_DMA_REQUIRED */
-
-/** @} */
+/*
+ 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 DMAv2/stm32_dma.c
+ * @brief Enhanced DMA helper driver code.
+ *
+ * @addtogroup STM32_DMA
+ * @details DMA sharing helper driver. In the STM32 the DMA streams are a
+ * shared resource, this driver allows to allocate and free DMA
+ * streams at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The DMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * ISRs when allocating streams.
+ * @{
+ */
+
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring DMA services
+ has been enabled.*/
+#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/**
+ * @brief Mask of the DMA1 streams in @p dma.allocated_mask.
+ */
+#define STM32_DMA1_STREAMS_MASK 0x000000FFU
+
+/**
+ * @brief Mask of the DMA2 streams in @p dma.allocated_mask.
+ */
+#define STM32_DMA2_STREAMS_MASK 0x0000FF00U
+
+#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
+
+#define DMA1_CH0_VARIANT DMAMUX1_Channel0
+#define DMA1_CH1_VARIANT DMAMUX1_Channel1
+#define DMA1_CH2_VARIANT DMAMUX1_Channel2
+#define DMA1_CH3_VARIANT DMAMUX1_Channel3
+#define DMA1_CH4_VARIANT DMAMUX1_Channel4
+#define DMA1_CH5_VARIANT DMAMUX1_Channel5
+#define DMA1_CH6_VARIANT DMAMUX1_Channel6
+#define DMA1_CH7_VARIANT DMAMUX1_Channel7
+#define DMA2_CH0_VARIANT DMAMUX1_Channel8
+#define DMA2_CH1_VARIANT DMAMUX1_Channel9
+#define DMA2_CH2_VARIANT DMAMUX1_Channel10
+#define DMA2_CH3_VARIANT DMAMUX1_Channel11
+#define DMA2_CH4_VARIANT DMAMUX1_Channel12
+#define DMA2_CH5_VARIANT DMAMUX1_Channel13
+#define DMA2_CH6_VARIANT DMAMUX1_Channel14
+#define DMA2_CH7_VARIANT DMAMUX1_Channel15
+
+#else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
+
+#define DMA1_CH0_VARIANT 0
+#define DMA1_CH1_VARIANT 0
+#define DMA1_CH2_VARIANT 0
+#define DMA1_CH3_VARIANT 0
+#define DMA1_CH4_VARIANT 0
+#define DMA1_CH5_VARIANT 0
+#define DMA1_CH6_VARIANT 0
+#define DMA1_CH7_VARIANT 0
+#define DMA2_CH0_VARIANT 0
+#define DMA2_CH1_VARIANT 0
+#define DMA2_CH2_VARIANT 0
+#define DMA2_CH3_VARIANT 0
+#define DMA2_CH4_VARIANT 0
+#define DMA2_CH5_VARIANT 0
+#define DMA2_CH6_VARIANT 0
+#define DMA2_CH7_VARIANT 0
+
+#endif /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA streams descriptors.
+ * @details This table keeps the association between an unique stream
+ * identifier and the involved physical registers.
+ * @note Don't use this array directly, use the appropriate wrapper macros
+ * instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
+ */
+const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
+ {DMA1_Stream0, &DMA1->LIFCR, DMA1_CH0_VARIANT, 0, 0, STM32_DMA1_CH0_NUMBER},
+ {DMA1_Stream1, &DMA1->LIFCR, DMA1_CH1_VARIANT, 6, 1, STM32_DMA1_CH1_NUMBER},
+ {DMA1_Stream2, &DMA1->LIFCR, DMA1_CH2_VARIANT, 16, 2, STM32_DMA1_CH2_NUMBER},
+ {DMA1_Stream3, &DMA1->LIFCR, DMA1_CH3_VARIANT, 22, 3, STM32_DMA1_CH3_NUMBER},
+ {DMA1_Stream4, &DMA1->HIFCR, DMA1_CH4_VARIANT, 0, 4, STM32_DMA1_CH4_NUMBER},
+ {DMA1_Stream5, &DMA1->HIFCR, DMA1_CH5_VARIANT, 6, 5, STM32_DMA1_CH5_NUMBER},
+ {DMA1_Stream6, &DMA1->HIFCR, DMA1_CH6_VARIANT, 16, 6, STM32_DMA1_CH6_NUMBER},
+ {DMA1_Stream7, &DMA1->HIFCR, DMA1_CH7_VARIANT, 22, 7, STM32_DMA1_CH7_NUMBER},
+ {DMA2_Stream0, &DMA2->LIFCR, DMA2_CH0_VARIANT, 0, 8, STM32_DMA2_CH0_NUMBER},
+ {DMA2_Stream1, &DMA2->LIFCR, DMA2_CH1_VARIANT, 6, 9, STM32_DMA2_CH1_NUMBER},
+ {DMA2_Stream2, &DMA2->LIFCR, DMA2_CH2_VARIANT, 16, 10, STM32_DMA2_CH2_NUMBER},
+ {DMA2_Stream3, &DMA2->LIFCR, DMA2_CH3_VARIANT, 22, 11, STM32_DMA2_CH3_NUMBER},
+ {DMA2_Stream4, &DMA2->HIFCR, DMA2_CH4_VARIANT, 0, 12, STM32_DMA2_CH4_NUMBER},
+ {DMA2_Stream5, &DMA2->HIFCR, DMA2_CH5_VARIANT, 6, 13, STM32_DMA2_CH5_NUMBER},
+ {DMA2_Stream6, &DMA2->HIFCR, DMA2_CH6_VARIANT, 16, 14, STM32_DMA2_CH6_NUMBER},
+ {DMA2_Stream7, &DMA2->HIFCR, DMA2_CH7_VARIANT, 22, 15, STM32_DMA2_CH7_NUMBER},
+};
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Global DMA-related data structures.
+ */
+static struct {
+ /**
+ * @brief Mask of the allocated streams.
+ */
+ uint32_t allocated_mask;
+ /**
+ * @brief DMA IRQ redirectors.
+ */
+ struct {
+ /**
+ * @brief DMA callback function.
+ */
+ stm32_dmaisr_t func;
+ /**
+ * @brief DMA callback parameter.
+ */
+ void *param;
+ } streams[STM32_DMA_STREAMS];
+} dma;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA1 stream 0 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH0_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 0U) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = flags << 0U;
+ if (dma.streams[0].func)
+ dma.streams[0].func(dma.streams[0].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 1 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 6U) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = flags << 6U;
+ if (dma.streams[1].func)
+ dma.streams[1].func(dma.streams[1].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 2 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 16U) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = flags << 16U;
+ if (dma.streams[2].func)
+ dma.streams[2].func(dma.streams[2].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 3 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->LISR >> 22U) & STM32_DMA_ISR_MASK;
+ DMA1->LIFCR = flags << 22U;
+ if (dma.streams[3].func)
+ dma.streams[3].func(dma.streams[3].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 4 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 0U) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = flags << 0U;
+ if (dma.streams[4].func)
+ dma.streams[4].func(dma.streams[4].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 5 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 6U) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = flags << 6U;
+ if (dma.streams[5].func)
+ dma.streams[5].func(dma.streams[5].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 6 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 16U) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = flags << 16U;
+ if (dma.streams[6].func)
+ dma.streams[6].func(dma.streams[6].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA1 stream 7 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA1->HISR >> 22U) & STM32_DMA_ISR_MASK;
+ DMA1->HIFCR = flags << 22U;
+ if (dma.streams[7].func)
+ dma.streams[7].func(dma.streams[7].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 0 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH0_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 0U) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = flags << 0U;
+ if (dma.streams[8].func)
+ dma.streams[8].func(dma.streams[8].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 1 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 6U) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = flags << 6U;
+ if (dma.streams[9].func)
+ dma.streams[9].func(dma.streams[9].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 2 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 16U) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = flags << 16U;
+ if (dma.streams[10].func)
+ dma.streams[10].func(dma.streams[10].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 3 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->LISR >> 22U) & STM32_DMA_ISR_MASK;
+ DMA2->LIFCR = flags << 22U;
+ if (dma.streams[11].func)
+ dma.streams[11].func(dma.streams[11].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 4 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 0U) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = flags << 0U;
+ if (dma.streams[12].func)
+ dma.streams[12].func(dma.streams[12].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 5 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 6U) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = flags << 6U;
+ if (dma.streams[13].func)
+ dma.streams[13].func(dma.streams[13].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 6 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH6_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 16U) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = flags << 16U;
+ if (dma.streams[14].func)
+ dma.streams[14].func(dma.streams[14].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief DMA2 stream 7 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA2_CH7_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ flags = (DMA2->HISR >> 22U) & STM32_DMA_ISR_MASK;
+ DMA2->HIFCR = flags << 22U;
+ if (dma.streams[15].func)
+ dma.streams[15].func(dma.streams[15].param, flags);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 DMA helper initialization.
+ *
+ * @init
+ */
+void dmaInit(void) {
+ unsigned i;
+
+ dma.allocated_mask = 0U;
+ for (i = 0U; i < STM32_DMA_STREAMS; i++) {
+ _stm32_dma_streams[i].stream->CR = STM32_DMA_CR_RESET_VALUE;
+ dma.streams[i].func = NULL;
+ }
+ DMA1->LIFCR = 0xFFFFFFFFU;
+ DMA1->HIFCR = 0xFFFFFFFFU;
+ DMA2->LIFCR = 0xFFFFFFFFU;
+ DMA2->HIFCR = 0xFFFFFFFFU;
+}
+
+/**
+ * @brief Allocates a DMA stream.
+ * @details The stream is allocated and, if required, the DMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific stream or:
+ * - @p STM32_DMA_STREAM_ID_ANY for any stream.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
+ * on DMA1.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
+ * on DMA2.
+ * .
+ * @param[in] priority IRQ priority for the DMA stream
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_dma_stream_t
+ * structure.
+ * @retval NULL if a/the stream is not available.
+ *
+ * @iclass
+ */
+const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param) {
+ uint32_t i, startid, endid;
+
+ osalDbgCheckClassI();
+
+ if (id < STM32_DMA_STREAMS) {
+ startid = id;
+ endid = id;
+ }
+#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
+ else if (id == STM32_DMA_STREAM_ID_ANY) {
+ startid = 0U;
+ endid = STM32_DMA_STREAMS - 1U;
+ }
+ else if (id == STM32_DMA_STREAM_ID_ANY_DMA1) {
+ startid = 0U;
+ endid = (STM32_DMA_STREAMS / 2U) - 1U;
+ }
+ else if (id == STM32_DMA_STREAM_ID_ANY_DMA2) {
+ startid = (STM32_DMA_STREAMS / 2U) - 1U;
+ endid = STM32_DMA_STREAMS - 1U;
+ }
+#endif
+ else {
+ osalDbgCheck(false);
+ return NULL;
+ }
+
+ for (i = startid; i <= endid; i++) {
+ uint32_t mask = (1U << i);
+ if ((dma.allocated_mask & mask) == 0U) {
+ const stm32_dma_stream_t *dmastp = STM32_DMA_STREAM(i);
+
+ /* Installs the DMA handler.*/
+ dma.streams[i].func = func;
+ dma.streams[i].param = param;
+ dma.allocated_mask |= mask;
+
+ /* Enabling DMA clocks required by the current streams set.*/
+ if ((STM32_DMA1_STREAMS_MASK & mask) != 0U) {
+ rccEnableDMA1(true);
+ }
+ if ((STM32_DMA2_STREAMS_MASK & mask) != 0U) {
+ rccEnableDMA2(true);
+ }
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccEnableDMAMUX)
+ /* Enabling DMAMUX if present.*/
+ if (dma.allocated_mask != 0U) {
+ rccEnableDMAMUX(true);
+ }
+#endif
+
+ /* Putting the stream in a safe state.*/
+ dmaStreamDisable(dmastp);
+ dmastp->stream->CR = STM32_DMA_CR_RESET_VALUE;
+ dmastp->stream->FCR = STM32_DMA_FCR_RESET_VALUE;
+
+ /* Enables the associated IRQ vector if a callback is defined.*/
+ if (func != NULL) {
+ nvicEnableVector(dmastp->vector, priority);
+ }
+
+ return dmastp;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Allocates a DMA stream.
+ * @details The stream is allocated and, if required, the DMA clock enabled.
+ * The function also enables the IRQ vector associated to the stream
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific stream or:
+ * - @p STM32_DMA_STREAM_ID_ANY for any stream.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
+ * on DMA1.
+ * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
+ * on DMA2.
+ * .
+ * @param[in] priority IRQ priority for the DMA stream
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_dma_stream_t
+ * structure.
+ * @retval NULL if a/the stream is not available.
+ *
+ * @api
+ */
+const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param) {
+ const stm32_dma_stream_t *dmastp;
+
+ osalSysLock();
+ dmastp = dmaStreamAllocI(id, priority, func, param);
+ osalSysUnlock();
+
+ return dmastp;
+}
+
+/**
+ * @brief Releases a DMA stream.
+ * @details The stream is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @iclass
+ */
+void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) {
+
+ osalDbgCheck(dmastp != NULL);
+
+ /* Check if the streams is not taken.*/
+ osalDbgAssert((dma.allocated_mask & (1U << dmastp->selfindex)) != 0U,
+ "not allocated");
+
+ /* Disables the associated IRQ vector.*/
+ nvicDisableVector(dmastp->vector);
+
+ /* Marks the stream as not allocated.*/
+ dma.allocated_mask &= ~(1U << dmastp->selfindex);
+
+ /* Shutting down clocks that are no more required, if any.*/
+ if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) {
+ rccDisableDMA1();
+ }
+ if ((dma.allocated_mask & STM32_DMA2_STREAMS_MASK) == 0U) {
+ rccDisableDMA2();
+ }
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccDisableDMAMUX)
+ /* Shutting down DMAMUX if present.*/
+ if (dma.allocated_mask == 0U) {
+ rccDisableDMAMUX();
+ }
+#endif
+}
+
+/**
+ * @brief Releases a DMA stream.
+ * @details The stream is freed and, if required, the DMA clock disabled.
+ * Trying to release a unallocated stream is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @api
+ */
+void dmaStreamFree(const stm32_dma_stream_t *dmastp) {
+
+ osalSysLock();
+ dmaStreamFreeI(dmastp);
+ osalSysUnlock();
+}
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Associates a peripheral request to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a @p stm32_dma_stream_t structure
+ * @param[in] per peripheral identifier
+ *
+ * @special
+ */
+void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per) {
+
+ osalDbgCheck(per < 256U);
+
+ dmastp->mux->CCR = per;
+}
+#endif
+
+#endif /* STM32_DMA_REQUIRED */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h
index 2562039328..dbd22c1e55 100644
--- a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h
+++ b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h
@@ -1,682 +1,682 @@
-/*
- 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 DMAv2/stm32_dma.h
- * @brief Enhanced-DMA helper driver header.
- *
- * @addtogroup STM32_DMA
- * @{
- */
-
-#ifndef STM32_DMA_H
-#define STM32_DMA_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief DMA capability.
- * @details if @p TRUE then the DMA is able of burst transfers, FIFOs,
- * scatter gather and other advanced features.
- */
-#define STM32_DMA_ADVANCED TRUE
-
-/**
- * @brief Total number of DMA streams.
- * @details This is the total number of streams among all the DMA units.
- */
-#define STM32_DMA_STREAMS 16U
-
-/**
- * @brief Mask of the ISR bits passed to the DMA callback functions.
- */
-#define STM32_DMA_ISR_MASK 0x3DU
-
-/**
- * @brief Returns the channel associated to the specified stream.
- *
- * @param[in] id the unique numeric stream identifier
- * @param[in] c a stream/channel association word, one channel per
- * nibble
- * @return Returns the channel associated to the stream.
- */
-#define STM32_DMA_GETCHANNEL(id, c) (((c) >> (((id) & 7U) * 4U)) & 15U)
-
-/**
- * @brief Checks if a DMA priority is within the valid range.
- * @param[in] prio DMA priority
- *
- * @retval The check result.
- * @retval false invalid DMA priority.
- * @retval true correct DMA priority.
- */
-#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__)
-/**
- * @brief Checks if a DMA stream id is within the valid range.
- *
- * @param[in] id DMA stream id
- * @retval The check result.
- * @retval false invalid DMA stream.
- * @retval true correct DMA stream.
- */
-#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) <= STM32_DMA_STREAMS))
-#else /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
-#if STM32_HAS_DMA2 == TRUE
-#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) <= (STM32_DMA_STREAMS + 2)))
-#else
-#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
- ((id) <= (STM32_DMA_STREAMS + 1)))
-#endif
-#endif /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
-
-/**
- * @brief Returns an unique numeric identifier for a DMA stream.
- *
- * @param[in] dma the DMA unit number
- * @param[in] stream the stream number
- * @return An unique numeric stream identifier.
- */
-#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1U) * 8U) + (stream))
-
-/**
- * @brief Returns a DMA stream identifier mask.
- *
- *
- * @param[in] dma the DMA unit number
- * @param[in] stream the stream number
- * @return A DMA stream identifier mask.
- */
-#define STM32_DMA_STREAM_ID_MSK(dma, stream) \
- (1U << STM32_DMA_STREAM_ID(dma, stream))
-
-/**
- * @brief Checks if a DMA stream unique identifier belongs to a mask.
- * @param[in] id the stream numeric identifier
- * @param[in] mask the stream numeric identifiers mask
- *
- * @retval The check result.
- * @retval false id does not belong to the mask.
- * @retval true id belongs to the mask.
- */
-#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__)
-/**
- * @name Special stream identifiers
- * @{
- */
-#define STM32_DMA_STREAM_ID_ANY STM32_DMA_STREAMS
-#define STM32_DMA_STREAM_ID_ANY_DMA1 (STM32_DMA_STREAM_ID_ANY + 1)
-#if STM32_HAS_DMA2 == TRUE
-#define STM32_DMA_STREAM_ID_ANY_DMA2 (STM32_DMA_STREAM_ID_ANY_DMA1 + 1)
-#endif
-/** @} */
-#endif
-
-/**
- * @name DMA streams identifiers
- * @{
- */
-/**
- * @brief Returns a pointer to a stm32_dma_stream_t structure.
- *
- * @param[in] id the stream numeric identifier
- * @return A pointer to the stm32_dma_stream_t constant structure
- * associated to the DMA stream.
- */
-#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id])
-
-#define STM32_DMA1_STREAM0 STM32_DMA_STREAM(0)
-#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(1)
-#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(2)
-#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(3)
-#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(4)
-#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(5)
-#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(6)
-#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(7)
-#define STM32_DMA2_STREAM0 STM32_DMA_STREAM(8)
-#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(9)
-#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(10)
-#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(11)
-#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(12)
-#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(13)
-#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(14)
-#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(15)
-/** @} */
-
-/**
- * @name CR register constants common to all DMA types
- * @{
- */
-#define STM32_DMA_CR_RESET_VALUE 0x00000000U
-#define STM32_DMA_CR_EN DMA_SxCR_EN
-#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE
-#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE
-#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE
-#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
-#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR
-#define STM32_DMA_CR_DIR_P2M 0
-#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0
-#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1
-#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC
-#define STM32_DMA_CR_PINC DMA_SxCR_PINC
-#define STM32_DMA_CR_MINC DMA_SxCR_MINC
-#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE
-#define STM32_DMA_CR_PSIZE_BYTE 0
-#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0
-#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1
-#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE
-#define STM32_DMA_CR_MSIZE_BYTE 0
-#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0
-#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1
-#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
- STM32_DMA_CR_MSIZE_MASK)
-#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL
-#define STM32_DMA_CR_PL(n) ((n) << 16U)
-/** @} */
-
-/**
- * @name CR register constants only found in DMAv2
- * @{
- */
-#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
-#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
-#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS
-#define STM32_DMA_CR_DBM DMA_SxCR_DBM
-#define STM32_DMA_CR_CT DMA_SxCR_CT
-#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST
-#define STM32_DMA_CR_PBURST_SINGLE 0U
-#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0
-#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1
-#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1)
-#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST
-#define STM32_DMA_CR_MBURST_SINGLE 0U
-#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0
-#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1
-#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1)
-#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(__DOXYGEN__)
-#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL
-#define STM32_DMA_CR_CHSEL(n) ((n) << 25U)
-#else
-#define STM32_DMA_CR_CHSEL_MASK 0U
-#define STM32_DMA_CR_CHSEL(n) 0U
-#endif
-/** @} */
-
-/**
- * @name FCR register constants only found in DMAv2
- * @{
- */
-#define STM32_DMA_FCR_RESET_VALUE 0x00000021U
-#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE
-#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS
-#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS
-#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH
-#define STM32_DMA_FCR_FTH_1Q 0
-#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0
-#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1
-#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1)
-/** @} */
-
-/**
- * @name Status flags passed to the ISR callbacks
- */
-#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0
-#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0
-#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0
-#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0
-#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_DMA_SUPPORTS_DMAMUX)
-#error "STM32_DMA_SUPPORTS_DMAMUX not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_DMA1)
-#error "STM32_HAS_DMA1 missing in registry"
-#endif
-
-#if !defined(STM32_HAS_DMA2)
-#error "STM32_HAS_DMA2 missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH0_HANDLER)
-#error "STM32_DMA1_CH0_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH1_HANDLER)
-#error "STM32_DMA1_CH1_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH2_HANDLER)
-#error "STM32_DMA1_CH2_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH3_HANDLER)
-#error "STM32_DMA1_CH3_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH4_HANDLER)
-#error "STM32_DMA1_CH4_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH5_HANDLER)
-#error "STM32_DMA1_CH5_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH6_HANDLER)
-#error "STM32_DMA1_CH6_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH7_HANDLER)
-#error "STM32_DMA1_CH7_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH0_HANDLER)
-#error "STM32_DMA2_CH0_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH1_HANDLER)
-#error "STM32_DMA2_CH1_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH2_HANDLER)
-#error "STM32_DMA2_CH2_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH3_HANDLER)
-#error "STM32_DMA2_CH3_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH4_HANDLER)
-#error "STM32_DMA2_CH4_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH5_HANDLER)
-#error "STM32_DMA2_CH5_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH6_HANDLER)
-#error "STM32_DMA2_CH6_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH7_HANDLER)
-#error "STM32_DMA2_CH7_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH0_NUMBER)
-#error "STM32_DMA1_CH0_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH1_NUMBER)
-#error "STM32_DMA1_CH1_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH2_NUMBER)
-#error "STM32_DMA1_CH2_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH3_NUMBER)
-#error "STM32_DMA1_CH3_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH4_NUMBER)
-#error "STM32_DMA1_CH4_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH5_NUMBER)
-#error "STM32_DMA1_CH5_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH6_NUMBER)
-#error "STM32_DMA1_CH6_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA1_CH7_NUMBER)
-#error "STM32_DMA1_CH7_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH0_NUMBER)
-#error "STM32_DMA2_CH0_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH1_NUMBER)
-#error "STM32_DMA2_CH1_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH2_NUMBER)
-#error "STM32_DMA2_CH2_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH3_NUMBER)
-#error "STM32_DMA2_CH3_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH4_NUMBER)
-#error "STM32_DMA2_CH4_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH5_NUMBER)
-#error "STM32_DMA2_CH5_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH6_NUMBER)
-#error "STM32_DMA2_CH6_NUMBER missing in registry"
-#endif
-
-#if !defined(STM32_DMA2_CH7_NUMBER)
-#error "STM32_DMA2_CH7_NUMBER missing in registry"
-#endif
-
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
-#include "stm32_dmamux.h"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 DMA ISR function type.
- *
- * @param[in] p parameter for the registered function
- * @param[in] flags pre-shifted content of the xISR register, the bits
- * are aligned to bit zero
- */
-typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
-
-/**
- * @brief STM32 DMA stream descriptor structure.
- */
-typedef struct {
- DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */
- volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
-#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
- DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */
-#else
- uint8_t dummy; /**< @brief Filler. */
-#endif
- uint8_t shift; /**< @brief Bits offset in xIFCR
- register. */
- uint8_t selfindex; /**< @brief Index to self in array. */
- uint8_t vector; /**< @brief Associated IRQ vector. */
-} stm32_dma_stream_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @name Macro Functions
- * @{
- */
-/**
- * @brief Associates a peripheral data register to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] addr value to be written in the PAR register
- *
- * @special
- */
-#define dmaStreamSetPeripheral(dmastp, addr) { \
- (dmastp)->stream->PAR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Associates a memory destination to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] addr value to be written in the M0AR register
- *
- * @special
- */
-#define dmaStreamSetMemory0(dmastp, addr) { \
- (dmastp)->stream->M0AR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Associates an alternate memory destination to a DMA stream.
- * @note This function can be invoked in both ISR or thread context.
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] addr value to be written in the M1AR register
- *
- * @special
- */
-#define dmaStreamSetMemory1(dmastp, addr) { \
- (dmastp)->stream->M1AR = (uint32_t)(addr); \
-}
-
-/**
- * @brief Sets the number of transfers to be performed.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] size value to be written in the CNDTR register
- *
- * @special
- */
-#define dmaStreamSetTransactionSize(dmastp, size) { \
- (dmastp)->stream->NDTR = (uint32_t)(size); \
-}
-
-/**
- * @brief Returns the number of transfers to be performed.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @return The number of transfers to be performed.
- *
- * @special
- */
-#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR))
-
-/**
- * @brief Programs the stream mode settings.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] mode value to be written in the CR register
- *
- * @special
- */
-#define dmaStreamSetMode(dmastp, mode) { \
- (dmastp)->stream->CR = (uint32_t)(mode); \
-}
-
-/**
- * @brief Programs the stream FIFO settings.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] mode value to be written in the FCR register
- *
- * @special
- */
-#define dmaStreamSetFIFO(dmastp, mode) { \
- (dmastp)->stream->FCR = (uint32_t)(mode); \
-}
-
-/**
- * @brief DMA stream enable.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-#define dmaStreamEnable(dmastp) { \
- (dmastp)->stream->CR |= STM32_DMA_CR_EN; \
-}
-
-/**
- * @brief DMA stream disable.
- * @details The function disables the specified stream, waits for the disable
- * operation to complete and then clears any pending interrupt.
- * @note This function can be invoked in both ISR or thread context.
- * @note Interrupts enabling flags are set to zero after this call, see
- * bug 3607518.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-#define dmaStreamDisable(dmastp) { \
- (dmastp)->stream->CR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
- STM32_DMA_CR_TEIE | STM32_DMA_CR_DMEIE | \
- STM32_DMA_CR_EN); \
- while (((dmastp)->stream->CR & STM32_DMA_CR_EN) != 0) \
- ; \
- dmaStreamClearInterrupt(dmastp); \
-}
-
-/**
- * @brief DMA stream interrupt sources clear.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- *
- * @special
- */
-#define dmaStreamClearInterrupt(dmastp) { \
- *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->shift; \
-}
-
-/**
- * @brief Starts a memory to memory operation using the specified stream.
- * @note The default transfer data mode is "byte to byte" but it can be
- * changed by specifying extra options in the @p mode parameter.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @param[in] mode value to be written in the CCR register, this value
- * is implicitly ORed with:
- * - @p STM32_DMA_CR_MINC
- * - @p STM32_DMA_CR_PINC
- * - @p STM32_DMA_CR_DIR_M2M
- * - @p STM32_DMA_CR_EN
- * .
- * @param[in] src source address
- * @param[in] dst destination address
- * @param[in] n number of data units to copy
- */
-#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
- dmaStreamSetPeripheral(dmastp, src); \
- dmaStreamSetMemory0(dmastp, dst); \
- dmaStreamSetTransactionSize(dmastp, n); \
- dmaStreamSetMode(dmastp, (mode) | \
- STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
- STM32_DMA_CR_DIR_M2M); \
- dmaStreamEnable(dmastp); \
-}
-
-/**
- * @brief Polled wait for DMA transfer end.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- */
-#define dmaWaitCompletion(dmastp) { \
- (dmastp)->stream->CR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
- STM32_DMA_CR_TEIE | STM32_DMA_CR_DMEIE); \
- while ((dmastp)->stream->CR & STM32_DMA_CR_EN) \
- ; \
- dmaStreamClearInterrupt(dmastp); \
-}
-
-/**
- * @brief DMA stream current target.
- * @note This function can be invoked in both ISR or thread context.
- * @pre The stream must have been allocated using @p dmaStreamAlloc().
- * @post After use the stream can be released using @p dmaStreamFree().
- *
- * @param[in] dmastp pointer to a stm32_dma_stream_t structure
- * @return Current memory target index.
- *
- * @special
- */
-#define dmaStreamGetCurrentTarget(dmastp) \
- (((dmastp)->stream->CR >> DMA_SxCR_CT_Pos) & 1U)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void dmaInit(void);
- const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param);
- const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
- uint32_t priority,
- stm32_dmaisr_t func,
- void *param);
- void dmaStreamFreeI(const stm32_dma_stream_t *dmastp);
- void dmaStreamFree(const stm32_dma_stream_t *dmastp);
-#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
- void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMA_H */
-
-/** @} */
+/*
+ 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 DMAv2/stm32_dma.h
+ * @brief Enhanced-DMA helper driver header.
+ *
+ * @addtogroup STM32_DMA
+ * @{
+ */
+
+#ifndef STM32_DMA_H
+#define STM32_DMA_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief DMA capability.
+ * @details if @p TRUE then the DMA is able of burst transfers, FIFOs,
+ * scatter gather and other advanced features.
+ */
+#define STM32_DMA_ADVANCED TRUE
+
+/**
+ * @brief Total number of DMA streams.
+ * @details This is the total number of streams among all the DMA units.
+ */
+#define STM32_DMA_STREAMS 16U
+
+/**
+ * @brief Mask of the ISR bits passed to the DMA callback functions.
+ */
+#define STM32_DMA_ISR_MASK 0x3DU
+
+/**
+ * @brief Returns the channel associated to the specified stream.
+ *
+ * @param[in] id the unique numeric stream identifier
+ * @param[in] c a stream/channel association word, one channel per
+ * nibble
+ * @return Returns the channel associated to the stream.
+ */
+#define STM32_DMA_GETCHANNEL(id, c) (((c) >> (((id) & 7U) * 4U)) & 15U)
+
+/**
+ * @brief Checks if a DMA priority is within the valid range.
+ * @param[in] prio DMA priority
+ *
+ * @retval The check result.
+ * @retval false invalid DMA priority.
+ * @retval true correct DMA priority.
+ */
+#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__)
+/**
+ * @brief Checks if a DMA stream id is within the valid range.
+ *
+ * @param[in] id DMA stream id
+ * @retval The check result.
+ * @retval false invalid DMA stream.
+ * @retval true correct DMA stream.
+ */
+#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) <= STM32_DMA_STREAMS))
+#else /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
+#if STM32_HAS_DMA2 == TRUE
+#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) <= (STM32_DMA_STREAMS + 2)))
+#else
+#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
+ ((id) <= (STM32_DMA_STREAMS + 1)))
+#endif
+#endif /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
+
+/**
+ * @brief Returns an unique numeric identifier for a DMA stream.
+ *
+ * @param[in] dma the DMA unit number
+ * @param[in] stream the stream number
+ * @return An unique numeric stream identifier.
+ */
+#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1U) * 8U) + (stream))
+
+/**
+ * @brief Returns a DMA stream identifier mask.
+ *
+ *
+ * @param[in] dma the DMA unit number
+ * @param[in] stream the stream number
+ * @return A DMA stream identifier mask.
+ */
+#define STM32_DMA_STREAM_ID_MSK(dma, stream) \
+ (1U << STM32_DMA_STREAM_ID(dma, stream))
+
+/**
+ * @brief Checks if a DMA stream unique identifier belongs to a mask.
+ * @param[in] id the stream numeric identifier
+ * @param[in] mask the stream numeric identifiers mask
+ *
+ * @retval The check result.
+ * @retval false id does not belong to the mask.
+ * @retval true id belongs to the mask.
+ */
+#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__)
+/**
+ * @name Special stream identifiers
+ * @{
+ */
+#define STM32_DMA_STREAM_ID_ANY STM32_DMA_STREAMS
+#define STM32_DMA_STREAM_ID_ANY_DMA1 (STM32_DMA_STREAM_ID_ANY + 1)
+#if STM32_HAS_DMA2 == TRUE
+#define STM32_DMA_STREAM_ID_ANY_DMA2 (STM32_DMA_STREAM_ID_ANY_DMA1 + 1)
+#endif
+/** @} */
+#endif
+
+/**
+ * @name DMA streams identifiers
+ * @{
+ */
+/**
+ * @brief Returns a pointer to a stm32_dma_stream_t structure.
+ *
+ * @param[in] id the stream numeric identifier
+ * @return A pointer to the stm32_dma_stream_t constant structure
+ * associated to the DMA stream.
+ */
+#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id])
+
+#define STM32_DMA1_STREAM0 STM32_DMA_STREAM(0)
+#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(1)
+#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(2)
+#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(3)
+#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(4)
+#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(5)
+#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(6)
+#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(7)
+#define STM32_DMA2_STREAM0 STM32_DMA_STREAM(8)
+#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(9)
+#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(10)
+#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(11)
+#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(12)
+#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(13)
+#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(14)
+#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(15)
+/** @} */
+
+/**
+ * @name CR register constants common to all DMA types
+ * @{
+ */
+#define STM32_DMA_CR_RESET_VALUE 0x00000000U
+#define STM32_DMA_CR_EN DMA_SxCR_EN
+#define STM32_DMA_CR_TEIE DMA_SxCR_TEIE
+#define STM32_DMA_CR_HTIE DMA_SxCR_HTIE
+#define STM32_DMA_CR_TCIE DMA_SxCR_TCIE
+#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
+#define STM32_DMA_CR_DIR_MASK DMA_SxCR_DIR
+#define STM32_DMA_CR_DIR_P2M 0
+#define STM32_DMA_CR_DIR_M2P DMA_SxCR_DIR_0
+#define STM32_DMA_CR_DIR_M2M DMA_SxCR_DIR_1
+#define STM32_DMA_CR_CIRC DMA_SxCR_CIRC
+#define STM32_DMA_CR_PINC DMA_SxCR_PINC
+#define STM32_DMA_CR_MINC DMA_SxCR_MINC
+#define STM32_DMA_CR_PSIZE_MASK DMA_SxCR_PSIZE
+#define STM32_DMA_CR_PSIZE_BYTE 0
+#define STM32_DMA_CR_PSIZE_HWORD DMA_SxCR_PSIZE_0
+#define STM32_DMA_CR_PSIZE_WORD DMA_SxCR_PSIZE_1
+#define STM32_DMA_CR_MSIZE_MASK DMA_SxCR_MSIZE
+#define STM32_DMA_CR_MSIZE_BYTE 0
+#define STM32_DMA_CR_MSIZE_HWORD DMA_SxCR_MSIZE_0
+#define STM32_DMA_CR_MSIZE_WORD DMA_SxCR_MSIZE_1
+#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
+ STM32_DMA_CR_MSIZE_MASK)
+#define STM32_DMA_CR_PL_MASK DMA_SxCR_PL
+#define STM32_DMA_CR_PL(n) ((n) << 16U)
+/** @} */
+
+/**
+ * @name CR register constants only found in DMAv2
+ * @{
+ */
+#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
+#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
+#define STM32_DMA_CR_PINCOS DMA_SxCR_PINCOS
+#define STM32_DMA_CR_DBM DMA_SxCR_DBM
+#define STM32_DMA_CR_CT DMA_SxCR_CT
+#define STM32_DMA_CR_PBURST_MASK DMA_SxCR_PBURST
+#define STM32_DMA_CR_PBURST_SINGLE 0U
+#define STM32_DMA_CR_PBURST_INCR4 DMA_SxCR_PBURST_0
+#define STM32_DMA_CR_PBURST_INCR8 DMA_SxCR_PBURST_1
+#define STM32_DMA_CR_PBURST_INCR16 (DMA_SxCR_PBURST_0 | DMA_SxCR_PBURST_1)
+#define STM32_DMA_CR_MBURST_MASK DMA_SxCR_MBURST
+#define STM32_DMA_CR_MBURST_SINGLE 0U
+#define STM32_DMA_CR_MBURST_INCR4 DMA_SxCR_MBURST_0
+#define STM32_DMA_CR_MBURST_INCR8 DMA_SxCR_MBURST_1
+#define STM32_DMA_CR_MBURST_INCR16 (DMA_SxCR_MBURST_0 | DMA_SxCR_MBURST_1)
+#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(__DOXYGEN__)
+#define STM32_DMA_CR_CHSEL_MASK DMA_SxCR_CHSEL
+#define STM32_DMA_CR_CHSEL(n) ((n) << 25U)
+#else
+#define STM32_DMA_CR_CHSEL_MASK 0U
+#define STM32_DMA_CR_CHSEL(n) 0U
+#endif
+/** @} */
+
+/**
+ * @name FCR register constants only found in DMAv2
+ * @{
+ */
+#define STM32_DMA_FCR_RESET_VALUE 0x00000021U
+#define STM32_DMA_FCR_FEIE DMA_SxFCR_FEIE
+#define STM32_DMA_FCR_FS_MASK DMA_SxFCR_FS
+#define STM32_DMA_FCR_DMDIS DMA_SxFCR_DMDIS
+#define STM32_DMA_FCR_FTH_MASK DMA_SxFCR_FTH
+#define STM32_DMA_FCR_FTH_1Q 0
+#define STM32_DMA_FCR_FTH_HALF DMA_SxFCR_FTH_0
+#define STM32_DMA_FCR_FTH_3Q DMA_SxFCR_FTH_1
+#define STM32_DMA_FCR_FTH_FULL (DMA_SxFCR_FTH_0 | DMA_SxFCR_FTH_1)
+/** @} */
+
+/**
+ * @name Status flags passed to the ISR callbacks
+ */
+#define STM32_DMA_ISR_FEIF DMA_LISR_FEIF0
+#define STM32_DMA_ISR_DMEIF DMA_LISR_DMEIF0
+#define STM32_DMA_ISR_TEIF DMA_LISR_TEIF0
+#define STM32_DMA_ISR_HTIF DMA_LISR_HTIF0
+#define STM32_DMA_ISR_TCIF DMA_LISR_TCIF0
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_DMA_SUPPORTS_DMAMUX)
+#error "STM32_DMA_SUPPORTS_DMAMUX not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_DMA1)
+#error "STM32_HAS_DMA1 missing in registry"
+#endif
+
+#if !defined(STM32_HAS_DMA2)
+#error "STM32_HAS_DMA2 missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH0_HANDLER)
+#error "STM32_DMA1_CH0_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH1_HANDLER)
+#error "STM32_DMA1_CH1_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH2_HANDLER)
+#error "STM32_DMA1_CH2_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH3_HANDLER)
+#error "STM32_DMA1_CH3_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH4_HANDLER)
+#error "STM32_DMA1_CH4_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH5_HANDLER)
+#error "STM32_DMA1_CH5_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH6_HANDLER)
+#error "STM32_DMA1_CH6_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH7_HANDLER)
+#error "STM32_DMA1_CH7_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH0_HANDLER)
+#error "STM32_DMA2_CH0_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH1_HANDLER)
+#error "STM32_DMA2_CH1_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH2_HANDLER)
+#error "STM32_DMA2_CH2_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH3_HANDLER)
+#error "STM32_DMA2_CH3_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH4_HANDLER)
+#error "STM32_DMA2_CH4_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH5_HANDLER)
+#error "STM32_DMA2_CH5_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH6_HANDLER)
+#error "STM32_DMA2_CH6_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH7_HANDLER)
+#error "STM32_DMA2_CH7_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH0_NUMBER)
+#error "STM32_DMA1_CH0_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH1_NUMBER)
+#error "STM32_DMA1_CH1_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH2_NUMBER)
+#error "STM32_DMA1_CH2_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH3_NUMBER)
+#error "STM32_DMA1_CH3_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH4_NUMBER)
+#error "STM32_DMA1_CH4_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH5_NUMBER)
+#error "STM32_DMA1_CH5_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH6_NUMBER)
+#error "STM32_DMA1_CH6_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA1_CH7_NUMBER)
+#error "STM32_DMA1_CH7_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH0_NUMBER)
+#error "STM32_DMA2_CH0_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH1_NUMBER)
+#error "STM32_DMA2_CH1_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH2_NUMBER)
+#error "STM32_DMA2_CH2_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH3_NUMBER)
+#error "STM32_DMA2_CH3_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH4_NUMBER)
+#error "STM32_DMA2_CH4_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH5_NUMBER)
+#error "STM32_DMA2_CH5_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH6_NUMBER)
+#error "STM32_DMA2_CH6_NUMBER missing in registry"
+#endif
+
+#if !defined(STM32_DMA2_CH7_NUMBER)
+#error "STM32_DMA2_CH7_NUMBER missing in registry"
+#endif
+
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
+#include "stm32_dmamux.h"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 DMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags pre-shifted content of the xISR register, the bits
+ * are aligned to bit zero
+ */
+typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
+
+/**
+ * @brief STM32 DMA stream descriptor structure.
+ */
+typedef struct {
+ DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */
+ volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
+#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
+ DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */
+#else
+ uint8_t dummy; /**< @brief Filler. */
+#endif
+ uint8_t shift; /**< @brief Bits offset in xIFCR
+ register. */
+ uint8_t selfindex; /**< @brief Index to self in array. */
+ uint8_t vector; /**< @brief Associated IRQ vector. */
+} stm32_dma_stream_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Associates a peripheral data register to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the PAR register
+ *
+ * @special
+ */
+#define dmaStreamSetPeripheral(dmastp, addr) { \
+ (dmastp)->stream->PAR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Associates a memory destination to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the M0AR register
+ *
+ * @special
+ */
+#define dmaStreamSetMemory0(dmastp, addr) { \
+ (dmastp)->stream->M0AR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Associates an alternate memory destination to a DMA stream.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] addr value to be written in the M1AR register
+ *
+ * @special
+ */
+#define dmaStreamSetMemory1(dmastp, addr) { \
+ (dmastp)->stream->M1AR = (uint32_t)(addr); \
+}
+
+/**
+ * @brief Sets the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] size value to be written in the CNDTR register
+ *
+ * @special
+ */
+#define dmaStreamSetTransactionSize(dmastp, size) { \
+ (dmastp)->stream->NDTR = (uint32_t)(size); \
+}
+
+/**
+ * @brief Returns the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @return The number of transfers to be performed.
+ *
+ * @special
+ */
+#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->stream->NDTR))
+
+/**
+ * @brief Programs the stream mode settings.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the CR register
+ *
+ * @special
+ */
+#define dmaStreamSetMode(dmastp, mode) { \
+ (dmastp)->stream->CR = (uint32_t)(mode); \
+}
+
+/**
+ * @brief Programs the stream FIFO settings.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the FCR register
+ *
+ * @special
+ */
+#define dmaStreamSetFIFO(dmastp, mode) { \
+ (dmastp)->stream->FCR = (uint32_t)(mode); \
+}
+
+/**
+ * @brief DMA stream enable.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamEnable(dmastp) { \
+ (dmastp)->stream->CR |= STM32_DMA_CR_EN; \
+}
+
+/**
+ * @brief DMA stream disable.
+ * @details The function disables the specified stream, waits for the disable
+ * operation to complete and then clears any pending interrupt.
+ * @note This function can be invoked in both ISR or thread context.
+ * @note Interrupts enabling flags are set to zero after this call, see
+ * bug 3607518.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamDisable(dmastp) { \
+ (dmastp)->stream->CR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_DMEIE | \
+ STM32_DMA_CR_EN); \
+ while (((dmastp)->stream->CR & STM32_DMA_CR_EN) != 0) \
+ ; \
+ dmaStreamClearInterrupt(dmastp); \
+}
+
+/**
+ * @brief DMA stream interrupt sources clear.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ *
+ * @special
+ */
+#define dmaStreamClearInterrupt(dmastp) { \
+ *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->shift; \
+}
+
+/**
+ * @brief Starts a memory to memory operation using the specified stream.
+ * @note The default transfer data mode is "byte to byte" but it can be
+ * changed by specifying extra options in the @p mode parameter.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @param[in] mode value to be written in the CCR register, this value
+ * is implicitly ORed with:
+ * - @p STM32_DMA_CR_MINC
+ * - @p STM32_DMA_CR_PINC
+ * - @p STM32_DMA_CR_DIR_M2M
+ * - @p STM32_DMA_CR_EN
+ * .
+ * @param[in] src source address
+ * @param[in] dst destination address
+ * @param[in] n number of data units to copy
+ */
+#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
+ dmaStreamSetPeripheral(dmastp, src); \
+ dmaStreamSetMemory0(dmastp, dst); \
+ dmaStreamSetTransactionSize(dmastp, n); \
+ dmaStreamSetMode(dmastp, (mode) | \
+ STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
+ STM32_DMA_CR_DIR_M2M); \
+ dmaStreamEnable(dmastp); \
+}
+
+/**
+ * @brief Polled wait for DMA transfer end.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ */
+#define dmaWaitCompletion(dmastp) { \
+ (dmastp)->stream->CR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_DMEIE); \
+ while ((dmastp)->stream->CR & STM32_DMA_CR_EN) \
+ ; \
+ dmaStreamClearInterrupt(dmastp); \
+}
+
+/**
+ * @brief DMA stream current target.
+ * @note This function can be invoked in both ISR or thread context.
+ * @pre The stream must have been allocated using @p dmaStreamAlloc().
+ * @post After use the stream can be released using @p dmaStreamFree().
+ *
+ * @param[in] dmastp pointer to a stm32_dma_stream_t structure
+ * @return Current memory target index.
+ *
+ * @special
+ */
+#define dmaStreamGetCurrentTarget(dmastp) \
+ (((dmastp)->stream->CR >> DMA_SxCR_CT_Pos) & 1U)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void dmaInit(void);
+ const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param);
+ const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
+ uint32_t priority,
+ stm32_dmaisr_t func,
+ void *param);
+ void dmaStreamFreeI(const stm32_dma_stream_t *dmastp);
+ void dmaStreamFree(const stm32_dma_stream_t *dmastp);
+#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
+ void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMA_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/EXTIv1/driver.mk b/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
index 63016f9d78..ffa86453bc 100644
--- a/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
@@ -1,2 +1,2 @@
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.c
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.c
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1
diff --git a/os/hal/ports/STM32/LLD/EXTIv1/notes.txt b/os/hal/ports/STM32/LLD/EXTIv1/notes.txt
index 0083d86ea2..a74c93e7c6 100644
--- a/os/hal/ports/STM32/LLD/EXTIv1/notes.txt
+++ b/os/hal/ports/STM32/LLD/EXTIv1/notes.txt
@@ -1,16 +1,16 @@
-STM32 EXTIv1 driver.
-
-Driver capability:
-
-- Support for the EXTI peripheral.
-
-The file registry must export:
-
-STM32_EXTI_HAS_GROUP2 - True if lines from 32 to 63 are present.
-STM32_EXTI_SEPARATE_RF - True if EXTI has separate status registers
- for falling and raising edges.
-STM32_EXTI_IMR1_MASK - Mask of the fixed lines that must not be
- configured by the driver (0..31).
-STM32_EXTI_IMR2_MASK - Mask of the fixed lines that must not be
- configured by the driver (32..63). Only required
- if STM32_EXTI_NUM_LINES is greater than 32.
+STM32 EXTIv1 driver.
+
+Driver capability:
+
+- Support for the EXTI peripheral.
+
+The file registry must export:
+
+STM32_EXTI_HAS_GROUP2 - True if lines from 32 to 63 are present.
+STM32_EXTI_SEPARATE_RF - True if EXTI has separate status registers
+ for falling and raising edges.
+STM32_EXTI_IMR1_MASK - Mask of the fixed lines that must not be
+ configured by the driver (0..31).
+STM32_EXTI_IMR2_MASK - Mask of the fixed lines that must not be
+ configured by the driver (32..63). Only required
+ if STM32_EXTI_NUM_LINES is greater than 32.
diff --git a/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.c b/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.c
index ba972f7739..79a01ebef6 100644
--- a/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.c
+++ b/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.c
@@ -1,218 +1,218 @@
-/*
- 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 EXTIv1/stm32_exti.c
- * @brief EXTI helper driver code.
- *
- * @addtogroup STM32_EXTI
- * @details EXTI sharing helper driver.
- * @{
- */
-
-#include "hal.h"
-
-/* The following macro is only defined if some driver requiring EXTI services
- has been enabled.*/
-#if defined(STM32_EXTI_REQUIRED) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 EXTI group 1 lines initialization.
- *
- * @param[in] mask mask of group 1 lines to be initialized
- * @param[in] mode initialization mode
- *
- * @api
- */
-void extiEnableGroup1(uint32_t mask, extimode_t mode) {
- uint32_t cmask;
-
- /* Mask including only configurable lines.*/
- cmask = mask & ~STM32_EXTI_IMR1_MASK;
-
- if ((mode & EXTI_MODE_EDGES_MASK) == 0U) {
- /* Disabling channels.*/
- EXTI->IMR1 &= ~mask;
- EXTI->EMR1 &= ~mask;
- EXTI->RTSR1 &= ~cmask;
- EXTI->FTSR1 &= ~cmask;
-#if STM32_EXTI_SEPARATE_RF == FALSE
- EXTI->PR1 = cmask;
-#else
- EXTI->RPR1 = cmask;
- EXTI->FPR1 = cmask;
-#endif
- }
- else {
- /* Programming edge registers.*/
- if (mode & EXTI_MODE_RISING_EDGE) {
- EXTI->RTSR1 |= cmask;
- }
- else {
- EXTI->RTSR1 &= ~cmask;
- }
- if (mode & EXTI_MODE_FALLING_EDGE) {
- EXTI->FTSR1 |= cmask;
- }
- else {
- EXTI->FTSR1 &= ~cmask;
- }
-
- /* Programming interrupt and event registers.*/
- if ((mode & EXTI_MODE_ACTION_MASK) == EXTI_MODE_ACTION_INTERRUPT) {
- EXTI->IMR1 |= mask;
- EXTI->EMR1 &= ~mask;
- }
- else {
- EXTI->EMR1 |= mask;
- EXTI->IMR1 &= ~mask;
- }
- }
-}
-
-#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief STM32 EXTI group 2 lines initialization.
- *
- * @param[in] mask mask of group 2 lines to be initialized
- * @param[in] mode initialization mode
- *
- * @api
- */
-void extiEnableGroup2(uint32_t mask, extimode_t mode) {
- uint32_t cmask;
-
- /* Mask including only configurable lines.*/
- cmask = mask & ~STM32_EXTI_IMR2_MASK;
-
- if ((mode & EXTI_MODE_EDGES_MASK) == 0U) {
- /* Disabling channels.*/
- EXTI->IMR2 &= ~mask;
- EXTI->EMR2 &= ~mask;
- EXTI->RTSR2 &= ~cmask;
- EXTI->FTSR2 &= ~cmask;
-#if STM32_EXTI_SEPARATE_RF == FALSE
- EXTI->PR2 = cmask;
-#else
- EXTI->RPR2 = cmask;
- EXTI->FPR2 = cmask;
-#endif
- }
- else {
- /* Programming edge registers.*/
- if (mode & EXTI_MODE_RISING_EDGE) {
- EXTI->RTSR2 |= cmask;
- }
- else {
- EXTI->RTSR2 &= ~cmask;
- }
- if (mode & EXTI_MODE_FALLING_EDGE) {
- EXTI->FTSR2 |= cmask;
- }
- else {
- EXTI->FTSR2 &= ~cmask;
- }
-
- /* Programming interrupt and event registers.*/
- if ((mode & EXTI_MODE_ACTION_MASK) == EXTI_MODE_ACTION_INTERRUPT) {
- EXTI->IMR2 |= mask;
- EXTI->EMR2 &= ~mask;
- }
- else {
- EXTI->EMR2 |= mask;
- EXTI->IMR2 &= ~mask;
- }
- }
-}
-#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
-
-/**
- * @brief STM32 EXTI line initialization.
- *
- * @param[in] line line to be initialized
- * @param[in] mode initialization mode
- *
- * @api
- */
-void extiEnableLine(extiline_t line, extimode_t mode) {
- uint32_t mask = (1U << (line & 0x1FU));
-
- osalDbgCheck(line < STM32_EXTI_NUM_LINES);
- osalDbgCheck((mode & ~EXTI_MODE_MASK) == 0U);
-
-#if STM32_EXTI_HAS_GROUP2 == TRUE
- if (line < 32) {
-#endif
- extiEnableGroup1(mask, mode);
-#if STM32_EXTI_HAS_GROUP2 == TRUE
- }
- else {
- extiEnableGroup2(mask, mode);
- }
-#endif
-}
-
-/**
- * @brief STM32 EXTI line IRQ status clearing.
- *
- * @param[in] line line to be initialized
- *
- * @api
- */
-void extiClearLine(extiline_t line) {
- uint32_t mask = (1U << (line & 0x1FU));
-
- osalDbgCheck(line < STM32_EXTI_NUM_LINES);
-
-#if STM32_EXTI_HAS_GROUP2 == TRUE
- if (line < 32) {
-#endif
- extiClearGroup1(mask);
-#if STM32_EXTI_HAS_GROUP2 == TRUE
- }
- else {
- extiClearGroup2(mask);
- }
-#endif
-}
-
-#endif /* STM32_EXTI_REQUIRED */
-
-/** @} */
+/*
+ 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 EXTIv1/stm32_exti.c
+ * @brief EXTI helper driver code.
+ *
+ * @addtogroup STM32_EXTI
+ * @details EXTI sharing helper driver.
+ * @{
+ */
+
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring EXTI services
+ has been enabled.*/
+#if defined(STM32_EXTI_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 EXTI group 1 lines initialization.
+ *
+ * @param[in] mask mask of group 1 lines to be initialized
+ * @param[in] mode initialization mode
+ *
+ * @api
+ */
+void extiEnableGroup1(uint32_t mask, extimode_t mode) {
+ uint32_t cmask;
+
+ /* Mask including only configurable lines.*/
+ cmask = mask & ~STM32_EXTI_IMR1_MASK;
+
+ if ((mode & EXTI_MODE_EDGES_MASK) == 0U) {
+ /* Disabling channels.*/
+ EXTI->IMR1 &= ~mask;
+ EXTI->EMR1 &= ~mask;
+ EXTI->RTSR1 &= ~cmask;
+ EXTI->FTSR1 &= ~cmask;
+#if STM32_EXTI_SEPARATE_RF == FALSE
+ EXTI->PR1 = cmask;
+#else
+ EXTI->RPR1 = cmask;
+ EXTI->FPR1 = cmask;
+#endif
+ }
+ else {
+ /* Programming edge registers.*/
+ if (mode & EXTI_MODE_RISING_EDGE) {
+ EXTI->RTSR1 |= cmask;
+ }
+ else {
+ EXTI->RTSR1 &= ~cmask;
+ }
+ if (mode & EXTI_MODE_FALLING_EDGE) {
+ EXTI->FTSR1 |= cmask;
+ }
+ else {
+ EXTI->FTSR1 &= ~cmask;
+ }
+
+ /* Programming interrupt and event registers.*/
+ if ((mode & EXTI_MODE_ACTION_MASK) == EXTI_MODE_ACTION_INTERRUPT) {
+ EXTI->IMR1 |= mask;
+ EXTI->EMR1 &= ~mask;
+ }
+ else {
+ EXTI->EMR1 |= mask;
+ EXTI->IMR1 &= ~mask;
+ }
+ }
+}
+
+#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief STM32 EXTI group 2 lines initialization.
+ *
+ * @param[in] mask mask of group 2 lines to be initialized
+ * @param[in] mode initialization mode
+ *
+ * @api
+ */
+void extiEnableGroup2(uint32_t mask, extimode_t mode) {
+ uint32_t cmask;
+
+ /* Mask including only configurable lines.*/
+ cmask = mask & ~STM32_EXTI_IMR2_MASK;
+
+ if ((mode & EXTI_MODE_EDGES_MASK) == 0U) {
+ /* Disabling channels.*/
+ EXTI->IMR2 &= ~mask;
+ EXTI->EMR2 &= ~mask;
+ EXTI->RTSR2 &= ~cmask;
+ EXTI->FTSR2 &= ~cmask;
+#if STM32_EXTI_SEPARATE_RF == FALSE
+ EXTI->PR2 = cmask;
+#else
+ EXTI->RPR2 = cmask;
+ EXTI->FPR2 = cmask;
+#endif
+ }
+ else {
+ /* Programming edge registers.*/
+ if (mode & EXTI_MODE_RISING_EDGE) {
+ EXTI->RTSR2 |= cmask;
+ }
+ else {
+ EXTI->RTSR2 &= ~cmask;
+ }
+ if (mode & EXTI_MODE_FALLING_EDGE) {
+ EXTI->FTSR2 |= cmask;
+ }
+ else {
+ EXTI->FTSR2 &= ~cmask;
+ }
+
+ /* Programming interrupt and event registers.*/
+ if ((mode & EXTI_MODE_ACTION_MASK) == EXTI_MODE_ACTION_INTERRUPT) {
+ EXTI->IMR2 |= mask;
+ EXTI->EMR2 &= ~mask;
+ }
+ else {
+ EXTI->EMR2 |= mask;
+ EXTI->IMR2 &= ~mask;
+ }
+ }
+}
+#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
+
+/**
+ * @brief STM32 EXTI line initialization.
+ *
+ * @param[in] line line to be initialized
+ * @param[in] mode initialization mode
+ *
+ * @api
+ */
+void extiEnableLine(extiline_t line, extimode_t mode) {
+ uint32_t mask = (1U << (line & 0x1FU));
+
+ osalDbgCheck(line < STM32_EXTI_NUM_LINES);
+ osalDbgCheck((mode & ~EXTI_MODE_MASK) == 0U);
+
+#if STM32_EXTI_HAS_GROUP2 == TRUE
+ if (line < 32) {
+#endif
+ extiEnableGroup1(mask, mode);
+#if STM32_EXTI_HAS_GROUP2 == TRUE
+ }
+ else {
+ extiEnableGroup2(mask, mode);
+ }
+#endif
+}
+
+/**
+ * @brief STM32 EXTI line IRQ status clearing.
+ *
+ * @param[in] line line to be initialized
+ *
+ * @api
+ */
+void extiClearLine(extiline_t line) {
+ uint32_t mask = (1U << (line & 0x1FU));
+
+ osalDbgCheck(line < STM32_EXTI_NUM_LINES);
+
+#if STM32_EXTI_HAS_GROUP2 == TRUE
+ if (line < 32) {
+#endif
+ extiClearGroup1(mask);
+#if STM32_EXTI_HAS_GROUP2 == TRUE
+ }
+ else {
+ extiClearGroup2(mask);
+ }
+#endif
+}
+
+#endif /* STM32_EXTI_REQUIRED */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h b/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h
index dadc58c508..a53813739b 100644
--- a/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h
+++ b/os/hal/ports/STM32/LLD/EXTIv1/stm32_exti.h
@@ -1,257 +1,257 @@
-/*
- 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 EXTIv1/stm32_exti.h
- * @brief EXTI helper driver header.
- *
- * @addtogroup STM32_EXTI
- * @{
- */
-
-#ifndef STM32_EXTI_H
-#define STM32_EXTI_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name EXTI channel modes
- * @{
- */
-#define EXTI_MODE_MASK 7U /**< @brief Mode parameter mask. */
-#define EXTI_MODE_EDGES_MASK 3U /**< @brief Edges field mask. */
-#define EXTI_MODE_DISABLED 0U /**< @brief Channel disabled. */
-#define EXTI_MODE_RISING_EDGE 1U /**< @brief Rising edge callback. */
-#define EXTI_MODE_FALLING_EDGE 2U /**< @brief Falling edge callback. */
-#define EXTI_MODE_BOTH_EDGES 3U /**< @brief Both edges callback. */
-#define EXTI_MODE_ACTION_MASK 4U /**< @brief Action field mask. */
-#define EXTI_MODE_ACTION_INTERRUPT 0U /**< @brief Interrupt mode. */
-#define EXTI_MODE_ACTION_EVENT 4U /**< @brief Event mode. */
-/** @} */
-
-/* Handling differences in ST headers.*/
-#if !defined(STM32H7XX) && !defined(STM32L4XX) && !defined(STM32L4XXP) && \
- !defined(STM32G0XX) && !defined(STM32G4XX)
-#define EMR1 EMR
-#define IMR1 IMR
-#define PR1 PR
-#define RTSR1 RTSR
-#define FTSR1 FTSR
-#endif
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_EXTI_NUM_LINES)
-#error "STM32_EXTI_NUM_LINES not defined in registry"
-#endif
-
-/* Checking for presence of bank 2 registers. If the definition is not
- present in registry then it is inferred by the number of channels (which
- is not an always-good method, see G0.*/
-#if !defined(STM32_EXTI_HAS_GROUP2)
-#if STM32_EXTI_NUM_LINES <= 32
-#define STM32_EXTI_HAS_GROUP2 FALSE
-#else
-#define STM32_EXTI_HAS_GROUP2 TRUE
-#endif
-#endif /* !defined(STM32_EXTI_HAS_GROUP2) */
-
-/* Determines if EXTI has dedicated CR register or if it is done in
- SYSCFG (old style).*/
-#if !defined(STM32_EXTI_HAS_CR)
-#define STM32_EXTI_HAS_CR FALSE
-#endif
-
-/* Determines if EXTI has dedicated separate registers for raising and
- falling edges.*/
-#if !defined(STM32_EXTI_SEPARATE_RF)
-#define STM32_EXTI_SEPARATE_RF FALSE
-#endif
-
-#if (STM32_EXTI_NUM_LINES < 0) || (STM32_EXTI_NUM_LINES > 63)
-#error "invalid STM32_EXTI_NUM_LINES value"
-#endif
-
-#if !defined(STM32_EXTI_IMR1_MASK)
-#error "STM32_EXTI_IMR1_MASK not defined in registry"
-#endif
-
-#if STM32_EXTI_NUM_LINES > 32
-#if !defined(STM32_EXTI_IMR2_MASK)
-#error "STM32_EXTI_IMR2_MASK not defined in registry"
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of an EXTI line identifier.
- */
-typedef uint32_t extiline_t;
-
-/**
- * @brief Type of an EXTI line mode.
- */
-typedef uint32_t extimode_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief From group 1 line number to mask.
- *
- * @param[in] line line number in range 0..31
- */
-#define EXTI_MASK1(line) (uint32_t)(1U << (line))
-
-/**
- * @brief From group 2 line number to mask.
- *
- * @param[in] line line number in range 32..63
- */
-#define EXTI_MASK2(line) (uint32_t)(1U << ((line) - 32U))
-
-/**
- * @brief STM32 EXTI group 1 IRQ status clearing.
- *
- * @param[in] mask mask of group 1 lines to be initialized
- *
- * @special
- */
-#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
-#define extiClearGroup1(mask) do { \
- osalDbgAssert(((mask) & STM32_EXTI_IMR1_MASK) == 0U, "fixed lines"); \
- EXTI->PR1 = (uint32_t)(mask); \
-} while (false)
-#else
-#define extiClearGroup1(mask) do { \
- osalDbgAssert(((mask) & STM32_EXTI_IMR1_MASK) == 0U, "fixed lines"); \
- EXTI->RPR1 = (uint32_t)(mask); \
- EXTI->FPR1 = (uint32_t)(mask); \
-} while (false)
-#endif
-
-#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief STM32 EXTI group 2 IRQ status clearing.
- *
- * @param[in] mask mask of group 2 lines to be initialized
- *
- * @special
- */
-#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
-#define extiClearGroup2(mask) do { \
- osalDbgAssert(((mask) & STM32_EXTI_IMR2_MASK) == 0U, "fixed lines"); \
- EXTI->PR2 = (uint32_t)(mask); \
-} while (false)
-#else
-#define extiClearGroup2(mask) do { \
- osalDbgAssert(((mask) & STM32_EXTI_IMR2_MASK) == 0U, "fixed lines"); \
- EXTI->RPR2 = (uint32_t)(mask); \
- EXTI->FPR2 = (uint32_t)(mask); \
-} while (false)
-#endif
-#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
-
-/**
- * @brief Serves an EXTI interrupt in group 1.
- *
- * @param[in] mask mask of lines to be cleared
- * @param[out] out mask of lines needing processing
- *
- * @special
- */
-#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
-#define extiGetAndClearGroup1(mask, out) do { \
- uint32_t pr1; \
- \
- pr1 = EXTI->PR1 & (mask); \
- (out) = pr1; \
- EXTI->PR1 = pr1; \
-} while (false)
-#else
-#define extiGetAndClearGroup1(mask, out) do { \
- uint32_t rpr1, fpr1; \
- \
- rpr1 = EXTI->RPR1 & (mask); \
- fpr1 = EXTI->FPR1 & (mask); \
- (out) = rpr1 | fpr1; \
- EXTI->RPR1 = rpr1; \
- EXTI->FPR1 = fpr1; \
-} while (false)
-#endif
-
-#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Serves an EXTI interrupt in group 2.
- *
- * @param[in] mask mask of lines to be cleared
- * @param[out] out mask of lines needing processing
- *
- * @special
- */
-#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
-#define extiGetAndClearGroup2(mask, out) do { \
- uint32_t pr2; \
- \
- pr2 = EXTI->PR2 & (mask); \
- (out) = pr2; \
- EXTI->PR2 = pr2; \
-} while (false)
-#else
-#define extiGetAndClearGroup2(mask, out) do { \
- uint32_t rpr2, fpr2; \
- \
- rpr2 = EXTI->RPR2 & (mask); \
- fpr2 = EXTI->FPR2 & (mask); \
- (out) = rpr2 | fpr2; \
- EXTI->RPR2 = rpr2; \
- EXTI->FPR2 = fpr2; \
-} while (false)
-#endif
-#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void extiEnableGroup1(uint32_t mask, extimode_t mode);
-#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
- void extiEnableGroup2(uint32_t mask, extimode_t mode);
-#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
- void extiEnableLine(extiline_t line, extimode_t mode);
- void extiClearLine(extiline_t line);
- #ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_EXTI_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 EXTIv1/stm32_exti.h
+ * @brief EXTI helper driver header.
+ *
+ * @addtogroup STM32_EXTI
+ * @{
+ */
+
+#ifndef STM32_EXTI_H
+#define STM32_EXTI_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name EXTI channel modes
+ * @{
+ */
+#define EXTI_MODE_MASK 7U /**< @brief Mode parameter mask. */
+#define EXTI_MODE_EDGES_MASK 3U /**< @brief Edges field mask. */
+#define EXTI_MODE_DISABLED 0U /**< @brief Channel disabled. */
+#define EXTI_MODE_RISING_EDGE 1U /**< @brief Rising edge callback. */
+#define EXTI_MODE_FALLING_EDGE 2U /**< @brief Falling edge callback. */
+#define EXTI_MODE_BOTH_EDGES 3U /**< @brief Both edges callback. */
+#define EXTI_MODE_ACTION_MASK 4U /**< @brief Action field mask. */
+#define EXTI_MODE_ACTION_INTERRUPT 0U /**< @brief Interrupt mode. */
+#define EXTI_MODE_ACTION_EVENT 4U /**< @brief Event mode. */
+/** @} */
+
+/* Handling differences in ST headers.*/
+#if !defined(STM32H7XX) && !defined(STM32L4XX) && !defined(STM32L4XXP) && \
+ !defined(STM32G0XX) && !defined(STM32G4XX)
+#define EMR1 EMR
+#define IMR1 IMR
+#define PR1 PR
+#define RTSR1 RTSR
+#define FTSR1 FTSR
+#endif
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_EXTI_NUM_LINES)
+#error "STM32_EXTI_NUM_LINES not defined in registry"
+#endif
+
+/* Checking for presence of bank 2 registers. If the definition is not
+ present in registry then it is inferred by the number of channels (which
+ is not an always-good method, see G0.*/
+#if !defined(STM32_EXTI_HAS_GROUP2)
+#if STM32_EXTI_NUM_LINES <= 32
+#define STM32_EXTI_HAS_GROUP2 FALSE
+#else
+#define STM32_EXTI_HAS_GROUP2 TRUE
+#endif
+#endif /* !defined(STM32_EXTI_HAS_GROUP2) */
+
+/* Determines if EXTI has dedicated CR register or if it is done in
+ SYSCFG (old style).*/
+#if !defined(STM32_EXTI_HAS_CR)
+#define STM32_EXTI_HAS_CR FALSE
+#endif
+
+/* Determines if EXTI has dedicated separate registers for raising and
+ falling edges.*/
+#if !defined(STM32_EXTI_SEPARATE_RF)
+#define STM32_EXTI_SEPARATE_RF FALSE
+#endif
+
+#if (STM32_EXTI_NUM_LINES < 0) || (STM32_EXTI_NUM_LINES > 63)
+#error "invalid STM32_EXTI_NUM_LINES value"
+#endif
+
+#if !defined(STM32_EXTI_IMR1_MASK)
+#error "STM32_EXTI_IMR1_MASK not defined in registry"
+#endif
+
+#if STM32_EXTI_NUM_LINES > 32
+#if !defined(STM32_EXTI_IMR2_MASK)
+#error "STM32_EXTI_IMR2_MASK not defined in registry"
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an EXTI line identifier.
+ */
+typedef uint32_t extiline_t;
+
+/**
+ * @brief Type of an EXTI line mode.
+ */
+typedef uint32_t extimode_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief From group 1 line number to mask.
+ *
+ * @param[in] line line number in range 0..31
+ */
+#define EXTI_MASK1(line) (uint32_t)(1U << (line))
+
+/**
+ * @brief From group 2 line number to mask.
+ *
+ * @param[in] line line number in range 32..63
+ */
+#define EXTI_MASK2(line) (uint32_t)(1U << ((line) - 32U))
+
+/**
+ * @brief STM32 EXTI group 1 IRQ status clearing.
+ *
+ * @param[in] mask mask of group 1 lines to be initialized
+ *
+ * @special
+ */
+#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
+#define extiClearGroup1(mask) do { \
+ osalDbgAssert(((mask) & STM32_EXTI_IMR1_MASK) == 0U, "fixed lines"); \
+ EXTI->PR1 = (uint32_t)(mask); \
+} while (false)
+#else
+#define extiClearGroup1(mask) do { \
+ osalDbgAssert(((mask) & STM32_EXTI_IMR1_MASK) == 0U, "fixed lines"); \
+ EXTI->RPR1 = (uint32_t)(mask); \
+ EXTI->FPR1 = (uint32_t)(mask); \
+} while (false)
+#endif
+
+#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief STM32 EXTI group 2 IRQ status clearing.
+ *
+ * @param[in] mask mask of group 2 lines to be initialized
+ *
+ * @special
+ */
+#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
+#define extiClearGroup2(mask) do { \
+ osalDbgAssert(((mask) & STM32_EXTI_IMR2_MASK) == 0U, "fixed lines"); \
+ EXTI->PR2 = (uint32_t)(mask); \
+} while (false)
+#else
+#define extiClearGroup2(mask) do { \
+ osalDbgAssert(((mask) & STM32_EXTI_IMR2_MASK) == 0U, "fixed lines"); \
+ EXTI->RPR2 = (uint32_t)(mask); \
+ EXTI->FPR2 = (uint32_t)(mask); \
+} while (false)
+#endif
+#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
+
+/**
+ * @brief Serves an EXTI interrupt in group 1.
+ *
+ * @param[in] mask mask of lines to be cleared
+ * @param[out] out mask of lines needing processing
+ *
+ * @special
+ */
+#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
+#define extiGetAndClearGroup1(mask, out) do { \
+ uint32_t pr1; \
+ \
+ pr1 = EXTI->PR1 & (mask); \
+ (out) = pr1; \
+ EXTI->PR1 = pr1; \
+} while (false)
+#else
+#define extiGetAndClearGroup1(mask, out) do { \
+ uint32_t rpr1, fpr1; \
+ \
+ rpr1 = EXTI->RPR1 & (mask); \
+ fpr1 = EXTI->FPR1 & (mask); \
+ (out) = rpr1 | fpr1; \
+ EXTI->RPR1 = rpr1; \
+ EXTI->FPR1 = fpr1; \
+} while (false)
+#endif
+
+#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Serves an EXTI interrupt in group 2.
+ *
+ * @param[in] mask mask of lines to be cleared
+ * @param[out] out mask of lines needing processing
+ *
+ * @special
+ */
+#if (STM32_EXTI_SEPARATE_RF == FALSE) || defined(__DOXYGEN__)
+#define extiGetAndClearGroup2(mask, out) do { \
+ uint32_t pr2; \
+ \
+ pr2 = EXTI->PR2 & (mask); \
+ (out) = pr2; \
+ EXTI->PR2 = pr2; \
+} while (false)
+#else
+#define extiGetAndClearGroup2(mask, out) do { \
+ uint32_t rpr2, fpr2; \
+ \
+ rpr2 = EXTI->RPR2 & (mask); \
+ fpr2 = EXTI->FPR2 & (mask); \
+ (out) = rpr2 | fpr2; \
+ EXTI->RPR2 = rpr2; \
+ EXTI->FPR2 = fpr2; \
+} while (false)
+#endif
+#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void extiEnableGroup1(uint32_t mask, extimode_t mode);
+#if (STM32_EXTI_HAS_GROUP2 == TRUE) || defined(__DOXYGEN__)
+ void extiEnableGroup2(uint32_t mask, extimode_t mode);
+#endif /* STM32_EXTI_HAS_GROUP2 == TRUE */
+ void extiEnableLine(extiline_t line, extimode_t mode);
+ void extiClearLine(extiline_t line);
+ #ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_EXTI_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/FDCANv1/driver.mk b/os/hal/ports/STM32/LLD/FDCANv1/driver.mk
index 734c3a0205..b69138ba64 100644
--- a/os/hal/ports/STM32/LLD/FDCANv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/FDCANv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1
diff --git a/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c b/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
index b6b46ee070..4307f94172 100644
--- a/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
+++ b/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.c
@@ -1,608 +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.
-*/
-
-/**
- * @file FDCANv1/hal_can_lld.c
- * @brief STM32 CAN subsystem low level driver source.
- *
- * @addtogroup CAN
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_CAN || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* Filter Standard Element Size in bytes.*/
-#define SRAMCAN_FLS_SIZE (1U * 4U)
-
-/* Filter Extended Element Size in bytes.*/
-#define SRAMCAN_FLE_SIZE (2U * 4U)
-
-/* RX FIFO 0 Elements Size in bytes.*/
-#define SRAMCAN_RF0_SIZE (18U * 4U)
-
-/* RX FIFO 1 Elements Size in bytes.*/
-#define SRAMCAN_RF1_SIZE (18U * 4U)
-
-/* RX Buffer Size in bytes.*/
-#define SRAMCAN_RB_SIZE (18U * 4U)
-
-/* TX Event FIFO Elements Size in bytes.*/
-#define SRAMCAN_TEF_SIZE (2U * 4U)
-
-/* TX FIFO/Queue Elements Size in bytes.*/
-#define SRAMCAN_TB_SIZE (18U * 4U)
-
-/* Trigger Memory Size in bytes.*/
-#define SRAMCAN_TM_SIZE (2U * 4U)
-
-/* Filter List Standard Start Address.*/
-#define SRAMCAN_FLSSA ((uint32_t)0)
-
-/* Filter List Extended Start Address.*/
-#define SRAMCAN_FLESA ((uint32_t)(SRAMCAN_FLSSA + \
- (STM32_FDCAN_FLS_NBR * SRAMCAN_FLS_SIZE)))
-
-/* RX FIFO 0 Start Address.*/
-#define SRAMCAN_RF0SA ((uint32_t)(SRAMCAN_FLESA + \
- (STM32_FDCAN_FLE_NBR * SRAMCAN_FLE_SIZE)))
-
-/* RX FIFO 1 Start Address.*/
-#define SRAMCAN_RF1SA ((uint32_t)(SRAMCAN_RF0SA + \
- (STM32_FDCAN_RF0_NBR * SRAMCAN_RF0_SIZE)))
-
-/* RX Buffer Start Address.*/
-#define SRAMCAN_RBSA ((uint32_t)(SRAMCAN_RF1SA + \
- (STM32_FDCAN_RF1_NBR * SRAMCAN_RF1_SIZE)))
-
-/* TX Event FIFO Start Address.*/
-#define SRAMCAN_TEFSA ((uint32_t)(SRAMCAN_RBSA + \
- (STM32_FDCAN_RB_NBR * SRAMCAN_RB_SIZE)))
-
-/* TX Buffers Start Address.*/
-#define SRAMCAN_TBSA ((uint32_t)(SRAMCAN_TEFSA + \
- (STM32_FDCAN_TEF_NBR * SRAMCAN_TEF_SIZE)))
-
-/* Trigger Memory Start Address.*/
-#define SRAMCAN_TMSA ((uint32_t)(SRAMCAN_TBSA + \
- (STM32_FDCAN_TB_NBR * SRAMCAN_TB_SIZE)))
-
-/* Message RAM size.*/
-#define SRAMCAN_SIZE ((uint32_t)(SRAMCAN_TMSA + \
- (STM32_FDCAN_TM_NBR * SRAMCAN_TM_SIZE)))
-
-
-#define TIMEOUT_INIT_MS 250U
-#define TIMEOUT_CSA_MS 250U
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief CAN1 driver identifier.*/
-#if STM32_CAN_USE_FDCAN1 || defined(__DOXYGEN__)
-CANDriver CAND1;
-#endif
-
-/** @brief CAN2 driver identifier.*/
-#if STM32_CAN_USE_FDCAN2 || defined(__DOXYGEN__)
-CANDriver CAND2;
-#endif
-
-/** @brief CAN3 driver identifier.*/
-#if STM32_CAN_USE_FDCAN3 || defined(__DOXYGEN__)
-CANDriver CAND3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint8_t dlc_to_bytes[] = {
- 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
- 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U
-};
-
-static uint32_t canclk;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static bool fdcan_clock_stop(CANDriver *canp) {
- systime_t start, end;
-
- /* Requesting clock stop then waiting for it to happen.*/
- canp->fdcan->CCCR |= FDCAN_CCCR_CSR;
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, TIME_MS2I(TIMEOUT_INIT_MS));
- while ((canp->fdcan->CCCR & FDCAN_CCCR_CSA) == 0U) {
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return true;
- }
- osalThreadSleepS(1);
- }
-
- return false;
-}
-
-static bool fdcan_init_mode(CANDriver *canp) {
- systime_t start, end;
-
- /* Going in initialization mode then waiting for it to happen.*/
- canp->fdcan->CCCR |= FDCAN_CCCR_INIT;
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, TIME_MS2I(TIMEOUT_INIT_MS));
- while ((canp->fdcan->CCCR & FDCAN_CCCR_INIT) == 0U) {
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return true;
- }
- osalThreadSleepS(1);
- }
-
- return false;
-}
-
-static bool fdcan_active_mode(CANDriver *canp) {
- systime_t start, end;
-
- /* Going in initialization mode then waiting for it to happen.*/
- canp->fdcan->CCCR &= ~FDCAN_CCCR_INIT;
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, TIME_MS2I(TIMEOUT_INIT_MS));
- while ((canp->fdcan->CCCR & FDCAN_CCCR_INIT) != 0U) {
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return true;
- }
- osalThreadSleepS(1);
- }
-
- return false;
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level CAN driver initialization.
- *
- * @notapi
- */
-void can_lld_init(void) {
-
- canclk = 0U;
-
- /* Unit reset.*/
- rccResetFDCAN();
-
-#if STM32_CAN_USE_FDCAN1
- /* Driver initialization.*/
- canObjectInit(&CAND1);
- CAND1.fdcan = FDCAN1;
- CAND1.ram_base = (uint32_t *)(SRAMCAN_BASE + 0U * SRAMCAN_SIZE);
-#endif
-
-#if STM32_CAN_USE_FDCAN2
- /* Driver initialization.*/
- canObjectInit(&CAND2);
- CAND2.fdcan = FDCAN2;
- CAND2.ram_base = (uint32_t *)(SRAMCAN_BASE + 1U * SRAMCAN_SIZE);
-#endif
-
-#if STM32_CAN_USE_FDCAN3
- /* Driver initialization.*/
- canObjectInit(&CAND3);
- CAND3.fdcan = FDCAN3;
- CAND3.ram_base = (uint32_t *)(SRAMCAN_BASE + 2U * SRAMCAN_SIZE);
-#endif
-}
-
-/**
- * @brief Configures and activates the CAN peripheral.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @return The operation result.
- * @retval false if the operation succeeded.
- * @retval true if the operation failed.
- *
- * @notapi
- */
-bool can_lld_start(CANDriver *canp) {
-
- /* Clock activation.*/
- rccEnableFDCAN(true);
-
- /* If it is the first activation then performing some extra
- initializations.*/
- if (canclk == 0U) {
- for (uint32_t *wp = canp->ram_base;
- wp < canp->ram_base + SRAMCAN_SIZE;
- wp += 1U) {
- *wp = (uint32_t)0U;
- }
- }
-
-#if STM32_CAN_USE_FDCAN1
- if (&CAND1 == canp) {
- canclk |= 1U;
- }
-#endif
-
-#if STM32_CAN_USE_FDCAN2
- if (&CAND2 == canp) {
- canclk |= 2U;
- }
-#endif
-
-#if STM32_CAN_USE_FDCAN3
- if (&CAND3 == canp) {
- canclk |= 4U;
- }
-#endif
-
- /* Requesting clock stop.*/
- if (fdcan_clock_stop(canp)) {
- osalDbgAssert(false, "CAN clock stop failed, check clocks and pin config");
- return true;
- }
-
- /* Going in initialization mode.*/
- if (fdcan_init_mode(canp)) {
- osalDbgAssert(false, "CAN initialization failed, check clocks and pin config");
- return true;
- }
-
- /* Configuration can be performed now.*/
- canp->fdcan->CCCR |= FDCAN_CCCR_CCE;
- canp->fdcan->CCCR &= ~(FDCAN_CCCR_CSR | FDCAN_CCCR_CSA);
-
- /* Setting up operation mode except driver-controlled bits.*/
- canp->fdcan->NBTP = canp->config->NBTP;
- canp->fdcan->DBTP = canp->config->DBTP;
- canp->fdcan->CCCR |= canp->config->CCCR & ~(FDCAN_CCCR_CSR | FDCAN_CCCR_CSA |
- FDCAN_CCCR_CCE | FDCAN_CCCR_INIT);
- canp->fdcan->TEST = canp->config->TEST;
-#ifdef STM32G4XX
- canp->fdcan->RXGFC = canp->config->RXGFC;
-#elif defined(STM32H7XX)
- canp->fdcan->GFC = canp->config->RXGFC;
-#else
-#error "Unsupported STM32 for FDCAN LLD driver"
-#endif
-
- /* Enabling interrupts, only using interrupt zero.*/
- canp->fdcan->IR = (uint32_t)-1;
- canp->fdcan->IE = FDCAN_IE_RF1NE | FDCAN_IE_RF1LE |
- FDCAN_IE_RF0NE | FDCAN_IE_RF0LE |
- FDCAN_IE_TCE;
- canp->fdcan->TXBTIE = FDCAN_TXBTIE_TIE;
- canp->fdcan->ILE = FDCAN_ILE_EINT0;
-
-#ifdef STM32H7XX
- /* H7 version of FDCAN has configurable memory layout, so configure it */
- canp->fdcan->SIDFC = STM32_FDCAN_FLS_NBR << 16 | SRAMCAN_FLSSA;
- canp->fdcan->XIDFC = STM32_FDCAN_FLE_NBR << 16 | SRAMCAN_FLESA;
- canp->fdcan->RXF0C = STM32_FDCAN_RF0_NBR << 16 | SRAMCAN_RF0SA;
- canp->fdcan->RXF1C = STM32_FDCAN_RF1_NBR << 16 | SRAMCAN_RF1SA;
- canp->fdcan->RXBC = SRAMCAN_RBSA;
- canp->fdcan->TXEFC = STM32_FDCAN_TEF_NBR << 16 | SRAMCAN_TEFSA;
- /* NB: this doesn't set NDTB, but sets TFQS to run in queue mode with no dedicated buffers */
- canp->fdcan->TXBC = STM32_FDCAN_TB_NBR << 24 | SRAMCAN_TBSA;
-
- /* set to use the full 18-byte size buffer elements */
- canp->fdcan->TXESC = 0x007;
- canp->fdcan->RXESC = 0x777;
-#endif /* STM32H7XX */
-
- /* Going in active mode.*/
- if (fdcan_active_mode(canp)) {
- osalDbgAssert(false, "CAN initialization failed, check clocks and pin config");
- return true;
- }
-
- return false;
-}
-
-/**
- * @brief Deactivates the CAN peripheral.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_stop(CANDriver *canp) {
-
- /* If in ready state then disables the CAN peripheral.*/
- if (canp->state == CAN_READY) {
- /* Disabling and clearing interrupts.*/
- canp->fdcan->IE = 0U;
- canp->fdcan->IR = (uint32_t)-1;
- canp->fdcan->ILE = 0U;
- canp->fdcan->TXBTIE = 0U;
-
- /* Disables the peripheral.*/
- (void) fdcan_clock_stop(canp);
-
-#if STM32_CAN_USE_FDCAN1
- if (&CAND1 == canp) {
- canclk &= ~1U;
- }
-#endif
-
-#if STM32_CAN_USE_FDCAN2
- if (&CAND2 == canp) {
- canclk &= ~2U;
- }
-#endif
-
-#if STM32_CAN_USE_FDCAN3
- if (&CAND3 == canp) {
- canclk &= ~4U;
- }
-#endif
-
- if (canclk == 0U) {
- rccDisableFDCAN();
- }
- }
-}
-
-/**
- * @brief Determines whether a frame can be transmitted.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- *
- * @return The queue space availability.
- * @retval false no space in the transmit queue.
- * @retval true transmit slot available.
- *
- * @notapi
- */
-bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
-
- (void)mailbox;
-
- return (bool)((canp->fdcan->TXFQS & FDCAN_TXFQS_TFQF) == 0U);
-}
-
-/**
- * @brief Inserts a frame into the transmit queue.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] ctfp pointer to the CAN frame to be transmitted
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- *
- * @notapi
- */
-void can_lld_transmit(CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp) {
- uint32_t put_index;
- uint32_t *tx_address;
-
- (void)mailbox;
-
- osalDbgCheck(dlc_to_bytes[ctfp->DLC] <= CAN_MAX_DLC_BYTES);
-
- /* Retrieve the TX FIFO put index.*/
- put_index = ((canp->fdcan->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
-
- /* Writing frame.*/
- tx_address = canp->ram_base +
- ((SRAMCAN_TBSA + (put_index * SRAMCAN_TB_SIZE)) / sizeof (uint32_t));
-
- *tx_address++ = ctfp->header32[0];
- *tx_address++ = ctfp->header32[1];
- for (unsigned i = 0U; i < dlc_to_bytes[ctfp->DLC]; i += 4U) {
- *tx_address++ = ctfp->data32[i / 4U];
- }
-
- /* Starting transmission.*/
- canp->fdcan->TXBAR = ((uint32_t)1 << put_index);
-}
-
-/**
- * @brief Determines whether a frame has been received.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- *
- * @return The queue space availability.
- * @retval false no space in the transmit queue.
- * @retval true transmit slot available.
- *
- * @notapi
- */
-bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
-
- switch (mailbox) {
- case CAN_ANY_MAILBOX:
- return can_lld_is_rx_nonempty(canp, 1U) ||
- can_lld_is_rx_nonempty(canp, 2U);
- case 1:
- return (bool)((canp->fdcan->RXF0S & FDCAN_RXF0S_F0FL) != 0U);
- case 2:
- return (bool)((canp->fdcan->RXF1S & FDCAN_RXF1S_F1FL) != 0U);
- default:
- return false;
- }
-}
-
-/**
- * @brief Receives a frame from the input queue.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
- * @param[out] crfp pointer to the buffer where the CAN frame is copied
- *
- * @notapi
- */
-void can_lld_receive(CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp) {
- uint32_t get_index;
- uint32_t *rx_address;
-
- if (mailbox == CAN_ANY_MAILBOX) {
- if (can_lld_is_rx_nonempty(canp, 1U)) {
- mailbox = 1U;
- }
- else if (can_lld_is_rx_nonempty(canp, 2U)) {
- mailbox = 2U;
- }
- else {
- return;
- }
- }
-
- if (mailbox == 1U) {
- /* GET index RXF0, add it and the length to the rx_address.*/
- get_index = (canp->fdcan->RXF0S & FDCAN_RXF0S_F0GI_Msk) >> FDCAN_RXF0S_F0GI_Pos;
- rx_address = canp->ram_base + (SRAMCAN_RF0SA +
- (get_index * SRAMCAN_RF0_SIZE)) / sizeof (uint32_t);
- }
- else {
- /* GET index RXF1, add it and the length to the rx_address.*/
- get_index = (canp->fdcan->RXF1S & FDCAN_RXF1S_F1GI_Msk) >> FDCAN_RXF1S_F1GI_Pos;
- rx_address = canp->ram_base + (SRAMCAN_RF1SA +
- (get_index * SRAMCAN_RF1_SIZE)) / sizeof (uint32_t);
- }
- crfp->header32[0] = *rx_address++;
- crfp->header32[1] = *rx_address++;
-
- /* Copy message from FDCAN peripheral's SRAM to structure. RAM is restricted
- to word aligned accesses, so up to 3 extra bytes may be copied.*/
- for (unsigned i = 0U; i < dlc_to_bytes[crfp->DLC]; i += 4U) {
- crfp->data32[i / 4U] = *rx_address++;
- }
-
- /* Acknowledge receipt by writing the get-index to the acknowledge
- register RXFxA then re-enable RX FIFO message arrived interrupt once
- the FIFO is emptied.*/
- if (mailbox == 1U) {
- uint32_t rxf0a = canp->fdcan->RXF0A;
- rxf0a &= ~FDCAN_RXF0A_F0AI_Msk;
- rxf0a |= get_index << FDCAN_RXF0A_F0AI_Pos;
- canp->fdcan->RXF0A = rxf0a;
-
- if (!can_lld_is_rx_nonempty(canp, mailbox)) {
-// canp->fdcan->IR = FDCAN_IR_RF0N;
- canp->fdcan->IE |= FDCAN_IE_RF0NE;
- }
- }
- else {
- uint32_t rxf1a = canp->fdcan->RXF1A;
- rxf1a &= ~FDCAN_RXF1A_F1AI_Msk;
- rxf1a |= get_index << FDCAN_RXF1A_F1AI_Pos;
- canp->fdcan->RXF1A = rxf1a;
-
- if (!can_lld_is_rx_nonempty(canp, mailbox)) {
-// canp->fdcan->IR = FDCAN_IR_RF1N;
- canp->fdcan->IE |= FDCAN_IE_RF1NE;
- }
- }
-}
-
-/**
- * @brief Tries to abort an ongoing transmission.
- *
- * @param[in] canp pointer to the @p CANDriver object
- * @param[in] mailbox mailbox number
- *
- * @notapi
- */
-void can_lld_abort(CANDriver *canp, canmbx_t mailbox) {
-
- (void)canp;
- (void)mailbox;
-}
-
-#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
-/**
- * @brief Enters the sleep mode.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_sleep(CANDriver *canp) {
-
- (void)canp;
-}
-
-/**
- * @brief Enforces leaving the sleep mode.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_wakeup(CANDriver *canp) {
-
- (void)canp;
-}
-#endif /* CAN_USE_SLEEP_MODE */
-
-/**
- * @brief FDCAN IRQ0 service routine.
- *
- * @param[in] canp pointer to the @p CANDriver object
- *
- * @notapi
- */
-void can_lld_serve_interrupt(CANDriver *canp) {
- uint32_t ir;
-
- /* Getting and clearing active IRQs.*/
- ir = canp->fdcan->IR;
- canp->fdcan->IR = ir;
-
- /* RX events.*/
- if ((ir & FDCAN_IR_RF0N) != 0U) {
- /* Disabling this source until the queue is emptied.*/
- canp->fdcan->IE &= ~FDCAN_IE_RF0NE;
- _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(1U));
- }
- if ((ir & FDCAN_IR_RF1N) != 0U) {
- /* Disabling this source until the queue is emptied.*/
- canp->fdcan->IE &= ~FDCAN_IE_RF1NE;
- _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(2U));
- }
-
- /* Overflow events.*/
- if (((ir & FDCAN_IR_RF0L) != 0U) || ((ir & FDCAN_IR_RF1L) != 0U) ) {
- _can_error_isr(canp, CAN_OVERFLOW_ERROR);
- }
-
- /* TX events.*/
- if ((ir & FDCAN_IR_TC) != 0U) {
- eventflags_t flags = 0U;
-
- flags |= 1U;
- _can_tx_empty_isr(canp, flags);
- }
-}
-
-#endif /* HAL_USE_CAN */
-
-/** @} */
+/*
+ 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 FDCANv1/hal_can_lld.c
+ * @brief STM32 CAN subsystem low level driver source.
+ *
+ * @addtogroup CAN
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_CAN || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* Filter Standard Element Size in bytes.*/
+#define SRAMCAN_FLS_SIZE (1U * 4U)
+
+/* Filter Extended Element Size in bytes.*/
+#define SRAMCAN_FLE_SIZE (2U * 4U)
+
+/* RX FIFO 0 Elements Size in bytes.*/
+#define SRAMCAN_RF0_SIZE (18U * 4U)
+
+/* RX FIFO 1 Elements Size in bytes.*/
+#define SRAMCAN_RF1_SIZE (18U * 4U)
+
+/* RX Buffer Size in bytes.*/
+#define SRAMCAN_RB_SIZE (18U * 4U)
+
+/* TX Event FIFO Elements Size in bytes.*/
+#define SRAMCAN_TEF_SIZE (2U * 4U)
+
+/* TX FIFO/Queue Elements Size in bytes.*/
+#define SRAMCAN_TB_SIZE (18U * 4U)
+
+/* Trigger Memory Size in bytes.*/
+#define SRAMCAN_TM_SIZE (2U * 4U)
+
+/* Filter List Standard Start Address.*/
+#define SRAMCAN_FLSSA ((uint32_t)0)
+
+/* Filter List Extended Start Address.*/
+#define SRAMCAN_FLESA ((uint32_t)(SRAMCAN_FLSSA + \
+ (STM32_FDCAN_FLS_NBR * SRAMCAN_FLS_SIZE)))
+
+/* RX FIFO 0 Start Address.*/
+#define SRAMCAN_RF0SA ((uint32_t)(SRAMCAN_FLESA + \
+ (STM32_FDCAN_FLE_NBR * SRAMCAN_FLE_SIZE)))
+
+/* RX FIFO 1 Start Address.*/
+#define SRAMCAN_RF1SA ((uint32_t)(SRAMCAN_RF0SA + \
+ (STM32_FDCAN_RF0_NBR * SRAMCAN_RF0_SIZE)))
+
+/* RX Buffer Start Address.*/
+#define SRAMCAN_RBSA ((uint32_t)(SRAMCAN_RF1SA + \
+ (STM32_FDCAN_RF1_NBR * SRAMCAN_RF1_SIZE)))
+
+/* TX Event FIFO Start Address.*/
+#define SRAMCAN_TEFSA ((uint32_t)(SRAMCAN_RBSA + \
+ (STM32_FDCAN_RB_NBR * SRAMCAN_RB_SIZE)))
+
+/* TX Buffers Start Address.*/
+#define SRAMCAN_TBSA ((uint32_t)(SRAMCAN_TEFSA + \
+ (STM32_FDCAN_TEF_NBR * SRAMCAN_TEF_SIZE)))
+
+/* Trigger Memory Start Address.*/
+#define SRAMCAN_TMSA ((uint32_t)(SRAMCAN_TBSA + \
+ (STM32_FDCAN_TB_NBR * SRAMCAN_TB_SIZE)))
+
+/* Message RAM size.*/
+#define SRAMCAN_SIZE ((uint32_t)(SRAMCAN_TMSA + \
+ (STM32_FDCAN_TM_NBR * SRAMCAN_TM_SIZE)))
+
+
+#define TIMEOUT_INIT_MS 250U
+#define TIMEOUT_CSA_MS 250U
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief CAN1 driver identifier.*/
+#if STM32_CAN_USE_FDCAN1 || defined(__DOXYGEN__)
+CANDriver CAND1;
+#endif
+
+/** @brief CAN2 driver identifier.*/
+#if STM32_CAN_USE_FDCAN2 || defined(__DOXYGEN__)
+CANDriver CAND2;
+#endif
+
+/** @brief CAN3 driver identifier.*/
+#if STM32_CAN_USE_FDCAN3 || defined(__DOXYGEN__)
+CANDriver CAND3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const uint8_t dlc_to_bytes[] = {
+ 0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
+ 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U
+};
+
+static uint32_t canclk;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+static bool fdcan_clock_stop(CANDriver *canp) {
+ systime_t start, end;
+
+ /* Requesting clock stop then waiting for it to happen.*/
+ canp->fdcan->CCCR |= FDCAN_CCCR_CSR;
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, TIME_MS2I(TIMEOUT_INIT_MS));
+ while ((canp->fdcan->CCCR & FDCAN_CCCR_CSA) == 0U) {
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return true;
+ }
+ osalThreadSleepS(1);
+ }
+
+ return false;
+}
+
+static bool fdcan_init_mode(CANDriver *canp) {
+ systime_t start, end;
+
+ /* Going in initialization mode then waiting for it to happen.*/
+ canp->fdcan->CCCR |= FDCAN_CCCR_INIT;
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, TIME_MS2I(TIMEOUT_INIT_MS));
+ while ((canp->fdcan->CCCR & FDCAN_CCCR_INIT) == 0U) {
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return true;
+ }
+ osalThreadSleepS(1);
+ }
+
+ return false;
+}
+
+static bool fdcan_active_mode(CANDriver *canp) {
+ systime_t start, end;
+
+ /* Going in initialization mode then waiting for it to happen.*/
+ canp->fdcan->CCCR &= ~FDCAN_CCCR_INIT;
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, TIME_MS2I(TIMEOUT_INIT_MS));
+ while ((canp->fdcan->CCCR & FDCAN_CCCR_INIT) != 0U) {
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return true;
+ }
+ osalThreadSleepS(1);
+ }
+
+ return false;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level CAN driver initialization.
+ *
+ * @notapi
+ */
+void can_lld_init(void) {
+
+ canclk = 0U;
+
+ /* Unit reset.*/
+ rccResetFDCAN();
+
+#if STM32_CAN_USE_FDCAN1
+ /* Driver initialization.*/
+ canObjectInit(&CAND1);
+ CAND1.fdcan = FDCAN1;
+ CAND1.ram_base = (uint32_t *)(SRAMCAN_BASE + 0U * SRAMCAN_SIZE);
+#endif
+
+#if STM32_CAN_USE_FDCAN2
+ /* Driver initialization.*/
+ canObjectInit(&CAND2);
+ CAND2.fdcan = FDCAN2;
+ CAND2.ram_base = (uint32_t *)(SRAMCAN_BASE + 1U * SRAMCAN_SIZE);
+#endif
+
+#if STM32_CAN_USE_FDCAN3
+ /* Driver initialization.*/
+ canObjectInit(&CAND3);
+ CAND3.fdcan = FDCAN3;
+ CAND3.ram_base = (uint32_t *)(SRAMCAN_BASE + 2U * SRAMCAN_SIZE);
+#endif
+}
+
+/**
+ * @brief Configures and activates the CAN peripheral.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @return The operation result.
+ * @retval false if the operation succeeded.
+ * @retval true if the operation failed.
+ *
+ * @notapi
+ */
+bool can_lld_start(CANDriver *canp) {
+
+ /* Clock activation.*/
+ rccEnableFDCAN(true);
+
+ /* If it is the first activation then performing some extra
+ initializations.*/
+ if (canclk == 0U) {
+ for (uint32_t *wp = canp->ram_base;
+ wp < canp->ram_base + SRAMCAN_SIZE;
+ wp += 1U) {
+ *wp = (uint32_t)0U;
+ }
+ }
+
+#if STM32_CAN_USE_FDCAN1
+ if (&CAND1 == canp) {
+ canclk |= 1U;
+ }
+#endif
+
+#if STM32_CAN_USE_FDCAN2
+ if (&CAND2 == canp) {
+ canclk |= 2U;
+ }
+#endif
+
+#if STM32_CAN_USE_FDCAN3
+ if (&CAND3 == canp) {
+ canclk |= 4U;
+ }
+#endif
+
+ /* Requesting clock stop.*/
+ if (fdcan_clock_stop(canp)) {
+ osalDbgAssert(false, "CAN clock stop failed, check clocks and pin config");
+ return true;
+ }
+
+ /* Going in initialization mode.*/
+ if (fdcan_init_mode(canp)) {
+ osalDbgAssert(false, "CAN initialization failed, check clocks and pin config");
+ return true;
+ }
+
+ /* Configuration can be performed now.*/
+ canp->fdcan->CCCR |= FDCAN_CCCR_CCE;
+ canp->fdcan->CCCR &= ~(FDCAN_CCCR_CSR | FDCAN_CCCR_CSA);
+
+ /* Setting up operation mode except driver-controlled bits.*/
+ canp->fdcan->NBTP = canp->config->NBTP;
+ canp->fdcan->DBTP = canp->config->DBTP;
+ canp->fdcan->CCCR |= canp->config->CCCR & ~(FDCAN_CCCR_CSR | FDCAN_CCCR_CSA |
+ FDCAN_CCCR_CCE | FDCAN_CCCR_INIT);
+ canp->fdcan->TEST = canp->config->TEST;
+#ifdef STM32G4XX
+ canp->fdcan->RXGFC = canp->config->RXGFC;
+#elif defined(STM32H7XX)
+ canp->fdcan->GFC = canp->config->RXGFC;
+#else
+#error "Unsupported STM32 for FDCAN LLD driver"
+#endif
+
+ /* Enabling interrupts, only using interrupt zero.*/
+ canp->fdcan->IR = (uint32_t)-1;
+ canp->fdcan->IE = FDCAN_IE_RF1NE | FDCAN_IE_RF1LE |
+ FDCAN_IE_RF0NE | FDCAN_IE_RF0LE |
+ FDCAN_IE_TCE;
+ canp->fdcan->TXBTIE = FDCAN_TXBTIE_TIE;
+ canp->fdcan->ILE = FDCAN_ILE_EINT0;
+
+#ifdef STM32H7XX
+ /* H7 version of FDCAN has configurable memory layout, so configure it */
+ canp->fdcan->SIDFC = STM32_FDCAN_FLS_NBR << 16 | SRAMCAN_FLSSA;
+ canp->fdcan->XIDFC = STM32_FDCAN_FLE_NBR << 16 | SRAMCAN_FLESA;
+ canp->fdcan->RXF0C = STM32_FDCAN_RF0_NBR << 16 | SRAMCAN_RF0SA;
+ canp->fdcan->RXF1C = STM32_FDCAN_RF1_NBR << 16 | SRAMCAN_RF1SA;
+ canp->fdcan->RXBC = SRAMCAN_RBSA;
+ canp->fdcan->TXEFC = STM32_FDCAN_TEF_NBR << 16 | SRAMCAN_TEFSA;
+ /* NB: this doesn't set NDTB, but sets TFQS to run in queue mode with no dedicated buffers */
+ canp->fdcan->TXBC = STM32_FDCAN_TB_NBR << 24 | SRAMCAN_TBSA;
+
+ /* set to use the full 18-byte size buffer elements */
+ canp->fdcan->TXESC = 0x007;
+ canp->fdcan->RXESC = 0x777;
+#endif /* STM32H7XX */
+
+ /* Going in active mode.*/
+ if (fdcan_active_mode(canp)) {
+ osalDbgAssert(false, "CAN initialization failed, check clocks and pin config");
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @brief Deactivates the CAN peripheral.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_stop(CANDriver *canp) {
+
+ /* If in ready state then disables the CAN peripheral.*/
+ if (canp->state == CAN_READY) {
+ /* Disabling and clearing interrupts.*/
+ canp->fdcan->IE = 0U;
+ canp->fdcan->IR = (uint32_t)-1;
+ canp->fdcan->ILE = 0U;
+ canp->fdcan->TXBTIE = 0U;
+
+ /* Disables the peripheral.*/
+ (void) fdcan_clock_stop(canp);
+
+#if STM32_CAN_USE_FDCAN1
+ if (&CAND1 == canp) {
+ canclk &= ~1U;
+ }
+#endif
+
+#if STM32_CAN_USE_FDCAN2
+ if (&CAND2 == canp) {
+ canclk &= ~2U;
+ }
+#endif
+
+#if STM32_CAN_USE_FDCAN3
+ if (&CAND3 == canp) {
+ canclk &= ~4U;
+ }
+#endif
+
+ if (canclk == 0U) {
+ rccDisableFDCAN();
+ }
+ }
+}
+
+/**
+ * @brief Determines whether a frame can be transmitted.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ *
+ * @return The queue space availability.
+ * @retval false no space in the transmit queue.
+ * @retval true transmit slot available.
+ *
+ * @notapi
+ */
+bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox) {
+
+ (void)mailbox;
+
+ return (bool)((canp->fdcan->TXFQS & FDCAN_TXFQS_TFQF) == 0U);
+}
+
+/**
+ * @brief Inserts a frame into the transmit queue.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] ctfp pointer to the CAN frame to be transmitted
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ *
+ * @notapi
+ */
+void can_lld_transmit(CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp) {
+ uint32_t put_index;
+ uint32_t *tx_address;
+
+ (void)mailbox;
+
+ osalDbgCheck(dlc_to_bytes[ctfp->DLC] <= CAN_MAX_DLC_BYTES);
+
+ /* Retrieve the TX FIFO put index.*/
+ put_index = ((canp->fdcan->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);
+
+ /* Writing frame.*/
+ tx_address = canp->ram_base +
+ ((SRAMCAN_TBSA + (put_index * SRAMCAN_TB_SIZE)) / sizeof (uint32_t));
+
+ *tx_address++ = ctfp->header32[0];
+ *tx_address++ = ctfp->header32[1];
+ for (unsigned i = 0U; i < dlc_to_bytes[ctfp->DLC]; i += 4U) {
+ *tx_address++ = ctfp->data32[i / 4U];
+ }
+
+ /* Starting transmission.*/
+ canp->fdcan->TXBAR = ((uint32_t)1 << put_index);
+}
+
+/**
+ * @brief Determines whether a frame has been received.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ *
+ * @return The queue space availability.
+ * @retval false no space in the transmit queue.
+ * @retval true transmit slot available.
+ *
+ * @notapi
+ */
+bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox) {
+
+ switch (mailbox) {
+ case CAN_ANY_MAILBOX:
+ return can_lld_is_rx_nonempty(canp, 1U) ||
+ can_lld_is_rx_nonempty(canp, 2U);
+ case 1:
+ return (bool)((canp->fdcan->RXF0S & FDCAN_RXF0S_F0FL) != 0U);
+ case 2:
+ return (bool)((canp->fdcan->RXF1S & FDCAN_RXF1S_F1FL) != 0U);
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Receives a frame from the input queue.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number, @p CAN_ANY_MAILBOX for any mailbox
+ * @param[out] crfp pointer to the buffer where the CAN frame is copied
+ *
+ * @notapi
+ */
+void can_lld_receive(CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp) {
+ uint32_t get_index;
+ uint32_t *rx_address;
+
+ if (mailbox == CAN_ANY_MAILBOX) {
+ if (can_lld_is_rx_nonempty(canp, 1U)) {
+ mailbox = 1U;
+ }
+ else if (can_lld_is_rx_nonempty(canp, 2U)) {
+ mailbox = 2U;
+ }
+ else {
+ return;
+ }
+ }
+
+ if (mailbox == 1U) {
+ /* GET index RXF0, add it and the length to the rx_address.*/
+ get_index = (canp->fdcan->RXF0S & FDCAN_RXF0S_F0GI_Msk) >> FDCAN_RXF0S_F0GI_Pos;
+ rx_address = canp->ram_base + (SRAMCAN_RF0SA +
+ (get_index * SRAMCAN_RF0_SIZE)) / sizeof (uint32_t);
+ }
+ else {
+ /* GET index RXF1, add it and the length to the rx_address.*/
+ get_index = (canp->fdcan->RXF1S & FDCAN_RXF1S_F1GI_Msk) >> FDCAN_RXF1S_F1GI_Pos;
+ rx_address = canp->ram_base + (SRAMCAN_RF1SA +
+ (get_index * SRAMCAN_RF1_SIZE)) / sizeof (uint32_t);
+ }
+ crfp->header32[0] = *rx_address++;
+ crfp->header32[1] = *rx_address++;
+
+ /* Copy message from FDCAN peripheral's SRAM to structure. RAM is restricted
+ to word aligned accesses, so up to 3 extra bytes may be copied.*/
+ for (unsigned i = 0U; i < dlc_to_bytes[crfp->DLC]; i += 4U) {
+ crfp->data32[i / 4U] = *rx_address++;
+ }
+
+ /* Acknowledge receipt by writing the get-index to the acknowledge
+ register RXFxA then re-enable RX FIFO message arrived interrupt once
+ the FIFO is emptied.*/
+ if (mailbox == 1U) {
+ uint32_t rxf0a = canp->fdcan->RXF0A;
+ rxf0a &= ~FDCAN_RXF0A_F0AI_Msk;
+ rxf0a |= get_index << FDCAN_RXF0A_F0AI_Pos;
+ canp->fdcan->RXF0A = rxf0a;
+
+ if (!can_lld_is_rx_nonempty(canp, mailbox)) {
+// canp->fdcan->IR = FDCAN_IR_RF0N;
+ canp->fdcan->IE |= FDCAN_IE_RF0NE;
+ }
+ }
+ else {
+ uint32_t rxf1a = canp->fdcan->RXF1A;
+ rxf1a &= ~FDCAN_RXF1A_F1AI_Msk;
+ rxf1a |= get_index << FDCAN_RXF1A_F1AI_Pos;
+ canp->fdcan->RXF1A = rxf1a;
+
+ if (!can_lld_is_rx_nonempty(canp, mailbox)) {
+// canp->fdcan->IR = FDCAN_IR_RF1N;
+ canp->fdcan->IE |= FDCAN_IE_RF1NE;
+ }
+ }
+}
+
+/**
+ * @brief Tries to abort an ongoing transmission.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ * @param[in] mailbox mailbox number
+ *
+ * @notapi
+ */
+void can_lld_abort(CANDriver *canp, canmbx_t mailbox) {
+
+ (void)canp;
+ (void)mailbox;
+}
+
+#if CAN_USE_SLEEP_MODE || defined(__DOXYGEN__)
+/**
+ * @brief Enters the sleep mode.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_sleep(CANDriver *canp) {
+
+ (void)canp;
+}
+
+/**
+ * @brief Enforces leaving the sleep mode.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_wakeup(CANDriver *canp) {
+
+ (void)canp;
+}
+#endif /* CAN_USE_SLEEP_MODE */
+
+/**
+ * @brief FDCAN IRQ0 service routine.
+ *
+ * @param[in] canp pointer to the @p CANDriver object
+ *
+ * @notapi
+ */
+void can_lld_serve_interrupt(CANDriver *canp) {
+ uint32_t ir;
+
+ /* Getting and clearing active IRQs.*/
+ ir = canp->fdcan->IR;
+ canp->fdcan->IR = ir;
+
+ /* RX events.*/
+ if ((ir & FDCAN_IR_RF0N) != 0U) {
+ /* Disabling this source until the queue is emptied.*/
+ canp->fdcan->IE &= ~FDCAN_IE_RF0NE;
+ _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(1U));
+ }
+ if ((ir & FDCAN_IR_RF1N) != 0U) {
+ /* Disabling this source until the queue is emptied.*/
+ canp->fdcan->IE &= ~FDCAN_IE_RF1NE;
+ _can_rx_full_isr(canp, CAN_MAILBOX_TO_MASK(2U));
+ }
+
+ /* Overflow events.*/
+ if (((ir & FDCAN_IR_RF0L) != 0U) || ((ir & FDCAN_IR_RF1L) != 0U) ) {
+ _can_error_isr(canp, CAN_OVERFLOW_ERROR);
+ }
+
+ /* TX events.*/
+ if ((ir & FDCAN_IR_TC) != 0U) {
+ eventflags_t flags = 0U;
+
+ flags |= 1U;
+ _can_tx_empty_isr(canp, flags);
+ }
+}
+
+#endif /* HAL_USE_CAN */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.h b/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.h
index ede1e459ec..6c41dcef4b 100644
--- a/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.h
+++ b/os/hal/ports/STM32/LLD/FDCANv1/hal_can_lld.h
@@ -1,490 +1,490 @@
-/*
- 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 FDCANv1/hal_can_lld.h
- * @brief STM32 CAN subsystem low level driver header.
- *
- * @addtogroup CAN
- * @{
- */
-
-#ifndef HAL_CAN_LLD_H
-#define HAL_CAN_LLD_H
-
-#if HAL_USE_CAN || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Maximum number of bytes in data of CAN packets.
- */
-#define CAN_MAX_DLC_BYTES 64
-
-/**
- * @brief Number of transmit mailboxes.
- */
-#define CAN_TX_MAILBOXES 1
-
-/**
- * @brief Number of receive mailboxes.
- */
-#define CAN_RX_MAILBOXES 2
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief CAN1 driver enable switch.
- * @details If set to @p TRUE the support for FDCAN1 is included.
- */
-#if !defined(STM32_CAN_USE_FDCAN1) || defined(__DOXYGEN__)
-#define STM32_CAN_USE_FDCAN1 FALSE
-#endif
-
-/**
- * @brief CAN2 driver enable switch.
- * @details If set to @p TRUE the support for FDCAN2 is included.
- */
-#if !defined(STM32_CAN_USE_FDCAN2) || defined(__DOXYGEN__)
-#define STM32_CAN_USE_FDCAN2 FALSE
-#endif
-
-/**
- * @brief CAN3 driver enable switch.
- * @details If set to @p TRUE the support for FDCAN3 is included.
- */
-#if !defined(STM32_CAN_USE_FDCAN3) || defined(__DOXYGEN__)
-#define STM32_CAN_USE_FDCAN3 FALSE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_FDCAN1)
-#error "STM32_HAS_FDCAN1 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_FDCAN2)
-#error "STM32_HAS_FDCAN2 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_FDCAN3)
-#error "STM32_HAS_FDCAN3 not defined in registry"
-#endif
-
-#if STM32_CAN_USE_FDCAN1 && !STM32_HAS_FDCAN1
-#error "FDCAN1 not present in the selected device"
-#endif
-
-#if STM32_CAN_USE_FDCAN2 && !STM32_HAS_FDCAN2
-#error "FDCAN2 not present in the selected device"
-#endif
-
-#if STM32_CAN_USE_FDCAN3 && !STM32_HAS_FDCAN3
-#error "FDCAN3 not present in the selected device"
-#endif
-
-#if !STM32_CAN_USE_FDCAN1 && !STM32_CAN_USE_FDCAN2 && !STM32_CAN_USE_FDCAN3
-#error "CAN driver activated but no FDCAN peripheral assigned"
-#endif
-
-#if !defined(STM32_FDCAN_FLS_NBR)
-#error "STM32_FDCAN_FLS_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_FLE_NBR)
-#error "STM32_FDCAN_FLE_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_RF0_NBR)
-#error "STM32_FDCAN_RF0_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_RF1_NBR)
-#error "STM32_FDCAN_RF1_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_RB_NBR)
-#error "STM32_FDCAN_RB_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_TEF_NBR)
-#error "STM32_FDCAN_TEF_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_TB_NBR)
-#error "STM32_FDCAN_TB_NBR not defined in registry"
-#endif
-
-#if !defined(STM32_FDCAN_TM_NBR)
-#error "STM32_FDCAN_TM_NBR not defined in registry"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a structure representing an CAN driver.
- */
-typedef struct CANDriver CANDriver;
-
-/**
- * @brief Type of a transmission mailbox index.
- */
-typedef uint32_t canmbx_t;
-
-#if (CAN_ENFORCE_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Type of a CAN notification callback.
- *
- * @param[in] canp pointer to the @p CANDriver object triggering the
- * callback
- * @param[in] flags flags associated to the mailbox callback
- */
-typedef void (*can_callback_t)(CANDriver *canp, uint32_t flags);
-#endif
-
-/**
- * @brief CAN transmission frame.
- * @note Accessing the frame data as word16 or word32 is not portable
- * because machine data endianness, it can be still useful for a
- * quick filling.
- */
-typedef struct {
- /**
- * @brief Frame header.
- */
- union {
- struct {
- union {
- struct {
- uint32_t EID:29; /**< @brief Extended identifier. */
- } ext;
- struct {
- uint32_t _R1:18; /**< @brief Reserved for offset. */
- uint32_t SID:11; /**< @brief Standard identifier. */
- } std;
- struct {
- uint32_t _R1:29; /**< @brief Reserved for offset. */
- uint32_t RTR:1; /**< @brief Remote transmit request.*/
- uint32_t XTD:1; /**< @brief Extended identifier. */
- uint32_t ESI:1; /**< @brief Error state indicator. */
- } common;
- };
- uint32_t _R2:16;
- uint32_t DLC:4; /**< @brief Data length code. */
- uint32_t BPS:1; /**< @brief Accepted non-matching
- frame. */
- uint32_t FDF:1; /**< @brief FDCAN frame format. */
- uint32_t _R3:1;
- uint32_t EFC:1; /**< @brief Event FIFO control. */
- uint32_t MM:8; /**< @brief Message event marker. */
- };
- uint32_t header32[2];
- };
- /**
- * @brief Frame data.
- */
- union {
- uint8_t data8[CAN_MAX_DLC_BYTES];
- uint16_t data16[CAN_MAX_DLC_BYTES / 2];
- uint32_t data32[CAN_MAX_DLC_BYTES / 4];
- };
-} CANTxFrame;
-
-/**
- * @brief CAN received frame.
- * @note Accessing the frame data as word16 or word32 is not portable
- * because machine data endianness, it can be still useful for a
- * quick filling.
- */
-typedef struct {
- /**
- * @brief Frame header.
- */
- union {
- struct {
- union {
- struct {
- uint32_t EID:29; /**< @brief Extended identifier. */
- } ext;
- struct {
- uint32_t _R1:18;
- uint32_t SID:11; /**< @brief Standard identifier. */
- } std;
- struct {
- uint32_t _R1:29; /**< @brief Reserved for offset. */
- uint32_t RTR:1; /**< @brief Remote transmit request.*/
- uint32_t XTD:1; /**< @brief Extended identifier. */
- uint32_t ESI:1; /**< @brief Error state indicator. */
- } common;
- };
- uint32_t RXTS:16; /**< @brief TX time stamp. */
- uint32_t DLC:4; /**< @brief Data length code. */
- uint32_t BRS:1; /**< @brief Bit rate switch. */
- uint32_t FDF:1; /**< @brief FDCAN frame format. */
- uint32_t _R2:2;
- uint32_t FIDX:7; /**< @brief Filter index. */
- uint32_t ANMF:1; /**< @brief Accepted non-matching
- frame. */
- };
- uint32_t header32[2];
- };
- /**
- * @brief Frame data.
- */
- union {
- uint8_t data8[CAN_MAX_DLC_BYTES];
- uint16_t data16[CAN_MAX_DLC_BYTES / 2];
- uint32_t data32[CAN_MAX_DLC_BYTES / 4];
- };
-} CANRxFrame;
-
-/**
- * @brief CAN standard filter.
- * @note Accessing the frame data as word16 or word32 is not portable
- * because machine data endianness, it can be still useful for a
- * quick filling.
- */
-typedef struct {
- union {
- struct {
- uint16_t SFID2:11;
- uint8_t _R1:5;
- uint16_t SFID1:11;
- uint8_t SFEC:3;
- uint8_t SFT:2;
- };
- union {
- uint32_t data32;
- uint16_t data16[2];
- uint8_t data8[4];
- };
- };
-} CANRxStandardFilter;
-
-
-/**
- * @brief CAN extended filter.
- * @note Accessing the frame data as word16 or word32 is not portable
- * because machine data endianness, it can be still useful for a
- * quick filling.
-*/
-typedef struct {
- union {
- struct {
- uint32_t EFID1:29;
- uint8_t EFEC:3;
- uint32_t EFID2:29;
- uint8_t _R1:1;
- uint8_t EFT:2;
- };
- union {
- uint32_t data32[2];
- uint16_t data16[4];
- uint8_t data8[8];
- };
- };
-} CANRxExtendedFilter;
-
-
-/**
- * @brief Driver configuration structure.
- */
-typedef struct {
- /**
- * @brief Nominal bit timing and prescaler register.
- */
- uint32_t NBTP;
- /**
- * @brief Data bit timing and prescaler register.
- */
- uint32_t DBTP;
- /**
- * @brief CC control register.
- */
- uint32_t CCCR;
- /**
- * @brief Test configuration register.
- */
- uint32_t TEST;
- /**
- * @brief Global filter configuration register.
- */
- uint32_t RXGFC;
-} CANConfig;
-
-/**
- * @brief Structure representing an CAN driver.
- */
-struct CANDriver {
- /**
- * @brief Driver state.
- */
- canstate_t state;
- /**
- * @brief Current configuration data.
- */
- const CANConfig *config;
- /**
- * @brief Transmission threads queue.
- */
- threads_queue_t txqueue;
- /**
- * @brief Receive threads queue.
- */
- threads_queue_t rxqueue;
-#if (CAN_ENFORCE_USE_CALLBACKS == FALSE) || defined(__DOXYGEN__)
- /**
- * @brief One or more frames become available.
- * @note After broadcasting this event it will not be broadcasted again
- * until the received frames queue has been completely emptied. It
- * is not broadcasted for each received frame. It is
- * responsibility of the application to empty the queue by
- * repeatedly invoking @p canReceive() when listening to this event.
- * This behavior minimizes the interrupt served by the system
- * because CAN traffic.
- * @note The flags associated to the listeners will indicate which
- * receive mailboxes become non-empty.
- */
- event_source_t rxfull_event;
- /**
- * @brief One or more transmission mailbox become available.
- * @note The flags associated to the listeners will indicate which
- * transmit mailboxes become empty.
- * @note The upper 16 bits are transmission error flags associated
- * to the transmit mailboxes.
- */
- event_source_t txempty_event;
- /**
- * @brief A CAN bus error happened.
- * @note The flags associated to the listeners will indicate that
- * receive error(s) have occurred.
- * @note In this implementation the upper 16 bits are filled with the
- * unprocessed content of the ESR register.
- */
- event_source_t error_event;
-#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
- /**
- * @brief Entering sleep state event.
- */
- event_source_t sleep_event;
- /**
- * @brief Exiting sleep state event.
- */
- event_source_t wakeup_event;
-#endif /* CAN_USE_SLEEP_MODE */
-#else /* CAN_ENFORCE_USE_CALLBACKS == TRUE */
- /**
- * @brief One or more frames become available.
- * @note After calling this function it will not be called again
- * until the received frames queue has been completely emptied. It
- * is not called for each received frame. It is
- * responsibility of the application to empty the queue by
- * repeatedly invoking @p chTryReceiveI().
- * This behavior minimizes the interrupt served by the system
- * because CAN traffic.
- */
- can_callback_t rxfull_cb;
- /**
- * @brief One or more transmission mailbox become available.
- * @note The flags associated to the callback will indicate which
- * transmit mailboxes become empty.
- */
- can_callback_t txempty_cb;
- /**
- * @brief A CAN bus error happened.
- */
- can_callback_t error_cb;
-#if (CAN_USE_SLEEP_MODE == TRUE) || defined (__DOXYGEN__)
- /**
- * @brief Exiting sleep state.
- */
- can_callback_t wakeup_cb;
-#endif
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the CAN registers.
- */
- FDCAN_GlobalTypeDef *fdcan;
- /**
- * @brief Pointer to FDCAN RAM base.
- */
- uint32_t *ram_base;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_CAN_USE_FDCAN1 && !defined(__DOXYGEN__)
-extern CANDriver CAND1;
-#endif
-
-#if STM32_CAN_USE_FDCAN2 && !defined(__DOXYGEN__)
-extern CANDriver CAND2;
-#endif
-
-#if STM32_CAN_USE_FDCAN3 && !defined(__DOXYGEN__)
-extern CANDriver CAND3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void can_lld_init(void);
- bool can_lld_start(CANDriver *canp);
- void can_lld_stop(CANDriver *canp);
- bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox);
- void can_lld_transmit(CANDriver *canp,
- canmbx_t mailbox,
- const CANTxFrame *crfp);
- bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox);
- void can_lld_receive(CANDriver *canp,
- canmbx_t mailbox,
- CANRxFrame *ctfp);
- void can_lld_abort(CANDriver *canp,
- canmbx_t mailbox);
-#if CAN_USE_SLEEP_MODE
- void can_lld_sleep(CANDriver *canp);
- void can_lld_wakeup(CANDriver *canp);
-#endif /* CAN_USE_SLEEP_MODE */
- void can_lld_serve_interrupt(CANDriver *canp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_CAN */
-
-#endif /* HAL_CAN_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 FDCANv1/hal_can_lld.h
+ * @brief STM32 CAN subsystem low level driver header.
+ *
+ * @addtogroup CAN
+ * @{
+ */
+
+#ifndef HAL_CAN_LLD_H
+#define HAL_CAN_LLD_H
+
+#if HAL_USE_CAN || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Maximum number of bytes in data of CAN packets.
+ */
+#define CAN_MAX_DLC_BYTES 64
+
+/**
+ * @brief Number of transmit mailboxes.
+ */
+#define CAN_TX_MAILBOXES 1
+
+/**
+ * @brief Number of receive mailboxes.
+ */
+#define CAN_RX_MAILBOXES 2
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief CAN1 driver enable switch.
+ * @details If set to @p TRUE the support for FDCAN1 is included.
+ */
+#if !defined(STM32_CAN_USE_FDCAN1) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_FDCAN1 FALSE
+#endif
+
+/**
+ * @brief CAN2 driver enable switch.
+ * @details If set to @p TRUE the support for FDCAN2 is included.
+ */
+#if !defined(STM32_CAN_USE_FDCAN2) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_FDCAN2 FALSE
+#endif
+
+/**
+ * @brief CAN3 driver enable switch.
+ * @details If set to @p TRUE the support for FDCAN3 is included.
+ */
+#if !defined(STM32_CAN_USE_FDCAN3) || defined(__DOXYGEN__)
+#define STM32_CAN_USE_FDCAN3 FALSE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_FDCAN1)
+#error "STM32_HAS_FDCAN1 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_FDCAN2)
+#error "STM32_HAS_FDCAN2 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_FDCAN3)
+#error "STM32_HAS_FDCAN3 not defined in registry"
+#endif
+
+#if STM32_CAN_USE_FDCAN1 && !STM32_HAS_FDCAN1
+#error "FDCAN1 not present in the selected device"
+#endif
+
+#if STM32_CAN_USE_FDCAN2 && !STM32_HAS_FDCAN2
+#error "FDCAN2 not present in the selected device"
+#endif
+
+#if STM32_CAN_USE_FDCAN3 && !STM32_HAS_FDCAN3
+#error "FDCAN3 not present in the selected device"
+#endif
+
+#if !STM32_CAN_USE_FDCAN1 && !STM32_CAN_USE_FDCAN2 && !STM32_CAN_USE_FDCAN3
+#error "CAN driver activated but no FDCAN peripheral assigned"
+#endif
+
+#if !defined(STM32_FDCAN_FLS_NBR)
+#error "STM32_FDCAN_FLS_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_FLE_NBR)
+#error "STM32_FDCAN_FLE_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_RF0_NBR)
+#error "STM32_FDCAN_RF0_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_RF1_NBR)
+#error "STM32_FDCAN_RF1_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_RB_NBR)
+#error "STM32_FDCAN_RB_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_TEF_NBR)
+#error "STM32_FDCAN_TEF_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_TB_NBR)
+#error "STM32_FDCAN_TB_NBR not defined in registry"
+#endif
+
+#if !defined(STM32_FDCAN_TM_NBR)
+#error "STM32_FDCAN_TM_NBR not defined in registry"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a structure representing an CAN driver.
+ */
+typedef struct CANDriver CANDriver;
+
+/**
+ * @brief Type of a transmission mailbox index.
+ */
+typedef uint32_t canmbx_t;
+
+#if (CAN_ENFORCE_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of a CAN notification callback.
+ *
+ * @param[in] canp pointer to the @p CANDriver object triggering the
+ * callback
+ * @param[in] flags flags associated to the mailbox callback
+ */
+typedef void (*can_callback_t)(CANDriver *canp, uint32_t flags);
+#endif
+
+/**
+ * @brief CAN transmission frame.
+ * @note Accessing the frame data as word16 or word32 is not portable
+ * because machine data endianness, it can be still useful for a
+ * quick filling.
+ */
+typedef struct {
+ /**
+ * @brief Frame header.
+ */
+ union {
+ struct {
+ union {
+ struct {
+ uint32_t EID:29; /**< @brief Extended identifier. */
+ } ext;
+ struct {
+ uint32_t _R1:18; /**< @brief Reserved for offset. */
+ uint32_t SID:11; /**< @brief Standard identifier. */
+ } std;
+ struct {
+ uint32_t _R1:29; /**< @brief Reserved for offset. */
+ uint32_t RTR:1; /**< @brief Remote transmit request.*/
+ uint32_t XTD:1; /**< @brief Extended identifier. */
+ uint32_t ESI:1; /**< @brief Error state indicator. */
+ } common;
+ };
+ uint32_t _R2:16;
+ uint32_t DLC:4; /**< @brief Data length code. */
+ uint32_t BPS:1; /**< @brief Accepted non-matching
+ frame. */
+ uint32_t FDF:1; /**< @brief FDCAN frame format. */
+ uint32_t _R3:1;
+ uint32_t EFC:1; /**< @brief Event FIFO control. */
+ uint32_t MM:8; /**< @brief Message event marker. */
+ };
+ uint32_t header32[2];
+ };
+ /**
+ * @brief Frame data.
+ */
+ union {
+ uint8_t data8[CAN_MAX_DLC_BYTES];
+ uint16_t data16[CAN_MAX_DLC_BYTES / 2];
+ uint32_t data32[CAN_MAX_DLC_BYTES / 4];
+ };
+} CANTxFrame;
+
+/**
+ * @brief CAN received frame.
+ * @note Accessing the frame data as word16 or word32 is not portable
+ * because machine data endianness, it can be still useful for a
+ * quick filling.
+ */
+typedef struct {
+ /**
+ * @brief Frame header.
+ */
+ union {
+ struct {
+ union {
+ struct {
+ uint32_t EID:29; /**< @brief Extended identifier. */
+ } ext;
+ struct {
+ uint32_t _R1:18;
+ uint32_t SID:11; /**< @brief Standard identifier. */
+ } std;
+ struct {
+ uint32_t _R1:29; /**< @brief Reserved for offset. */
+ uint32_t RTR:1; /**< @brief Remote transmit request.*/
+ uint32_t XTD:1; /**< @brief Extended identifier. */
+ uint32_t ESI:1; /**< @brief Error state indicator. */
+ } common;
+ };
+ uint32_t RXTS:16; /**< @brief TX time stamp. */
+ uint32_t DLC:4; /**< @brief Data length code. */
+ uint32_t BRS:1; /**< @brief Bit rate switch. */
+ uint32_t FDF:1; /**< @brief FDCAN frame format. */
+ uint32_t _R2:2;
+ uint32_t FIDX:7; /**< @brief Filter index. */
+ uint32_t ANMF:1; /**< @brief Accepted non-matching
+ frame. */
+ };
+ uint32_t header32[2];
+ };
+ /**
+ * @brief Frame data.
+ */
+ union {
+ uint8_t data8[CAN_MAX_DLC_BYTES];
+ uint16_t data16[CAN_MAX_DLC_BYTES / 2];
+ uint32_t data32[CAN_MAX_DLC_BYTES / 4];
+ };
+} CANRxFrame;
+
+/**
+ * @brief CAN standard filter.
+ * @note Accessing the frame data as word16 or word32 is not portable
+ * because machine data endianness, it can be still useful for a
+ * quick filling.
+ */
+typedef struct {
+ union {
+ struct {
+ uint16_t SFID2:11;
+ uint8_t _R1:5;
+ uint16_t SFID1:11;
+ uint8_t SFEC:3;
+ uint8_t SFT:2;
+ };
+ union {
+ uint32_t data32;
+ uint16_t data16[2];
+ uint8_t data8[4];
+ };
+ };
+} CANRxStandardFilter;
+
+
+/**
+ * @brief CAN extended filter.
+ * @note Accessing the frame data as word16 or word32 is not portable
+ * because machine data endianness, it can be still useful for a
+ * quick filling.
+*/
+typedef struct {
+ union {
+ struct {
+ uint32_t EFID1:29;
+ uint8_t EFEC:3;
+ uint32_t EFID2:29;
+ uint8_t _R1:1;
+ uint8_t EFT:2;
+ };
+ union {
+ uint32_t data32[2];
+ uint16_t data16[4];
+ uint8_t data8[8];
+ };
+ };
+} CANRxExtendedFilter;
+
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Nominal bit timing and prescaler register.
+ */
+ uint32_t NBTP;
+ /**
+ * @brief Data bit timing and prescaler register.
+ */
+ uint32_t DBTP;
+ /**
+ * @brief CC control register.
+ */
+ uint32_t CCCR;
+ /**
+ * @brief Test configuration register.
+ */
+ uint32_t TEST;
+ /**
+ * @brief Global filter configuration register.
+ */
+ uint32_t RXGFC;
+} CANConfig;
+
+/**
+ * @brief Structure representing an CAN driver.
+ */
+struct CANDriver {
+ /**
+ * @brief Driver state.
+ */
+ canstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const CANConfig *config;
+ /**
+ * @brief Transmission threads queue.
+ */
+ threads_queue_t txqueue;
+ /**
+ * @brief Receive threads queue.
+ */
+ threads_queue_t rxqueue;
+#if (CAN_ENFORCE_USE_CALLBACKS == FALSE) || defined(__DOXYGEN__)
+ /**
+ * @brief One or more frames become available.
+ * @note After broadcasting this event it will not be broadcasted again
+ * until the received frames queue has been completely emptied. It
+ * is not broadcasted for each received frame. It is
+ * responsibility of the application to empty the queue by
+ * repeatedly invoking @p canReceive() when listening to this event.
+ * This behavior minimizes the interrupt served by the system
+ * because CAN traffic.
+ * @note The flags associated to the listeners will indicate which
+ * receive mailboxes become non-empty.
+ */
+ event_source_t rxfull_event;
+ /**
+ * @brief One or more transmission mailbox become available.
+ * @note The flags associated to the listeners will indicate which
+ * transmit mailboxes become empty.
+ * @note The upper 16 bits are transmission error flags associated
+ * to the transmit mailboxes.
+ */
+ event_source_t txempty_event;
+ /**
+ * @brief A CAN bus error happened.
+ * @note The flags associated to the listeners will indicate that
+ * receive error(s) have occurred.
+ * @note In this implementation the upper 16 bits are filled with the
+ * unprocessed content of the ESR register.
+ */
+ event_source_t error_event;
+#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
+ /**
+ * @brief Entering sleep state event.
+ */
+ event_source_t sleep_event;
+ /**
+ * @brief Exiting sleep state event.
+ */
+ event_source_t wakeup_event;
+#endif /* CAN_USE_SLEEP_MODE */
+#else /* CAN_ENFORCE_USE_CALLBACKS == TRUE */
+ /**
+ * @brief One or more frames become available.
+ * @note After calling this function it will not be called again
+ * until the received frames queue has been completely emptied. It
+ * is not called for each received frame. It is
+ * responsibility of the application to empty the queue by
+ * repeatedly invoking @p chTryReceiveI().
+ * This behavior minimizes the interrupt served by the system
+ * because CAN traffic.
+ */
+ can_callback_t rxfull_cb;
+ /**
+ * @brief One or more transmission mailbox become available.
+ * @note The flags associated to the callback will indicate which
+ * transmit mailboxes become empty.
+ */
+ can_callback_t txempty_cb;
+ /**
+ * @brief A CAN bus error happened.
+ */
+ can_callback_t error_cb;
+#if (CAN_USE_SLEEP_MODE == TRUE) || defined (__DOXYGEN__)
+ /**
+ * @brief Exiting sleep state.
+ */
+ can_callback_t wakeup_cb;
+#endif
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the CAN registers.
+ */
+ FDCAN_GlobalTypeDef *fdcan;
+ /**
+ * @brief Pointer to FDCAN RAM base.
+ */
+ uint32_t *ram_base;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_CAN_USE_FDCAN1 && !defined(__DOXYGEN__)
+extern CANDriver CAND1;
+#endif
+
+#if STM32_CAN_USE_FDCAN2 && !defined(__DOXYGEN__)
+extern CANDriver CAND2;
+#endif
+
+#if STM32_CAN_USE_FDCAN3 && !defined(__DOXYGEN__)
+extern CANDriver CAND3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void can_lld_init(void);
+ bool can_lld_start(CANDriver *canp);
+ void can_lld_stop(CANDriver *canp);
+ bool can_lld_is_tx_empty(CANDriver *canp, canmbx_t mailbox);
+ void can_lld_transmit(CANDriver *canp,
+ canmbx_t mailbox,
+ const CANTxFrame *crfp);
+ bool can_lld_is_rx_nonempty(CANDriver *canp, canmbx_t mailbox);
+ void can_lld_receive(CANDriver *canp,
+ canmbx_t mailbox,
+ CANRxFrame *ctfp);
+ void can_lld_abort(CANDriver *canp,
+ canmbx_t mailbox);
+#if CAN_USE_SLEEP_MODE
+ void can_lld_sleep(CANDriver *canp);
+ void can_lld_wakeup(CANDriver *canp);
+#endif /* CAN_USE_SLEEP_MODE */
+ void can_lld_serve_interrupt(CANDriver *canp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_CAN */
+
+#endif /* HAL_CAN_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv1/driver.mk b/os/hal/ports/STM32/LLD/GPIOv1/driver.mk
index 5e428a7719..3a9768ee69 100644
--- a/os/hal/ports/STM32/LLD/GPIOv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/GPIOv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1
diff --git a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
index 99106bce7f..caefd2f93f 100644
--- a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.c
@@ -1,300 +1,300 @@
-/*
- 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 GPIOv1/hal_pal_lld.c
- * @brief STM32 PAL low level driver code.
- *
- * @addtogroup PAL
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_PAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if STM32_HAS_GPIOG
-#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
- RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
- RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \
- RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN)
-#elif STM32_HAS_GPIOE
-#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
- RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
- RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN)
-#else
-#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
- RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
- RCC_APB2ENR_AFIOEN)
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Event records for the 16 GPIO EXTI channels.
- */
-palevent_t _pal_events[16];
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 I/O ports configuration.
- * @details Ports A-D(E, F, G) clocks enabled, AFIO clock enabled.
- *
- * @param[in] config the STM32 ports configuration
- *
- * @notapi
- */
-void _pal_lld_init(const PALConfig *config) {
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
- unsigned i;
-
- for (i = 0; i < 16; i++) {
- _pal_init_event(i);
- }
-#endif
-
- /*
- * Enables the GPIO related clocks.
- */
- rccEnableAPB2(APB2_EN_MASK, true);
-
- /*
- * Initial GPIO setup.
- */
- GPIOA->ODR = config->PAData.odr;
- GPIOA->CRH = config->PAData.crh;
- GPIOA->CRL = config->PAData.crl;
- GPIOB->ODR = config->PBData.odr;
- GPIOB->CRH = config->PBData.crh;
- GPIOB->CRL = config->PBData.crl;
- GPIOC->ODR = config->PCData.odr;
- GPIOC->CRH = config->PCData.crh;
- GPIOC->CRL = config->PCData.crl;
- GPIOD->ODR = config->PDData.odr;
- GPIOD->CRH = config->PDData.crh;
- GPIOD->CRL = config->PDData.crl;
-#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
- GPIOE->ODR = config->PEData.odr;
- GPIOE->CRH = config->PEData.crh;
- GPIOE->CRL = config->PEData.crl;
-#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
- GPIOF->ODR = config->PFData.odr;
- GPIOF->CRH = config->PFData.crh;
- GPIOF->CRL = config->PFData.crl;
-#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
- GPIOG->ODR = config->PGData.odr;
- GPIOG->CRH = config->PGData.crh;
- GPIOG->CRL = config->PGData.crl;
-#endif
-#endif
-#endif
-}
-
-/**
- * @brief Pads mode setup.
- * @details This function programs a pads group belonging to the same port
- * with the specified mode.
- * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port the port identifier
- * @param[in] mask the group mask
- * @param[in] mode the mode
- *
- * @notapi
- */
-void _pal_lld_setgroupmode(ioportid_t port,
- ioportmask_t mask,
- iomode_t mode) {
- static const uint8_t cfgtab[] = {
- 4, /* PAL_MODE_RESET, implemented as input.*/
- 2, /* PAL_MODE_UNCONNECTED, implemented as push pull output 2MHz.*/
- 4, /* PAL_MODE_INPUT */
- 8, /* PAL_MODE_INPUT_PULLUP */
- 8, /* PAL_MODE_INPUT_PULLDOWN */
- 0, /* PAL_MODE_INPUT_ANALOG */
- 3, /* PAL_MODE_OUTPUT_PUSHPULL, 50MHz.*/
- 7, /* PAL_MODE_OUTPUT_OPENDRAIN, 50MHz.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 8, /* Reserved.*/
- 0xB, /* PAL_MODE_STM32_ALTERNATE_PUSHPULL, 50MHz.*/
- 0xF, /* PAL_MODE_STM32_ALTERNATE_OPENDRAIN, 50MHz.*/
- };
- uint32_t mh, ml, crh, crl, cfg;
- unsigned i;
-
- if (mode == PAL_MODE_INPUT_PULLUP)
- port->BSRR = mask;
- else if (mode == PAL_MODE_INPUT_PULLDOWN)
- port->BRR = mask;
- cfg = cfgtab[mode];
- mh = ml = crh = crl = 0;
- for (i = 0; i < 8; i++) {
- ml <<= 4;
- mh <<= 4;
- crl <<= 4;
- crh <<= 4;
- if ((mask & 0x0080) == 0)
- ml |= 0xf;
- else
- crl |= cfg;
- if ((mask & 0x8000) == 0)
- mh |= 0xf;
- else
- crh |= cfg;
- mask <<= 1;
- }
- port->CRH = (port->CRH & mh) | crh;
- port->CRL = (port->CRL & ml) | crl;
-}
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
-/**
- * @brief Pad event enable.
- * @note Programming an unknown or unsupported mode is silently ignored.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] mode pad event mode
- *
- * @notapi
- */
-void _pal_lld_enablepadevent(ioportid_t port,
- iopadid_t pad,
- ioeventmode_t mode) {
-
- uint32_t padmask, cridx, croff, crmask, portidx;
-
- /* Mask of the pad.*/
- padmask = 1U << (uint32_t)pad;
-
- /* Multiple channel setting of the same channel not allowed, first disable
- it. This is done because on STM32 the same channel cannot be mapped on
- multiple ports.*/
- osalDbgAssert(((EXTI->RTSR & padmask) == 0U) &&
- ((EXTI->FTSR & padmask) == 0U), "channel already in use");
-
- /* Index and mask of the SYSCFG CR register to be used.*/
- cridx = (uint32_t)pad >> 2U;
- croff = ((uint32_t)pad & 3U) * 4U;
- crmask = ~(0xFU << croff);
-
- /* Port index is obtained assuming that GPIO ports are placed at regular
- 0x400 intervals in memory space. So far this is true for all devices.*/
- portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
-
- /* Port selection in SYSCFG.*/
- AFIO->EXTICR[cridx] = (AFIO->EXTICR[cridx] & crmask) | (portidx << croff);
-
- /* Programming edge registers.*/
- if (mode & PAL_EVENT_MODE_RISING_EDGE)
- EXTI->RTSR |= padmask;
- else
- EXTI->RTSR &= ~padmask;
- if (mode & PAL_EVENT_MODE_FALLING_EDGE)
- EXTI->FTSR |= padmask;
- else
- EXTI->FTSR &= ~padmask;
-
- /* Programming interrupt and event registers.*/
- EXTI->IMR |= padmask;
- EXTI->EMR &= ~padmask;
-}
-
-/**
- * @brief Pad event disable.
- * @details This function disables previously programmed event callbacks.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
- uint32_t padmask, rtsr1, ftsr1;
-
- rtsr1 = EXTI->RTSR;
- ftsr1 = EXTI->FTSR;
-
- /* Mask of the pad.*/
- padmask = 1U << (uint32_t)pad;
-
- /* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
- if (((rtsr1 | ftsr1) & padmask) != 0U) {
- uint32_t cridx, croff, crport, portidx;
-
- /* Index and mask of the SYSCFG CR register to be used.*/
- cridx = (uint32_t)pad >> 2U;
- croff = ((uint32_t)pad & 3U) * 4U;
-
- /* Port index is obtained assuming that GPIO ports are placed at regular
- 0x400 intervals in memory space. So far this is true for all devices.*/
- portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
-
- crport = (AFIO->EXTICR[cridx] >> croff) & 0xFU;
-
- osalDbgAssert(crport == portidx, "channel mapped on different port");
-
- /* Disabling channel.*/
- EXTI->IMR &= ~padmask;
- EXTI->EMR &= ~padmask;
- EXTI->RTSR = rtsr1 & ~padmask;
- EXTI->FTSR = ftsr1 & ~padmask;
- EXTI->PR = padmask;
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT
- /* Callback cleared and/or thread reset.*/
- _pal_clear_event(pad);
-#endif
- }
-}
-#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
-
-#endif /* HAL_USE_PAL */
-
-/** @} */
+/*
+ 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 GPIOv1/hal_pal_lld.c
+ * @brief STM32 PAL low level driver code.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#if STM32_HAS_GPIOG
+#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
+ RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
+ RCC_APB2ENR_IOPEEN | RCC_APB2ENR_IOPFEN | \
+ RCC_APB2ENR_IOPGEN | RCC_APB2ENR_AFIOEN)
+#elif STM32_HAS_GPIOE
+#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
+ RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
+ RCC_APB2ENR_IOPEEN | RCC_APB2ENR_AFIOEN)
+#else
+#define APB2_EN_MASK (RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | \
+ RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | \
+ RCC_APB2ENR_AFIOEN)
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Event records for the 16 GPIO EXTI channels.
+ */
+palevent_t _pal_events[16];
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 I/O ports configuration.
+ * @details Ports A-D(E, F, G) clocks enabled, AFIO clock enabled.
+ *
+ * @param[in] config the STM32 ports configuration
+ *
+ * @notapi
+ */
+void _pal_lld_init(const PALConfig *config) {
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+ unsigned i;
+
+ for (i = 0; i < 16; i++) {
+ _pal_init_event(i);
+ }
+#endif
+
+ /*
+ * Enables the GPIO related clocks.
+ */
+ rccEnableAPB2(APB2_EN_MASK, true);
+
+ /*
+ * Initial GPIO setup.
+ */
+ GPIOA->ODR = config->PAData.odr;
+ GPIOA->CRH = config->PAData.crh;
+ GPIOA->CRL = config->PAData.crl;
+ GPIOB->ODR = config->PBData.odr;
+ GPIOB->CRH = config->PBData.crh;
+ GPIOB->CRL = config->PBData.crl;
+ GPIOC->ODR = config->PCData.odr;
+ GPIOC->CRH = config->PCData.crh;
+ GPIOC->CRL = config->PCData.crl;
+ GPIOD->ODR = config->PDData.odr;
+ GPIOD->CRH = config->PDData.crh;
+ GPIOD->CRL = config->PDData.crl;
+#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
+ GPIOE->ODR = config->PEData.odr;
+ GPIOE->CRH = config->PEData.crh;
+ GPIOE->CRL = config->PEData.crl;
+#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
+ GPIOF->ODR = config->PFData.odr;
+ GPIOF->CRH = config->PFData.crh;
+ GPIOF->CRL = config->PFData.crl;
+#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
+ GPIOG->ODR = config->PGData.odr;
+ GPIOG->CRH = config->PGData.crh;
+ GPIOG->CRL = config->PGData.crl;
+#endif
+#endif
+#endif
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull output at 2MHz.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @notapi
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode) {
+ static const uint8_t cfgtab[] = {
+ 4, /* PAL_MODE_RESET, implemented as input.*/
+ 2, /* PAL_MODE_UNCONNECTED, implemented as push pull output 2MHz.*/
+ 4, /* PAL_MODE_INPUT */
+ 8, /* PAL_MODE_INPUT_PULLUP */
+ 8, /* PAL_MODE_INPUT_PULLDOWN */
+ 0, /* PAL_MODE_INPUT_ANALOG */
+ 3, /* PAL_MODE_OUTPUT_PUSHPULL, 50MHz.*/
+ 7, /* PAL_MODE_OUTPUT_OPENDRAIN, 50MHz.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 8, /* Reserved.*/
+ 0xB, /* PAL_MODE_STM32_ALTERNATE_PUSHPULL, 50MHz.*/
+ 0xF, /* PAL_MODE_STM32_ALTERNATE_OPENDRAIN, 50MHz.*/
+ };
+ uint32_t mh, ml, crh, crl, cfg;
+ unsigned i;
+
+ if (mode == PAL_MODE_INPUT_PULLUP)
+ port->BSRR = mask;
+ else if (mode == PAL_MODE_INPUT_PULLDOWN)
+ port->BRR = mask;
+ cfg = cfgtab[mode];
+ mh = ml = crh = crl = 0;
+ for (i = 0; i < 8; i++) {
+ ml <<= 4;
+ mh <<= 4;
+ crl <<= 4;
+ crh <<= 4;
+ if ((mask & 0x0080) == 0)
+ ml |= 0xf;
+ else
+ crl |= cfg;
+ if ((mask & 0x8000) == 0)
+ mh |= 0xf;
+ else
+ crh |= cfg;
+ mask <<= 1;
+ }
+ port->CRH = (port->CRH & mh) | crh;
+ port->CRL = (port->CRL & ml) | crl;
+}
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+/**
+ * @brief Pad event enable.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad event mode
+ *
+ * @notapi
+ */
+void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode) {
+
+ uint32_t padmask, cridx, croff, crmask, portidx;
+
+ /* Mask of the pad.*/
+ padmask = 1U << (uint32_t)pad;
+
+ /* Multiple channel setting of the same channel not allowed, first disable
+ it. This is done because on STM32 the same channel cannot be mapped on
+ multiple ports.*/
+ osalDbgAssert(((EXTI->RTSR & padmask) == 0U) &&
+ ((EXTI->FTSR & padmask) == 0U), "channel already in use");
+
+ /* Index and mask of the SYSCFG CR register to be used.*/
+ cridx = (uint32_t)pad >> 2U;
+ croff = ((uint32_t)pad & 3U) * 4U;
+ crmask = ~(0xFU << croff);
+
+ /* Port index is obtained assuming that GPIO ports are placed at regular
+ 0x400 intervals in memory space. So far this is true for all devices.*/
+ portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
+
+ /* Port selection in SYSCFG.*/
+ AFIO->EXTICR[cridx] = (AFIO->EXTICR[cridx] & crmask) | (portidx << croff);
+
+ /* Programming edge registers.*/
+ if (mode & PAL_EVENT_MODE_RISING_EDGE)
+ EXTI->RTSR |= padmask;
+ else
+ EXTI->RTSR &= ~padmask;
+ if (mode & PAL_EVENT_MODE_FALLING_EDGE)
+ EXTI->FTSR |= padmask;
+ else
+ EXTI->FTSR &= ~padmask;
+
+ /* Programming interrupt and event registers.*/
+ EXTI->IMR |= padmask;
+ EXTI->EMR &= ~padmask;
+}
+
+/**
+ * @brief Pad event disable.
+ * @details This function disables previously programmed event callbacks.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
+ uint32_t padmask, rtsr1, ftsr1;
+
+ rtsr1 = EXTI->RTSR;
+ ftsr1 = EXTI->FTSR;
+
+ /* Mask of the pad.*/
+ padmask = 1U << (uint32_t)pad;
+
+ /* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
+ if (((rtsr1 | ftsr1) & padmask) != 0U) {
+ uint32_t cridx, croff, crport, portidx;
+
+ /* Index and mask of the SYSCFG CR register to be used.*/
+ cridx = (uint32_t)pad >> 2U;
+ croff = ((uint32_t)pad & 3U) * 4U;
+
+ /* Port index is obtained assuming that GPIO ports are placed at regular
+ 0x400 intervals in memory space. So far this is true for all devices.*/
+ portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
+
+ crport = (AFIO->EXTICR[cridx] >> croff) & 0xFU;
+
+ osalDbgAssert(crport == portidx, "channel mapped on different port");
+
+ /* Disabling channel.*/
+ EXTI->IMR &= ~padmask;
+ EXTI->EMR &= ~padmask;
+ EXTI->RTSR = rtsr1 & ~padmask;
+ EXTI->FTSR = ftsr1 & ~padmask;
+ EXTI->PR = padmask;
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT
+ /* Callback cleared and/or thread reset.*/
+ _pal_clear_event(pad);
+#endif
+ }
+}
+#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
+
+#endif /* HAL_USE_PAL */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h
index 63bc006d44..2b7d2dfc0d 100644
--- a/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv1/hal_pal_lld.h
@@ -1,459 +1,459 @@
-/*
- 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 GPIOv1/hal_pal_lld.h
- * @brief STM32 PAL low level driver header.
- *
- * @addtogroup PAL
- * @{
- */
-
-#ifndef HAL_PAL_LLD_H
-#define HAL_PAL_LLD_H
-
-#if HAL_USE_PAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Unsupported modes and specific modes */
-/*===========================================================================*/
-
-/**
- * @name STM32-specific I/O mode flags
- * @{
- */
-/**
- * @brief STM32 specific alternate push-pull output mode.
- */
-#define PAL_MODE_STM32_ALTERNATE_PUSHPULL 16
-
-/**
- * @brief STM32 specific alternate open-drain output mode.
- */
-#define PAL_MODE_STM32_ALTERNATE_OPENDRAIN 17
-/** @} */
-
-/*===========================================================================*/
-/* I/O Ports Types and constants. */
-/*===========================================================================*/
-
-/**
- * @name Port related definitions
- * @{
- */
-/**
- * @brief Width, in bits, of an I/O port.
- */
-#define PAL_IOPORTS_WIDTH 16
-
-/**
- * @brief Whole port mask.
- * @details This macro specifies all the valid bits into a port.
- */
-#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
-/** @} */
-
-/**
- * @name Line handling macros
- * @{
- */
-/**
- * @brief Forms a line identifier.
- * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
- * of this type is platform-dependent.
- * @note In this driver the pad number is encoded in the lower 4 bits of
- * the GPIO address which are guaranteed to be zero.
- */
-#define PAL_LINE(port, pad) \
- ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
-
-/**
- * @brief Decodes a port identifier from a line identifier.
- */
-#define PAL_PORT(line) \
- ((GPIO_TypeDef *)(((uint32_t)(line)) & 0xFFFFFFF0U))
-
-/**
- * @brief Decodes a pad identifier from a line identifier.
- */
-#define PAL_PAD(line) \
- ((uint32_t)((uint32_t)(line) & 0x0000000FU))
-
-/**
- * @brief Value identifying an invalid line.
- */
-#define PAL_NOLINE 0U
-/** @} */
-
-/**
- * @brief GPIO port setup info.
- */
-typedef struct {
- /** Initial value for ODR register.*/
- uint32_t odr;
- /** Initial value for CRL register.*/
- uint32_t crl;
- /** Initial value for CRH register.*/
- uint32_t crh;
-} stm32_gpio_setup_t;
-
-/**
- * @brief STM32 GPIO static initializer.
- * @details An instance of this structure must be passed to @p palInit() at
- * system startup time in order to initialize the digital I/O
- * subsystem. This represents only the initial setup, specific pads
- * or whole ports can be reprogrammed at later time.
- */
-typedef struct {
- /** @brief Port A setup data.*/
- stm32_gpio_setup_t PAData;
- /** @brief Port B setup data.*/
- stm32_gpio_setup_t PBData;
- /** @brief Port C setup data.*/
- stm32_gpio_setup_t PCData;
- /** @brief Port D setup data.*/
- stm32_gpio_setup_t PDData;
-#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
- /** @brief Port E setup data.*/
- stm32_gpio_setup_t PEData;
-#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
- /** @brief Port F setup data.*/
- stm32_gpio_setup_t PFData;
-#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
- /** @brief Port G setup data.*/
- stm32_gpio_setup_t PGData;
-#endif
-#endif
-#endif
-} PALConfig;
-
-/**
- * @brief Digital I/O port sized unsigned type.
- */
-typedef uint32_t ioportmask_t;
-
-/**
- * @brief Digital I/O modes.
- */
-typedef uint32_t iomode_t;
-
-/**
- * @brief Type of an I/O line.
- */
-typedef uint32_t ioline_t;
-
-/**
- * @brief Type of an event mode.
- */
-typedef uint32_t ioeventmode_t;
-
-/**
- * @brief Port Identifier.
- * @details This type can be a scalar or some kind of pointer, do not make
- * any assumption about it, use the provided macros when populating
- * variables of this type.
- */
-typedef GPIO_TypeDef * ioportid_t;
-
-/**
- * @brief Type of an pad identifier.
- */
-typedef uint32_t iopadid_t;
-
-/*===========================================================================*/
-/* I/O Ports Identifiers. */
-/* The low level driver wraps the definitions already present in the STM32 */
-/* firmware library. */
-/*===========================================================================*/
-
-/**
- * @brief GPIO port A identifier.
- */
-#if STM32_HAS_GPIOA || defined(__DOXYGEN__)
-#define IOPORT1 GPIOA
-#endif
-
-/**
- * @brief GPIO port B identifier.
- */
-#if STM32_HAS_GPIOB || defined(__DOXYGEN__)
-#define IOPORT2 GPIOB
-#endif
-
-/**
- * @brief GPIO port C identifier.
- */
-#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
-#define IOPORT3 GPIOC
-#endif
-
-/**
- * @brief GPIO port D identifier.
- */
-#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
-#define IOPORT4 GPIOD
-#endif
-
-/**
- * @brief GPIO port E identifier.
- */
-#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
-#define IOPORT5 GPIOE
-#endif
-
-/**
- * @brief GPIO port F identifier.
- */
-#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
-#define IOPORT6 GPIOF
-#endif
-
-/**
- * @brief GPIO port G identifier.
- */
-#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
-#define IOPORT7 GPIOG
-#endif
-
-/*===========================================================================*/
-/* Implementation, some of the following macros could be implemented as */
-/* functions, if so please put them in pal_lld.c. */
-/*===========================================================================*/
-
-/**
- * @brief GPIO ports subsystem initialization.
- *
- * @notapi
- */
-#define pal_lld_init(config) _pal_lld_init(config)
-
-/**
- * @brief Reads an I/O port.
- * @details This function is implemented by reading the GPIO IDR register, the
- * implementation has no side effects.
- * @note This function is not meant to be invoked directly by the application
- * code.
- *
- * @param[in] port port identifier
- * @return The port bits.
- *
- * @notapi
- */
-#define pal_lld_readport(port) ((ioportmask_t)((port)->IDR))
-
-/**
- * @brief Reads the output latch.
- * @details This function is implemented by reading the GPIO ODR register, the
- * implementation has no side effects.
- * @note This function is not meant to be invoked directly by the application
- * code.
- *
- * @param[in] port port identifier
- * @return The latched logical states.
- *
- * @notapi
- */
-#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODR))
-
-/**
- * @brief Writes on a I/O port.
- * @details This function is implemented by writing the GPIO ODR register, the
- * implementation has no side effects.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be written on the specified port
- *
- * @notapi
- */
-#define pal_lld_writeport(port, bits) ((port)->ODR = (uint32_t)(bits))
-
-/**
- * @brief Sets a bits mask on a I/O port.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be ORed on the specified port
- *
- * @notapi
- */
-#define pal_lld_setport(port, bits) ((port)->BSRR = (uint32_t)(bits))
-
-/**
- * @brief Clears a bits mask on a I/O port.
- * @details This function is implemented by writing the GPIO BRR register, the
- * implementation has no side effects.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be cleared on the specified port
- *
- * @notapi
- */
-#define pal_lld_clearport(port, bits) ((port)->BRR = (uint32_t)(bits))
-
-/**
- * @brief Writes a group of bits.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port port identifier
- * @param[in] mask group mask
- * @param[in] offset the group bit offset within the port
- * @param[in] bits bits to be written. Values exceeding the group
- * width are masked.
- *
- * @notapi
- */
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \
- ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \
- (port)->BSRR = w; \
-}
-
-/**
- * @brief Pads group mode setup.
- * @details This function programs a pads group belonging to the same port
- * with the specified mode.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port port identifier
- * @param[in] mask group mask
- * @param[in] offset group bit offset within the port
- * @param[in] mode group mode
- *
- * @notapi
- */
-#define pal_lld_setgroupmode(port, mask, offset, mode) \
- _pal_lld_setgroupmode(port, mask << offset, mode)
-
-/**
- * @brief Writes a logical state on an output pad.
- * @note Writing on pads programmed as pull-up or pull-down has the side
- * effect to modify the resistor setting because the output latched
- * data is used for the resistor selection.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] bit logical value, the value must be @p PAL_LOW or
- * @p PAL_HIGH
- *
- * @notapi
- */
-#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
-
-/**
- * @brief Pad event enable.
- * @note Programming an unknown or unsupported mode is silently ignored.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] mode pad event mode
- *
- * @notapi
- */
-#define pal_lld_enablepadevent(port, pad, mode) \
- _pal_lld_enablepadevent(port, pad, mode)
-
-/**
- * @brief Pad event disable.
- * @details This function disables previously programmed event callbacks.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-#define pal_lld_disablepadevent(port, pad) \
- _pal_lld_disablepadevent(port, pad)
-
-/**
- * @brief Returns a PAL event structure associated to a pad.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-#define pal_lld_get_pad_event(port, pad) \
- &_pal_events[pad]; (void)(port)
-
-/**
- * @brief Returns a PAL event structure associated to a line.
- *
- * @param[in] line line identifier
- *
- * @notapi
- */
-#define pal_lld_get_line_event(line) \
- &_pal_events[PAL_PAD(line)]
-
-/**
- * @brief Pad event enable check.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @return Pad event status.
- * @retval false if the pad event is disabled.
- * @retval true if the pad event is enabled.
- *
- * @notapi
- */
-#define pal_lld_ispadeventenabled(port, pad) \
- (bool)((EXTI->IMR & (1U << (uint32_t)pad)) != 0U)
-
-#if !defined(__DOXYGEN__)
-extern const PALConfig pal_default_config;
-#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
-extern palevent_t _pal_events[16];
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void _pal_lld_init(const PALConfig *config);
- void _pal_lld_setgroupmode(ioportid_t port,
- ioportmask_t mask,
- iomode_t mode);
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT
- void _pal_lld_enablepadevent(ioportid_t port,
- iopadid_t pad,
- ioeventmode_t mode);
- void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_PAL */
-
-#endif /* HAL_PAL_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 GPIOv1/hal_pal_lld.h
+ * @brief STM32 PAL low level driver header.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#ifndef HAL_PAL_LLD_H
+#define HAL_PAL_LLD_H
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+/**
+ * @name STM32-specific I/O mode flags
+ * @{
+ */
+/**
+ * @brief STM32 specific alternate push-pull output mode.
+ */
+#define PAL_MODE_STM32_ALTERNATE_PUSHPULL 16
+
+/**
+ * @brief STM32 specific alternate open-drain output mode.
+ */
+#define PAL_MODE_STM32_ALTERNATE_OPENDRAIN 17
+/** @} */
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @name Port related definitions
+ * @{
+ */
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @details This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+/** @} */
+
+/**
+ * @name Line handling macros
+ * @{
+ */
+/**
+ * @brief Forms a line identifier.
+ * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
+ * of this type is platform-dependent.
+ * @note In this driver the pad number is encoded in the lower 4 bits of
+ * the GPIO address which are guaranteed to be zero.
+ */
+#define PAL_LINE(port, pad) \
+ ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
+
+/**
+ * @brief Decodes a port identifier from a line identifier.
+ */
+#define PAL_PORT(line) \
+ ((GPIO_TypeDef *)(((uint32_t)(line)) & 0xFFFFFFF0U))
+
+/**
+ * @brief Decodes a pad identifier from a line identifier.
+ */
+#define PAL_PAD(line) \
+ ((uint32_t)((uint32_t)(line) & 0x0000000FU))
+
+/**
+ * @brief Value identifying an invalid line.
+ */
+#define PAL_NOLINE 0U
+/** @} */
+
+/**
+ * @brief GPIO port setup info.
+ */
+typedef struct {
+ /** Initial value for ODR register.*/
+ uint32_t odr;
+ /** Initial value for CRL register.*/
+ uint32_t crl;
+ /** Initial value for CRH register.*/
+ uint32_t crh;
+} stm32_gpio_setup_t;
+
+/**
+ * @brief STM32 GPIO static initializer.
+ * @details An instance of this structure must be passed to @p palInit() at
+ * system startup time in order to initialize the digital I/O
+ * subsystem. This represents only the initial setup, specific pads
+ * or whole ports can be reprogrammed at later time.
+ */
+typedef struct {
+ /** @brief Port A setup data.*/
+ stm32_gpio_setup_t PAData;
+ /** @brief Port B setup data.*/
+ stm32_gpio_setup_t PBData;
+ /** @brief Port C setup data.*/
+ stm32_gpio_setup_t PCData;
+ /** @brief Port D setup data.*/
+ stm32_gpio_setup_t PDData;
+#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
+ /** @brief Port E setup data.*/
+ stm32_gpio_setup_t PEData;
+#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
+ /** @brief Port F setup data.*/
+ stm32_gpio_setup_t PFData;
+#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
+ /** @brief Port G setup data.*/
+ stm32_gpio_setup_t PGData;
+#endif
+#endif
+#endif
+} PALConfig;
+
+/**
+ * @brief Digital I/O port sized unsigned type.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Digital I/O modes.
+ */
+typedef uint32_t iomode_t;
+
+/**
+ * @brief Type of an I/O line.
+ */
+typedef uint32_t ioline_t;
+
+/**
+ * @brief Type of an event mode.
+ */
+typedef uint32_t ioeventmode_t;
+
+/**
+ * @brief Port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef GPIO_TypeDef * ioportid_t;
+
+/**
+ * @brief Type of an pad identifier.
+ */
+typedef uint32_t iopadid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/* The low level driver wraps the definitions already present in the STM32 */
+/* firmware library. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO port A identifier.
+ */
+#if STM32_HAS_GPIOA || defined(__DOXYGEN__)
+#define IOPORT1 GPIOA
+#endif
+
+/**
+ * @brief GPIO port B identifier.
+ */
+#if STM32_HAS_GPIOB || defined(__DOXYGEN__)
+#define IOPORT2 GPIOB
+#endif
+
+/**
+ * @brief GPIO port C identifier.
+ */
+#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
+#define IOPORT3 GPIOC
+#endif
+
+/**
+ * @brief GPIO port D identifier.
+ */
+#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
+#define IOPORT4 GPIOD
+#endif
+
+/**
+ * @brief GPIO port E identifier.
+ */
+#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
+#define IOPORT5 GPIOE
+#endif
+
+/**
+ * @brief GPIO port F identifier.
+ */
+#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
+#define IOPORT6 GPIOF
+#endif
+
+/**
+ * @brief GPIO port G identifier.
+ */
+#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
+#define IOPORT7 GPIOG
+#endif
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO ports subsystem initialization.
+ *
+ * @notapi
+ */
+#define pal_lld_init(config) _pal_lld_init(config)
+
+/**
+ * @brief Reads an I/O port.
+ * @details This function is implemented by reading the GPIO IDR register, the
+ * implementation has no side effects.
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ *
+ * @param[in] port port identifier
+ * @return The port bits.
+ *
+ * @notapi
+ */
+#define pal_lld_readport(port) ((ioportmask_t)((port)->IDR))
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the GPIO ODR register, the
+ * implementation has no side effects.
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ *
+ * @param[in] port port identifier
+ * @return The latched logical states.
+ *
+ * @notapi
+ */
+#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODR))
+
+/**
+ * @brief Writes on a I/O port.
+ * @details This function is implemented by writing the GPIO ODR register, the
+ * implementation has no side effects.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be written on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_writeport(port, bits) ((port)->ODR = (uint32_t)(bits))
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be ORed on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_setport(port, bits) ((port)->BSRR = (uint32_t)(bits))
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BRR register, the
+ * implementation has no side effects.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be cleared on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_clearport(port, bits) ((port)->BRR = (uint32_t)(bits))
+
+/**
+ * @brief Writes a group of bits.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits bits to be written. Values exceeding the group
+ * width are masked.
+ *
+ * @notapi
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) { \
+ uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \
+ ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \
+ (port)->BSRR = w; \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] mode group mode
+ *
+ * @notapi
+ */
+#define pal_lld_setgroupmode(port, mask, offset, mode) \
+ _pal_lld_setgroupmode(port, mask << offset, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ * @note Writing on pads programmed as pull-up or pull-down has the side
+ * effect to modify the resistor setting because the output latched
+ * data is used for the resistor selection.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] bit logical value, the value must be @p PAL_LOW or
+ * @p PAL_HIGH
+ *
+ * @notapi
+ */
+#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
+
+/**
+ * @brief Pad event enable.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad event mode
+ *
+ * @notapi
+ */
+#define pal_lld_enablepadevent(port, pad, mode) \
+ _pal_lld_enablepadevent(port, pad, mode)
+
+/**
+ * @brief Pad event disable.
+ * @details This function disables previously programmed event callbacks.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_disablepadevent(port, pad) \
+ _pal_lld_disablepadevent(port, pad)
+
+/**
+ * @brief Returns a PAL event structure associated to a pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_get_pad_event(port, pad) \
+ &_pal_events[pad]; (void)(port)
+
+/**
+ * @brief Returns a PAL event structure associated to a line.
+ *
+ * @param[in] line line identifier
+ *
+ * @notapi
+ */
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
+/**
+ * @brief Pad event enable check.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @return Pad event status.
+ * @retval false if the pad event is disabled.
+ * @retval true if the pad event is enabled.
+ *
+ * @notapi
+ */
+#define pal_lld_ispadeventenabled(port, pad) \
+ (bool)((EXTI->IMR & (1U << (uint32_t)pad)) != 0U)
+
+#if !defined(__DOXYGEN__)
+extern const PALConfig pal_default_config;
+#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
+extern palevent_t _pal_events[16];
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(const PALConfig *config);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode);
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT
+ void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode);
+ void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_PAL */
+
+#endif /* HAL_PAL_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/driver.mk b/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
index 387ed83f5a..304546bba6 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
index ef2fb9a16d..1973e67c61 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.c
@@ -1,271 +1,271 @@
-/*
- 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 GPIOv2/hal_pal_lld.c
- * @brief STM32 PAL low level driver code.
- *
- * @addtogroup PAL
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_PAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Event records for the 16 GPIO EXTI channels.
- */
-palevent_t _pal_events[16];
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief PAL driver initialization.
- *
- * @notapi
- */
-void _pal_lld_init(void) {
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
- unsigned i;
-
- for (i = 0; i < 16; i++) {
- _pal_init_event(i);
- }
-#endif
-}
-
-/**
- * @brief Pads mode setup.
- * @details This function programs a pads group belonging to the same port
- * with the specified mode.
- * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum
- * speed.
- *
- * @param[in] port the port identifier
- * @param[in] mask the group mask
- * @param[in] mode the mode
- *
- * @notapi
- */
-void _pal_lld_setgroupmode(ioportid_t port,
- ioportmask_t mask,
- iomode_t mode) {
-
- uint32_t moder = (mode & PAL_STM32_MODE_MASK) >> 0;
- uint32_t otyper = (mode & PAL_STM32_OTYPE_MASK) >> 2;
- uint32_t ospeedr = (mode & PAL_STM32_OSPEED_MASK) >> 3;
- uint32_t pupdr = (mode & PAL_STM32_PUPDR_MASK) >> 5;
- uint32_t altr = (mode & PAL_STM32_ALTERNATE_MASK) >> 7;
- uint32_t bit = 0;
- while (true) {
- if ((mask & 1) != 0) {
- uint32_t altrmask, m1, m2, m4;
-
- altrmask = altr << ((bit & 7) * 4);
- m1 = 1 << bit;
- m2 = 3 << (bit * 2);
- m4 = 15 << ((bit & 7) * 4);
- port->OTYPER = (port->OTYPER & ~m1) | otyper;
- port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr;
- port->PUPDR = (port->PUPDR & ~m2) | pupdr;
- if ((mode & PAL_STM32_MODE_MASK) == PAL_STM32_MODE_ALTERNATE) {
- /* If going in alternate mode then the alternate number is set
- before switching mode in order to avoid glitches.*/
- if (bit < 8)
- port->AFRL = (port->AFRL & ~m4) | altrmask;
- else
- port->AFRH = (port->AFRH & ~m4) | altrmask;
- port->MODER = (port->MODER & ~m2) | moder;
- }
- else {
- /* If going into a non-alternate mode then the mode is switched
- before setting the alternate mode in order to avoid glitches.*/
- port->MODER = (port->MODER & ~m2) | moder;
- if (bit < 8)
- port->AFRL = (port->AFRL & ~m4) | altrmask;
- else
- port->AFRH = (port->AFRH & ~m4) | altrmask;
- }
- }
- mask >>= 1;
- if (!mask)
- return;
- otyper <<= 1;
- ospeedr <<= 2;
- pupdr <<= 2;
- moder <<= 2;
- bit++;
- }
-}
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
-/**
- * @brief Pad event enable.
- * @note Programming an unknown or unsupported mode is silently ignored.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] mode pad event mode
- *
- * @notapi
- */
-void _pal_lld_enablepadevent(ioportid_t port,
- iopadid_t pad,
- ioeventmode_t mode) {
-
- uint32_t padmask, cridx, croff, crmask, portidx;
-
- /* Mask of the pad.*/
- padmask = 1U << (uint32_t)pad;
-
- /* Multiple channel setting of the same channel not allowed, first disable
- it. This is done because on STM32 the same channel cannot be mapped on
- multiple ports.*/
- osalDbgAssert(((EXTI->RTSR1 & padmask) == 0U) &&
- ((EXTI->FTSR1 & padmask) == 0U), "channel already in use");
-
- /* Port index is obtained assuming that GPIO ports are placed at regular
- 0x400 intervals in memory space. So far this is true for all devices.*/
- portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
-
- /* Index and mask of the CR register to be used.*/
- cridx = (uint32_t)pad >> 2U;
-#if STM32_EXTI_HAS_CR == FALSE
- croff = ((uint32_t)pad & 3U) * 4U;
- crmask = ~(0xFU << croff);
- SYSCFG->EXTICR[cridx] = (SYSCFG->EXTICR[cridx] & crmask) | (portidx << croff);
-#else
- croff = ((uint32_t)pad & 3U) * 8U;
- crmask = ~(0xFFU << croff);
- EXTI->EXTICR[cridx] = (EXTI->EXTICR[cridx] & crmask) | (portidx << croff);
-#endif
-
- /* Programming edge registers.*/
- if (mode & PAL_EVENT_MODE_RISING_EDGE)
- EXTI->RTSR1 |= padmask;
- else
- EXTI->RTSR1 &= ~padmask;
- if (mode & PAL_EVENT_MODE_FALLING_EDGE)
- EXTI->FTSR1 |= padmask;
- else
- EXTI->FTSR1 &= ~padmask;
-
- /* Programming interrupt and event registers.*/
-#if defined(STM32_EXTI_ENHANCED)
- EXTI_D1->IMR1 |= padmask;
- EXTI_D1->EMR1 &= ~padmask;
-#else
- EXTI->IMR1 |= padmask;
- EXTI->EMR1 &= ~padmask;
-#endif
-}
-
-/**
- * @brief Pad event disable.
- * @details This function disables previously programmed event callbacks.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
- uint32_t padmask, rtsr1, ftsr1;
-
- rtsr1 = EXTI->RTSR1;
- ftsr1 = EXTI->FTSR1;
-
- /* Mask of the pad.*/
- padmask = 1U << (uint32_t)pad;
-
- /* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
- if (((rtsr1 | ftsr1) & padmask) != 0U) {
- uint32_t cridx, croff, crport, portidx;
-
- /* Port index is obtained assuming that GPIO ports are placed at regular
- 0x400 intervals in memory space. So far this is true for all devices.*/
- portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
-
- /* Index and mask of the CR register to be used.*/
- cridx = (uint32_t)pad >> 2U;
-#if STM32_EXTI_HAS_CR == FALSE
- croff = ((uint32_t)pad & 3U) * 4U;
- crport = (SYSCFG->EXTICR[cridx] >> croff) & 0xFU;
-#else
- croff = ((uint32_t)pad & 3U) * 8U;
- crport = (EXTI->EXTICR[cridx] >> croff) & 0xFFU;
-#endif
-
- osalDbgAssert(crport == portidx, "channel mapped on different port");
-
-#if defined(STM32_EXTI_ENHANCED)
- /* Disabling channel.*/
- EXTI_D1->IMR1 &= ~padmask;
- EXTI_D1->EMR1 &= ~padmask;
- EXTI->RTSR1 = rtsr1 & ~padmask;
- EXTI->FTSR1 = ftsr1 & ~padmask;
- EXTI_D1->PR1 = padmask;
-#else
- /* Disabling channel.*/
- EXTI->IMR1 &= ~padmask;
- EXTI->EMR1 &= ~padmask;
- EXTI->RTSR1 = rtsr1 & ~padmask;
- EXTI->FTSR1 = ftsr1 & ~padmask;
-#if STM32_EXTI_SEPARATE_RF == FALSE
- EXTI->PR1 = padmask;
-#else
- EXTI->RPR1 = padmask;
- EXTI->FPR1 = padmask;
-#endif
-#endif
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT
- /* Callback cleared and/or thread reset.*/
- _pal_clear_event(pad);
-#endif
- }
-}
-#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
-
-#endif /* HAL_USE_PAL */
-
-/** @} */
+/*
+ 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 GPIOv2/hal_pal_lld.c
+ * @brief STM32 PAL low level driver code.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Event records for the 16 GPIO EXTI channels.
+ */
+palevent_t _pal_events[16];
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief PAL driver initialization.
+ *
+ * @notapi
+ */
+void _pal_lld_init(void) {
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+ unsigned i;
+
+ for (i = 0; i < 16; i++) {
+ _pal_init_event(i);
+ }
+#endif
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum
+ * speed.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @notapi
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode) {
+
+ uint32_t moder = (mode & PAL_STM32_MODE_MASK) >> 0;
+ uint32_t otyper = (mode & PAL_STM32_OTYPE_MASK) >> 2;
+ uint32_t ospeedr = (mode & PAL_STM32_OSPEED_MASK) >> 3;
+ uint32_t pupdr = (mode & PAL_STM32_PUPDR_MASK) >> 5;
+ uint32_t altr = (mode & PAL_STM32_ALTERNATE_MASK) >> 7;
+ uint32_t bit = 0;
+ while (true) {
+ if ((mask & 1) != 0) {
+ uint32_t altrmask, m1, m2, m4;
+
+ altrmask = altr << ((bit & 7) * 4);
+ m1 = 1 << bit;
+ m2 = 3 << (bit * 2);
+ m4 = 15 << ((bit & 7) * 4);
+ port->OTYPER = (port->OTYPER & ~m1) | otyper;
+ port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr;
+ port->PUPDR = (port->PUPDR & ~m2) | pupdr;
+ if ((mode & PAL_STM32_MODE_MASK) == PAL_STM32_MODE_ALTERNATE) {
+ /* If going in alternate mode then the alternate number is set
+ before switching mode in order to avoid glitches.*/
+ if (bit < 8)
+ port->AFRL = (port->AFRL & ~m4) | altrmask;
+ else
+ port->AFRH = (port->AFRH & ~m4) | altrmask;
+ port->MODER = (port->MODER & ~m2) | moder;
+ }
+ else {
+ /* If going into a non-alternate mode then the mode is switched
+ before setting the alternate mode in order to avoid glitches.*/
+ port->MODER = (port->MODER & ~m2) | moder;
+ if (bit < 8)
+ port->AFRL = (port->AFRL & ~m4) | altrmask;
+ else
+ port->AFRH = (port->AFRH & ~m4) | altrmask;
+ }
+ }
+ mask >>= 1;
+ if (!mask)
+ return;
+ otyper <<= 1;
+ ospeedr <<= 2;
+ pupdr <<= 2;
+ moder <<= 2;
+ bit++;
+ }
+}
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+/**
+ * @brief Pad event enable.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad event mode
+ *
+ * @notapi
+ */
+void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode) {
+
+ uint32_t padmask, cridx, croff, crmask, portidx;
+
+ /* Mask of the pad.*/
+ padmask = 1U << (uint32_t)pad;
+
+ /* Multiple channel setting of the same channel not allowed, first disable
+ it. This is done because on STM32 the same channel cannot be mapped on
+ multiple ports.*/
+ osalDbgAssert(((EXTI->RTSR1 & padmask) == 0U) &&
+ ((EXTI->FTSR1 & padmask) == 0U), "channel already in use");
+
+ /* Port index is obtained assuming that GPIO ports are placed at regular
+ 0x400 intervals in memory space. So far this is true for all devices.*/
+ portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
+
+ /* Index and mask of the CR register to be used.*/
+ cridx = (uint32_t)pad >> 2U;
+#if STM32_EXTI_HAS_CR == FALSE
+ croff = ((uint32_t)pad & 3U) * 4U;
+ crmask = ~(0xFU << croff);
+ SYSCFG->EXTICR[cridx] = (SYSCFG->EXTICR[cridx] & crmask) | (portidx << croff);
+#else
+ croff = ((uint32_t)pad & 3U) * 8U;
+ crmask = ~(0xFFU << croff);
+ EXTI->EXTICR[cridx] = (EXTI->EXTICR[cridx] & crmask) | (portidx << croff);
+#endif
+
+ /* Programming edge registers.*/
+ if (mode & PAL_EVENT_MODE_RISING_EDGE)
+ EXTI->RTSR1 |= padmask;
+ else
+ EXTI->RTSR1 &= ~padmask;
+ if (mode & PAL_EVENT_MODE_FALLING_EDGE)
+ EXTI->FTSR1 |= padmask;
+ else
+ EXTI->FTSR1 &= ~padmask;
+
+ /* Programming interrupt and event registers.*/
+#if defined(STM32_EXTI_ENHANCED)
+ EXTI_D1->IMR1 |= padmask;
+ EXTI_D1->EMR1 &= ~padmask;
+#else
+ EXTI->IMR1 |= padmask;
+ EXTI->EMR1 &= ~padmask;
+#endif
+}
+
+/**
+ * @brief Pad event disable.
+ * @details This function disables previously programmed event callbacks.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
+ uint32_t padmask, rtsr1, ftsr1;
+
+ rtsr1 = EXTI->RTSR1;
+ ftsr1 = EXTI->FTSR1;
+
+ /* Mask of the pad.*/
+ padmask = 1U << (uint32_t)pad;
+
+ /* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
+ if (((rtsr1 | ftsr1) & padmask) != 0U) {
+ uint32_t cridx, croff, crport, portidx;
+
+ /* Port index is obtained assuming that GPIO ports are placed at regular
+ 0x400 intervals in memory space. So far this is true for all devices.*/
+ portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
+
+ /* Index and mask of the CR register to be used.*/
+ cridx = (uint32_t)pad >> 2U;
+#if STM32_EXTI_HAS_CR == FALSE
+ croff = ((uint32_t)pad & 3U) * 4U;
+ crport = (SYSCFG->EXTICR[cridx] >> croff) & 0xFU;
+#else
+ croff = ((uint32_t)pad & 3U) * 8U;
+ crport = (EXTI->EXTICR[cridx] >> croff) & 0xFFU;
+#endif
+
+ osalDbgAssert(crport == portidx, "channel mapped on different port");
+
+#if defined(STM32_EXTI_ENHANCED)
+ /* Disabling channel.*/
+ EXTI_D1->IMR1 &= ~padmask;
+ EXTI_D1->EMR1 &= ~padmask;
+ EXTI->RTSR1 = rtsr1 & ~padmask;
+ EXTI->FTSR1 = ftsr1 & ~padmask;
+ EXTI_D1->PR1 = padmask;
+#else
+ /* Disabling channel.*/
+ EXTI->IMR1 &= ~padmask;
+ EXTI->EMR1 &= ~padmask;
+ EXTI->RTSR1 = rtsr1 & ~padmask;
+ EXTI->FTSR1 = ftsr1 & ~padmask;
+#if STM32_EXTI_SEPARATE_RF == FALSE
+ EXTI->PR1 = padmask;
+#else
+ EXTI->RPR1 = padmask;
+ EXTI->FPR1 = padmask;
+#endif
+#endif
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT
+ /* Callback cleared and/or thread reset.*/
+ _pal_clear_event(pad);
+#endif
+ }
+}
+#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
+
+#endif /* HAL_USE_PAL */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h
index 15b541b056..5a322ca6c0 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv2/hal_pal_lld.h
@@ -1,514 +1,514 @@
-/*
- 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 GPIOv2/hal_pal_lld.h
- * @brief STM32 PAL low level driver header.
- *
- * @addtogroup PAL
- * @{
- */
-
-#ifndef HAL_PAL_LLD_H
-#define HAL_PAL_LLD_H
-
-#include "stm32_gpio.h"
-
-#if HAL_USE_PAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Unsupported modes and specific modes */
-/*===========================================================================*/
-
-/* Specifies palInit() without parameter, required until all platforms will
- be updated to the new style.*/
-#define PAL_NEW_INIT
-
-#undef PAL_MODE_RESET
-#undef PAL_MODE_UNCONNECTED
-#undef PAL_MODE_INPUT
-#undef PAL_MODE_INPUT_PULLUP
-#undef PAL_MODE_INPUT_PULLDOWN
-#undef PAL_MODE_INPUT_ANALOG
-#undef PAL_MODE_OUTPUT_PUSHPULL
-#undef PAL_MODE_OUTPUT_OPENDRAIN
-
-/**
- * @name STM32-specific I/O mode flags
- * @{
- */
-#define PAL_STM32_MODE_MASK (3U << 0U)
-#define PAL_STM32_MODE_INPUT (0U << 0U)
-#define PAL_STM32_MODE_OUTPUT (1U << 0U)
-#define PAL_STM32_MODE_ALTERNATE (2U << 0U)
-#define PAL_STM32_MODE_ANALOG (3U << 0U)
-
-#define PAL_STM32_OTYPE_MASK (1U << 2U)
-#define PAL_STM32_OTYPE_PUSHPULL (0U << 2U)
-#define PAL_STM32_OTYPE_OPENDRAIN (1U << 2U)
-
-#define PAL_STM32_OSPEED_MASK (3U << 3U)
-#define PAL_STM32_OSPEED_LOWEST (0U << 3U)
-#if defined(STM32F0XX) || defined(STM32F30X) || defined(STM32F37X)
-#define PAL_STM32_OSPEED_MID (1U << 3U)
-#else
-#define PAL_STM32_OSPEED_MID1 (1U << 3U)
-#define PAL_STM32_OSPEED_MID2 (2U << 3U)
-#endif
-#define PAL_STM32_OSPEED_HIGHEST (3U << 3U)
-
-#define PAL_STM32_PUPDR_MASK (3U << 5U)
-#define PAL_STM32_PUPDR_FLOATING (0U << 5U)
-#define PAL_STM32_PUPDR_PULLUP (1U << 5U)
-#define PAL_STM32_PUPDR_PULLDOWN (2U << 5U)
-
-#define PAL_STM32_ALTERNATE_MASK (15U << 7U)
-#define PAL_STM32_ALTERNATE(n) ((n) << 7U)
-
-/**
- * @brief Alternate function.
- *
- * @param[in] n alternate function selector
- */
-#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \
- PAL_STM32_ALTERNATE(n))
-/** @} */
-
-/**
- * @name Standard I/O mode flags
- * @{
- */
-/**
- * @brief Implemented as input.
- */
-#define PAL_MODE_RESET PAL_STM32_MODE_INPUT
-
-/**
- * @brief Implemented as input with pull-up.
- */
-#define PAL_MODE_UNCONNECTED PAL_MODE_INPUT_PULLUP
-
-/**
- * @brief Regular input high-Z pad.
- */
-#define PAL_MODE_INPUT PAL_STM32_MODE_INPUT
-
-/**
- * @brief Input pad with weak pull up resistor.
- */
-#define PAL_MODE_INPUT_PULLUP (PAL_STM32_MODE_INPUT | \
- PAL_STM32_PUPDR_PULLUP)
-
-/**
- * @brief Input pad with weak pull down resistor.
- */
-#define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \
- PAL_STM32_PUPDR_PULLDOWN)
-
-/**
- * @brief Analog input mode.
- */
-#define PAL_MODE_INPUT_ANALOG PAL_STM32_MODE_ANALOG
-
-/**
- * @brief Push-pull output pad.
- */
-#define PAL_MODE_OUTPUT_PUSHPULL (PAL_STM32_MODE_OUTPUT | \
- PAL_STM32_OTYPE_PUSHPULL)
-
-/**
- * @brief Open-drain output pad.
- */
-#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \
- PAL_STM32_OTYPE_OPENDRAIN)
-/** @} */
-
-/*===========================================================================*/
-/* I/O Ports Types and constants. */
-/*===========================================================================*/
-
-/**
- * @name Port related definitions
- * @{
- */
-/**
- * @brief Width, in bits, of an I/O port.
- */
-#define PAL_IOPORTS_WIDTH 16
-
-/**
- * @brief Whole port mask.
- * @details This macro specifies all the valid bits into a port.
- */
-#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
-/** @} */
-
-/**
- * @name Line handling macros
- * @{
- */
-/**
- * @brief Forms a line identifier.
- * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
- * of this type is platform-dependent.
- * @note In this driver the pad number is encoded in the lower 4 bits of
- * the GPIO address which are guaranteed to be zero.
- */
-#define PAL_LINE(port, pad) \
- ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
-
-/**
- * @brief Decodes a port identifier from a line identifier.
- */
-#define PAL_PORT(line) \
- ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
-
-/**
- * @brief Decodes a pad identifier from a line identifier.
- */
-#define PAL_PAD(line) \
- ((uint32_t)((uint32_t)(line) & 0x0000000FU))
-
-/**
- * @brief Value identifying an invalid line.
- */
-#define PAL_NOLINE 0U
-/** @} */
-
-/**
- * @brief Type of digital I/O port sized unsigned integer.
- */
-typedef uint32_t ioportmask_t;
-
-/**
- * @brief Type of digital I/O modes.
- */
-typedef uint32_t iomode_t;
-
-/**
- * @brief Type of an I/O line.
- */
-typedef uint32_t ioline_t;
-
-/**
- * @brief Type of an event mode.
- */
-typedef uint32_t ioeventmode_t;
-
-/**
- * @brief Type of a port Identifier.
- * @details This type can be a scalar or some kind of pointer, do not make
- * any assumption about it, use the provided macros when populating
- * variables of this type.
- */
-typedef stm32_gpio_t * ioportid_t;
-
-/**
- * @brief Type of an pad identifier.
- */
-typedef uint32_t iopadid_t;
-
-/*===========================================================================*/
-/* I/O Ports Identifiers. */
-/* The low level driver wraps the definitions already present in the STM32 */
-/* firmware library. */
-/*===========================================================================*/
-
-/**
- * @brief GPIO port A identifier.
- */
-#if STM32_HAS_GPIOA || defined(__DOXYGEN__)
-#define IOPORT1 GPIOA
-#endif
-
-/**
- * @brief GPIO port B identifier.
- */
-#if STM32_HAS_GPIOB || defined(__DOXYGEN__)
-#define IOPORT2 GPIOB
-#endif
-
-/**
- * @brief GPIO port C identifier.
- */
-#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
-#define IOPORT3 GPIOC
-#endif
-
-/**
- * @brief GPIO port D identifier.
- */
-#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
-#define IOPORT4 GPIOD
-#endif
-
-/**
- * @brief GPIO port E identifier.
- */
-#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
-#define IOPORT5 GPIOE
-#endif
-
-/**
- * @brief GPIO port F identifier.
- */
-#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
-#define IOPORT6 GPIOF
-#endif
-
-/**
- * @brief GPIO port G identifier.
- */
-#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
-#define IOPORT7 GPIOG
-#endif
-
-/**
- * @brief GPIO port H identifier.
- */
-#if STM32_HAS_GPIOH || defined(__DOXYGEN__)
-#define IOPORT8 GPIOH
-#endif
-
-/**
- * @brief GPIO port I identifier.
- */
-#if STM32_HAS_GPIOI || defined(__DOXYGEN__)
-#define IOPORT9 GPIOI
-#endif
-
-/**
- * @brief GPIO port J identifier.
- */
-#if STM32_HAS_GPIOJ || defined(__DOXYGEN__)
-#define IOPORT10 GPIOJ
-#endif
-
-/**
- * @brief GPIO port K identifier.
- */
-#if STM32_HAS_GPIOK || defined(__DOXYGEN__)
-#define IOPORT11 GPIOK
-#endif
-
-/*===========================================================================*/
-/* Implementation, some of the following macros could be implemented as */
-/* functions, if so please put them in pal_lld.c. */
-/*===========================================================================*/
-
-/**
- * @brief GPIO ports subsystem initialization.
- *
- * @notapi
- */
-#define pal_lld_init() _pal_lld_init()
-
-/**
- * @brief Reads an I/O port.
- * @details This function is implemented by reading the GPIO IDR register, the
- * implementation has no side effects.
- * @note This function is not meant to be invoked directly by the application
- * code.
- *
- * @param[in] port port identifier
- * @return The port bits.
- *
- * @notapi
- */
-#define pal_lld_readport(port) ((ioportmask_t)((port)->IDR))
-
-/**
- * @brief Reads the output latch.
- * @details This function is implemented by reading the GPIO ODR register, the
- * implementation has no side effects.
- * @note This function is not meant to be invoked directly by the application
- * code.
- *
- * @param[in] port port identifier
- * @return The latched logical states.
- *
- * @notapi
- */
-#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODR))
-
-/**
- * @brief Writes on a I/O port.
- * @details This function is implemented by writing the GPIO ODR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be written on the specified port
- *
- * @notapi
- */
-#define pal_lld_writeport(port, bits) ((port)->ODR = (uint32_t)(bits))
-
-/**
- * @brief Sets a bits mask on a I/O port.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be ORed on the specified port
- *
- * @notapi
- */
-#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits))
-
-/**
- * @brief Clears a bits mask on a I/O port.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be cleared on the specified port
- *
- * @notapi
- */
-#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits))
-
-/**
- * @brief Writes a group of bits.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] mask group mask
- * @param[in] offset the group bit offset within the port
- * @param[in] bits bits to be written. Values exceeding the group
- * width are masked.
- *
- * @notapi
- */
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \
- ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \
- (port)->BSRR.W = w; \
-}
-
-/**
- * @brief Pads group mode setup.
- * @details This function programs a pads group belonging to the same port
- * with the specified mode.
- *
- * @param[in] port port identifier
- * @param[in] mask group mask
- * @param[in] offset group bit offset within the port
- * @param[in] mode group mode
- *
- * @notapi
- */
-#define pal_lld_setgroupmode(port, mask, offset, mode) \
- _pal_lld_setgroupmode(port, mask << offset, mode)
-
-/**
- * @brief Writes a logical state on an output pad.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] bit logical value, the value must be @p PAL_LOW or
- * @p PAL_HIGH
- *
- * @notapi
- */
-#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
-
-/**
- * @brief Pad event enable.
- * @note Programming an unknown or unsupported mode is silently ignored.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] mode pad event mode
- *
- * @notapi
- */
-#define pal_lld_enablepadevent(port, pad, mode) \
- _pal_lld_enablepadevent(port, pad, mode)
-
-/**
- * @brief Pad event disable.
- * @details This function disables previously programmed event callbacks.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-#define pal_lld_disablepadevent(port, pad) \
- _pal_lld_disablepadevent(port, pad)
-
-/**
- * @brief Returns a PAL event structure associated to a pad.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-#define pal_lld_get_pad_event(port, pad) \
- &_pal_events[pad]; (void)(port)
-
-/**
- * @brief Returns a PAL event structure associated to a line.
- *
- * @param[in] line line identifier
- *
- * @notapi
- */
-#define pal_lld_get_line_event(line) \
- &_pal_events[PAL_PAD(line)]
-
-/**
- * @brief Pad event enable check.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @return Pad event status.
- * @retval false if the pad event is disabled.
- * @retval true if the pad event is enabled.
- *
- * @notapi
- */
-#define pal_lld_ispadeventenabled(port, pad) \
- (bool)((EXTI->IMR1 & (1U << (uint32_t)pad)) != 0U)
-
-#if !defined(__DOXYGEN__)
-#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
-extern palevent_t _pal_events[16];
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void _pal_lld_init(void);
- void _pal_lld_setgroupmode(ioportid_t port,
- ioportmask_t mask,
- iomode_t mode);
- void _pal_lld_enablepadevent(ioportid_t port,
- iopadid_t pad,
- ioeventmode_t mode);
- void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_PAL */
-
-#endif /* HAL_PAL_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 GPIOv2/hal_pal_lld.h
+ * @brief STM32 PAL low level driver header.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#ifndef HAL_PAL_LLD_H
+#define HAL_PAL_LLD_H
+
+#include "stm32_gpio.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+/* Specifies palInit() without parameter, required until all platforms will
+ be updated to the new style.*/
+#define PAL_NEW_INIT
+
+#undef PAL_MODE_RESET
+#undef PAL_MODE_UNCONNECTED
+#undef PAL_MODE_INPUT
+#undef PAL_MODE_INPUT_PULLUP
+#undef PAL_MODE_INPUT_PULLDOWN
+#undef PAL_MODE_INPUT_ANALOG
+#undef PAL_MODE_OUTPUT_PUSHPULL
+#undef PAL_MODE_OUTPUT_OPENDRAIN
+
+/**
+ * @name STM32-specific I/O mode flags
+ * @{
+ */
+#define PAL_STM32_MODE_MASK (3U << 0U)
+#define PAL_STM32_MODE_INPUT (0U << 0U)
+#define PAL_STM32_MODE_OUTPUT (1U << 0U)
+#define PAL_STM32_MODE_ALTERNATE (2U << 0U)
+#define PAL_STM32_MODE_ANALOG (3U << 0U)
+
+#define PAL_STM32_OTYPE_MASK (1U << 2U)
+#define PAL_STM32_OTYPE_PUSHPULL (0U << 2U)
+#define PAL_STM32_OTYPE_OPENDRAIN (1U << 2U)
+
+#define PAL_STM32_OSPEED_MASK (3U << 3U)
+#define PAL_STM32_OSPEED_LOWEST (0U << 3U)
+#if defined(STM32F0XX) || defined(STM32F30X) || defined(STM32F37X)
+#define PAL_STM32_OSPEED_MID (1U << 3U)
+#else
+#define PAL_STM32_OSPEED_MID1 (1U << 3U)
+#define PAL_STM32_OSPEED_MID2 (2U << 3U)
+#endif
+#define PAL_STM32_OSPEED_HIGHEST (3U << 3U)
+
+#define PAL_STM32_PUPDR_MASK (3U << 5U)
+#define PAL_STM32_PUPDR_FLOATING (0U << 5U)
+#define PAL_STM32_PUPDR_PULLUP (1U << 5U)
+#define PAL_STM32_PUPDR_PULLDOWN (2U << 5U)
+
+#define PAL_STM32_ALTERNATE_MASK (15U << 7U)
+#define PAL_STM32_ALTERNATE(n) ((n) << 7U)
+
+/**
+ * @brief Alternate function.
+ *
+ * @param[in] n alternate function selector
+ */
+#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \
+ PAL_STM32_ALTERNATE(n))
+/** @} */
+
+/**
+ * @name Standard I/O mode flags
+ * @{
+ */
+/**
+ * @brief Implemented as input.
+ */
+#define PAL_MODE_RESET PAL_STM32_MODE_INPUT
+
+/**
+ * @brief Implemented as input with pull-up.
+ */
+#define PAL_MODE_UNCONNECTED PAL_MODE_INPUT_PULLUP
+
+/**
+ * @brief Regular input high-Z pad.
+ */
+#define PAL_MODE_INPUT PAL_STM32_MODE_INPUT
+
+/**
+ * @brief Input pad with weak pull up resistor.
+ */
+#define PAL_MODE_INPUT_PULLUP (PAL_STM32_MODE_INPUT | \
+ PAL_STM32_PUPDR_PULLUP)
+
+/**
+ * @brief Input pad with weak pull down resistor.
+ */
+#define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \
+ PAL_STM32_PUPDR_PULLDOWN)
+
+/**
+ * @brief Analog input mode.
+ */
+#define PAL_MODE_INPUT_ANALOG PAL_STM32_MODE_ANALOG
+
+/**
+ * @brief Push-pull output pad.
+ */
+#define PAL_MODE_OUTPUT_PUSHPULL (PAL_STM32_MODE_OUTPUT | \
+ PAL_STM32_OTYPE_PUSHPULL)
+
+/**
+ * @brief Open-drain output pad.
+ */
+#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \
+ PAL_STM32_OTYPE_OPENDRAIN)
+/** @} */
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @name Port related definitions
+ * @{
+ */
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @details This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+/** @} */
+
+/**
+ * @name Line handling macros
+ * @{
+ */
+/**
+ * @brief Forms a line identifier.
+ * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
+ * of this type is platform-dependent.
+ * @note In this driver the pad number is encoded in the lower 4 bits of
+ * the GPIO address which are guaranteed to be zero.
+ */
+#define PAL_LINE(port, pad) \
+ ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
+
+/**
+ * @brief Decodes a port identifier from a line identifier.
+ */
+#define PAL_PORT(line) \
+ ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
+
+/**
+ * @brief Decodes a pad identifier from a line identifier.
+ */
+#define PAL_PAD(line) \
+ ((uint32_t)((uint32_t)(line) & 0x0000000FU))
+
+/**
+ * @brief Value identifying an invalid line.
+ */
+#define PAL_NOLINE 0U
+/** @} */
+
+/**
+ * @brief Type of digital I/O port sized unsigned integer.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Type of digital I/O modes.
+ */
+typedef uint32_t iomode_t;
+
+/**
+ * @brief Type of an I/O line.
+ */
+typedef uint32_t ioline_t;
+
+/**
+ * @brief Type of an event mode.
+ */
+typedef uint32_t ioeventmode_t;
+
+/**
+ * @brief Type of a port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef stm32_gpio_t * ioportid_t;
+
+/**
+ * @brief Type of an pad identifier.
+ */
+typedef uint32_t iopadid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/* The low level driver wraps the definitions already present in the STM32 */
+/* firmware library. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO port A identifier.
+ */
+#if STM32_HAS_GPIOA || defined(__DOXYGEN__)
+#define IOPORT1 GPIOA
+#endif
+
+/**
+ * @brief GPIO port B identifier.
+ */
+#if STM32_HAS_GPIOB || defined(__DOXYGEN__)
+#define IOPORT2 GPIOB
+#endif
+
+/**
+ * @brief GPIO port C identifier.
+ */
+#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
+#define IOPORT3 GPIOC
+#endif
+
+/**
+ * @brief GPIO port D identifier.
+ */
+#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
+#define IOPORT4 GPIOD
+#endif
+
+/**
+ * @brief GPIO port E identifier.
+ */
+#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
+#define IOPORT5 GPIOE
+#endif
+
+/**
+ * @brief GPIO port F identifier.
+ */
+#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
+#define IOPORT6 GPIOF
+#endif
+
+/**
+ * @brief GPIO port G identifier.
+ */
+#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
+#define IOPORT7 GPIOG
+#endif
+
+/**
+ * @brief GPIO port H identifier.
+ */
+#if STM32_HAS_GPIOH || defined(__DOXYGEN__)
+#define IOPORT8 GPIOH
+#endif
+
+/**
+ * @brief GPIO port I identifier.
+ */
+#if STM32_HAS_GPIOI || defined(__DOXYGEN__)
+#define IOPORT9 GPIOI
+#endif
+
+/**
+ * @brief GPIO port J identifier.
+ */
+#if STM32_HAS_GPIOJ || defined(__DOXYGEN__)
+#define IOPORT10 GPIOJ
+#endif
+
+/**
+ * @brief GPIO port K identifier.
+ */
+#if STM32_HAS_GPIOK || defined(__DOXYGEN__)
+#define IOPORT11 GPIOK
+#endif
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO ports subsystem initialization.
+ *
+ * @notapi
+ */
+#define pal_lld_init() _pal_lld_init()
+
+/**
+ * @brief Reads an I/O port.
+ * @details This function is implemented by reading the GPIO IDR register, the
+ * implementation has no side effects.
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ *
+ * @param[in] port port identifier
+ * @return The port bits.
+ *
+ * @notapi
+ */
+#define pal_lld_readport(port) ((ioportmask_t)((port)->IDR))
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the GPIO ODR register, the
+ * implementation has no side effects.
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ *
+ * @param[in] port port identifier
+ * @return The latched logical states.
+ *
+ * @notapi
+ */
+#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODR))
+
+/**
+ * @brief Writes on a I/O port.
+ * @details This function is implemented by writing the GPIO ODR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be written on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_writeport(port, bits) ((port)->ODR = (uint32_t)(bits))
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be ORed on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits))
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be cleared on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits))
+
+/**
+ * @brief Writes a group of bits.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits bits to be written. Values exceeding the group
+ * width are masked.
+ *
+ * @notapi
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) { \
+ uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \
+ ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \
+ (port)->BSRR.W = w; \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] mode group mode
+ *
+ * @notapi
+ */
+#define pal_lld_setgroupmode(port, mask, offset, mode) \
+ _pal_lld_setgroupmode(port, mask << offset, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] bit logical value, the value must be @p PAL_LOW or
+ * @p PAL_HIGH
+ *
+ * @notapi
+ */
+#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
+
+/**
+ * @brief Pad event enable.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad event mode
+ *
+ * @notapi
+ */
+#define pal_lld_enablepadevent(port, pad, mode) \
+ _pal_lld_enablepadevent(port, pad, mode)
+
+/**
+ * @brief Pad event disable.
+ * @details This function disables previously programmed event callbacks.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_disablepadevent(port, pad) \
+ _pal_lld_disablepadevent(port, pad)
+
+/**
+ * @brief Returns a PAL event structure associated to a pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_get_pad_event(port, pad) \
+ &_pal_events[pad]; (void)(port)
+
+/**
+ * @brief Returns a PAL event structure associated to a line.
+ *
+ * @param[in] line line identifier
+ *
+ * @notapi
+ */
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
+/**
+ * @brief Pad event enable check.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @return Pad event status.
+ * @retval false if the pad event is disabled.
+ * @retval true if the pad event is enabled.
+ *
+ * @notapi
+ */
+#define pal_lld_ispadeventenabled(port, pad) \
+ (bool)((EXTI->IMR1 & (1U << (uint32_t)pad)) != 0U)
+
+#if !defined(__DOXYGEN__)
+#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
+extern palevent_t _pal_events[16];
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(void);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode);
+ void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode);
+ void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_PAL */
+
+#endif /* HAL_PAL_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/stm32_gpio.h b/os/hal/ports/STM32/LLD/GPIOv2/stm32_gpio.h
index 83fd51e7ca..a0a040aabe 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/stm32_gpio.h
+++ b/os/hal/ports/STM32/LLD/GPIOv2/stm32_gpio.h
@@ -1,111 +1,111 @@
-/*
- 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 GPIOv2/stm32_gpio.h
- * @brief STM32 GPIO units common header.
- * @note This file requires definitions from the ST STM32 header file.
- *
- * @addtogroup STM32_GPIOv2
- * @{
- */
-
-#ifndef STM32_GPIO_H
-#define STM32_GPIO_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/* Discarded definitions from the ST headers, the PAL driver uses its own
- definitions in order to have an unified handling for all devices.
- Unfortunately the ST headers have no uniform definitions for the same
- objects across the various sub-families.*/
-#undef GPIOA
-#undef GPIOB
-#undef GPIOC
-#undef GPIOD
-#undef GPIOE
-#undef GPIOF
-#undef GPIOG
-#undef GPIOH
-#undef GPIOI
-#undef GPIOJ
-#undef GPIOK
-
-/**
- * @name GPIO ports definitions
- * @{
- */
-#define GPIOA ((stm32_gpio_t *)GPIOA_BASE)
-#define GPIOB ((stm32_gpio_t *)GPIOB_BASE)
-#define GPIOC ((stm32_gpio_t *)GPIOC_BASE)
-#define GPIOD ((stm32_gpio_t *)GPIOD_BASE)
-#define GPIOE ((stm32_gpio_t *)GPIOE_BASE)
-#define GPIOF ((stm32_gpio_t *)GPIOF_BASE)
-#define GPIOG ((stm32_gpio_t *)GPIOG_BASE)
-#define GPIOH ((stm32_gpio_t *)GPIOH_BASE)
-#define GPIOI ((stm32_gpio_t *)GPIOI_BASE)
-#define GPIOJ ((stm32_gpio_t *)GPIOJ_BASE)
-#define GPIOK ((stm32_gpio_t *)GPIOK_BASE)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 GPIO registers block.
- */
-typedef struct {
-
- volatile uint32_t MODER;
- volatile uint32_t OTYPER;
- volatile uint32_t OSPEEDR;
- volatile uint32_t PUPDR;
- volatile uint32_t IDR;
- volatile uint32_t ODR;
- volatile union {
- uint32_t W;
- struct {
- uint16_t set;
- uint16_t clear;
- } H;
- } BSRR;
- volatile uint32_t LOCKR;
- volatile uint32_t AFRL;
- volatile uint32_t AFRH;
-} stm32_gpio_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#endif /* STM32_GPIO_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 GPIOv2/stm32_gpio.h
+ * @brief STM32 GPIO units common header.
+ * @note This file requires definitions from the ST STM32 header file.
+ *
+ * @addtogroup STM32_GPIOv2
+ * @{
+ */
+
+#ifndef STM32_GPIO_H
+#define STM32_GPIO_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/* Discarded definitions from the ST headers, the PAL driver uses its own
+ definitions in order to have an unified handling for all devices.
+ Unfortunately the ST headers have no uniform definitions for the same
+ objects across the various sub-families.*/
+#undef GPIOA
+#undef GPIOB
+#undef GPIOC
+#undef GPIOD
+#undef GPIOE
+#undef GPIOF
+#undef GPIOG
+#undef GPIOH
+#undef GPIOI
+#undef GPIOJ
+#undef GPIOK
+
+/**
+ * @name GPIO ports definitions
+ * @{
+ */
+#define GPIOA ((stm32_gpio_t *)GPIOA_BASE)
+#define GPIOB ((stm32_gpio_t *)GPIOB_BASE)
+#define GPIOC ((stm32_gpio_t *)GPIOC_BASE)
+#define GPIOD ((stm32_gpio_t *)GPIOD_BASE)
+#define GPIOE ((stm32_gpio_t *)GPIOE_BASE)
+#define GPIOF ((stm32_gpio_t *)GPIOF_BASE)
+#define GPIOG ((stm32_gpio_t *)GPIOG_BASE)
+#define GPIOH ((stm32_gpio_t *)GPIOH_BASE)
+#define GPIOI ((stm32_gpio_t *)GPIOI_BASE)
+#define GPIOJ ((stm32_gpio_t *)GPIOJ_BASE)
+#define GPIOK ((stm32_gpio_t *)GPIOK_BASE)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 GPIO registers block.
+ */
+typedef struct {
+
+ volatile uint32_t MODER;
+ volatile uint32_t OTYPER;
+ volatile uint32_t OSPEEDR;
+ volatile uint32_t PUPDR;
+ volatile uint32_t IDR;
+ volatile uint32_t ODR;
+ volatile union {
+ uint32_t W;
+ struct {
+ uint16_t set;
+ uint16_t clear;
+ } H;
+ } BSRR;
+ volatile uint32_t LOCKR;
+ volatile uint32_t AFRL;
+ volatile uint32_t AFRH;
+} stm32_gpio_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#endif /* STM32_GPIO_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv3/driver.mk b/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
index b2db0f3139..39e4d7bb75 100644
--- a/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
+++ b/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3
diff --git a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
index 92b61b52bc..2e748bb651 100644
--- a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.c
@@ -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.
-*/
-
-/**
- * @file GPIOv3/hal_pal_lld.c
- * @brief STM32 PAL low level driver code.
- *
- * @addtogroup PAL
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_PAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Event records for the 16 GPIO EXTI channels.
- */
-palevent_t _pal_events[16];
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief PAL driver initialization.
- *
- * @notapi
- */
-void _pal_lld_init(void) {
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
- unsigned i;
-
- for (i = 0; i < 16; i++) {
- _pal_init_event(i);
- }
-#endif
-}
-
-/**
- * @brief Pads mode setup.
- * @details This function programs a pads group belonging to the same port
- * with the specified mode.
- * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum
- * speed.
- *
- * @param[in] port the port identifier
- * @param[in] mask the group mask
- * @param[in] mode the mode
- *
- * @notapi
- */
-void _pal_lld_setgroupmode(ioportid_t port,
- ioportmask_t mask,
- iomode_t mode) {
-
- uint32_t moder = (mode & PAL_STM32_MODE_MASK) >> 0;
- uint32_t otyper = (mode & PAL_STM32_OTYPE_MASK) >> 2;
- uint32_t ospeedr = (mode & PAL_STM32_OSPEED_MASK) >> 3;
- uint32_t pupdr = (mode & PAL_STM32_PUPDR_MASK) >> 5;
- uint32_t altr = (mode & PAL_STM32_ALTERNATE_MASK) >> 7;
- uint32_t ascr = (mode & PAL_STM32_ASCR_MASK) >> 11;
- uint32_t lockr = (mode & PAL_STM32_LOCKR_MASK) >> 12;
- uint32_t bit = 0;
- while (true) {
- if ((mask & 1) != 0) {
- uint32_t altrmask, m1, m2, m4;
-
- altrmask = altr << ((bit & 7) * 4);
- m1 = 1 << bit;
- m2 = 3 << (bit * 2);
- m4 = 15 << ((bit & 7) * 4);
- port->OTYPER = (port->OTYPER & ~m1) | otyper;
- port->ASCR = (port->ASCR & ~m1) | ascr;
- port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr;
- port->PUPDR = (port->PUPDR & ~m2) | pupdr;
- if ((mode & PAL_STM32_MODE_MASK) == PAL_STM32_MODE_ALTERNATE) {
- /* If going in alternate mode then the alternate number is set
- before switching mode in order to avoid glitches.*/
- if (bit < 8)
- port->AFRL = (port->AFRL & ~m4) | altrmask;
- else
- port->AFRH = (port->AFRH & ~m4) | altrmask;
- port->MODER = (port->MODER & ~m2) | moder;
- }
- else {
- /* If going into a non-alternate mode then the mode is switched
- before setting the alternate mode in order to avoid glitches.*/
- port->MODER = (port->MODER & ~m2) | moder;
- if (bit < 8)
- port->AFRL = (port->AFRL & ~m4) | altrmask;
- else
- port->AFRH = (port->AFRH & ~m4) | altrmask;
- }
- port->LOCKR = (port->LOCKR & ~m1) | lockr;
- }
- mask >>= 1;
- if (!mask)
- return;
- otyper <<= 1;
- ascr <<= 1;
- ospeedr <<= 2;
- pupdr <<= 2;
- moder <<= 2;
- bit++;
- }
-}
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
-/**
- * @brief Pad event enable.
- * @note Programming an unknown or unsupported mode is silently ignored.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] mode pad event mode
- *
- * @notapi
- */
-void _pal_lld_enablepadevent(ioportid_t port,
- iopadid_t pad,
- ioeventmode_t mode) {
-
- uint32_t padmask, cridx, croff, crmask, portidx;
-
- /* Mask of the pad.*/
- padmask = 1U << (uint32_t)pad;
-
- /* Multiple channel setting of the same channel not allowed, first disable
- it. This is done because on STM32 the same channel cannot be mapped on
- multiple ports.*/
- osalDbgAssert(((EXTI->RTSR1 & padmask) == 0U) &&
- ((EXTI->FTSR1 & padmask) == 0U), "channel already in use");
-
- /* Index and mask of the SYSCFG CR register to be used.*/
- cridx = (uint32_t)pad >> 2U;
- croff = ((uint32_t)pad & 3U) * 4U;
- crmask = ~(0xFU << croff);
-
- /* Port index is obtained assuming that GPIO ports are placed at regular
- 0x400 intervals in memory space. So far this is true for all devices.*/
- portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
-
- /* Port selection in SYSCFG.*/
- SYSCFG->EXTICR[cridx] = (SYSCFG->EXTICR[cridx] & crmask) | (portidx << croff);
-
- /* Programming edge registers.*/
- if (mode & PAL_EVENT_MODE_RISING_EDGE)
- EXTI->RTSR1 |= padmask;
- else
- EXTI->RTSR1 &= ~padmask;
- if (mode & PAL_EVENT_MODE_FALLING_EDGE)
- EXTI->FTSR1 |= padmask;
- else
- EXTI->FTSR1 &= ~padmask;
-
- /* Programming interrupt and event registers.*/
- EXTI->IMR1 |= padmask;
- EXTI->EMR1 &= ~padmask;
-}
-
-/**
- * @brief Pad event disable.
- * @details This function disables previously programmed event callbacks.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
- uint32_t padmask, rtsr1, ftsr1;
-
- rtsr1 = EXTI->RTSR1;
- ftsr1 = EXTI->FTSR1;
-
- /* Mask of the pad.*/
- padmask = 1U << (uint32_t)pad;
-
- /* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
- if (((rtsr1 | ftsr1) & padmask) != 0U) {
- uint32_t cridx, croff, crport, portidx;
-
- /* Index and mask of the SYSCFG CR register to be used.*/
- cridx = (uint32_t)pad >> 2U;
- croff = ((uint32_t)pad & 3U) * 4U;
-
- /* Port index is obtained assuming that GPIO ports are placed at regular
- 0x400 intervals in memory space. So far this is true for all devices.*/
- portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
-
- crport = (SYSCFG->EXTICR[cridx] >> croff) & 0xFU;
-
- osalDbgAssert(crport == portidx, "channel mapped on different port");
-
- /* Disabling channel.*/
- EXTI->IMR1 &= ~padmask;
- EXTI->EMR1 &= ~padmask;
- EXTI->RTSR1 = rtsr1 & ~padmask;
- EXTI->FTSR1 = ftsr1 & ~padmask;
- EXTI->PR1 = padmask;
-
-#if PAL_USE_CALLBACKS || PAL_USE_WAIT
- /* Callback cleared and/or thread reset.*/
- _pal_clear_event(pad);
-#endif
- }
-}
-#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
-
-#endif /* HAL_USE_PAL */
-
-/** @} */
+/*
+ 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 GPIOv3/hal_pal_lld.c
+ * @brief STM32 PAL low level driver code.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Event records for the 16 GPIO EXTI channels.
+ */
+palevent_t _pal_events[16];
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief PAL driver initialization.
+ *
+ * @notapi
+ */
+void _pal_lld_init(void) {
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+ unsigned i;
+
+ for (i = 0; i < 16; i++) {
+ _pal_init_event(i);
+ }
+#endif
+}
+
+/**
+ * @brief Pads mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ * @note @p PAL_MODE_UNCONNECTED is implemented as push pull at minimum
+ * speed.
+ *
+ * @param[in] port the port identifier
+ * @param[in] mask the group mask
+ * @param[in] mode the mode
+ *
+ * @notapi
+ */
+void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode) {
+
+ uint32_t moder = (mode & PAL_STM32_MODE_MASK) >> 0;
+ uint32_t otyper = (mode & PAL_STM32_OTYPE_MASK) >> 2;
+ uint32_t ospeedr = (mode & PAL_STM32_OSPEED_MASK) >> 3;
+ uint32_t pupdr = (mode & PAL_STM32_PUPDR_MASK) >> 5;
+ uint32_t altr = (mode & PAL_STM32_ALTERNATE_MASK) >> 7;
+ uint32_t ascr = (mode & PAL_STM32_ASCR_MASK) >> 11;
+ uint32_t lockr = (mode & PAL_STM32_LOCKR_MASK) >> 12;
+ uint32_t bit = 0;
+ while (true) {
+ if ((mask & 1) != 0) {
+ uint32_t altrmask, m1, m2, m4;
+
+ altrmask = altr << ((bit & 7) * 4);
+ m1 = 1 << bit;
+ m2 = 3 << (bit * 2);
+ m4 = 15 << ((bit & 7) * 4);
+ port->OTYPER = (port->OTYPER & ~m1) | otyper;
+ port->ASCR = (port->ASCR & ~m1) | ascr;
+ port->OSPEEDR = (port->OSPEEDR & ~m2) | ospeedr;
+ port->PUPDR = (port->PUPDR & ~m2) | pupdr;
+ if ((mode & PAL_STM32_MODE_MASK) == PAL_STM32_MODE_ALTERNATE) {
+ /* If going in alternate mode then the alternate number is set
+ before switching mode in order to avoid glitches.*/
+ if (bit < 8)
+ port->AFRL = (port->AFRL & ~m4) | altrmask;
+ else
+ port->AFRH = (port->AFRH & ~m4) | altrmask;
+ port->MODER = (port->MODER & ~m2) | moder;
+ }
+ else {
+ /* If going into a non-alternate mode then the mode is switched
+ before setting the alternate mode in order to avoid glitches.*/
+ port->MODER = (port->MODER & ~m2) | moder;
+ if (bit < 8)
+ port->AFRL = (port->AFRL & ~m4) | altrmask;
+ else
+ port->AFRH = (port->AFRH & ~m4) | altrmask;
+ }
+ port->LOCKR = (port->LOCKR & ~m1) | lockr;
+ }
+ mask >>= 1;
+ if (!mask)
+ return;
+ otyper <<= 1;
+ ascr <<= 1;
+ ospeedr <<= 2;
+ pupdr <<= 2;
+ moder <<= 2;
+ bit++;
+ }
+}
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
+/**
+ * @brief Pad event enable.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad event mode
+ *
+ * @notapi
+ */
+void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode) {
+
+ uint32_t padmask, cridx, croff, crmask, portidx;
+
+ /* Mask of the pad.*/
+ padmask = 1U << (uint32_t)pad;
+
+ /* Multiple channel setting of the same channel not allowed, first disable
+ it. This is done because on STM32 the same channel cannot be mapped on
+ multiple ports.*/
+ osalDbgAssert(((EXTI->RTSR1 & padmask) == 0U) &&
+ ((EXTI->FTSR1 & padmask) == 0U), "channel already in use");
+
+ /* Index and mask of the SYSCFG CR register to be used.*/
+ cridx = (uint32_t)pad >> 2U;
+ croff = ((uint32_t)pad & 3U) * 4U;
+ crmask = ~(0xFU << croff);
+
+ /* Port index is obtained assuming that GPIO ports are placed at regular
+ 0x400 intervals in memory space. So far this is true for all devices.*/
+ portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
+
+ /* Port selection in SYSCFG.*/
+ SYSCFG->EXTICR[cridx] = (SYSCFG->EXTICR[cridx] & crmask) | (portidx << croff);
+
+ /* Programming edge registers.*/
+ if (mode & PAL_EVENT_MODE_RISING_EDGE)
+ EXTI->RTSR1 |= padmask;
+ else
+ EXTI->RTSR1 &= ~padmask;
+ if (mode & PAL_EVENT_MODE_FALLING_EDGE)
+ EXTI->FTSR1 |= padmask;
+ else
+ EXTI->FTSR1 &= ~padmask;
+
+ /* Programming interrupt and event registers.*/
+ EXTI->IMR1 |= padmask;
+ EXTI->EMR1 &= ~padmask;
+}
+
+/**
+ * @brief Pad event disable.
+ * @details This function disables previously programmed event callbacks.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad) {
+ uint32_t padmask, rtsr1, ftsr1;
+
+ rtsr1 = EXTI->RTSR1;
+ ftsr1 = EXTI->FTSR1;
+
+ /* Mask of the pad.*/
+ padmask = 1U << (uint32_t)pad;
+
+ /* If either RTRS1 or FTSR1 is enabled then the channel is in use.*/
+ if (((rtsr1 | ftsr1) & padmask) != 0U) {
+ uint32_t cridx, croff, crport, portidx;
+
+ /* Index and mask of the SYSCFG CR register to be used.*/
+ cridx = (uint32_t)pad >> 2U;
+ croff = ((uint32_t)pad & 3U) * 4U;
+
+ /* Port index is obtained assuming that GPIO ports are placed at regular
+ 0x400 intervals in memory space. So far this is true for all devices.*/
+ portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 10U) & 0xFU;
+
+ crport = (SYSCFG->EXTICR[cridx] >> croff) & 0xFU;
+
+ osalDbgAssert(crport == portidx, "channel mapped on different port");
+
+ /* Disabling channel.*/
+ EXTI->IMR1 &= ~padmask;
+ EXTI->EMR1 &= ~padmask;
+ EXTI->RTSR1 = rtsr1 & ~padmask;
+ EXTI->FTSR1 = ftsr1 & ~padmask;
+ EXTI->PR1 = padmask;
+
+#if PAL_USE_CALLBACKS || PAL_USE_WAIT
+ /* Callback cleared and/or thread reset.*/
+ _pal_clear_event(pad);
+#endif
+ }
+}
+#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
+
+#endif /* HAL_USE_PAL */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h
index 9824257dba..c1f2eb210b 100644
--- a/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h
+++ b/os/hal/ports/STM32/LLD/GPIOv3/hal_pal_lld.h
@@ -1,554 +1,554 @@
-/*
- 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 GPIOv3/hal_pal_lld.h
- * @brief STM32 PAL low level driver header.
- *
- * @addtogroup PAL
- * @{
- */
-
-#ifndef HAL_PAL_LLD_H
-#define HAL_PAL_LLD_H
-
-#include "stm32_gpio.h"
-
-#if HAL_USE_PAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Unsupported modes and specific modes */
-/*===========================================================================*/
-
-/* Specifies palInit() without parameter, required until all platforms will
- be updated to the new style.*/
-#define PAL_NEW_INIT
-
-#undef PAL_MODE_RESET
-#undef PAL_MODE_UNCONNECTED
-#undef PAL_MODE_INPUT
-#undef PAL_MODE_INPUT_PULLUP
-#undef PAL_MODE_INPUT_PULLDOWN
-#undef PAL_MODE_INPUT_ANALOG
-#undef PAL_MODE_OUTPUT_PUSHPULL
-#undef PAL_MODE_OUTPUT_OPENDRAIN
-
-/**
- * @name STM32-specific I/O mode flags
- * @{
- */
-#define PAL_STM32_MODE_MASK (3U << 0U)
-#define PAL_STM32_MODE_INPUT (0U << 0U)
-#define PAL_STM32_MODE_OUTPUT (1U << 0U)
-#define PAL_STM32_MODE_ALTERNATE (2U << 0U)
-#define PAL_STM32_MODE_ANALOG (3U << 0U)
-
-#define PAL_STM32_OTYPE_MASK (1U << 2U)
-#define PAL_STM32_OTYPE_PUSHPULL (0U << 2U)
-#define PAL_STM32_OTYPE_OPENDRAIN (1U << 2U)
-
-#define PAL_STM32_OSPEED_MASK (3U << 3U)
-#define PAL_STM32_OSPEED_LOW (0U << 3U)
-#define PAL_STM32_OSPEED_MEDIUM (1U << 3U)
-#define PAL_STM32_OSPEED_FAST (2U << 3U)
-#define PAL_STM32_OSPEED_HIGH (3U << 3U)
-
-#define PAL_STM32_PUPDR_MASK (3U << 5U)
-#define PAL_STM32_PUPDR_FLOATING (0U << 5U)
-#define PAL_STM32_PUPDR_PULLUP (1U << 5U)
-#define PAL_STM32_PUPDR_PULLDOWN (2U << 5U)
-
-#define PAL_STM32_ALTERNATE_MASK (15U << 7U)
-#define PAL_STM32_ALTERNATE(n) ((n) << 7U)
-
-#define PAL_STM32_ASCR_MASK (1U << 11U)
-#define PAL_STM32_ASCR_OFF (0U << 11U)
-#define PAL_STM32_ASCR_ON (1U << 11U)
-
-#define PAL_STM32_LOCKR_MASK (1U << 12U)
-#define PAL_STM32_LOCKR_OFF (0U << 12U)
-#define PAL_STM32_LOCKR_ON (1U << 12U)
-
-/**
- * @brief Alternate function.
- *
- * @param[in] n alternate function selector
- */
-#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \
- PAL_STM32_ALTERNATE(n))
-/** @} */
-
-/**
- * @name Standard I/O mode flags
- * @{
- */
-/**
- * @brief Implemented as input.
- */
-#define PAL_MODE_RESET PAL_STM32_MODE_INPUT
-
-/**
- * @brief Implemented as analog with analog switch disabled and lock.
- */
-#define PAL_MODE_UNCONNECTED (PAL_STM32_MODE_ANALOG | \
- PAL_STM32_ASCR_OFF | \
- PAL_STM32_LOCKR_ON)
-
-/**
- * @brief Regular input high-Z pad.
- */
-#define PAL_MODE_INPUT PAL_STM32_MODE_INPUT
-
-/**
- * @brief Input pad with weak pull up resistor.
- */
-#define PAL_MODE_INPUT_PULLUP (PAL_STM32_MODE_INPUT | \
- PAL_STM32_PUPDR_PULLUP)
-
-/**
- * @brief Input pad with weak pull down resistor.
- */
-#define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \
- PAL_STM32_PUPDR_PULLDOWN)
-
-/**
- * @brief Analog input mode.
- */
-#define PAL_MODE_INPUT_ANALOG (PAL_STM32_MODE_ANALOG | \
- PAL_STM32_ASCR_ON)
-
-/**
- * @brief Push-pull output pad.
- */
-#define PAL_MODE_OUTPUT_PUSHPULL (PAL_STM32_MODE_OUTPUT | \
- PAL_STM32_OTYPE_PUSHPULL)
-
-/**
- * @brief Open-drain output pad.
- */
-#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \
- PAL_STM32_OTYPE_OPENDRAIN)
-/** @} */
-
-/* Discarded definitions from the ST headers, the PAL driver uses its own
- definitions in order to have an unified handling for all devices.
- Unfortunately the ST headers have no uniform definitions for the same
- objects across the various sub-families.*/
-#undef GPIOA
-#undef GPIOB
-#undef GPIOC
-#undef GPIOD
-#undef GPIOE
-#undef GPIOF
-#undef GPIOG
-#undef GPIOH
-#undef GPIOI
-#undef GPIOJ
-#undef GPIOK
-
-/**
- * @name GPIO ports definitions
- * @{
- */
-#define GPIOA ((stm32_gpio_t *)GPIOA_BASE)
-#define GPIOB ((stm32_gpio_t *)GPIOB_BASE)
-#define GPIOC ((stm32_gpio_t *)GPIOC_BASE)
-#define GPIOD ((stm32_gpio_t *)GPIOD_BASE)
-#define GPIOE ((stm32_gpio_t *)GPIOE_BASE)
-#define GPIOF ((stm32_gpio_t *)GPIOF_BASE)
-#define GPIOG ((stm32_gpio_t *)GPIOG_BASE)
-#define GPIOH ((stm32_gpio_t *)GPIOH_BASE)
-#define GPIOI ((stm32_gpio_t *)GPIOI_BASE)
-#define GPIOJ ((stm32_gpio_t *)GPIOJ_BASE)
-#define GPIOK ((stm32_gpio_t *)GPIOK_BASE)
-/** @} */
-
-/*===========================================================================*/
-/* I/O Ports Types and constants. */
-/*===========================================================================*/
-
-/**
- * @name Port related definitions
- * @{
- */
-/**
- * @brief Width, in bits, of an I/O port.
- */
-#define PAL_IOPORTS_WIDTH 16
-
-/**
- * @brief Whole port mask.
- * @details This macro specifies all the valid bits into a port.
- */
-#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
-/** @} */
-
-/**
- * @name Line handling macros
- * @{
- */
-/**
- * @brief Forms a line identifier.
- * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
- * of this type is platform-dependent.
- * @note In this driver the pad number is encoded in the lower 4 bits of
- * the GPIO address which are guaranteed to be zero.
- */
-#define PAL_LINE(port, pad) \
- ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
-
-/**
- * @brief Decodes a port identifier from a line identifier.
- */
-#define PAL_PORT(line) \
- ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
-
-/**
- * @brief Decodes a pad identifier from a line identifier.
- */
-#define PAL_PAD(line) \
- ((uint32_t)((uint32_t)(line) & 0x0000000FU))
-
-/**
- * @brief Value identifying an invalid line.
- */
-#define PAL_NOLINE 0U
-/** @} */
-
-/**
- * @brief Type of digital I/O port sized unsigned integer.
- */
-typedef uint32_t ioportmask_t;
-
-/**
- * @brief Type of digital I/O modes.
- */
-typedef uint32_t iomode_t;
-
-/**
- * @brief Type of an I/O line.
- */
-typedef uint32_t ioline_t;
-
-/**
- * @brief Type of an event mode.
- */
-typedef uint32_t ioeventmode_t;
-
-/**
- * @brief Type of a port Identifier.
- * @details This type can be a scalar or some kind of pointer, do not make
- * any assumption about it, use the provided macros when populating
- * variables of this type.
- */
-typedef stm32_gpio_t * ioportid_t;
-
-/**
- * @brief Type of an pad identifier.
- */
-typedef uint32_t iopadid_t;
-
-/*===========================================================================*/
-/* I/O Ports Identifiers. */
-/* The low level driver wraps the definitions already present in the STM32 */
-/* firmware library. */
-/*===========================================================================*/
-
-/**
- * @brief GPIO port A identifier.
- */
-#if STM32_HAS_GPIOA || defined(__DOXYGEN__)
-#define IOPORT1 GPIOA
-#endif
-
-/**
- * @brief GPIO port B identifier.
- */
-#if STM32_HAS_GPIOB || defined(__DOXYGEN__)
-#define IOPORT2 GPIOB
-#endif
-
-/**
- * @brief GPIO port C identifier.
- */
-#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
-#define IOPORT3 GPIOC
-#endif
-
-/**
- * @brief GPIO port D identifier.
- */
-#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
-#define IOPORT4 GPIOD
-#endif
-
-/**
- * @brief GPIO port E identifier.
- */
-#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
-#define IOPORT5 GPIOE
-#endif
-
-/**
- * @brief GPIO port F identifier.
- */
-#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
-#define IOPORT6 GPIOF
-#endif
-
-/**
- * @brief GPIO port G identifier.
- */
-#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
-#define IOPORT7 GPIOG
-#endif
-
-/**
- * @brief GPIO port H identifier.
- */
-#if STM32_HAS_GPIOH || defined(__DOXYGEN__)
-#define IOPORT8 GPIOH
-#endif
-
-/**
- * @brief GPIO port I identifier.
- */
-#if STM32_HAS_GPIOI || defined(__DOXYGEN__)
-#define IOPORT9 GPIOI
-#endif
-
-/**
- * @brief GPIO port J identifier.
- */
-#if STM32_HAS_GPIOJ || defined(__DOXYGEN__)
-#define IOPORT10 GPIOJ
-#endif
-
-/**
- * @brief GPIO port K identifier.
- */
-#if STM32_HAS_GPIOK || defined(__DOXYGEN__)
-#define IOPORT11 GPIOK
-#endif
-
-/*===========================================================================*/
-/* Implementation, some of the following macros could be implemented as */
-/* functions, if so please put them in pal_lld.c. */
-/*===========================================================================*/
-
-/**
- * @brief GPIO ports subsystem initialization.
- *
- * @notapi
- */
-#define pal_lld_init() _pal_lld_init()
-
-/**
- * @brief Reads an I/O port.
- * @details This function is implemented by reading the GPIO IDR register, the
- * implementation has no side effects.
- * @note This function is not meant to be invoked directly by the application
- * code.
- *
- * @param[in] port port identifier
- * @return The port bits.
- *
- * @notapi
- */
-#define pal_lld_readport(port) ((ioportmask_t)((port)->IDR))
-
-/**
- * @brief Reads the output latch.
- * @details This function is implemented by reading the GPIO ODR register, the
- * implementation has no side effects.
- * @note This function is not meant to be invoked directly by the application
- * code.
- *
- * @param[in] port port identifier
- * @return The latched logical states.
- *
- * @notapi
- */
-#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODR))
-
-/**
- * @brief Writes on a I/O port.
- * @details This function is implemented by writing the GPIO ODR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be written on the specified port
- *
- * @notapi
- */
-#define pal_lld_writeport(port, bits) ((port)->ODR = (uint32_t)(bits))
-
-/**
- * @brief Sets a bits mask on a I/O port.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be ORed on the specified port
- *
- * @notapi
- */
-#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits))
-
-/**
- * @brief Clears a bits mask on a I/O port.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] bits bits to be cleared on the specified port
- *
- * @notapi
- */
-#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits))
-
-/**
- * @brief Writes a group of bits.
- * @details This function is implemented by writing the GPIO BSRR register, the
- * implementation has no side effects.
- *
- * @param[in] port port identifier
- * @param[in] mask group mask
- * @param[in] offset the group bit offset within the port
- * @param[in] bits bits to be written. Values exceeding the group
- * width are masked.
- *
- * @notapi
- */
-#define pal_lld_writegroup(port, mask, offset, bits) { \
- uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \
- ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \
- (port)->BSRR.W = w; \
-}
-
-/**
- * @brief Pads group mode setup.
- * @details This function programs a pads group belonging to the same port
- * with the specified mode.
- *
- * @param[in] port port identifier
- * @param[in] mask group mask
- * @param[in] offset group bit offset within the port
- * @param[in] mode group mode
- *
- * @notapi
- */
-#define pal_lld_setgroupmode(port, mask, offset, mode) \
- _pal_lld_setgroupmode(port, mask << offset, mode)
-
-/**
- * @brief Writes a logical state on an output pad.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] bit logical value, the value must be @p PAL_LOW or
- * @p PAL_HIGH
- *
- * @notapi
- */
-#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
-
-/**
- * @brief Pad event enable.
- * @note Programming an unknown or unsupported mode is silently ignored.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @param[in] mode pad event mode
- *
- * @notapi
- */
-#define pal_lld_enablepadevent(port, pad, mode) \
- _pal_lld_enablepadevent(port, pad, mode)
-
-/**
- * @brief Pad event disable.
- * @details This function disables previously programmed event callbacks.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-#define pal_lld_disablepadevent(port, pad) \
- _pal_lld_disablepadevent(port, pad)
-
-/**
- * @brief Returns a PAL event structure associated to a pad.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- *
- * @notapi
- */
-#define pal_lld_get_pad_event(port, pad) \
- &_pal_events[pad]; (void)(port)
-
-/**
- * @brief Returns a PAL event structure associated to a line.
- *
- * @param[in] line line identifier
- *
- * @notapi
- */
-#define pal_lld_get_line_event(line) \
- &_pal_events[PAL_PAD(line)]
-
-/**
- * @brief Pad event enable check.
- *
- * @param[in] port port identifier
- * @param[in] pad pad number within the port
- * @return Pad event status.
- * @retval false if the pad event is disabled.
- * @retval true if the pad event is enabled.
- *
- * @notapi
- */
-#define pal_lld_ispadeventenabled(port, pad) \
- (bool)((EXTI->IMR1 & (1U << (uint32_t)pad)) != 0U)
-
-#if !defined(__DOXYGEN__)
-#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
-extern palevent_t _pal_events[16];
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void _pal_lld_init(void);
- void _pal_lld_setgroupmode(ioportid_t port,
- ioportmask_t mask,
- iomode_t mode);
- void _pal_lld_enablepadevent(ioportid_t port,
- iopadid_t pad,
- ioeventmode_t mode);
- void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_PAL */
-
-#endif /* HAL_PAL_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 GPIOv3/hal_pal_lld.h
+ * @brief STM32 PAL low level driver header.
+ *
+ * @addtogroup PAL
+ * @{
+ */
+
+#ifndef HAL_PAL_LLD_H
+#define HAL_PAL_LLD_H
+
+#include "stm32_gpio.h"
+
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Unsupported modes and specific modes */
+/*===========================================================================*/
+
+/* Specifies palInit() without parameter, required until all platforms will
+ be updated to the new style.*/
+#define PAL_NEW_INIT
+
+#undef PAL_MODE_RESET
+#undef PAL_MODE_UNCONNECTED
+#undef PAL_MODE_INPUT
+#undef PAL_MODE_INPUT_PULLUP
+#undef PAL_MODE_INPUT_PULLDOWN
+#undef PAL_MODE_INPUT_ANALOG
+#undef PAL_MODE_OUTPUT_PUSHPULL
+#undef PAL_MODE_OUTPUT_OPENDRAIN
+
+/**
+ * @name STM32-specific I/O mode flags
+ * @{
+ */
+#define PAL_STM32_MODE_MASK (3U << 0U)
+#define PAL_STM32_MODE_INPUT (0U << 0U)
+#define PAL_STM32_MODE_OUTPUT (1U << 0U)
+#define PAL_STM32_MODE_ALTERNATE (2U << 0U)
+#define PAL_STM32_MODE_ANALOG (3U << 0U)
+
+#define PAL_STM32_OTYPE_MASK (1U << 2U)
+#define PAL_STM32_OTYPE_PUSHPULL (0U << 2U)
+#define PAL_STM32_OTYPE_OPENDRAIN (1U << 2U)
+
+#define PAL_STM32_OSPEED_MASK (3U << 3U)
+#define PAL_STM32_OSPEED_LOW (0U << 3U)
+#define PAL_STM32_OSPEED_MEDIUM (1U << 3U)
+#define PAL_STM32_OSPEED_FAST (2U << 3U)
+#define PAL_STM32_OSPEED_HIGH (3U << 3U)
+
+#define PAL_STM32_PUPDR_MASK (3U << 5U)
+#define PAL_STM32_PUPDR_FLOATING (0U << 5U)
+#define PAL_STM32_PUPDR_PULLUP (1U << 5U)
+#define PAL_STM32_PUPDR_PULLDOWN (2U << 5U)
+
+#define PAL_STM32_ALTERNATE_MASK (15U << 7U)
+#define PAL_STM32_ALTERNATE(n) ((n) << 7U)
+
+#define PAL_STM32_ASCR_MASK (1U << 11U)
+#define PAL_STM32_ASCR_OFF (0U << 11U)
+#define PAL_STM32_ASCR_ON (1U << 11U)
+
+#define PAL_STM32_LOCKR_MASK (1U << 12U)
+#define PAL_STM32_LOCKR_OFF (0U << 12U)
+#define PAL_STM32_LOCKR_ON (1U << 12U)
+
+/**
+ * @brief Alternate function.
+ *
+ * @param[in] n alternate function selector
+ */
+#define PAL_MODE_ALTERNATE(n) (PAL_STM32_MODE_ALTERNATE | \
+ PAL_STM32_ALTERNATE(n))
+/** @} */
+
+/**
+ * @name Standard I/O mode flags
+ * @{
+ */
+/**
+ * @brief Implemented as input.
+ */
+#define PAL_MODE_RESET PAL_STM32_MODE_INPUT
+
+/**
+ * @brief Implemented as analog with analog switch disabled and lock.
+ */
+#define PAL_MODE_UNCONNECTED (PAL_STM32_MODE_ANALOG | \
+ PAL_STM32_ASCR_OFF | \
+ PAL_STM32_LOCKR_ON)
+
+/**
+ * @brief Regular input high-Z pad.
+ */
+#define PAL_MODE_INPUT PAL_STM32_MODE_INPUT
+
+/**
+ * @brief Input pad with weak pull up resistor.
+ */
+#define PAL_MODE_INPUT_PULLUP (PAL_STM32_MODE_INPUT | \
+ PAL_STM32_PUPDR_PULLUP)
+
+/**
+ * @brief Input pad with weak pull down resistor.
+ */
+#define PAL_MODE_INPUT_PULLDOWN (PAL_STM32_MODE_INPUT | \
+ PAL_STM32_PUPDR_PULLDOWN)
+
+/**
+ * @brief Analog input mode.
+ */
+#define PAL_MODE_INPUT_ANALOG (PAL_STM32_MODE_ANALOG | \
+ PAL_STM32_ASCR_ON)
+
+/**
+ * @brief Push-pull output pad.
+ */
+#define PAL_MODE_OUTPUT_PUSHPULL (PAL_STM32_MODE_OUTPUT | \
+ PAL_STM32_OTYPE_PUSHPULL)
+
+/**
+ * @brief Open-drain output pad.
+ */
+#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_STM32_MODE_OUTPUT | \
+ PAL_STM32_OTYPE_OPENDRAIN)
+/** @} */
+
+/* Discarded definitions from the ST headers, the PAL driver uses its own
+ definitions in order to have an unified handling for all devices.
+ Unfortunately the ST headers have no uniform definitions for the same
+ objects across the various sub-families.*/
+#undef GPIOA
+#undef GPIOB
+#undef GPIOC
+#undef GPIOD
+#undef GPIOE
+#undef GPIOF
+#undef GPIOG
+#undef GPIOH
+#undef GPIOI
+#undef GPIOJ
+#undef GPIOK
+
+/**
+ * @name GPIO ports definitions
+ * @{
+ */
+#define GPIOA ((stm32_gpio_t *)GPIOA_BASE)
+#define GPIOB ((stm32_gpio_t *)GPIOB_BASE)
+#define GPIOC ((stm32_gpio_t *)GPIOC_BASE)
+#define GPIOD ((stm32_gpio_t *)GPIOD_BASE)
+#define GPIOE ((stm32_gpio_t *)GPIOE_BASE)
+#define GPIOF ((stm32_gpio_t *)GPIOF_BASE)
+#define GPIOG ((stm32_gpio_t *)GPIOG_BASE)
+#define GPIOH ((stm32_gpio_t *)GPIOH_BASE)
+#define GPIOI ((stm32_gpio_t *)GPIOI_BASE)
+#define GPIOJ ((stm32_gpio_t *)GPIOJ_BASE)
+#define GPIOK ((stm32_gpio_t *)GPIOK_BASE)
+/** @} */
+
+/*===========================================================================*/
+/* I/O Ports Types and constants. */
+/*===========================================================================*/
+
+/**
+ * @name Port related definitions
+ * @{
+ */
+/**
+ * @brief Width, in bits, of an I/O port.
+ */
+#define PAL_IOPORTS_WIDTH 16
+
+/**
+ * @brief Whole port mask.
+ * @details This macro specifies all the valid bits into a port.
+ */
+#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
+/** @} */
+
+/**
+ * @name Line handling macros
+ * @{
+ */
+/**
+ * @brief Forms a line identifier.
+ * @details A port/pad pair are encoded into an @p ioline_t type. The encoding
+ * of this type is platform-dependent.
+ * @note In this driver the pad number is encoded in the lower 4 bits of
+ * the GPIO address which are guaranteed to be zero.
+ */
+#define PAL_LINE(port, pad) \
+ ((ioline_t)((uint32_t)(port)) | ((uint32_t)(pad)))
+
+/**
+ * @brief Decodes a port identifier from a line identifier.
+ */
+#define PAL_PORT(line) \
+ ((stm32_gpio_t *)(((uint32_t)(line)) & 0xFFFFFFF0U))
+
+/**
+ * @brief Decodes a pad identifier from a line identifier.
+ */
+#define PAL_PAD(line) \
+ ((uint32_t)((uint32_t)(line) & 0x0000000FU))
+
+/**
+ * @brief Value identifying an invalid line.
+ */
+#define PAL_NOLINE 0U
+/** @} */
+
+/**
+ * @brief Type of digital I/O port sized unsigned integer.
+ */
+typedef uint32_t ioportmask_t;
+
+/**
+ * @brief Type of digital I/O modes.
+ */
+typedef uint32_t iomode_t;
+
+/**
+ * @brief Type of an I/O line.
+ */
+typedef uint32_t ioline_t;
+
+/**
+ * @brief Type of an event mode.
+ */
+typedef uint32_t ioeventmode_t;
+
+/**
+ * @brief Type of a port Identifier.
+ * @details This type can be a scalar or some kind of pointer, do not make
+ * any assumption about it, use the provided macros when populating
+ * variables of this type.
+ */
+typedef stm32_gpio_t * ioportid_t;
+
+/**
+ * @brief Type of an pad identifier.
+ */
+typedef uint32_t iopadid_t;
+
+/*===========================================================================*/
+/* I/O Ports Identifiers. */
+/* The low level driver wraps the definitions already present in the STM32 */
+/* firmware library. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO port A identifier.
+ */
+#if STM32_HAS_GPIOA || defined(__DOXYGEN__)
+#define IOPORT1 GPIOA
+#endif
+
+/**
+ * @brief GPIO port B identifier.
+ */
+#if STM32_HAS_GPIOB || defined(__DOXYGEN__)
+#define IOPORT2 GPIOB
+#endif
+
+/**
+ * @brief GPIO port C identifier.
+ */
+#if STM32_HAS_GPIOC || defined(__DOXYGEN__)
+#define IOPORT3 GPIOC
+#endif
+
+/**
+ * @brief GPIO port D identifier.
+ */
+#if STM32_HAS_GPIOD || defined(__DOXYGEN__)
+#define IOPORT4 GPIOD
+#endif
+
+/**
+ * @brief GPIO port E identifier.
+ */
+#if STM32_HAS_GPIOE || defined(__DOXYGEN__)
+#define IOPORT5 GPIOE
+#endif
+
+/**
+ * @brief GPIO port F identifier.
+ */
+#if STM32_HAS_GPIOF || defined(__DOXYGEN__)
+#define IOPORT6 GPIOF
+#endif
+
+/**
+ * @brief GPIO port G identifier.
+ */
+#if STM32_HAS_GPIOG || defined(__DOXYGEN__)
+#define IOPORT7 GPIOG
+#endif
+
+/**
+ * @brief GPIO port H identifier.
+ */
+#if STM32_HAS_GPIOH || defined(__DOXYGEN__)
+#define IOPORT8 GPIOH
+#endif
+
+/**
+ * @brief GPIO port I identifier.
+ */
+#if STM32_HAS_GPIOI || defined(__DOXYGEN__)
+#define IOPORT9 GPIOI
+#endif
+
+/**
+ * @brief GPIO port J identifier.
+ */
+#if STM32_HAS_GPIOJ || defined(__DOXYGEN__)
+#define IOPORT10 GPIOJ
+#endif
+
+/**
+ * @brief GPIO port K identifier.
+ */
+#if STM32_HAS_GPIOK || defined(__DOXYGEN__)
+#define IOPORT11 GPIOK
+#endif
+
+/*===========================================================================*/
+/* Implementation, some of the following macros could be implemented as */
+/* functions, if so please put them in pal_lld.c. */
+/*===========================================================================*/
+
+/**
+ * @brief GPIO ports subsystem initialization.
+ *
+ * @notapi
+ */
+#define pal_lld_init() _pal_lld_init()
+
+/**
+ * @brief Reads an I/O port.
+ * @details This function is implemented by reading the GPIO IDR register, the
+ * implementation has no side effects.
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ *
+ * @param[in] port port identifier
+ * @return The port bits.
+ *
+ * @notapi
+ */
+#define pal_lld_readport(port) ((ioportmask_t)((port)->IDR))
+
+/**
+ * @brief Reads the output latch.
+ * @details This function is implemented by reading the GPIO ODR register, the
+ * implementation has no side effects.
+ * @note This function is not meant to be invoked directly by the application
+ * code.
+ *
+ * @param[in] port port identifier
+ * @return The latched logical states.
+ *
+ * @notapi
+ */
+#define pal_lld_readlatch(port) ((ioportmask_t)((port)->ODR))
+
+/**
+ * @brief Writes on a I/O port.
+ * @details This function is implemented by writing the GPIO ODR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be written on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_writeport(port, bits) ((port)->ODR = (uint32_t)(bits))
+
+/**
+ * @brief Sets a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be ORed on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_setport(port, bits) ((port)->BSRR.H.set = (uint16_t)(bits))
+
+/**
+ * @brief Clears a bits mask on a I/O port.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] bits bits to be cleared on the specified port
+ *
+ * @notapi
+ */
+#define pal_lld_clearport(port, bits) ((port)->BSRR.H.clear = (uint16_t)(bits))
+
+/**
+ * @brief Writes a group of bits.
+ * @details This function is implemented by writing the GPIO BSRR register, the
+ * implementation has no side effects.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset the group bit offset within the port
+ * @param[in] bits bits to be written. Values exceeding the group
+ * width are masked.
+ *
+ * @notapi
+ */
+#define pal_lld_writegroup(port, mask, offset, bits) { \
+ uint32_t w = ((~(uint32_t)(bits) & (uint32_t)(mask)) << (16U + (offset))) | \
+ ((uint32_t)(bits) & (uint32_t)(mask)) << (offset); \
+ (port)->BSRR.W = w; \
+}
+
+/**
+ * @brief Pads group mode setup.
+ * @details This function programs a pads group belonging to the same port
+ * with the specified mode.
+ *
+ * @param[in] port port identifier
+ * @param[in] mask group mask
+ * @param[in] offset group bit offset within the port
+ * @param[in] mode group mode
+ *
+ * @notapi
+ */
+#define pal_lld_setgroupmode(port, mask, offset, mode) \
+ _pal_lld_setgroupmode(port, mask << offset, mode)
+
+/**
+ * @brief Writes a logical state on an output pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] bit logical value, the value must be @p PAL_LOW or
+ * @p PAL_HIGH
+ *
+ * @notapi
+ */
+#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
+
+/**
+ * @brief Pad event enable.
+ * @note Programming an unknown or unsupported mode is silently ignored.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @param[in] mode pad event mode
+ *
+ * @notapi
+ */
+#define pal_lld_enablepadevent(port, pad, mode) \
+ _pal_lld_enablepadevent(port, pad, mode)
+
+/**
+ * @brief Pad event disable.
+ * @details This function disables previously programmed event callbacks.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_disablepadevent(port, pad) \
+ _pal_lld_disablepadevent(port, pad)
+
+/**
+ * @brief Returns a PAL event structure associated to a pad.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ *
+ * @notapi
+ */
+#define pal_lld_get_pad_event(port, pad) \
+ &_pal_events[pad]; (void)(port)
+
+/**
+ * @brief Returns a PAL event structure associated to a line.
+ *
+ * @param[in] line line identifier
+ *
+ * @notapi
+ */
+#define pal_lld_get_line_event(line) \
+ &_pal_events[PAL_PAD(line)]
+
+/**
+ * @brief Pad event enable check.
+ *
+ * @param[in] port port identifier
+ * @param[in] pad pad number within the port
+ * @return Pad event status.
+ * @retval false if the pad event is disabled.
+ * @retval true if the pad event is enabled.
+ *
+ * @notapi
+ */
+#define pal_lld_ispadeventenabled(port, pad) \
+ (bool)((EXTI->IMR1 & (1U << (uint32_t)pad)) != 0U)
+
+#if !defined(__DOXYGEN__)
+#if (PAL_USE_WAIT == TRUE) || (PAL_USE_CALLBACKS == TRUE)
+extern palevent_t _pal_events[16];
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void _pal_lld_init(void);
+ void _pal_lld_setgroupmode(ioportid_t port,
+ ioportmask_t mask,
+ iomode_t mode);
+ void _pal_lld_enablepadevent(ioportid_t port,
+ iopadid_t pad,
+ ioeventmode_t mode);
+ void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_PAL */
+
+#endif /* HAL_PAL_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv3/stm32_gpio.h b/os/hal/ports/STM32/LLD/GPIOv3/stm32_gpio.h
index c8ce1df81a..79ffa7ca87 100644
--- a/os/hal/ports/STM32/LLD/GPIOv3/stm32_gpio.h
+++ b/os/hal/ports/STM32/LLD/GPIOv3/stm32_gpio.h
@@ -1,113 +1,113 @@
-/*
- 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 GPIOv3/stm32_gpio.h
- * @brief STM32 GPIO units common header.
- * @note This file requires definitions from the ST STM32 header file.
- *
- * @addtogroup STM32_GPIOv3
- * @{
- */
-
-#ifndef STM32_GPIO_H
-#define STM32_GPIO_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/* Discarded definitions from the ST headers, the PAL driver uses its own
- definitions in order to have an unified handling for all devices.
- Unfortunately the ST headers have no uniform definitions for the same
- objects across the various sub-families.*/
-#undef GPIOA
-#undef GPIOB
-#undef GPIOC
-#undef GPIOD
-#undef GPIOE
-#undef GPIOF
-#undef GPIOG
-#undef GPIOH
-#undef GPIOI
-#undef GPIOJ
-#undef GPIOK
-
-/**
- * @name GPIO ports definitions
- * @{
- */
-#define GPIOA ((stm32_gpio_t *)GPIOA_BASE)
-#define GPIOB ((stm32_gpio_t *)GPIOB_BASE)
-#define GPIOC ((stm32_gpio_t *)GPIOC_BASE)
-#define GPIOD ((stm32_gpio_t *)GPIOD_BASE)
-#define GPIOE ((stm32_gpio_t *)GPIOE_BASE)
-#define GPIOF ((stm32_gpio_t *)GPIOF_BASE)
-#define GPIOG ((stm32_gpio_t *)GPIOG_BASE)
-#define GPIOH ((stm32_gpio_t *)GPIOH_BASE)
-#define GPIOI ((stm32_gpio_t *)GPIOI_BASE)
-#define GPIOJ ((stm32_gpio_t *)GPIOJ_BASE)
-#define GPIOK ((stm32_gpio_t *)GPIOK_BASE)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 GPIO registers block.
- */
-typedef struct {
-
- volatile uint32_t MODER;
- volatile uint32_t OTYPER;
- volatile uint32_t OSPEEDR;
- volatile uint32_t PUPDR;
- volatile uint32_t IDR;
- volatile uint32_t ODR;
- volatile union {
- uint32_t W;
- struct {
- uint16_t set;
- uint16_t clear;
- } H;
- } BSRR;
- volatile uint32_t LOCKR;
- volatile uint32_t AFRL;
- volatile uint32_t AFRH;
- volatile uint32_t BRR;
- volatile uint32_t ASCR;
-} stm32_gpio_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#endif /* STM32_GPIO_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 GPIOv3/stm32_gpio.h
+ * @brief STM32 GPIO units common header.
+ * @note This file requires definitions from the ST STM32 header file.
+ *
+ * @addtogroup STM32_GPIOv3
+ * @{
+ */
+
+#ifndef STM32_GPIO_H
+#define STM32_GPIO_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/* Discarded definitions from the ST headers, the PAL driver uses its own
+ definitions in order to have an unified handling for all devices.
+ Unfortunately the ST headers have no uniform definitions for the same
+ objects across the various sub-families.*/
+#undef GPIOA
+#undef GPIOB
+#undef GPIOC
+#undef GPIOD
+#undef GPIOE
+#undef GPIOF
+#undef GPIOG
+#undef GPIOH
+#undef GPIOI
+#undef GPIOJ
+#undef GPIOK
+
+/**
+ * @name GPIO ports definitions
+ * @{
+ */
+#define GPIOA ((stm32_gpio_t *)GPIOA_BASE)
+#define GPIOB ((stm32_gpio_t *)GPIOB_BASE)
+#define GPIOC ((stm32_gpio_t *)GPIOC_BASE)
+#define GPIOD ((stm32_gpio_t *)GPIOD_BASE)
+#define GPIOE ((stm32_gpio_t *)GPIOE_BASE)
+#define GPIOF ((stm32_gpio_t *)GPIOF_BASE)
+#define GPIOG ((stm32_gpio_t *)GPIOG_BASE)
+#define GPIOH ((stm32_gpio_t *)GPIOH_BASE)
+#define GPIOI ((stm32_gpio_t *)GPIOI_BASE)
+#define GPIOJ ((stm32_gpio_t *)GPIOJ_BASE)
+#define GPIOK ((stm32_gpio_t *)GPIOK_BASE)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 GPIO registers block.
+ */
+typedef struct {
+
+ volatile uint32_t MODER;
+ volatile uint32_t OTYPER;
+ volatile uint32_t OSPEEDR;
+ volatile uint32_t PUPDR;
+ volatile uint32_t IDR;
+ volatile uint32_t ODR;
+ volatile union {
+ uint32_t W;
+ struct {
+ uint16_t set;
+ uint16_t clear;
+ } H;
+ } BSRR;
+ volatile uint32_t LOCKR;
+ volatile uint32_t AFRL;
+ volatile uint32_t AFRH;
+ volatile uint32_t BRR;
+ volatile uint32_t ASCR;
+} stm32_gpio_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#endif /* STM32_GPIO_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/driver.mk b/os/hal/ports/STM32/LLD/I2Cv1/driver.mk
index 476dcb8b40..f8cca018e9 100644
--- a/os/hal/ports/STM32/LLD/I2Cv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/I2Cv1/driver.mk
@@ -1,21 +1,21 @@
-ifeq ($(USE_HAL_I2C_FALLBACK),yes)
- # Fallback SW driver.
- ifeq ($(USE_SMART_BUILD),yes)
- ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
- PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
- endif
- else
- PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
- endif
- PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C
-else
- # Default HW driver.
- ifeq ($(USE_SMART_BUILD),yes)
- ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
- PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
- endif
- else
- PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
- endif
- PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1
-endif
+ifeq ($(USE_HAL_I2C_FALLBACK),yes)
+ # Fallback SW driver.
+ ifeq ($(USE_SMART_BUILD),yes)
+ ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
+ PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
+ endif
+ else
+ PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
+ endif
+ PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C
+else
+ # Default HW driver.
+ ifeq ($(USE_SMART_BUILD),yes)
+ ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
+ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
+ endif
+ else
+ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
+ endif
+ PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1
+endif
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
index 3fc2289bd1..833715cf0c 100644
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
@@ -1,889 +1,889 @@
-/*
- 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 I2Cv1/hal_i2c_lld.c
- * @brief STM32 I2C subsystem low level driver source.
- *
- * @addtogroup I2C
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_I2C || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define I2C1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \
- STM32_I2C1_RX_DMA_CHN)
-
-#define I2C1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \
- STM32_I2C1_TX_DMA_CHN)
-
-#define I2C2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \
- STM32_I2C2_RX_DMA_CHN)
-
-#define I2C2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \
- STM32_I2C2_TX_DMA_CHN)
-
-#define I2C3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM, \
- STM32_I2C3_RX_DMA_CHN)
-
-#define I2C3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM, \
- STM32_I2C3_TX_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-#define I2C_EV5_MASTER_MODE_SELECT \
- ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB))
-
-#define I2C_EV5_MASTER_MODE_SELECT_NO_BUSY \
- ((uint32_t)((I2C_SR2_MSL << 16) | I2C_SR1_SB))
-
-#define I2C_EV6_MASTER_TRA_MODE_SELECTED \
- ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | \
- I2C_SR1_ADDR | I2C_SR1_TXE))
-
-#define I2C_EV6_MASTER_REC_MODE_SELECTED \
- ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR))
-
-#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED \
- ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | \
- I2C_SR1_BTF | I2C_SR1_TXE))
-
-#define I2C_EV9_MASTER_ADD10 \
- ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_ADD10))
-
-#define I2C_EV_MASK 0x00FFFFFF
-
-#define I2C_ERROR_MASK \
- ((uint16_t)(I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_OVR | \
- I2C_SR1_PECERR | I2C_SR1_TIMEOUT | I2C_SR1_SMBALERT))
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief I2C1 driver identifier.*/
-#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
-I2CDriver I2CD1;
-#endif
-
-/** @brief I2C2 driver identifier.*/
-#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
-I2CDriver I2CD2;
-#endif
-
-/** @brief I2C3 driver identifier.*/
-#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
-I2CDriver I2CD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Aborts an I2C transaction.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_abort_operation(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Stops the I2C peripheral.*/
- dp->CR1 = I2C_CR1_SWRST;
- dp->CR1 = 0;
- dp->CR2 = 0;
- dp->SR1 = 0;
-
- /* Stops the associated DMA streams.*/
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
-}
-
-/**
- * @brief Set clock speed.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_set_clock(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- uint16_t regCCR, clock_div;
- int32_t clock_speed = i2cp->config->clock_speed;
- i2cdutycycle_t duty = i2cp->config->duty_cycle;
-
- osalDbgCheck((i2cp != NULL) &&
- (clock_speed > 0) &&
- (clock_speed <= 400000));
-
- /* CR2 Configuration.*/
- dp->CR2 &= (uint16_t)~I2C_CR2_FREQ;
- dp->CR2 |= (uint16_t)I2C_CLK_FREQ;
-
- /* CCR Configuration.*/
- regCCR = 0;
- clock_div = I2C_CCR_CCR;
-
- if (clock_speed <= 100000) {
- /* Configure clock_div in standard mode.*/
- osalDbgAssert(duty == STD_DUTY_CYCLE, "invalid standard mode duty cycle");
-
- /* Standard mode clock_div calculate: Tlow/Thigh = 1/1.*/
- osalDbgAssert((STM32_PCLK1 % (clock_speed * 2)) == 0,
- "PCLK1 must be divisible without remainder");
- clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 2));
-
- osalDbgAssert(clock_div >= 0x04,
- "clock divider less then 0x04 not allowed");
- regCCR |= (clock_div & I2C_CCR_CCR);
-
- /* Sets the Maximum Rise Time for standard mode.*/
- dp->TRISE = I2C_CLK_FREQ + 1;
- }
- else if (clock_speed <= 400000) {
- /* Configure clock_div in fast mode.*/
- osalDbgAssert((duty == FAST_DUTY_CYCLE_2) ||
- (duty == FAST_DUTY_CYCLE_16_9),
- "invalid fast mode duty cycle");
-
- if (duty == FAST_DUTY_CYCLE_2) {
- /* Fast mode clock_div calculate: Tlow/Thigh = 2/1.*/
- osalDbgAssert((STM32_PCLK1 % (clock_speed * 3)) == 0,
- "PCLK1 must be divided without remainder");
- clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 3));
- }
- else if (duty == FAST_DUTY_CYCLE_16_9) {
- /* Fast mode clock_div calculate: Tlow/Thigh = 16/9.*/
- osalDbgAssert((STM32_PCLK1 % (clock_speed * 25)) == 0,
- "PCLK1 must be divided without remainder");
- clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 25));
- regCCR |= I2C_CCR_DUTY;
- }
-
- osalDbgAssert(clock_div >= 0x01,
- "clock divider less then 0x04 not allowed");
- regCCR |= (I2C_CCR_FS | (clock_div & I2C_CCR_CCR));
-
- /* Sets the Maximum Rise Time for fast mode.*/
- dp->TRISE = (I2C_CLK_FREQ * 300 / 1000) + 1;
- }
-
- osalDbgAssert((clock_div <= I2C_CCR_CCR), "the selected clock is too low");
-
- dp->CCR = regCCR;
-}
-
-/**
- * @brief Set operation mode of I2C hardware.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_set_opmode(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- i2copmode_t opmode = i2cp->config->op_mode;
- uint16_t regCR1;
-
- regCR1 = dp->CR1;
- switch (opmode) {
- case OPMODE_I2C:
- regCR1 &= (uint16_t)~(I2C_CR1_SMBUS|I2C_CR1_SMBTYPE);
- break;
- case OPMODE_SMBUS_DEVICE:
- regCR1 |= I2C_CR1_SMBUS;
- regCR1 &= (uint16_t)~(I2C_CR1_SMBTYPE);
- break;
- case OPMODE_SMBUS_HOST:
- regCR1 |= (I2C_CR1_SMBUS|I2C_CR1_SMBTYPE);
- break;
- }
- dp->CR1 = regCR1;
-}
-
-/**
- * @brief I2C shared ISR code.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- uint32_t regSR2 = dp->SR2;
- uint32_t event = dp->SR1;
-
- /* Interrupts are disabled just before dmaStreamEnable() because there
- is no need of interrupts until next transaction begin. All the work is
- done by the DMA.*/
- switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
- case I2C_EV5_MASTER_MODE_SELECT:
- case I2C_EV5_MASTER_MODE_SELECT_NO_BUSY:
- if ((i2cp->addr >> 8) > 0) {
- /* 10-bit address: 1 1 1 1 0 X X R/W */
- dp->DR = 0xF0 | (0x6 & (i2cp->addr >> 8)) | (0x1 & i2cp->addr);
- } else {
- dp->DR = i2cp->addr;
- }
- break;
- case I2C_EV9_MASTER_ADD10:
- /* Set second addr byte (10-bit addressing)*/
- dp->DR = (0xFF & (i2cp->addr >> 1));
- break;
- case I2C_EV6_MASTER_REC_MODE_SELECTED:
- dp->CR2 &= ~I2C_CR2_ITEVTEN;
- dmaStreamEnable(i2cp->dmarx);
- dp->CR2 |= I2C_CR2_LAST; /* Needed in receiver mode. */
- if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2)
- dp->CR1 &= ~I2C_CR1_ACK;
- break;
- case I2C_EV6_MASTER_TRA_MODE_SELECTED:
- dp->CR2 &= ~I2C_CR2_ITEVTEN;
- dmaStreamEnable(i2cp->dmatx);
- break;
- case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
- /* Catches BTF event after the end of transmission.*/
- (void)dp->DR; /* clear BTF.*/
- if (dmaStreamGetTransactionSize(i2cp->dmarx) > 0) {
- /* Starts "read after write" operation, LSB = 1 -> receive.*/
- i2cp->addr |= 0x01;
- dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
- return;
- }
- dp->CR2 &= ~I2C_CR2_ITEVTEN;
- dp->CR1 |= I2C_CR1_STOP;
- _i2c_wakeup_isr(i2cp);
- break;
- default:
- break;
- }
- /* Clear ADDR flag. */
- if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
- (void)dp->SR2;
-
- /* Errata 2.4.6 for STM32F40x, Spurious Bus Error detection in Master mode.*/
- if (event & I2C_SR1_BERR) {
- dp->SR1 &= ~I2C_SR1_BERR;
- }
-}
-
-/**
- * @brief DMA RX end IRQ handler.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] flags pre-shifted content of the ISR register
- *
- * @notapi
- */
-static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* DMA errors handling.*/
-#if defined(STM32_I2C_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_I2C_DMA_ERROR_HOOK(i2cp);
- }
-#else
- (void)flags;
-#endif
-
- dmaStreamDisable(i2cp->dmarx);
-
- dp->CR2 &= ~I2C_CR2_LAST;
- dp->CR1 &= ~I2C_CR1_ACK;
- dp->CR1 |= I2C_CR1_STOP;
- _i2c_wakeup_isr(i2cp);
-}
-
-/**
- * @brief DMA TX end IRQ handler.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* DMA errors handling.*/
-#if defined(STM32_I2C_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_I2C_DMA_ERROR_HOOK(i2cp);
- }
-#else
- (void)flags;
-#endif
-
- dmaStreamDisable(i2cp->dmatx);
- /* Enables interrupts to catch BTF event meaning transmission part complete.
- Interrupt handler will decide to generate STOP or to begin receiving part
- of R/W transaction itself.*/
- dp->CR2 |= I2C_CR2_ITEVTEN;
-}
-
-/**
- * @brief I2C error handler.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] sr content of the SR1 register to be decoded
- *
- * @notapi
- */
-static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) {
-
- /* Clears interrupt flags just to be safe.*/
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
-
- i2cp->errors = I2C_NO_ERROR;
-
- if (sr & I2C_SR1_BERR) { /* Bus error. */
- i2cp->errors |= I2C_BUS_ERROR;
- /* Errata 2.4.6 for STM32F40x, Spurious Bus Error detection in
- Master mode.*/
- i2cp->i2c->SR1 &= ~I2C_SR1_BERR;
- }
-
- if (sr & I2C_SR1_ARLO) /* Arbitration lost. */
- i2cp->errors |= I2C_ARBITRATION_LOST;
-
- if (sr & I2C_SR1_AF) { /* Acknowledge fail. */
- i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN;
- i2cp->i2c->CR1 |= I2C_CR1_STOP; /* Setting stop bit. */
- i2cp->errors |= I2C_ACK_FAILURE;
- }
-
- if (sr & I2C_SR1_OVR) /* Overrun. */
- i2cp->errors |= I2C_OVERRUN;
-
- if (sr & I2C_SR1_TIMEOUT) /* SMBus Timeout. */
- i2cp->errors |= I2C_TIMEOUT;
-
- if (sr & I2C_SR1_PECERR) /* PEC error. */
- i2cp->errors |= I2C_PEC_ERROR;
-
- if (sr & I2C_SR1_SMBALERT) /* SMBus alert. */
- i2cp->errors |= I2C_SMB_ALERT;
-
- /* If some error has been identified then sends wakes the waiting thread.*/
- if (i2cp->errors != I2C_NO_ERROR)
- _i2c_wakeup_error_isr(i2cp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
-/**
- * @brief I2C1 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- i2c_lld_serve_event_interrupt(&I2CD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief I2C1 error interrupt handler.
- */
-OSAL_IRQ_HANDLER(STM32_I2C1_ERROR_HANDLER) {
- uint16_t sr = I2CD1.i2c->SR1;
-
- OSAL_IRQ_PROLOGUE();
-
- I2CD1.i2c->SR1 = ~(sr & I2C_ERROR_MASK);
- i2c_lld_serve_error_interrupt(&I2CD1, sr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
-/**
- * @brief I2C2 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- i2c_lld_serve_event_interrupt(&I2CD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief I2C2 error interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C2_ERROR_HANDLER) {
- uint16_t sr = I2CD2.i2c->SR1;
-
- OSAL_IRQ_PROLOGUE();
-
- I2CD2.i2c->SR1 = ~(sr & I2C_ERROR_MASK);
- i2c_lld_serve_error_interrupt(&I2CD2, sr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
-/**
- * @brief I2C3 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- i2c_lld_serve_event_interrupt(&I2CD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief I2C3 error interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C3_ERROR_HANDLER) {
- uint16_t sr = I2CD3.i2c->SR1;
-
- OSAL_IRQ_PROLOGUE();
-
- I2CD3.i2c->SR1 = ~(sr & I2C_ERROR_MASK);
- i2c_lld_serve_error_interrupt(&I2CD3, sr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_I2C_USE_I2C3 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level I2C driver initialization.
- *
- * @notapi
- */
-void i2c_lld_init(void) {
-
-#if STM32_I2C_USE_I2C1
- i2cObjectInit(&I2CD1);
- I2CD1.thread = NULL;
- I2CD1.i2c = I2C1;
- I2CD1.dmarx = NULL;
- I2CD1.dmatx = NULL;
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2
- i2cObjectInit(&I2CD2);
- I2CD2.thread = NULL;
- I2CD2.i2c = I2C2;
- I2CD2.dmarx = NULL;
- I2CD2.dmatx = NULL;
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3
- i2cObjectInit(&I2CD3);
- I2CD3.thread = NULL;
- I2CD3.i2c = I2C3;
- I2CD3.dmarx = NULL;
- I2CD3.dmatx = NULL;
-#endif /* STM32_I2C_USE_I2C3 */
-}
-
-/**
- * @brief Configures and activates the I2C peripheral.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-void i2c_lld_start(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* If in stopped state then enables the I2C and DMA clocks.*/
- if (i2cp->state == I2C_STOP) {
-
- i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
- STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DIR_M2P;
- i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
- STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DIR_P2M;
-
-#if STM32_I2C_USE_I2C1
- if (&I2CD1 == i2cp) {
- rccResetI2C1();
-
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
- STM32_I2C_I2C1_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C1_TX_DMA_STREAM,
- STM32_I2C_I2C1_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableI2C1(true);
- nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
- nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
- }
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2
- if (&I2CD2 == i2cp) {
- rccResetI2C2();
-
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
- STM32_I2C_I2C2_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C2_TX_DMA_STREAM,
- STM32_I2C_I2C2_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableI2C2(true);
- nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
- nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
- }
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3
- if (&I2CD3 == i2cp) {
- rccResetI2C3();
-
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
- STM32_I2C_I2C3_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C3_TX_DMA_STREAM,
- STM32_I2C_I2C3_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableI2C3(true);
- nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
- nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
- }
-#endif /* STM32_I2C_USE_I2C3 */
- }
-
- /* I2C registers pointed by the DMA.*/
- dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
- dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
-
- /* Reset i2c peripheral.*/
- dp->CR1 = I2C_CR1_SWRST;
- dp->CR1 = 0;
- dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
-
- /* Setup I2C parameters.*/
- i2c_lld_set_clock(i2cp);
- i2c_lld_set_opmode(i2cp);
-
- /* Ready to go.*/
- dp->CR1 |= I2C_CR1_PE;
-}
-
-/**
- * @brief Deactivates the I2C peripheral.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-void i2c_lld_stop(I2CDriver *i2cp) {
-
- /* If not in stopped state then disables the I2C clock.*/
- if (i2cp->state != I2C_STOP) {
-
- /* I2C disable.*/
- i2c_lld_abort_operation(i2cp);
- dmaStreamFreeI(i2cp->dmatx);
- dmaStreamFreeI(i2cp->dmarx);
- i2cp->dmatx = NULL;
- i2cp->dmarx = NULL;
-
-#if STM32_I2C_USE_I2C1
- if (&I2CD1 == i2cp) {
- nvicDisableVector(I2C1_EV_IRQn);
- nvicDisableVector(I2C1_ER_IRQn);
- rccDisableI2C1();
- }
-#endif
-
-#if STM32_I2C_USE_I2C2
- if (&I2CD2 == i2cp) {
- nvicDisableVector(I2C2_EV_IRQn);
- nvicDisableVector(I2C2_ER_IRQn);
- rccDisableI2C2();
- }
-#endif
-
-#if STM32_I2C_USE_I2C3
- if (&I2CD3 == i2cp) {
- nvicDisableVector(I2C3_EV_IRQn);
- nvicDisableVector(I2C3_ER_IRQn);
- rccDisableI2C3();
- }
-#endif
- }
-}
-
-/**
- * @brief Receives data via the I2C bus as master.
- * @details Number of receiving bytes must be more than 1 on STM32F1x. This is
- * hardware restriction.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- * @param[out] rxbuf pointer to the receive buffer
- * @param[in] rxbytes number of bytes to be received
- * @param[in] timeout the number of ticks before the operation timeouts,
- * the following special values are allowed:
- * - @a TIME_INFINITE no timeout.
- * .
- * @return The operation status.
- * @retval MSG_OK if the function succeeded.
- * @retval MSG_RESET if one or more I2C errors occurred, the errors can
- * be retrieved using @p i2cGetErrors().
- * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
- * timeout the driver must be stopped and restarted
- * because the bus is in an uncertain state.
- *
- * @notapi
- */
-msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout) {
- I2C_TypeDef *dp = i2cp->i2c;
- systime_t start, end;
- msg_t msg;
-
-#if defined(STM32F1XX_I2C)
- osalDbgCheck(rxbytes > 1);
-#endif
-
- /* Resetting error flags for this transfer.*/
- i2cp->errors = I2C_NO_ERROR;
-
- /* Initializes driver fields, LSB = 1 -> receive.*/
- i2cp->addr = (addr << 1) | 0x01;
-
- /* Releases the lock from high level driver.*/
- osalSysUnlock();
-
- /* RX DMA setup.*/
- dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
- dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
- dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
-
- /* Calculating the time window for the timeout on the busy bus condition.*/
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
-
- /* Waits until BUSY flag is reset or, alternatively, for a timeout
- condition.*/
- while (true) {
- osalSysLock();
-
- /* If the bus is not busy then the operation can continue, note, the
- loop is exited in the locked state.*/
- if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
- break;
-
- /* If the system time went outside the allowed window then a timeout
- condition is returned.*/
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- dmaStreamDisable(i2cp->dmarx);
- return MSG_TIMEOUT;
- }
-
- osalSysUnlock();
- }
-
- /* Starts the operation.*/
- dp->CR2 |= I2C_CR2_ITEVTEN;
- dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
-
- /* Waits for the operation completion or a timeout.*/
- msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
- if (msg != MSG_OK) {
- dmaStreamDisable(i2cp->dmarx);
- }
-
- return msg;
-}
-
-/**
- * @brief Transmits data via the I2C bus as master.
- * @details Number of receiving bytes must be 0 or more than 1 on STM32F1x.
- * This is hardware restriction.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- * @param[in] txbuf pointer to the transmit buffer
- * @param[in] txbytes number of bytes to be transmitted
- * @param[out] rxbuf pointer to the receive buffer
- * @param[in] rxbytes number of bytes to be received
- * @param[in] timeout the number of ticks before the operation timeouts,
- * the following special values are allowed:
- * - @a TIME_INFINITE no timeout.
- * .
- * @return The operation status.
- * @retval MSG_OK if the function succeeded.
- * @retval MSG_RESET if one or more I2C errors occurred, the errors can
- * be retrieved using @p i2cGetErrors().
- * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
- * timeout the driver must be stopped and restarted
- * because the bus is in an uncertain state.
- *
- * @notapi
- */
-msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
- const uint8_t *txbuf, size_t txbytes,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout) {
- I2C_TypeDef *dp = i2cp->i2c;
- systime_t start, end;
- msg_t msg;
-
-#if defined(STM32F1XX_I2C)
- osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
-#endif
-
- /* Resetting error flags for this transfer.*/
- i2cp->errors = I2C_NO_ERROR;
-
- /* Initializes driver fields, LSB = 0 -> transmit.*/
- i2cp->addr = (addr << 1);
-
- /* Releases the lock from high level driver.*/
- osalSysUnlock();
-
- /* TX DMA setup.*/
- dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
- dmaStreamSetMemory0(i2cp->dmatx, txbuf);
- dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
-
- /* RX DMA setup.*/
- dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
- dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
- dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
-
- /* Calculating the time window for the timeout on the busy bus condition.*/
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
-
- /* Waits until BUSY flag is reset or, alternatively, for a timeout
- condition.*/
- while (true) {
- osalSysLock();
-
- /* If the bus is not busy then the operation can continue, note, the
- loop is exited in the locked state.*/
- if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
- break;
-
- /* If the system time went outside the allowed window then a timeout
- condition is returned.*/
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
- return MSG_TIMEOUT;
- }
-
- osalSysUnlock();
- }
-
- /* Starts the operation.*/
- dp->CR2 |= I2C_CR2_ITEVTEN;
- dp->CR1 |= I2C_CR1_START;
-
- /* Waits for the operation completion or a timeout.*/
- msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
- if (msg != MSG_OK) {
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
- }
-
- return msg;
-}
-
-#endif /* HAL_USE_I2C */
-
-/** @} */
+/*
+ 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 I2Cv1/hal_i2c_lld.c
+ * @brief STM32 I2C subsystem low level driver source.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define I2C1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \
+ STM32_I2C1_RX_DMA_CHN)
+
+#define I2C1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \
+ STM32_I2C1_TX_DMA_CHN)
+
+#define I2C2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \
+ STM32_I2C2_RX_DMA_CHN)
+
+#define I2C2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \
+ STM32_I2C2_TX_DMA_CHN)
+
+#define I2C3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM, \
+ STM32_I2C3_RX_DMA_CHN)
+
+#define I2C3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM, \
+ STM32_I2C3_TX_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define I2C_EV5_MASTER_MODE_SELECT \
+ ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_SB))
+
+#define I2C_EV5_MASTER_MODE_SELECT_NO_BUSY \
+ ((uint32_t)((I2C_SR2_MSL << 16) | I2C_SR1_SB))
+
+#define I2C_EV6_MASTER_TRA_MODE_SELECTED \
+ ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | \
+ I2C_SR1_ADDR | I2C_SR1_TXE))
+
+#define I2C_EV6_MASTER_REC_MODE_SELECTED \
+ ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR))
+
+#define I2C_EV8_2_MASTER_BYTE_TRANSMITTED \
+ ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | \
+ I2C_SR1_BTF | I2C_SR1_TXE))
+
+#define I2C_EV9_MASTER_ADD10 \
+ ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY) << 16) | I2C_SR1_ADD10))
+
+#define I2C_EV_MASK 0x00FFFFFF
+
+#define I2C_ERROR_MASK \
+ ((uint16_t)(I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_OVR | \
+ I2C_SR1_PECERR | I2C_SR1_TIMEOUT | I2C_SR1_SMBALERT))
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief I2C1 driver identifier.*/
+#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
+I2CDriver I2CD1;
+#endif
+
+/** @brief I2C2 driver identifier.*/
+#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
+I2CDriver I2CD2;
+#endif
+
+/** @brief I2C3 driver identifier.*/
+#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
+I2CDriver I2CD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Aborts an I2C transaction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_abort_operation(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Stops the I2C peripheral.*/
+ dp->CR1 = I2C_CR1_SWRST;
+ dp->CR1 = 0;
+ dp->CR2 = 0;
+ dp->SR1 = 0;
+
+ /* Stops the associated DMA streams.*/
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+}
+
+/**
+ * @brief Set clock speed.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_set_clock(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ uint16_t regCCR, clock_div;
+ int32_t clock_speed = i2cp->config->clock_speed;
+ i2cdutycycle_t duty = i2cp->config->duty_cycle;
+
+ osalDbgCheck((i2cp != NULL) &&
+ (clock_speed > 0) &&
+ (clock_speed <= 400000));
+
+ /* CR2 Configuration.*/
+ dp->CR2 &= (uint16_t)~I2C_CR2_FREQ;
+ dp->CR2 |= (uint16_t)I2C_CLK_FREQ;
+
+ /* CCR Configuration.*/
+ regCCR = 0;
+ clock_div = I2C_CCR_CCR;
+
+ if (clock_speed <= 100000) {
+ /* Configure clock_div in standard mode.*/
+ osalDbgAssert(duty == STD_DUTY_CYCLE, "invalid standard mode duty cycle");
+
+ /* Standard mode clock_div calculate: Tlow/Thigh = 1/1.*/
+ osalDbgAssert((STM32_PCLK1 % (clock_speed * 2)) == 0,
+ "PCLK1 must be divisible without remainder");
+ clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 2));
+
+ osalDbgAssert(clock_div >= 0x04,
+ "clock divider less then 0x04 not allowed");
+ regCCR |= (clock_div & I2C_CCR_CCR);
+
+ /* Sets the Maximum Rise Time for standard mode.*/
+ dp->TRISE = I2C_CLK_FREQ + 1;
+ }
+ else if (clock_speed <= 400000) {
+ /* Configure clock_div in fast mode.*/
+ osalDbgAssert((duty == FAST_DUTY_CYCLE_2) ||
+ (duty == FAST_DUTY_CYCLE_16_9),
+ "invalid fast mode duty cycle");
+
+ if (duty == FAST_DUTY_CYCLE_2) {
+ /* Fast mode clock_div calculate: Tlow/Thigh = 2/1.*/
+ osalDbgAssert((STM32_PCLK1 % (clock_speed * 3)) == 0,
+ "PCLK1 must be divided without remainder");
+ clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 3));
+ }
+ else if (duty == FAST_DUTY_CYCLE_16_9) {
+ /* Fast mode clock_div calculate: Tlow/Thigh = 16/9.*/
+ osalDbgAssert((STM32_PCLK1 % (clock_speed * 25)) == 0,
+ "PCLK1 must be divided without remainder");
+ clock_div = (uint16_t)(STM32_PCLK1 / (clock_speed * 25));
+ regCCR |= I2C_CCR_DUTY;
+ }
+
+ osalDbgAssert(clock_div >= 0x01,
+ "clock divider less then 0x04 not allowed");
+ regCCR |= (I2C_CCR_FS | (clock_div & I2C_CCR_CCR));
+
+ /* Sets the Maximum Rise Time for fast mode.*/
+ dp->TRISE = (I2C_CLK_FREQ * 300 / 1000) + 1;
+ }
+
+ osalDbgAssert((clock_div <= I2C_CCR_CCR), "the selected clock is too low");
+
+ dp->CCR = regCCR;
+}
+
+/**
+ * @brief Set operation mode of I2C hardware.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_set_opmode(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ i2copmode_t opmode = i2cp->config->op_mode;
+ uint16_t regCR1;
+
+ regCR1 = dp->CR1;
+ switch (opmode) {
+ case OPMODE_I2C:
+ regCR1 &= (uint16_t)~(I2C_CR1_SMBUS|I2C_CR1_SMBTYPE);
+ break;
+ case OPMODE_SMBUS_DEVICE:
+ regCR1 |= I2C_CR1_SMBUS;
+ regCR1 &= (uint16_t)~(I2C_CR1_SMBTYPE);
+ break;
+ case OPMODE_SMBUS_HOST:
+ regCR1 |= (I2C_CR1_SMBUS|I2C_CR1_SMBTYPE);
+ break;
+ }
+ dp->CR1 = regCR1;
+}
+
+/**
+ * @brief I2C shared ISR code.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ uint32_t regSR2 = dp->SR2;
+ uint32_t event = dp->SR1;
+
+ /* Interrupts are disabled just before dmaStreamEnable() because there
+ is no need of interrupts until next transaction begin. All the work is
+ done by the DMA.*/
+ switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
+ case I2C_EV5_MASTER_MODE_SELECT:
+ case I2C_EV5_MASTER_MODE_SELECT_NO_BUSY:
+ if ((i2cp->addr >> 8) > 0) {
+ /* 10-bit address: 1 1 1 1 0 X X R/W */
+ dp->DR = 0xF0 | (0x6 & (i2cp->addr >> 8)) | (0x1 & i2cp->addr);
+ } else {
+ dp->DR = i2cp->addr;
+ }
+ break;
+ case I2C_EV9_MASTER_ADD10:
+ /* Set second addr byte (10-bit addressing)*/
+ dp->DR = (0xFF & (i2cp->addr >> 1));
+ break;
+ case I2C_EV6_MASTER_REC_MODE_SELECTED:
+ dp->CR2 &= ~I2C_CR2_ITEVTEN;
+ dmaStreamEnable(i2cp->dmarx);
+ dp->CR2 |= I2C_CR2_LAST; /* Needed in receiver mode. */
+ if (dmaStreamGetTransactionSize(i2cp->dmarx) < 2)
+ dp->CR1 &= ~I2C_CR1_ACK;
+ break;
+ case I2C_EV6_MASTER_TRA_MODE_SELECTED:
+ dp->CR2 &= ~I2C_CR2_ITEVTEN;
+ dmaStreamEnable(i2cp->dmatx);
+ break;
+ case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
+ /* Catches BTF event after the end of transmission.*/
+ (void)dp->DR; /* clear BTF.*/
+ if (dmaStreamGetTransactionSize(i2cp->dmarx) > 0) {
+ /* Starts "read after write" operation, LSB = 1 -> receive.*/
+ i2cp->addr |= 0x01;
+ dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
+ return;
+ }
+ dp->CR2 &= ~I2C_CR2_ITEVTEN;
+ dp->CR1 |= I2C_CR1_STOP;
+ _i2c_wakeup_isr(i2cp);
+ break;
+ default:
+ break;
+ }
+ /* Clear ADDR flag. */
+ if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
+ (void)dp->SR2;
+
+ /* Errata 2.4.6 for STM32F40x, Spurious Bus Error detection in Master mode.*/
+ if (event & I2C_SR1_BERR) {
+ dp->SR1 &= ~I2C_SR1_BERR;
+ }
+}
+
+/**
+ * @brief DMA RX end IRQ handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* DMA errors handling.*/
+#if defined(STM32_I2C_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_I2C_DMA_ERROR_HOOK(i2cp);
+ }
+#else
+ (void)flags;
+#endif
+
+ dmaStreamDisable(i2cp->dmarx);
+
+ dp->CR2 &= ~I2C_CR2_LAST;
+ dp->CR1 &= ~I2C_CR1_ACK;
+ dp->CR1 |= I2C_CR1_STOP;
+ _i2c_wakeup_isr(i2cp);
+}
+
+/**
+ * @brief DMA TX end IRQ handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* DMA errors handling.*/
+#if defined(STM32_I2C_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_I2C_DMA_ERROR_HOOK(i2cp);
+ }
+#else
+ (void)flags;
+#endif
+
+ dmaStreamDisable(i2cp->dmatx);
+ /* Enables interrupts to catch BTF event meaning transmission part complete.
+ Interrupt handler will decide to generate STOP or to begin receiving part
+ of R/W transaction itself.*/
+ dp->CR2 |= I2C_CR2_ITEVTEN;
+}
+
+/**
+ * @brief I2C error handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] sr content of the SR1 register to be decoded
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) {
+
+ /* Clears interrupt flags just to be safe.*/
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+
+ i2cp->errors = I2C_NO_ERROR;
+
+ if (sr & I2C_SR1_BERR) { /* Bus error. */
+ i2cp->errors |= I2C_BUS_ERROR;
+ /* Errata 2.4.6 for STM32F40x, Spurious Bus Error detection in
+ Master mode.*/
+ i2cp->i2c->SR1 &= ~I2C_SR1_BERR;
+ }
+
+ if (sr & I2C_SR1_ARLO) /* Arbitration lost. */
+ i2cp->errors |= I2C_ARBITRATION_LOST;
+
+ if (sr & I2C_SR1_AF) { /* Acknowledge fail. */
+ i2cp->i2c->CR2 &= ~I2C_CR2_ITEVTEN;
+ i2cp->i2c->CR1 |= I2C_CR1_STOP; /* Setting stop bit. */
+ i2cp->errors |= I2C_ACK_FAILURE;
+ }
+
+ if (sr & I2C_SR1_OVR) /* Overrun. */
+ i2cp->errors |= I2C_OVERRUN;
+
+ if (sr & I2C_SR1_TIMEOUT) /* SMBus Timeout. */
+ i2cp->errors |= I2C_TIMEOUT;
+
+ if (sr & I2C_SR1_PECERR) /* PEC error. */
+ i2cp->errors |= I2C_PEC_ERROR;
+
+ if (sr & I2C_SR1_SMBALERT) /* SMBus alert. */
+ i2cp->errors |= I2C_SMB_ALERT;
+
+ /* If some error has been identified then sends wakes the waiting thread.*/
+ if (i2cp->errors != I2C_NO_ERROR)
+ _i2c_wakeup_error_isr(i2cp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
+/**
+ * @brief I2C1 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ i2c_lld_serve_event_interrupt(&I2CD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief I2C1 error interrupt handler.
+ */
+OSAL_IRQ_HANDLER(STM32_I2C1_ERROR_HANDLER) {
+ uint16_t sr = I2CD1.i2c->SR1;
+
+ OSAL_IRQ_PROLOGUE();
+
+ I2CD1.i2c->SR1 = ~(sr & I2C_ERROR_MASK);
+ i2c_lld_serve_error_interrupt(&I2CD1, sr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
+/**
+ * @brief I2C2 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ i2c_lld_serve_event_interrupt(&I2CD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief I2C2 error interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C2_ERROR_HANDLER) {
+ uint16_t sr = I2CD2.i2c->SR1;
+
+ OSAL_IRQ_PROLOGUE();
+
+ I2CD2.i2c->SR1 = ~(sr & I2C_ERROR_MASK);
+ i2c_lld_serve_error_interrupt(&I2CD2, sr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
+/**
+ * @brief I2C3 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ i2c_lld_serve_event_interrupt(&I2CD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief I2C3 error interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C3_ERROR_HANDLER) {
+ uint16_t sr = I2CD3.i2c->SR1;
+
+ OSAL_IRQ_PROLOGUE();
+
+ I2CD3.i2c->SR1 = ~(sr & I2C_ERROR_MASK);
+ i2c_lld_serve_error_interrupt(&I2CD3, sr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_I2C_USE_I2C3 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2C driver initialization.
+ *
+ * @notapi
+ */
+void i2c_lld_init(void) {
+
+#if STM32_I2C_USE_I2C1
+ i2cObjectInit(&I2CD1);
+ I2CD1.thread = NULL;
+ I2CD1.i2c = I2C1;
+ I2CD1.dmarx = NULL;
+ I2CD1.dmatx = NULL;
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2
+ i2cObjectInit(&I2CD2);
+ I2CD2.thread = NULL;
+ I2CD2.i2c = I2C2;
+ I2CD2.dmarx = NULL;
+ I2CD2.dmatx = NULL;
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3
+ i2cObjectInit(&I2CD3);
+ I2CD3.thread = NULL;
+ I2CD3.i2c = I2C3;
+ I2CD3.dmarx = NULL;
+ I2CD3.dmatx = NULL;
+#endif /* STM32_I2C_USE_I2C3 */
+}
+
+/**
+ * @brief Configures and activates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_start(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* If in stopped state then enables the I2C and DMA clocks.*/
+ if (i2cp->state == I2C_STOP) {
+
+ i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DIR_M2P;
+ i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DIR_P2M;
+
+#if STM32_I2C_USE_I2C1
+ if (&I2CD1 == i2cp) {
+ rccResetI2C1();
+
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
+ STM32_I2C_I2C1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C1_TX_DMA_STREAM,
+ STM32_I2C_I2C1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableI2C1(true);
+ nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
+ nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY);
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
+ }
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2
+ if (&I2CD2 == i2cp) {
+ rccResetI2C2();
+
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
+ STM32_I2C_I2C2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C2_TX_DMA_STREAM,
+ STM32_I2C_I2C2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableI2C2(true);
+ nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
+ nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY);
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
+ }
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3
+ if (&I2CD3 == i2cp) {
+ rccResetI2C3();
+
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
+ STM32_I2C_I2C3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C3_TX_DMA_STREAM,
+ STM32_I2C_I2C3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableI2C3(true);
+ nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
+ nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY);
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
+ }
+#endif /* STM32_I2C_USE_I2C3 */
+ }
+
+ /* I2C registers pointed by the DMA.*/
+ dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
+ dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
+
+ /* Reset i2c peripheral.*/
+ dp->CR1 = I2C_CR1_SWRST;
+ dp->CR1 = 0;
+ dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
+
+ /* Setup I2C parameters.*/
+ i2c_lld_set_clock(i2cp);
+ i2c_lld_set_opmode(i2cp);
+
+ /* Ready to go.*/
+ dp->CR1 |= I2C_CR1_PE;
+}
+
+/**
+ * @brief Deactivates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_stop(I2CDriver *i2cp) {
+
+ /* If not in stopped state then disables the I2C clock.*/
+ if (i2cp->state != I2C_STOP) {
+
+ /* I2C disable.*/
+ i2c_lld_abort_operation(i2cp);
+ dmaStreamFreeI(i2cp->dmatx);
+ dmaStreamFreeI(i2cp->dmarx);
+ i2cp->dmatx = NULL;
+ i2cp->dmarx = NULL;
+
+#if STM32_I2C_USE_I2C1
+ if (&I2CD1 == i2cp) {
+ nvicDisableVector(I2C1_EV_IRQn);
+ nvicDisableVector(I2C1_ER_IRQn);
+ rccDisableI2C1();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C2
+ if (&I2CD2 == i2cp) {
+ nvicDisableVector(I2C2_EV_IRQn);
+ nvicDisableVector(I2C2_ER_IRQn);
+ rccDisableI2C2();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C3
+ if (&I2CD3 == i2cp) {
+ nvicDisableVector(I2C3_EV_IRQn);
+ nvicDisableVector(I2C3_ER_IRQn);
+ rccDisableI2C3();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Receives data via the I2C bus as master.
+ * @details Number of receiving bytes must be more than 1 on STM32F1x. This is
+ * hardware restriction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval MSG_OK if the function succeeded.
+ * @retval MSG_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ systime_t start, end;
+ msg_t msg;
+
+#if defined(STM32F1XX_I2C)
+ osalDbgCheck(rxbytes > 1);
+#endif
+
+ /* Resetting error flags for this transfer.*/
+ i2cp->errors = I2C_NO_ERROR;
+
+ /* Initializes driver fields, LSB = 1 -> receive.*/
+ i2cp->addr = (addr << 1) | 0x01;
+
+ /* Releases the lock from high level driver.*/
+ osalSysUnlock();
+
+ /* RX DMA setup.*/
+ dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
+ dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
+
+ /* Calculating the time window for the timeout on the busy bus condition.*/
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
+
+ /* Waits until BUSY flag is reset or, alternatively, for a timeout
+ condition.*/
+ while (true) {
+ osalSysLock();
+
+ /* If the bus is not busy then the operation can continue, note, the
+ loop is exited in the locked state.*/
+ if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
+ break;
+
+ /* If the system time went outside the allowed window then a timeout
+ condition is returned.*/
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ dmaStreamDisable(i2cp->dmarx);
+ return MSG_TIMEOUT;
+ }
+
+ osalSysUnlock();
+ }
+
+ /* Starts the operation.*/
+ dp->CR2 |= I2C_CR2_ITEVTEN;
+ dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
+
+ /* Waits for the operation completion or a timeout.*/
+ msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
+ if (msg != MSG_OK) {
+ dmaStreamDisable(i2cp->dmarx);
+ }
+
+ return msg;
+}
+
+/**
+ * @brief Transmits data via the I2C bus as master.
+ * @details Number of receiving bytes must be 0 or more than 1 on STM32F1x.
+ * This is hardware restriction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[in] txbuf pointer to the transmit buffer
+ * @param[in] txbytes number of bytes to be transmitted
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval MSG_OK if the function succeeded.
+ * @retval MSG_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ systime_t start, end;
+ msg_t msg;
+
+#if defined(STM32F1XX_I2C)
+ osalDbgCheck((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL)));
+#endif
+
+ /* Resetting error flags for this transfer.*/
+ i2cp->errors = I2C_NO_ERROR;
+
+ /* Initializes driver fields, LSB = 0 -> transmit.*/
+ i2cp->addr = (addr << 1);
+
+ /* Releases the lock from high level driver.*/
+ osalSysUnlock();
+
+ /* TX DMA setup.*/
+ dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
+ dmaStreamSetMemory0(i2cp->dmatx, txbuf);
+ dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
+
+ /* RX DMA setup.*/
+ dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
+ dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
+
+ /* Calculating the time window for the timeout on the busy bus condition.*/
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
+
+ /* Waits until BUSY flag is reset or, alternatively, for a timeout
+ condition.*/
+ while (true) {
+ osalSysLock();
+
+ /* If the bus is not busy then the operation can continue, note, the
+ loop is exited in the locked state.*/
+ if (!(dp->SR2 & I2C_SR2_BUSY) && !(dp->CR1 & I2C_CR1_STOP))
+ break;
+
+ /* If the system time went outside the allowed window then a timeout
+ condition is returned.*/
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+ return MSG_TIMEOUT;
+ }
+
+ osalSysUnlock();
+ }
+
+ /* Starts the operation.*/
+ dp->CR2 |= I2C_CR2_ITEVTEN;
+ dp->CR1 |= I2C_CR1_START;
+
+ /* Waits for the operation completion or a timeout.*/
+ msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
+ if (msg != MSG_OK) {
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+ }
+
+ return msg;
+}
+
+#endif /* HAL_USE_I2C */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
index 1328d47686..5ac9b03cf5 100644
--- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
+++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
@@ -1,513 +1,513 @@
-/*
- 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 I2Cv1/hal_i2c_lld.h
- * @brief STM32 I2C subsystem low level driver header.
- *
- * @addtogroup I2C
- * @{
- */
-
-#ifndef HAL_I2C_LLD_H
-#define HAL_I2C_LLD_H
-
-#if HAL_USE_I2C || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Peripheral clock frequency.
- */
-#define I2C_CLK_FREQ ((STM32_PCLK1) / 1000000)
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief I2C1 driver enable switch.
- * @details If set to @p TRUE the support for I2C1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C1 FALSE
-#endif
-
-/**
- * @brief I2C2 driver enable switch.
- * @details If set to @p TRUE the support for I2C2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C2 FALSE
-#endif
-
-/**
- * @brief I2C3 driver enable switch.
- * @details If set to @p TRUE the support for I2C3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C3 FALSE
-#endif
-
-/**
- * @brief I2C timeout on busy condition in milliseconds.
- */
-#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_I2C_BUSY_TIMEOUT 50
-#endif
-
-/**
- * @brief I2C1 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C2 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C3 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_IRQ_PRIORITY 10
-#endif
-
-/**
-* @brief I2C1 DMA priority (0..3|lowest..highest).
-* @note The priority level is used for both the TX and RX DMA streams but
-* because of the streams ordering the RX stream has always priority
-* over the TX stream.
-*/
-#if !defined(STM32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_DMA_PRIORITY 1
-#endif
-
-/**
-* @brief I2C2 DMA priority (0..3|lowest..highest).
-* @note The priority level is used for both the TX and RX DMA streams but
-* because of the streams ordering the RX stream has always priority
-* over the TX stream.
-*/
-#if !defined(STM32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_DMA_PRIORITY 1
-#endif
-
-/**
-* @brief I2C3 DMA priority (0..3|lowest..highest).
-* @note The priority level is used for both the TX and RX DMA streams but
-* because of the streams ordering the RX stream has always priority
-* over the TX stream.
-*/
-#if !defined(STM32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
-#endif
-
-#if STM32_ADVANCED_DMA || defined(__DOXYGEN__)
-
-/**
- * @brief DMA stream used for I2C1 RX operations.
- * @note This option is only available on platforms with enhanced DMA.
- */
-#if !defined(STM32_I2C_I2C1_RX_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
-#endif
-
-/**
- * @brief DMA stream used for I2C1 TX operations.
- * @note This option is only available on platforms with enhanced DMA.
- */
-#if !defined(STM32_I2C_I2C1_TX_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#endif
-
-/**
- * @brief DMA stream used for I2C2 RX operations.
- * @note This option is only available on platforms with enhanced DMA.
- */
-#if !defined(STM32_I2C_I2C2_RX_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#endif
-
-/**
- * @brief DMA stream used for I2C2 TX operations.
- * @note This option is only available on platforms with enhanced DMA.
- */
-#if !defined(STM32_I2C_I2C2_TX_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#endif
-
-/**
- * @brief DMA stream used for I2C3 RX operations.
- * @note This option is only available on platforms with enhanced DMA.
- */
-#if !defined(STM32_I2C_I2C3_RX_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#endif
-
-/**
- * @brief DMA stream used for I2C3 TX operations.
- * @note This option is only available on platforms with enhanced DMA.
- */
-#if !defined(STM32_I2C_I2C3_TX_DMA_STREAM) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#endif
-
-#else /* !STM32_ADVANCED_DMA */
-
-/* Fixed streams for platforms using the old DMA peripheral, the values are
- valid for both STM32F1xx and STM32L1xx.*/
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#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, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#endif /* !STM32_ADVANCED_DMA*/
-
-/* Flag for the whole STM32F1XX family. */
-#if defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \
- defined(STM32F10X_HD_VL) || defined(STM32F10X_LD) || \
- defined(STM32F10X_MD) || defined(STM32F10X_HD) || \
- defined(STM32F10X_XL) || defined(STM32F10X_CL)
-#define STM32F1XX_I2C
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/** @brief error checks */
-#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
-#error "I2C1 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
-#error "I2C2 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
-#error "I2C3 not present in the selected device"
-#endif
-
-#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && \
- !STM32_I2C_USE_I2C3
-#error "I2C driver activated but no I2C peripheral assigned"
-#endif
-
-#if STM32_I2C_USE_I2C1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C1"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C2"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C3"
-#endif
-
-#if STM32_I2C_USE_I2C1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C1"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C2"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C3"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_I2C_USE_I2C1 && (!defined(STM32_I2C_I2C1_RX_DMA_STREAM) || \
- !defined(STM32_I2C_I2C1_TX_DMA_STREAM))
-#error "I2C1 DMA streams not defined"
-#endif
-
-#if STM32_I2C_USE_I2C2 && (!defined(STM32_I2C_I2C2_RX_DMA_STREAM) || \
- !defined(STM32_I2C_I2C2_TX_DMA_STREAM))
-#error "I2C2 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_I2C_USE_I2C1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \
- STM32_I2C1_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C1 RX"
-#endif
-
-#if STM32_I2C_USE_I2C1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \
- STM32_I2C1_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C1 TX"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \
- STM32_I2C2_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C2 RX"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \
- STM32_I2C2_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C2 TX"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \
- STM32_I2C3_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C3 RX"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \
- STM32_I2C3_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C3 TX"
-#endif
-#endif /* STM32_ADVANCED_DMA */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/* Check clock range. */
-#if defined(STM32F4XX)
-#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 42)
-#error "I2C peripheral clock frequency out of range."
-#endif
-
-#elif defined(STM32L1XX)
-#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 32)
-#error "I2C peripheral clock frequency out of range."
-#endif
-
-#elif defined(STM32F2XX)
-#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 30)
-#error "I2C peripheral clock frequency out of range."
-#endif
-
-#elif defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \
- defined(STM32F10X_HD_VL)
-#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 24)
-#error "I2C peripheral clock frequency out of range."
-#endif
-
-#elif defined(STM32F10X_LD) || defined(STM32F10X_MD) || \
- defined(STM32F10X_HD) || defined(STM32F10X_XL) || \
- defined(STM32F10X_CL)
-#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 36)
-#error "I2C peripheral clock frequency out of range."
-#endif
-#else
-#error "unspecified, unsupported or invalid STM32 platform"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type representing an I2C address.
- */
-typedef uint16_t i2caddr_t;
-
-/**
- * @brief Type of I2C driver condition flags.
- */
-typedef uint32_t i2cflags_t;
-
-/**
- * @brief Supported modes for the I2C bus.
- */
-typedef enum {
- OPMODE_I2C = 1,
- OPMODE_SMBUS_DEVICE = 2,
- OPMODE_SMBUS_HOST = 3,
-} i2copmode_t;
-
-/**
- * @brief Supported duty cycle modes for the I2C bus.
- */
-typedef enum {
- STD_DUTY_CYCLE = 1,
- FAST_DUTY_CYCLE_2 = 2,
- FAST_DUTY_CYCLE_16_9 = 3,
-} i2cdutycycle_t;
-
-/**
- * @brief Type of I2C driver configuration structure.
- */
-typedef struct {
- /* End of the mandatory fields.*/
- i2copmode_t op_mode; /**< @brief Specifies the I2C mode. */
- uint32_t clock_speed; /**< @brief Specifies the clock frequency.
- @note Must be set to a value lower
- than 400kHz. */
- i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode
- duty cycle. */
-} I2CConfig;
-
-/**
- * @brief Type of a structure representing an I2C driver.
- */
-typedef struct I2CDriver I2CDriver;
-
-/**
- * @brief Structure representing an I2C driver.
- */
-struct I2CDriver {
- /**
- * @brief Driver state.
- */
- i2cstate_t state;
- /**
- * @brief Current configuration data.
- */
- const I2CConfig *config;
- /**
- * @brief Error flags.
- */
- i2cflags_t errors;
-#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
- /**
- * @brief Mutex protecting the bus.
- */
- mutex_t mutex;
-#endif /* I2C_USE_MUTUAL_EXCLUSION */
-#if defined(I2C_DRIVER_EXT_FIELDS)
- I2C_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion.
- */
- thread_reference_t thread;
- /**
- * @brief Current slave address without R/W bit.
- */
- i2caddr_t addr;
- /**
- * @brief RX DMA mode bit mask.
- */
- uint32_t rxdmamode;
- /**
- * @brief TX DMA mode bit mask.
- */
- uint32_t txdmamode;
- /**
- * @brief Receive DMA channel.
- */
- const stm32_dma_stream_t *dmarx;
- /**
- * @brief Transmit DMA channel.
- */
- const stm32_dma_stream_t *dmatx;
- /**
- * @brief Pointer to the I2Cx registers block.
- */
- I2C_TypeDef *i2c;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Get errors from I2C driver.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-#if STM32_I2C_USE_I2C1
-extern I2CDriver I2CD1;
-#endif
-
-#if STM32_I2C_USE_I2C2
-extern I2CDriver I2CD2;
-#endif
-
-#if STM32_I2C_USE_I2C3
-extern I2CDriver I2CD3;
-#endif
-#endif /* !defined(__DOXYGEN__) */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void i2c_lld_init(void);
- void i2c_lld_start(I2CDriver *i2cp);
- void i2c_lld_stop(I2CDriver *i2cp);
- msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
- const uint8_t *txbuf, size_t txbytes,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout);
- msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_I2C */
-
-#endif /* HAL_I2C_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 I2Cv1/hal_i2c_lld.h
+ * @brief STM32 I2C subsystem low level driver header.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#ifndef HAL_I2C_LLD_H
+#define HAL_I2C_LLD_H
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Peripheral clock frequency.
+ */
+#define I2C_CLK_FREQ ((STM32_PCLK1) / 1000000)
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2C1 driver enable switch.
+ * @details If set to @p TRUE the support for I2C1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C1 FALSE
+#endif
+
+/**
+ * @brief I2C2 driver enable switch.
+ * @details If set to @p TRUE the support for I2C2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C2 FALSE
+#endif
+
+/**
+ * @brief I2C3 driver enable switch.
+ * @details If set to @p TRUE the support for I2C3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C3 FALSE
+#endif
+
+/**
+ * @brief I2C timeout on busy condition in milliseconds.
+ */
+#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_I2C_BUSY_TIMEOUT 50
+#endif
+
+/**
+ * @brief I2C1 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C2 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C3 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_IRQ_PRIORITY 10
+#endif
+
+/**
+* @brief I2C1 DMA priority (0..3|lowest..highest).
+* @note The priority level is used for both the TX and RX DMA streams but
+* because of the streams ordering the RX stream has always priority
+* over the TX stream.
+*/
+#if !defined(STM32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#endif
+
+/**
+* @brief I2C2 DMA priority (0..3|lowest..highest).
+* @note The priority level is used for both the TX and RX DMA streams but
+* because of the streams ordering the RX stream has always priority
+* over the TX stream.
+*/
+#if !defined(STM32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#endif
+
+/**
+* @brief I2C3 DMA priority (0..3|lowest..highest).
+* @note The priority level is used for both the TX and RX DMA streams but
+* because of the streams ordering the RX stream has always priority
+* over the TX stream.
+*/
+#if !defined(STM32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+#endif
+
+#if STM32_ADVANCED_DMA || defined(__DOXYGEN__)
+
+/**
+ * @brief DMA stream used for I2C1 RX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2C_I2C1_RX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
+#endif
+
+/**
+ * @brief DMA stream used for I2C1 TX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2C_I2C1_TX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#endif
+
+/**
+ * @brief DMA stream used for I2C2 RX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2C_I2C2_RX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#endif
+
+/**
+ * @brief DMA stream used for I2C2 TX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2C_I2C2_TX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#endif
+
+/**
+ * @brief DMA stream used for I2C3 RX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2C_I2C3_RX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#endif
+
+/**
+ * @brief DMA stream used for I2C3 TX operations.
+ * @note This option is only available on platforms with enhanced DMA.
+ */
+#if !defined(STM32_I2C_I2C3_TX_DMA_STREAM) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#endif
+
+#else /* !STM32_ADVANCED_DMA */
+
+/* Fixed streams for platforms using the old DMA peripheral, the values are
+ valid for both STM32F1xx and STM32L1xx.*/
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#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, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#endif /* !STM32_ADVANCED_DMA*/
+
+/* Flag for the whole STM32F1XX family. */
+#if defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \
+ defined(STM32F10X_HD_VL) || defined(STM32F10X_LD) || \
+ defined(STM32F10X_MD) || defined(STM32F10X_HD) || \
+ defined(STM32F10X_XL) || defined(STM32F10X_CL)
+#define STM32F1XX_I2C
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/** @brief error checks */
+#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
+#error "I2C1 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
+#error "I2C2 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
+#error "I2C3 not present in the selected device"
+#endif
+
+#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && \
+ !STM32_I2C_USE_I2C3
+#error "I2C driver activated but no I2C peripheral assigned"
+#endif
+
+#if STM32_I2C_USE_I2C1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C1"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C2"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C3"
+#endif
+
+#if STM32_I2C_USE_I2C1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C1"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C2"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C3"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_I2C_USE_I2C1 && (!defined(STM32_I2C_I2C1_RX_DMA_STREAM) || \
+ !defined(STM32_I2C_I2C1_TX_DMA_STREAM))
+#error "I2C1 DMA streams not defined"
+#endif
+
+#if STM32_I2C_USE_I2C2 && (!defined(STM32_I2C_I2C2_RX_DMA_STREAM) || \
+ !defined(STM32_I2C_I2C2_TX_DMA_STREAM))
+#error "I2C2 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_I2C_USE_I2C1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \
+ STM32_I2C1_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C1 RX"
+#endif
+
+#if STM32_I2C_USE_I2C1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \
+ STM32_I2C1_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C1 TX"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \
+ STM32_I2C2_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C2 RX"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \
+ STM32_I2C2_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C2 TX"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \
+ STM32_I2C3_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C3 RX"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \
+ STM32_I2C3_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C3 TX"
+#endif
+#endif /* STM32_ADVANCED_DMA */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/* Check clock range. */
+#if defined(STM32F4XX)
+#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 42)
+#error "I2C peripheral clock frequency out of range."
+#endif
+
+#elif defined(STM32L1XX)
+#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 32)
+#error "I2C peripheral clock frequency out of range."
+#endif
+
+#elif defined(STM32F2XX)
+#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 30)
+#error "I2C peripheral clock frequency out of range."
+#endif
+
+#elif defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \
+ defined(STM32F10X_HD_VL)
+#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 24)
+#error "I2C peripheral clock frequency out of range."
+#endif
+
+#elif defined(STM32F10X_LD) || defined(STM32F10X_MD) || \
+ defined(STM32F10X_HD) || defined(STM32F10X_XL) || \
+ defined(STM32F10X_CL)
+#if !(I2C_CLK_FREQ >= 2) && (I2C_CLK_FREQ <= 36)
+#error "I2C peripheral clock frequency out of range."
+#endif
+#else
+#error "unspecified, unsupported or invalid STM32 platform"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type representing an I2C address.
+ */
+typedef uint16_t i2caddr_t;
+
+/**
+ * @brief Type of I2C driver condition flags.
+ */
+typedef uint32_t i2cflags_t;
+
+/**
+ * @brief Supported modes for the I2C bus.
+ */
+typedef enum {
+ OPMODE_I2C = 1,
+ OPMODE_SMBUS_DEVICE = 2,
+ OPMODE_SMBUS_HOST = 3,
+} i2copmode_t;
+
+/**
+ * @brief Supported duty cycle modes for the I2C bus.
+ */
+typedef enum {
+ STD_DUTY_CYCLE = 1,
+ FAST_DUTY_CYCLE_2 = 2,
+ FAST_DUTY_CYCLE_16_9 = 3,
+} i2cdutycycle_t;
+
+/**
+ * @brief Type of I2C driver configuration structure.
+ */
+typedef struct {
+ /* End of the mandatory fields.*/
+ i2copmode_t op_mode; /**< @brief Specifies the I2C mode. */
+ uint32_t clock_speed; /**< @brief Specifies the clock frequency.
+ @note Must be set to a value lower
+ than 400kHz. */
+ i2cdutycycle_t duty_cycle; /**< @brief Specifies the I2C fast mode
+ duty cycle. */
+} I2CConfig;
+
+/**
+ * @brief Type of a structure representing an I2C driver.
+ */
+typedef struct I2CDriver I2CDriver;
+
+/**
+ * @brief Structure representing an I2C driver.
+ */
+struct I2CDriver {
+ /**
+ * @brief Driver state.
+ */
+ i2cstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const I2CConfig *config;
+ /**
+ * @brief Error flags.
+ */
+ i2cflags_t errors;
+#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the bus.
+ */
+ mutex_t mutex;
+#endif /* I2C_USE_MUTUAL_EXCLUSION */
+#if defined(I2C_DRIVER_EXT_FIELDS)
+ I2C_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion.
+ */
+ thread_reference_t thread;
+ /**
+ * @brief Current slave address without R/W bit.
+ */
+ i2caddr_t addr;
+ /**
+ * @brief RX DMA mode bit mask.
+ */
+ uint32_t rxdmamode;
+ /**
+ * @brief TX DMA mode bit mask.
+ */
+ uint32_t txdmamode;
+ /**
+ * @brief Receive DMA channel.
+ */
+ const stm32_dma_stream_t *dmarx;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const stm32_dma_stream_t *dmatx;
+ /**
+ * @brief Pointer to the I2Cx registers block.
+ */
+ I2C_TypeDef *i2c;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Get errors from I2C driver.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+#if STM32_I2C_USE_I2C1
+extern I2CDriver I2CD1;
+#endif
+
+#if STM32_I2C_USE_I2C2
+extern I2CDriver I2CD2;
+#endif
+
+#if STM32_I2C_USE_I2C3
+extern I2CDriver I2CD3;
+#endif
+#endif /* !defined(__DOXYGEN__) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2c_lld_init(void);
+ void i2c_lld_start(I2CDriver *i2cp);
+ void i2c_lld_stop(I2CDriver *i2cp);
+ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout);
+ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2C */
+
+#endif /* HAL_I2C_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/I2Cv2/driver.mk b/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
index 69b63ced67..06fb82ff8f 100644
--- a/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
@@ -1,21 +1,21 @@
-ifeq ($(USE_HAL_I2C_FALLBACK),yes)
- # Fallback SW driver.
- ifeq ($(USE_SMART_BUILD),yes)
- ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
- PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
- endif
- else
- PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
- endif
- PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C
-else
- # Default HW driver.
- ifeq ($(USE_SMART_BUILD),yes)
- ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
- PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
- endif
- else
- PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
- endif
- PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2
-endif
+ifeq ($(USE_HAL_I2C_FALLBACK),yes)
+ # Fallback SW driver.
+ ifeq ($(USE_SMART_BUILD),yes)
+ ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
+ PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
+ endif
+ else
+ PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
+ endif
+ PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C
+else
+ # Default HW driver.
+ ifeq ($(USE_SMART_BUILD),yes)
+ ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
+ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
+ endif
+ else
+ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
+ endif
+ PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2
+endif
diff --git a/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c b/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
index 06c285834a..8ce2be7666 100644
--- a/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
+++ b/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.c
@@ -1,1169 +1,1169 @@
-/*
- 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 I2Cv2/hal_i2c_lld.c
- * @brief STM32 I2C subsystem low level driver source.
- *
- * @addtogroup I2C
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_I2C || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if STM32_I2C_USE_DMA == TRUE
-#define DMAMODE_COMMON \
- (STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | \
- STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE | \
- STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE)
-
-#define I2C1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \
- STM32_I2C1_RX_DMA_CHN)
-
-#define I2C1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \
- STM32_I2C1_TX_DMA_CHN)
-
-#define I2C2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \
- STM32_I2C2_RX_DMA_CHN)
-
-#define I2C2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \
- STM32_I2C2_TX_DMA_CHN)
-
-#define I2C3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM, \
- STM32_I2C3_RX_DMA_CHN)
-
-#define I2C3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM, \
- STM32_I2C3_TX_DMA_CHN)
-
-#define I2C4_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C4_RX_DMA_STREAM, \
- STM32_I2C4_RX_DMA_CHN)
-
-#define I2C4_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2C_I2C4_TX_DMA_STREAM, \
- STM32_I2C4_TX_DMA_CHN)
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if STM32_I2C_USE_DMA == TRUE
-#define i2c_lld_get_rxbytes(i2cp) dmaStreamGetTransactionSize((i2cp)->dmarx)
-#define i2c_lld_get_txbytes(i2cp) dmaStreamGetTransactionSize((i2cp)->dmatx)
-#else
-#define i2c_lld_get_rxbytes(i2cp) (i2cp)->rxbytes
-#define i2c_lld_get_txbytes(i2cp) (i2cp)->txbytes
-#endif
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-#define I2C_ERROR_MASK \
- ((uint32_t)(I2C_ISR_BERR | I2C_ISR_ARLO | I2C_ISR_OVR | I2C_ISR_PECERR | \
- I2C_ISR_TIMEOUT | I2C_ISR_ALERT))
-
-#define I2C_INT_MASK \
- ((uint32_t)(I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF | \
- I2C_ISR_ADDR | I2C_ISR_RXNE | I2C_ISR_TXIS))
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief I2C1 driver identifier.*/
-#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
-I2CDriver I2CD1;
-#endif
-
-/** @brief I2C2 driver identifier.*/
-#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
-I2CDriver I2CD2;
-#endif
-
-/** @brief I2C3 driver identifier.*/
-#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
-I2CDriver I2CD3;
-#endif
-
-/** @brief I2C4 driver identifier.*/
-#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
-I2CDriver I2CD4;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Slave address setup.
- * @note The RW bit is set to zero internally.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- *
- * @notapi
- */
-static void i2c_lld_set_address(I2CDriver *i2cp, i2caddr_t addr) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Address alignment depends on the addressing mode selected.*/
- if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0U)
- dp->CR2 = (uint32_t)addr << 1U;
- else
- dp->CR2 = (uint32_t)addr;
-}
-
-/**
- * @brief I2C RX transfer setup.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_setup_rx_transfer(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- uint32_t reload;
- size_t n;
-
- /* The unit can transfer 255 bytes maximum in a single operation.*/
- n = i2c_lld_get_rxbytes(i2cp);
- if (n > 255U) {
- n = 255U;
- reload = I2C_CR2_RELOAD;
- }
- else {
- reload = 0U;
- }
-
- /* Configures the CR2 registers with both the calculated and static
- settings.*/
- dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
- I2C_CR2_RD_WRN | (n << 16U) | reload;
-}
-
-/**
- * @brief I2C TX transfer setup.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_setup_tx_transfer(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- uint32_t reload;
- size_t n;
-
- /* The unit can transfer 255 bytes maximum in a single operation.*/
- n = i2c_lld_get_txbytes(i2cp);
- if (n > 255U) {
- n = 255U;
- reload = I2C_CR2_RELOAD;
- }
- else {
- reload = 0U;
- }
-
- /* Configures the CR2 registers with both the calculated and static
- settings.*/
- dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
- (n << 16U) | reload;
-}
-
-/**
- * @brief Aborts an I2C transaction.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_abort_operation(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- if (dp->CR1 & I2C_CR1_PE) {
- /* Stops the I2C peripheral.*/
- dp->CR1 &= ~I2C_CR1_PE;
- while (dp->CR1 & I2C_CR1_PE)
- dp->CR1 &= ~I2C_CR1_PE;
- dp->CR1 |= I2C_CR1_PE;
- }
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Stops the associated DMA streams.*/
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
-#else
- dp->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
-#endif
-}
-
-/**
- * @brief I2C shared ISR code.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] isr content of the ISR register to be decoded
- *
- * @notapi
- */
-static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Special case of a received NACK, the transfer is aborted.*/
- if ((isr & I2C_ISR_NACKF) != 0U) {
-#if STM32_I2C_USE_DMA == TRUE
- /* Stops the associated DMA streams.*/
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
-#endif
-
- /* Error flag.*/
- i2cp->errors |= I2C_ACK_FAILURE;
-
- /* Transaction finished sending the STOP.*/
- dp->CR2 |= I2C_CR2_STOP;
-
- /* Make sure no more interrupts.*/
- dp->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_TXIE | I2C_CR1_RXIE);
-
- /* Errors are signaled to the upper layer.*/
- _i2c_wakeup_error_isr(i2cp);
-
- return;
- }
-
-#if STM32_I2C_USE_DMA == FALSE
- /* Handling of data transfer if the DMA mode is disabled.*/
- {
- uint32_t cr1 = dp->CR1;
-
- if (i2cp->state == I2C_ACTIVE_TX) {
- /* Transmission phase.*/
- if (((cr1 &I2C_CR1_TXIE) != 0U) && ((isr & I2C_ISR_TXIS) != 0U)) {
- dp->TXDR = (uint32_t)*i2cp->txptr;
- i2cp->txptr++;
- i2cp->txbytes--;
- if (i2cp->txbytes == 0U) {
- dp->CR1 &= ~I2C_CR1_TXIE;
- }
- }
- }
- else {
- /* Receive phase.*/
- if (((cr1 & I2C_CR1_RXIE) != 0U) && ((isr & I2C_ISR_RXNE) != 0U)) {
- *i2cp->rxptr = (uint8_t)dp->RXDR;
- i2cp->rxptr++;
- i2cp->rxbytes--;
- if (i2cp->rxbytes == 0U) {
- dp->CR1 &= ~I2C_CR1_RXIE;
- }
- }
- }
- }
-#endif
-
- /* Partial transfer handling, restarting the transfer and returning.*/
- if ((isr & I2C_ISR_TCR) != 0U) {
- if (i2cp->state == I2C_ACTIVE_TX) {
- i2c_lld_setup_tx_transfer(i2cp);
- }
- else {
- i2c_lld_setup_rx_transfer(i2cp);
- }
- return;
- }
-
- /* The following condition is true if a transfer phase has been completed.*/
- if ((isr & I2C_ISR_TC) != 0U) {
- if (i2cp->state == I2C_ACTIVE_TX) {
- /* End of the transmit phase.*/
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Disabling TX DMA channel.*/
- dmaStreamDisable(i2cp->dmatx);
-#endif
-
- /* Starting receive phase if necessary.*/
- if (i2c_lld_get_rxbytes(i2cp) > 0U) {
- /* Setting up the peripheral.*/
- i2c_lld_setup_rx_transfer(i2cp);
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Enabling RX DMA.*/
- dmaStreamEnable(i2cp->dmarx);
-#else
- /* RX interrupt enabled.*/
- dp->CR1 |= I2C_CR1_RXIE;
-#endif
-
- /* Starts the read operation.*/
- dp->CR2 |= I2C_CR2_START;
-
- /* State change.*/
- i2cp->state = I2C_ACTIVE_RX;
-
- /* Note, returning because the transaction is not over yet.*/
- return;
- }
- }
- else {
- /* End of the receive phase.*/
-#if STM32_I2C_USE_DMA == TRUE
- /* Disabling RX DMA channel.*/
- dmaStreamDisable(i2cp->dmarx);
-#endif
- }
-
- /* Transaction finished sending the STOP.*/
- dp->CR2 |= I2C_CR2_STOP;
-
- /* Make sure no more 'Transfer Complete' interrupts.*/
- dp->CR1 &= ~I2C_CR1_TCIE;
-
- /* Normal transaction end.*/
- _i2c_wakeup_isr(i2cp);
- }
-}
-
-/**
- * @brief I2C error handler.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] isr content of the ISR register to be decoded
- *
- * @notapi
- */
-static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t isr) {
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Clears DMA interrupt flags just to be safe.*/
- dmaStreamDisable(i2cp->dmatx);
- dmaStreamDisable(i2cp->dmarx);
-#else
- /* Disabling RX and TX interrupts.*/
- i2cp->i2c->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
-#endif
-
- if (isr & I2C_ISR_BERR)
- i2cp->errors |= I2C_BUS_ERROR;
-
- if (isr & I2C_ISR_ARLO)
- i2cp->errors |= I2C_ARBITRATION_LOST;
-
- if (isr & I2C_ISR_OVR)
- i2cp->errors |= I2C_OVERRUN;
-
- if (isr & I2C_ISR_TIMEOUT)
- i2cp->errors |= I2C_TIMEOUT;
-
- /* If some error has been identified then sends wakes the waiting thread.*/
- if (i2cp->errors != I2C_NO_ERROR)
- _i2c_wakeup_error_isr(i2cp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
-#if defined(STM32_I2C1_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C1 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C1_GLOBAL_HANDLER) {
- uint32_t isr = I2CD1.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD1.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD1, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C1_EVENT_HANDLER) && defined(STM32_I2C1_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
- uint32_t isr = I2CD1.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD1.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C1_ERROR_HANDLER) {
- uint32_t isr = I2CD1.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD1.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C1 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
-#if defined(STM32_I2C2_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C2 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C2_GLOBAL_HANDLER) {
- uint32_t isr = I2CD2.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD2.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD2, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C2_EVENT_HANDLER) && defined(STM32_I2C2_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
- uint32_t isr = I2CD2.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD2.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C2_ERROR_HANDLER) {
- uint32_t isr = I2CD2.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD2.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C2 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
-#if defined(STM32_I2C3_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C3 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C3_GLOBAL_HANDLER) {
- uint32_t isr = I2CD3.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD3.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD3, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C3_EVENT_HANDLER) && defined(STM32_I2C3_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
- uint32_t isr = I2CD3.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD3.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C3_ERROR_HANDLER) {
- uint32_t isr = I2CD3.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD3.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C3 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C3 */
-
-#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
-#if defined(STM32_I2C4_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C4 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C4_GLOBAL_HANDLER) {
- uint32_t isr = I2CD4.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD4.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD4, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C4_EVENT_HANDLER) && defined(STM32_I2C4_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C4_EVENT_HANDLER) {
- uint32_t isr = I2CD4.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD4.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C4_ERROR_HANDLER) {
- uint32_t isr = I2CD4.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD4.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C4 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C4 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level I2C driver initialization.
- *
- * @notapi
- */
-void i2c_lld_init(void) {
-
-#if STM32_I2C_USE_I2C1
- i2cObjectInit(&I2CD1);
- I2CD1.thread = NULL;
- I2CD1.i2c = I2C1;
-#if STM32_I2C_USE_DMA == TRUE
- I2CD1.dmarx = NULL;
- I2CD1.dmatx = NULL;
-#endif
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2
- i2cObjectInit(&I2CD2);
- I2CD2.thread = NULL;
- I2CD2.i2c = I2C2;
-#if STM32_I2C_USE_DMA == TRUE
- I2CD2.dmarx = NULL;
- I2CD2.dmatx = NULL;
-#endif
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3
- i2cObjectInit(&I2CD3);
- I2CD3.thread = NULL;
- I2CD3.i2c = I2C3;
-#if STM32_I2C_USE_DMA == TRUE
- I2CD3.dmarx = NULL;
- I2CD3.dmatx = NULL;
-#endif
-#endif /* STM32_I2C_USE_I2C3 */
-
-#if STM32_I2C_USE_I2C4
- i2cObjectInit(&I2CD4);
- I2CD4.thread = NULL;
- I2CD4.i2c = I2C4;
-#if STM32_I2C_USE_DMA == TRUE
- I2CD4.dmarx = NULL;
- I2CD4.dmatx = NULL;
-#endif
-#endif /* STM32_I2C_USE_I2C4 */
-}
-
-/**
- * @brief Configures and activates the I2C peripheral.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-void i2c_lld_start(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Make sure I2C peripheral is disabled */
- dp->CR1 &= ~I2C_CR1_PE;
-
- /* If in stopped state then enables the I2C and DMA clocks.*/
- if (i2cp->state == I2C_STOP) {
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Common DMA modes.*/
- i2cp->txdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_M2P;
- i2cp->rxdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_P2M;
-#endif
-
-#if STM32_I2C_USE_I2C1
- if (&I2CD1 == i2cp) {
-
- rccResetI2C1();
- rccEnableI2C1(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
- STM32_I2C_I2C1_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C1_TX_DMA_STREAM,
- STM32_I2C_I2C1_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C1_RX);
- dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C1_TX);
-#endif
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
-#elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C1_EVENT_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C1_ERROR_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
-#else
-#error "I2C1 interrupt numbers not defined"
-#endif
- }
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2
- if (&I2CD2 == i2cp) {
-
- rccResetI2C2();
- rccEnableI2C2(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
- STM32_I2C_I2C2_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C2_TX_DMA_STREAM,
- STM32_I2C_I2C2_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C2_RX);
- dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C2_TX);
-#endif
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
-#elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C2_EVENT_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C2_ERROR_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
-#else
-#error "I2C2 interrupt numbers not defined"
-#endif
- }
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3
- if (&I2CD3 == i2cp) {
-
- rccResetI2C3();
- rccEnableI2C3(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
- STM32_I2C_I2C3_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C3_TX_DMA_STREAM,
- STM32_I2C_I2C3_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C3_RX);
- dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C3_TX);
-#endif
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C3_GLOBAL_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
-#elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C3_EVENT_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C3_ERROR_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
-#else
-#error "I2C3 interrupt numbers not defined"
-#endif
- }
-#endif /* STM32_I2C_USE_I2C3 */
-
-#if STM32_I2C_USE_I2C4
- if (&I2CD4 == i2cp) {
-
- rccResetI2C4();
- rccEnableI2C4(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C4_RX_DMA_STREAM,
- STM32_I2C_I2C4_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
- i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C4_TX_DMA_STREAM,
- STM32_I2C_I2C4_IRQ_PRIORITY,
- NULL,
- (void *)i2cp);
- osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C4_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C4_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C4_RX);
- dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C4_TX);
-#endif
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C4_GLOBAL_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
-#elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C4_EVENT_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C4_ERROR_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
-#else
-#error "I2C4 interrupt numbers not defined"
-#endif
- }
-#endif /* STM32_I2C_USE_I2C4 */
- }
-
-#if STM32_I2C_USE_DMA == TRUE
- /* I2C registers pointed by the DMA.*/
- dmaStreamSetPeripheral(i2cp->dmarx, &dp->RXDR);
- dmaStreamSetPeripheral(i2cp->dmatx, &dp->TXDR);
-#endif
-
- /* Reset i2c peripheral, the TCIE bit will be handled separately.*/
- dp->CR1 = i2cp->config->cr1 |
-#if STM32_I2C_USE_DMA == TRUE
- I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN | /* Enable only if using DMA */
-#endif
- I2C_CR1_ERRIE | I2C_CR1_NACKIE;
-
- /* Setup I2C parameters.*/
- dp->TIMINGR = i2cp->config->timingr;
-
- /* Ready to go.*/
- dp->CR1 |= I2C_CR1_PE;
-}
-
-/**
- * @brief Deactivates the I2C peripheral.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-void i2c_lld_stop(I2CDriver *i2cp) {
-
- /* If not in stopped state then disables the I2C clock.*/
- if (i2cp->state != I2C_STOP) {
-
- /* I2C disable.*/
- i2c_lld_abort_operation(i2cp);
-#if STM32_I2C_USE_DMA == TRUE
- dmaStreamFreeI(i2cp->dmatx);
- dmaStreamFreeI(i2cp->dmarx);
- i2cp->dmatx = NULL;
- i2cp->dmarx = NULL;
-#endif
-
-#if STM32_I2C_USE_I2C1
- if (&I2CD1 == i2cp) {
-#if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicDisableVector(STM32_I2C1_GLOBAL_NUMBER);
-#elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER)
- nvicDisableVector(STM32_I2C1_EVENT_NUMBER);
- nvicDisableVector(STM32_I2C1_ERROR_NUMBER);
-#else
-#error "I2C1 interrupt numbers not defined"
-#endif
-
- rccDisableI2C1();
- }
-#endif
-
-#if STM32_I2C_USE_I2C2
- if (&I2CD2 == i2cp) {
-#if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicDisableVector(STM32_I2C2_GLOBAL_NUMBER);
-#elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER)
- nvicDisableVector(STM32_I2C2_EVENT_NUMBER);
- nvicDisableVector(STM32_I2C2_ERROR_NUMBER);
-#else
-#error "I2C2 interrupt numbers not defined"
-#endif
-
- rccDisableI2C2();
- }
-#endif
-
-#if STM32_I2C_USE_I2C3
- if (&I2CD3 == i2cp) {
-#if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicDisableVector(STM32_I2C3_GLOBAL_NUMBER);
-#elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER)
- nvicDisableVector(STM32_I2C3_EVENT_NUMBER);
- nvicDisableVector(STM32_I2C3_ERROR_NUMBER);
-#else
-#error "I2C3 interrupt numbers not defined"
-#endif
-
- rccDisableI2C3();
- }
-#endif
-
-#if STM32_I2C_USE_I2C4
- if (&I2CD4 == i2cp) {
-#if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicDisableVector(STM32_I2C4_GLOBAL_NUMBER);
-#elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER)
- nvicDisableVector(STM32_I2C4_EVENT_NUMBER);
- nvicDisableVector(STM32_I2C4_ERROR_NUMBER);
-#else
-#error "I2C4 interrupt numbers not defined"
-#endif
-
- rccDisableI2C4();
- }
-#endif
- }
-}
-
-/**
- * @brief Receives data via the I2C bus as master.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- * @param[out] rxbuf pointer to the receive buffer
- * @param[in] rxbytes number of bytes to be received
- * @param[in] timeout the number of ticks before the operation timeouts,
- * the following special values are allowed:
- * - @a TIME_INFINITE no timeout.
- * .
- * @return The operation status.
- * @retval MSG_OK if the function succeeded.
- * @retval MSG_RESET if one or more I2C errors occurred, the errors can
- * be retrieved using @p i2cGetErrors().
- * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
- * timeout the driver must be stopped and restarted
- * because the bus is in an uncertain state.
- *
- * @notapi
- */
-msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout) {
- msg_t msg;
- I2C_TypeDef *dp = i2cp->i2c;
- systime_t start, end;
-
- /* Resetting error flags for this transfer.*/
- i2cp->errors = I2C_NO_ERROR;
-
- /* Releases the lock from high level driver.*/
- osalSysUnlock();
-
-#if STM32_I2C_USE_DMA == TRUE
- /* RX DMA setup.*/
- dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
- dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
- dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
-#else
- i2cp->rxptr = rxbuf;
- i2cp->rxbytes = rxbytes;
-#endif
-
- /* Calculating the time window for the timeout on the busy bus condition.*/
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
-
- /* Waits until BUSY flag is reset or, alternatively, for a timeout
- condition.*/
- while (true) {
- osalSysLock();
-
- /* If the bus is not busy then the operation can continue, note, the
- loop is exited in the locked state.*/
- if ((dp->ISR & I2C_ISR_BUSY) == 0)
- break;
-
- /* If the system time went outside the allowed window then a timeout
- condition is returned.*/
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return MSG_TIMEOUT;
- }
-
- osalSysUnlock();
- }
-
- /* Setting up the slave address.*/
- i2c_lld_set_address(i2cp, addr);
-
- /* Setting up the peripheral.*/
- i2c_lld_setup_rx_transfer(i2cp);
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Enabling RX DMA.*/
- dmaStreamEnable(i2cp->dmarx);
-
- /* Transfer complete interrupt enabled.*/
- dp->CR1 |= I2C_CR1_TCIE;
-#else
-
- /* Transfer complete and RX interrupts enabled.*/
- dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_RXIE;
-#endif
-
- /* Starts the operation.*/
- dp->CR2 |= I2C_CR2_START;
-
- /* Waits for the operation completion or a timeout.*/
- msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
-
- /* In case of a software timeout a STOP is sent as an extreme attempt
- to release the bus and DMA is forcibly disabled.*/
- if (msg == MSG_TIMEOUT) {
- dp->CR2 |= I2C_CR2_STOP;
-#if STM32_I2C_USE_DMA == TRUE
- dmaStreamDisable(i2cp->dmarx);
-#endif
- }
-
- return msg;
-}
-
-/**
- * @brief Transmits data via the I2C bus as master.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- * @param[in] txbuf pointer to the transmit buffer
- * @param[in] txbytes number of bytes to be transmitted
- * @param[out] rxbuf pointer to the receive buffer
- * @param[in] rxbytes number of bytes to be received
- * @param[in] timeout the number of ticks before the operation timeouts,
- * the following special values are allowed:
- * - @a TIME_INFINITE no timeout.
- * .
- * @return The operation status.
- * @retval MSG_OK if the function succeeded.
- * @retval MSG_RESET if one or more I2C errors occurred, the errors can
- * be retrieved using @p i2cGetErrors().
- * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
- * timeout the driver must be stopped and restarted
- * because the bus is in an uncertain state.
- *
- * @notapi
- */
-msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
- const uint8_t *txbuf, size_t txbytes,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout) {
- msg_t msg;
- I2C_TypeDef *dp = i2cp->i2c;
- systime_t start, end;
-
- /* Resetting error flags for this transfer.*/
- i2cp->errors = I2C_NO_ERROR;
-
- /* Releases the lock from high level driver.*/
- osalSysUnlock();
-
-#if STM32_I2C_USE_DMA == TRUE
- /* TX DMA setup.*/
- dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
- dmaStreamSetMemory0(i2cp->dmatx, txbuf);
- dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
-
- /* RX DMA setup, note, rxbytes can be zero but we write the value anyway.*/
- dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
- dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
- dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
-#else
- i2cp->txptr = txbuf;
- i2cp->txbytes = txbytes;
- i2cp->rxptr = rxbuf;
- i2cp->rxbytes = rxbytes;
-#endif
-
- /* Calculating the time window for the timeout on the busy bus condition.*/
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
-
- /* Waits until BUSY flag is reset or, alternatively, for a timeout
- condition.*/
- while (true) {
- osalSysLock();
-
- /* If the bus is not busy then the operation can continue, note, the
- loop is exited in the locked state.*/
- if ((dp->ISR & I2C_ISR_BUSY) == 0)
- break;
-
- /* If the system time went outside the allowed window then a timeout
- condition is returned.*/
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return MSG_TIMEOUT;
- }
-
- osalSysUnlock();
- }
-
- /* Setting up the slave address.*/
- i2c_lld_set_address(i2cp, addr);
-
- /* Preparing the transfer.*/
- i2c_lld_setup_tx_transfer(i2cp);
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Enabling TX DMA.*/
- dmaStreamEnable(i2cp->dmatx);
-
- /* Transfer complete interrupt enabled.*/
- dp->CR1 |= I2C_CR1_TCIE;
-#else
- /* Transfer complete and TX interrupts enabled.*/
- dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_TXIE;
-#endif
-
- /* Starts the operation.*/
- dp->CR2 |= I2C_CR2_START;
-
- /* Waits for the operation completion or a timeout.*/
- msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
-
- /* In case of a software timeout a STOP is sent as an extreme attempt
- to release the bus and DMA is forcibly disabled.*/
- if (msg == MSG_TIMEOUT) {
- dp->CR2 |= I2C_CR2_STOP;
-#if STM32_I2C_USE_DMA == TRUE
- dmaStreamDisable(i2cp->dmarx);
- dmaStreamDisable(i2cp->dmatx);
-#endif
- }
-
- return msg;
-}
-
-#endif /* HAL_USE_I2C */
-
-/** @} */
+/*
+ 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 I2Cv2/hal_i2c_lld.c
+ * @brief STM32 I2C subsystem low level driver source.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#if STM32_I2C_USE_DMA == TRUE
+#define DMAMODE_COMMON \
+ (STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | \
+ STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE | \
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE)
+
+#define I2C1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \
+ STM32_I2C1_RX_DMA_CHN)
+
+#define I2C1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \
+ STM32_I2C1_TX_DMA_CHN)
+
+#define I2C2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \
+ STM32_I2C2_RX_DMA_CHN)
+
+#define I2C2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \
+ STM32_I2C2_TX_DMA_CHN)
+
+#define I2C3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM, \
+ STM32_I2C3_RX_DMA_CHN)
+
+#define I2C3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM, \
+ STM32_I2C3_TX_DMA_CHN)
+
+#define I2C4_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C4_RX_DMA_STREAM, \
+ STM32_I2C4_RX_DMA_CHN)
+
+#define I2C4_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2C_I2C4_TX_DMA_STREAM, \
+ STM32_I2C4_TX_DMA_CHN)
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if STM32_I2C_USE_DMA == TRUE
+#define i2c_lld_get_rxbytes(i2cp) dmaStreamGetTransactionSize((i2cp)->dmarx)
+#define i2c_lld_get_txbytes(i2cp) dmaStreamGetTransactionSize((i2cp)->dmatx)
+#else
+#define i2c_lld_get_rxbytes(i2cp) (i2cp)->rxbytes
+#define i2c_lld_get_txbytes(i2cp) (i2cp)->txbytes
+#endif
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define I2C_ERROR_MASK \
+ ((uint32_t)(I2C_ISR_BERR | I2C_ISR_ARLO | I2C_ISR_OVR | I2C_ISR_PECERR | \
+ I2C_ISR_TIMEOUT | I2C_ISR_ALERT))
+
+#define I2C_INT_MASK \
+ ((uint32_t)(I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF | \
+ I2C_ISR_ADDR | I2C_ISR_RXNE | I2C_ISR_TXIS))
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief I2C1 driver identifier.*/
+#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
+I2CDriver I2CD1;
+#endif
+
+/** @brief I2C2 driver identifier.*/
+#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
+I2CDriver I2CD2;
+#endif
+
+/** @brief I2C3 driver identifier.*/
+#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
+I2CDriver I2CD3;
+#endif
+
+/** @brief I2C4 driver identifier.*/
+#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
+I2CDriver I2CD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Slave address setup.
+ * @note The RW bit is set to zero internally.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ *
+ * @notapi
+ */
+static void i2c_lld_set_address(I2CDriver *i2cp, i2caddr_t addr) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Address alignment depends on the addressing mode selected.*/
+ if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0U)
+ dp->CR2 = (uint32_t)addr << 1U;
+ else
+ dp->CR2 = (uint32_t)addr;
+}
+
+/**
+ * @brief I2C RX transfer setup.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_setup_rx_transfer(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ uint32_t reload;
+ size_t n;
+
+ /* The unit can transfer 255 bytes maximum in a single operation.*/
+ n = i2c_lld_get_rxbytes(i2cp);
+ if (n > 255U) {
+ n = 255U;
+ reload = I2C_CR2_RELOAD;
+ }
+ else {
+ reload = 0U;
+ }
+
+ /* Configures the CR2 registers with both the calculated and static
+ settings.*/
+ dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
+ I2C_CR2_RD_WRN | (n << 16U) | reload;
+}
+
+/**
+ * @brief I2C TX transfer setup.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_setup_tx_transfer(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ uint32_t reload;
+ size_t n;
+
+ /* The unit can transfer 255 bytes maximum in a single operation.*/
+ n = i2c_lld_get_txbytes(i2cp);
+ if (n > 255U) {
+ n = 255U;
+ reload = I2C_CR2_RELOAD;
+ }
+ else {
+ reload = 0U;
+ }
+
+ /* Configures the CR2 registers with both the calculated and static
+ settings.*/
+ dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
+ (n << 16U) | reload;
+}
+
+/**
+ * @brief Aborts an I2C transaction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_abort_operation(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ if (dp->CR1 & I2C_CR1_PE) {
+ /* Stops the I2C peripheral.*/
+ dp->CR1 &= ~I2C_CR1_PE;
+ while (dp->CR1 & I2C_CR1_PE)
+ dp->CR1 &= ~I2C_CR1_PE;
+ dp->CR1 |= I2C_CR1_PE;
+ }
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Stops the associated DMA streams.*/
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+#else
+ dp->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
+#endif
+}
+
+/**
+ * @brief I2C shared ISR code.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] isr content of the ISR register to be decoded
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Special case of a received NACK, the transfer is aborted.*/
+ if ((isr & I2C_ISR_NACKF) != 0U) {
+#if STM32_I2C_USE_DMA == TRUE
+ /* Stops the associated DMA streams.*/
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+#endif
+
+ /* Error flag.*/
+ i2cp->errors |= I2C_ACK_FAILURE;
+
+ /* Transaction finished sending the STOP.*/
+ dp->CR2 |= I2C_CR2_STOP;
+
+ /* Make sure no more interrupts.*/
+ dp->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_TXIE | I2C_CR1_RXIE);
+
+ /* Errors are signaled to the upper layer.*/
+ _i2c_wakeup_error_isr(i2cp);
+
+ return;
+ }
+
+#if STM32_I2C_USE_DMA == FALSE
+ /* Handling of data transfer if the DMA mode is disabled.*/
+ {
+ uint32_t cr1 = dp->CR1;
+
+ if (i2cp->state == I2C_ACTIVE_TX) {
+ /* Transmission phase.*/
+ if (((cr1 &I2C_CR1_TXIE) != 0U) && ((isr & I2C_ISR_TXIS) != 0U)) {
+ dp->TXDR = (uint32_t)*i2cp->txptr;
+ i2cp->txptr++;
+ i2cp->txbytes--;
+ if (i2cp->txbytes == 0U) {
+ dp->CR1 &= ~I2C_CR1_TXIE;
+ }
+ }
+ }
+ else {
+ /* Receive phase.*/
+ if (((cr1 & I2C_CR1_RXIE) != 0U) && ((isr & I2C_ISR_RXNE) != 0U)) {
+ *i2cp->rxptr = (uint8_t)dp->RXDR;
+ i2cp->rxptr++;
+ i2cp->rxbytes--;
+ if (i2cp->rxbytes == 0U) {
+ dp->CR1 &= ~I2C_CR1_RXIE;
+ }
+ }
+ }
+ }
+#endif
+
+ /* Partial transfer handling, restarting the transfer and returning.*/
+ if ((isr & I2C_ISR_TCR) != 0U) {
+ if (i2cp->state == I2C_ACTIVE_TX) {
+ i2c_lld_setup_tx_transfer(i2cp);
+ }
+ else {
+ i2c_lld_setup_rx_transfer(i2cp);
+ }
+ return;
+ }
+
+ /* The following condition is true if a transfer phase has been completed.*/
+ if ((isr & I2C_ISR_TC) != 0U) {
+ if (i2cp->state == I2C_ACTIVE_TX) {
+ /* End of the transmit phase.*/
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Disabling TX DMA channel.*/
+ dmaStreamDisable(i2cp->dmatx);
+#endif
+
+ /* Starting receive phase if necessary.*/
+ if (i2c_lld_get_rxbytes(i2cp) > 0U) {
+ /* Setting up the peripheral.*/
+ i2c_lld_setup_rx_transfer(i2cp);
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Enabling RX DMA.*/
+ dmaStreamEnable(i2cp->dmarx);
+#else
+ /* RX interrupt enabled.*/
+ dp->CR1 |= I2C_CR1_RXIE;
+#endif
+
+ /* Starts the read operation.*/
+ dp->CR2 |= I2C_CR2_START;
+
+ /* State change.*/
+ i2cp->state = I2C_ACTIVE_RX;
+
+ /* Note, returning because the transaction is not over yet.*/
+ return;
+ }
+ }
+ else {
+ /* End of the receive phase.*/
+#if STM32_I2C_USE_DMA == TRUE
+ /* Disabling RX DMA channel.*/
+ dmaStreamDisable(i2cp->dmarx);
+#endif
+ }
+
+ /* Transaction finished sending the STOP.*/
+ dp->CR2 |= I2C_CR2_STOP;
+
+ /* Make sure no more 'Transfer Complete' interrupts.*/
+ dp->CR1 &= ~I2C_CR1_TCIE;
+
+ /* Normal transaction end.*/
+ _i2c_wakeup_isr(i2cp);
+ }
+}
+
+/**
+ * @brief I2C error handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] isr content of the ISR register to be decoded
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t isr) {
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Clears DMA interrupt flags just to be safe.*/
+ dmaStreamDisable(i2cp->dmatx);
+ dmaStreamDisable(i2cp->dmarx);
+#else
+ /* Disabling RX and TX interrupts.*/
+ i2cp->i2c->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
+#endif
+
+ if (isr & I2C_ISR_BERR)
+ i2cp->errors |= I2C_BUS_ERROR;
+
+ if (isr & I2C_ISR_ARLO)
+ i2cp->errors |= I2C_ARBITRATION_LOST;
+
+ if (isr & I2C_ISR_OVR)
+ i2cp->errors |= I2C_OVERRUN;
+
+ if (isr & I2C_ISR_TIMEOUT)
+ i2cp->errors |= I2C_TIMEOUT;
+
+ /* If some error has been identified then sends wakes the waiting thread.*/
+ if (i2cp->errors != I2C_NO_ERROR)
+ _i2c_wakeup_error_isr(i2cp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
+#if defined(STM32_I2C1_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C1 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C1_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD1.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD1.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD1, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C1_EVENT_HANDLER) && defined(STM32_I2C1_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
+ uint32_t isr = I2CD1.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD1.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C1_ERROR_HANDLER) {
+ uint32_t isr = I2CD1.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD1.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C1 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
+#if defined(STM32_I2C2_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C2 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C2_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD2.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD2.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD2, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C2_EVENT_HANDLER) && defined(STM32_I2C2_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
+ uint32_t isr = I2CD2.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD2.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C2_ERROR_HANDLER) {
+ uint32_t isr = I2CD2.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD2.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C2 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
+#if defined(STM32_I2C3_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C3 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C3_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD3.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD3.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD3, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C3_EVENT_HANDLER) && defined(STM32_I2C3_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
+ uint32_t isr = I2CD3.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD3.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C3_ERROR_HANDLER) {
+ uint32_t isr = I2CD3.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD3.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C3 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C3 */
+
+#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
+#if defined(STM32_I2C4_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C4 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C4_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD4.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD4.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD4, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C4_EVENT_HANDLER) && defined(STM32_I2C4_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C4_EVENT_HANDLER) {
+ uint32_t isr = I2CD4.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD4.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C4_ERROR_HANDLER) {
+ uint32_t isr = I2CD4.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD4.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C4 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C4 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2C driver initialization.
+ *
+ * @notapi
+ */
+void i2c_lld_init(void) {
+
+#if STM32_I2C_USE_I2C1
+ i2cObjectInit(&I2CD1);
+ I2CD1.thread = NULL;
+ I2CD1.i2c = I2C1;
+#if STM32_I2C_USE_DMA == TRUE
+ I2CD1.dmarx = NULL;
+ I2CD1.dmatx = NULL;
+#endif
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2
+ i2cObjectInit(&I2CD2);
+ I2CD2.thread = NULL;
+ I2CD2.i2c = I2C2;
+#if STM32_I2C_USE_DMA == TRUE
+ I2CD2.dmarx = NULL;
+ I2CD2.dmatx = NULL;
+#endif
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3
+ i2cObjectInit(&I2CD3);
+ I2CD3.thread = NULL;
+ I2CD3.i2c = I2C3;
+#if STM32_I2C_USE_DMA == TRUE
+ I2CD3.dmarx = NULL;
+ I2CD3.dmatx = NULL;
+#endif
+#endif /* STM32_I2C_USE_I2C3 */
+
+#if STM32_I2C_USE_I2C4
+ i2cObjectInit(&I2CD4);
+ I2CD4.thread = NULL;
+ I2CD4.i2c = I2C4;
+#if STM32_I2C_USE_DMA == TRUE
+ I2CD4.dmarx = NULL;
+ I2CD4.dmatx = NULL;
+#endif
+#endif /* STM32_I2C_USE_I2C4 */
+}
+
+/**
+ * @brief Configures and activates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_start(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Make sure I2C peripheral is disabled */
+ dp->CR1 &= ~I2C_CR1_PE;
+
+ /* If in stopped state then enables the I2C and DMA clocks.*/
+ if (i2cp->state == I2C_STOP) {
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Common DMA modes.*/
+ i2cp->txdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_M2P;
+ i2cp->rxdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_P2M;
+#endif
+
+#if STM32_I2C_USE_I2C1
+ if (&I2CD1 == i2cp) {
+
+ rccResetI2C1();
+ rccEnableI2C1(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
+ STM32_I2C_I2C1_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C1_TX_DMA_STREAM,
+ STM32_I2C_I2C1_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C1_RX);
+ dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C1_TX);
+#endif
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
+#elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C1_EVENT_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C1_ERROR_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
+#else
+#error "I2C1 interrupt numbers not defined"
+#endif
+ }
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2
+ if (&I2CD2 == i2cp) {
+
+ rccResetI2C2();
+ rccEnableI2C2(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
+ STM32_I2C_I2C2_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C2_TX_DMA_STREAM,
+ STM32_I2C_I2C2_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C2_RX);
+ dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C2_TX);
+#endif
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
+#elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C2_EVENT_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C2_ERROR_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
+#else
+#error "I2C2 interrupt numbers not defined"
+#endif
+ }
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3
+ if (&I2CD3 == i2cp) {
+
+ rccResetI2C3();
+ rccEnableI2C3(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
+ STM32_I2C_I2C3_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C3_TX_DMA_STREAM,
+ STM32_I2C_I2C3_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C3_RX);
+ dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C3_TX);
+#endif
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C3_GLOBAL_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
+#elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C3_EVENT_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C3_ERROR_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
+#else
+#error "I2C3 interrupt numbers not defined"
+#endif
+ }
+#endif /* STM32_I2C_USE_I2C3 */
+
+#if STM32_I2C_USE_I2C4
+ if (&I2CD4 == i2cp) {
+
+ rccResetI2C4();
+ rccEnableI2C4(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C4_RX_DMA_STREAM,
+ STM32_I2C_I2C4_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmarx != NULL, "unable to allocate stream");
+ i2cp->dmatx = dmaStreamAllocI(STM32_I2C_I2C4_TX_DMA_STREAM,
+ STM32_I2C_I2C4_IRQ_PRIORITY,
+ NULL,
+ (void *)i2cp);
+ osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C4_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C4_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(i2cp->dmarx, STM32_DMAMUX1_I2C4_RX);
+ dmaSetRequestSource(i2cp->dmatx, STM32_DMAMUX1_I2C4_TX);
+#endif
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C4_GLOBAL_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
+#elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C4_EVENT_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C4_ERROR_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
+#else
+#error "I2C4 interrupt numbers not defined"
+#endif
+ }
+#endif /* STM32_I2C_USE_I2C4 */
+ }
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* I2C registers pointed by the DMA.*/
+ dmaStreamSetPeripheral(i2cp->dmarx, &dp->RXDR);
+ dmaStreamSetPeripheral(i2cp->dmatx, &dp->TXDR);
+#endif
+
+ /* Reset i2c peripheral, the TCIE bit will be handled separately.*/
+ dp->CR1 = i2cp->config->cr1 |
+#if STM32_I2C_USE_DMA == TRUE
+ I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN | /* Enable only if using DMA */
+#endif
+ I2C_CR1_ERRIE | I2C_CR1_NACKIE;
+
+ /* Setup I2C parameters.*/
+ dp->TIMINGR = i2cp->config->timingr;
+
+ /* Ready to go.*/
+ dp->CR1 |= I2C_CR1_PE;
+}
+
+/**
+ * @brief Deactivates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_stop(I2CDriver *i2cp) {
+
+ /* If not in stopped state then disables the I2C clock.*/
+ if (i2cp->state != I2C_STOP) {
+
+ /* I2C disable.*/
+ i2c_lld_abort_operation(i2cp);
+#if STM32_I2C_USE_DMA == TRUE
+ dmaStreamFreeI(i2cp->dmatx);
+ dmaStreamFreeI(i2cp->dmarx);
+ i2cp->dmatx = NULL;
+ i2cp->dmarx = NULL;
+#endif
+
+#if STM32_I2C_USE_I2C1
+ if (&I2CD1 == i2cp) {
+#if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicDisableVector(STM32_I2C1_GLOBAL_NUMBER);
+#elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER)
+ nvicDisableVector(STM32_I2C1_EVENT_NUMBER);
+ nvicDisableVector(STM32_I2C1_ERROR_NUMBER);
+#else
+#error "I2C1 interrupt numbers not defined"
+#endif
+
+ rccDisableI2C1();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C2
+ if (&I2CD2 == i2cp) {
+#if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicDisableVector(STM32_I2C2_GLOBAL_NUMBER);
+#elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER)
+ nvicDisableVector(STM32_I2C2_EVENT_NUMBER);
+ nvicDisableVector(STM32_I2C2_ERROR_NUMBER);
+#else
+#error "I2C2 interrupt numbers not defined"
+#endif
+
+ rccDisableI2C2();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C3
+ if (&I2CD3 == i2cp) {
+#if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicDisableVector(STM32_I2C3_GLOBAL_NUMBER);
+#elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER)
+ nvicDisableVector(STM32_I2C3_EVENT_NUMBER);
+ nvicDisableVector(STM32_I2C3_ERROR_NUMBER);
+#else
+#error "I2C3 interrupt numbers not defined"
+#endif
+
+ rccDisableI2C3();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C4
+ if (&I2CD4 == i2cp) {
+#if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicDisableVector(STM32_I2C4_GLOBAL_NUMBER);
+#elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER)
+ nvicDisableVector(STM32_I2C4_EVENT_NUMBER);
+ nvicDisableVector(STM32_I2C4_ERROR_NUMBER);
+#else
+#error "I2C4 interrupt numbers not defined"
+#endif
+
+ rccDisableI2C4();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Receives data via the I2C bus as master.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval MSG_OK if the function succeeded.
+ * @retval MSG_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout) {
+ msg_t msg;
+ I2C_TypeDef *dp = i2cp->i2c;
+ systime_t start, end;
+
+ /* Resetting error flags for this transfer.*/
+ i2cp->errors = I2C_NO_ERROR;
+
+ /* Releases the lock from high level driver.*/
+ osalSysUnlock();
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* RX DMA setup.*/
+ dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
+ dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
+#else
+ i2cp->rxptr = rxbuf;
+ i2cp->rxbytes = rxbytes;
+#endif
+
+ /* Calculating the time window for the timeout on the busy bus condition.*/
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
+
+ /* Waits until BUSY flag is reset or, alternatively, for a timeout
+ condition.*/
+ while (true) {
+ osalSysLock();
+
+ /* If the bus is not busy then the operation can continue, note, the
+ loop is exited in the locked state.*/
+ if ((dp->ISR & I2C_ISR_BUSY) == 0)
+ break;
+
+ /* If the system time went outside the allowed window then a timeout
+ condition is returned.*/
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return MSG_TIMEOUT;
+ }
+
+ osalSysUnlock();
+ }
+
+ /* Setting up the slave address.*/
+ i2c_lld_set_address(i2cp, addr);
+
+ /* Setting up the peripheral.*/
+ i2c_lld_setup_rx_transfer(i2cp);
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Enabling RX DMA.*/
+ dmaStreamEnable(i2cp->dmarx);
+
+ /* Transfer complete interrupt enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE;
+#else
+
+ /* Transfer complete and RX interrupts enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_RXIE;
+#endif
+
+ /* Starts the operation.*/
+ dp->CR2 |= I2C_CR2_START;
+
+ /* Waits for the operation completion or a timeout.*/
+ msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
+
+ /* In case of a software timeout a STOP is sent as an extreme attempt
+ to release the bus and DMA is forcibly disabled.*/
+ if (msg == MSG_TIMEOUT) {
+ dp->CR2 |= I2C_CR2_STOP;
+#if STM32_I2C_USE_DMA == TRUE
+ dmaStreamDisable(i2cp->dmarx);
+#endif
+ }
+
+ return msg;
+}
+
+/**
+ * @brief Transmits data via the I2C bus as master.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[in] txbuf pointer to the transmit buffer
+ * @param[in] txbytes number of bytes to be transmitted
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval MSG_OK if the function succeeded.
+ * @retval MSG_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout) {
+ msg_t msg;
+ I2C_TypeDef *dp = i2cp->i2c;
+ systime_t start, end;
+
+ /* Resetting error flags for this transfer.*/
+ i2cp->errors = I2C_NO_ERROR;
+
+ /* Releases the lock from high level driver.*/
+ osalSysUnlock();
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* TX DMA setup.*/
+ dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
+ dmaStreamSetMemory0(i2cp->dmatx, txbuf);
+ dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
+
+ /* RX DMA setup, note, rxbytes can be zero but we write the value anyway.*/
+ dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
+ dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
+#else
+ i2cp->txptr = txbuf;
+ i2cp->txbytes = txbytes;
+ i2cp->rxptr = rxbuf;
+ i2cp->rxbytes = rxbytes;
+#endif
+
+ /* Calculating the time window for the timeout on the busy bus condition.*/
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
+
+ /* Waits until BUSY flag is reset or, alternatively, for a timeout
+ condition.*/
+ while (true) {
+ osalSysLock();
+
+ /* If the bus is not busy then the operation can continue, note, the
+ loop is exited in the locked state.*/
+ if ((dp->ISR & I2C_ISR_BUSY) == 0)
+ break;
+
+ /* If the system time went outside the allowed window then a timeout
+ condition is returned.*/
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return MSG_TIMEOUT;
+ }
+
+ osalSysUnlock();
+ }
+
+ /* Setting up the slave address.*/
+ i2c_lld_set_address(i2cp, addr);
+
+ /* Preparing the transfer.*/
+ i2c_lld_setup_tx_transfer(i2cp);
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Enabling TX DMA.*/
+ dmaStreamEnable(i2cp->dmatx);
+
+ /* Transfer complete interrupt enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE;
+#else
+ /* Transfer complete and TX interrupts enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_TXIE;
+#endif
+
+ /* Starts the operation.*/
+ dp->CR2 |= I2C_CR2_START;
+
+ /* Waits for the operation completion or a timeout.*/
+ msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
+
+ /* In case of a software timeout a STOP is sent as an extreme attempt
+ to release the bus and DMA is forcibly disabled.*/
+ if (msg == MSG_TIMEOUT) {
+ dp->CR2 |= I2C_CR2_STOP;
+#if STM32_I2C_USE_DMA == TRUE
+ dmaStreamDisable(i2cp->dmarx);
+ dmaStreamDisable(i2cp->dmatx);
+#endif
+ }
+
+ return msg;
+}
+
+#endif /* HAL_USE_I2C */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.h
index b1004e793d..453026122c 100644
--- a/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.h
+++ b/os/hal/ports/STM32/LLD/I2Cv2/hal_i2c_lld.h
@@ -1,509 +1,509 @@
-/*
- 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 I2Cv2/hal_i2c_lld.h
- * @brief STM32 I2C subsystem low level driver header.
- *
- * @addtogroup I2C
- * @{
- */
-
-#ifndef HAL_I2C_LLD_H
-#define HAL_I2C_LLD_H
-
-#if HAL_USE_I2C || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name TIMINGR register definitions
- * @{
- */
-#define STM32_TIMINGR_PRESC_MASK (15U << 28)
-#define STM32_TIMINGR_PRESC(n) ((n) << 28)
-#define STM32_TIMINGR_SCLDEL_MASK (15U << 20)
-#define STM32_TIMINGR_SCLDEL(n) ((n) << 20)
-#define STM32_TIMINGR_SDADEL_MASK (15U << 16)
-#define STM32_TIMINGR_SDADEL(n) ((n) << 16)
-#define STM32_TIMINGR_SCLH_MASK (255U << 8)
-#define STM32_TIMINGR_SCLH(n) ((n) << 8)
-#define STM32_TIMINGR_SCLL_MASK (255U << 0)
-#define STM32_TIMINGR_SCLL(n) ((n) << 0)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief I2C1 driver enable switch.
- * @details If set to @p TRUE the support for I2C1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C1 FALSE
-#endif
-
-/**
- * @brief I2C2 driver enable switch.
- * @details If set to @p TRUE the support for I2C2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C2 FALSE
-#endif
-
-/**
- * @brief I2C3 driver enable switch.
- * @details If set to @p TRUE the support for I2C3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C3 FALSE
-#endif
-
-/**
- * @brief I2C4 driver enable switch.
- * @details If set to @p TRUE the support for I2C4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C4) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C4 FALSE
-#endif
-
-/**
- * @brief I2C timeout on busy condition in milliseconds.
- */
-#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_I2C_BUSY_TIMEOUT 50
-#endif
-
-/**
- * @brief I2C1 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C2 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C3 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C4 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C4_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DMA use switch.
- */
-#if !defined(STM32_I2C_USE_DMA) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_DMA TRUE
-#endif
-
-/**
- * @brief I2C1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C4_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/** @brief error checks */
-#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
-#error "I2C1 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
-#error "I2C2 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
-#error "I2C3 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C4 && !STM32_HAS_I2C4
-#error "I2C4 not present in the selected device"
-#endif
-
-#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && !STM32_I2C_USE_I2C3 && \
- !STM32_I2C_USE_I2C4
-#error "I2C driver activated but no I2C peripheral assigned"
-#endif
-
-#if STM32_I2C_USE_I2C1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C1"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C2"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C3"
-#endif
-
-#if STM32_I2C_USE_I2C4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C4"
-#endif
-
-#if STM32_I2C_USE_DMA == TRUE
-#if STM32_I2C_USE_I2C1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C1"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C2"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C3"
-#endif
-
-#if STM32_I2C_USE_I2C4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C4"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_I2C_USE_I2C1 && (!defined(STM32_I2C_I2C1_RX_DMA_STREAM) || \
- !defined(STM32_I2C_I2C1_TX_DMA_STREAM))
-#error "I2C1 DMA streams not defined"
-#endif
-
-#if STM32_I2C_USE_I2C2 && (!defined(STM32_I2C_I2C2_RX_DMA_STREAM) || \
- !defined(STM32_I2C_I2C2_TX_DMA_STREAM))
-#error "I2C2 DMA streams not defined"
-#endif
-
-#if STM32_I2C_USE_I2C3 && (!defined(STM32_I2C_I2C3_RX_DMA_STREAM) || \
- !defined(STM32_I2C_I2C3_TX_DMA_STREAM))
-#error "I2C3 DMA streams not defined"
-#endif
-
-#if STM32_I2C_USE_I2C4 && (!defined(STM32_I2C_I2C4_RX_DMA_STREAM) || \
- !defined(STM32_I2C_I2C4_TX_DMA_STREAM))
-#error "I2C4 DMA streams not defined"
-#endif
-
-/* Devices without DMAMUX require an additional check.*/
-#if !STM32_DMA_SUPPORTS_DMAMUX
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_I2C_USE_I2C1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \
- STM32_I2C1_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C1 RX"
-#endif
-
-#if STM32_I2C_USE_I2C1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \
- STM32_I2C1_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C1 TX"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \
- STM32_I2C2_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C2 RX"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \
- STM32_I2C2_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C2 TX"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \
- STM32_I2C3_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C3 RX"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \
- STM32_I2C3_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C3 TX"
-#endif
-
-#if STM32_I2C_USE_I2C4 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C4_RX_DMA_STREAM, \
- STM32_I2C4_RX_DMA_MSK)
-#error "invalid DMA stream associated to I2C4 RX"
-#endif
-
-#if STM32_I2C_USE_I2C4 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C4_TX_DMA_STREAM, \
- STM32_I2C4_TX_DMA_MSK)
-#error "invalid DMA stream associated to I2C4 TX"
-#endif
-
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-#endif /* STM32_ADVANCED_DMA */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type representing an I2C address.
- */
-typedef uint16_t i2caddr_t;
-
-/**
- * @brief Type of I2C driver condition flags.
- */
-typedef uint32_t i2cflags_t;
-
-/**
- * @brief Type of I2C driver configuration structure.
- */
-typedef struct {
- /**
- * @brief TIMINGR register initialization.
- * @note Refer to the STM32 reference manual, the values are affected
- * by the system clock settings in mcuconf.h.
- */
- uint32_t timingr;
- /**
- * @brief CR1 register initialization.
- * @note Leave to zero unless you know what you are doing.
- */
- uint32_t cr1;
- /**
- * @brief CR2 register initialization.
- * @note Only the ADD10 bit can eventually be specified here.
- */
- uint32_t cr2;
-} I2CConfig;
-
-/**
- * @brief Type of a structure representing an I2C driver.
- */
-typedef struct I2CDriver I2CDriver;
-
-/**
- * @brief Structure representing an I2C driver.
- */
-struct I2CDriver {
- /**
- * @brief Driver state.
- */
- i2cstate_t state;
- /**
- * @brief Current configuration data.
- */
- const I2CConfig *config;
- /**
- * @brief Error flags.
- */
- i2cflags_t errors;
-#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
- mutex_t mutex;
-#endif /* I2C_USE_MUTUAL_EXCLUSION */
-#if defined(I2C_DRIVER_EXT_FIELDS)
- I2C_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion.
- */
- thread_reference_t thread;
-#if (STM32_I2C_USE_DMA == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief RX DMA mode bit mask.
- */
- uint32_t rxdmamode;
- /**
- * @brief TX DMA mode bit mask.
- */
- uint32_t txdmamode;
- /**
- * @brief Receive DMA channel.
- */
- const stm32_dma_stream_t *dmarx;
- /**
- * @brief Transmit DMA channel.
- */
- const stm32_dma_stream_t *dmatx;
-#else /* STM32_I2C_USE_DMA == FALSE */
- /**
- * @brief Pointer to the next TX buffer location.
- */
- const uint8_t *txptr;
- /**
- * @brief Number of bytes in TX phase.
- */
- size_t txbytes;
- /**
- * @brief Pointer to the next RX buffer location.
- */
- uint8_t *rxptr;
- /**
- * @brief Number of bytes in RX phase.
- */
- size_t rxbytes;
-#endif /* STM32_I2C_USE_DMA == FALSE */
- /**
- * @brief Pointer to the I2Cx registers block.
- */
- I2C_TypeDef *i2c;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Get errors from I2C driver.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-#if STM32_I2C_USE_I2C1
-extern I2CDriver I2CD1;
-#endif
-
-#if STM32_I2C_USE_I2C2
-extern I2CDriver I2CD2;
-#endif
-
-#if STM32_I2C_USE_I2C3
-extern I2CDriver I2CD3;
-#endif
-
-#if STM32_I2C_USE_I2C4
-extern I2CDriver I2CD4;
-#endif
-
-#endif /* !defined(__DOXYGEN__) */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void i2c_lld_init(void);
- void i2c_lld_start(I2CDriver *i2cp);
- void i2c_lld_stop(I2CDriver *i2cp);
- msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
- const uint8_t *txbuf, size_t txbytes,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout);
- msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_I2C */
-
-#endif /* HAL_I2C_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 I2Cv2/hal_i2c_lld.h
+ * @brief STM32 I2C subsystem low level driver header.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#ifndef HAL_I2C_LLD_H
+#define HAL_I2C_LLD_H
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name TIMINGR register definitions
+ * @{
+ */
+#define STM32_TIMINGR_PRESC_MASK (15U << 28)
+#define STM32_TIMINGR_PRESC(n) ((n) << 28)
+#define STM32_TIMINGR_SCLDEL_MASK (15U << 20)
+#define STM32_TIMINGR_SCLDEL(n) ((n) << 20)
+#define STM32_TIMINGR_SDADEL_MASK (15U << 16)
+#define STM32_TIMINGR_SDADEL(n) ((n) << 16)
+#define STM32_TIMINGR_SCLH_MASK (255U << 8)
+#define STM32_TIMINGR_SCLH(n) ((n) << 8)
+#define STM32_TIMINGR_SCLL_MASK (255U << 0)
+#define STM32_TIMINGR_SCLL(n) ((n) << 0)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2C1 driver enable switch.
+ * @details If set to @p TRUE the support for I2C1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C1 FALSE
+#endif
+
+/**
+ * @brief I2C2 driver enable switch.
+ * @details If set to @p TRUE the support for I2C2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C2 FALSE
+#endif
+
+/**
+ * @brief I2C3 driver enable switch.
+ * @details If set to @p TRUE the support for I2C3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C3 FALSE
+#endif
+
+/**
+ * @brief I2C4 driver enable switch.
+ * @details If set to @p TRUE the support for I2C4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C4) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C4 FALSE
+#endif
+
+/**
+ * @brief I2C timeout on busy condition in milliseconds.
+ */
+#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_I2C_BUSY_TIMEOUT 50
+#endif
+
+/**
+ * @brief I2C1 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C2 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C3 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C4 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C4_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DMA use switch.
+ */
+#if !defined(STM32_I2C_USE_DMA) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_DMA TRUE
+#endif
+
+/**
+ * @brief I2C1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C4_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/** @brief error checks */
+#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
+#error "I2C1 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
+#error "I2C2 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
+#error "I2C3 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C4 && !STM32_HAS_I2C4
+#error "I2C4 not present in the selected device"
+#endif
+
+#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && !STM32_I2C_USE_I2C3 && \
+ !STM32_I2C_USE_I2C4
+#error "I2C driver activated but no I2C peripheral assigned"
+#endif
+
+#if STM32_I2C_USE_I2C1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C1"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C2"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C3"
+#endif
+
+#if STM32_I2C_USE_I2C4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C4"
+#endif
+
+#if STM32_I2C_USE_DMA == TRUE
+#if STM32_I2C_USE_I2C1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C1"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C2"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C3"
+#endif
+
+#if STM32_I2C_USE_I2C4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C4"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_I2C_USE_I2C1 && (!defined(STM32_I2C_I2C1_RX_DMA_STREAM) || \
+ !defined(STM32_I2C_I2C1_TX_DMA_STREAM))
+#error "I2C1 DMA streams not defined"
+#endif
+
+#if STM32_I2C_USE_I2C2 && (!defined(STM32_I2C_I2C2_RX_DMA_STREAM) || \
+ !defined(STM32_I2C_I2C2_TX_DMA_STREAM))
+#error "I2C2 DMA streams not defined"
+#endif
+
+#if STM32_I2C_USE_I2C3 && (!defined(STM32_I2C_I2C3_RX_DMA_STREAM) || \
+ !defined(STM32_I2C_I2C3_TX_DMA_STREAM))
+#error "I2C3 DMA streams not defined"
+#endif
+
+#if STM32_I2C_USE_I2C4 && (!defined(STM32_I2C_I2C4_RX_DMA_STREAM) || \
+ !defined(STM32_I2C_I2C4_TX_DMA_STREAM))
+#error "I2C4 DMA streams not defined"
+#endif
+
+/* Devices without DMAMUX require an additional check.*/
+#if !STM32_DMA_SUPPORTS_DMAMUX
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_I2C_USE_I2C1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_RX_DMA_STREAM, \
+ STM32_I2C1_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C1 RX"
+#endif
+
+#if STM32_I2C_USE_I2C1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C1_TX_DMA_STREAM, \
+ STM32_I2C1_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C1 TX"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_RX_DMA_STREAM, \
+ STM32_I2C2_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C2 RX"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C2_TX_DMA_STREAM, \
+ STM32_I2C2_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C2 TX"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_RX_DMA_STREAM, \
+ STM32_I2C3_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C3 RX"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C3_TX_DMA_STREAM, \
+ STM32_I2C3_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C3 TX"
+#endif
+
+#if STM32_I2C_USE_I2C4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C4_RX_DMA_STREAM, \
+ STM32_I2C4_RX_DMA_MSK)
+#error "invalid DMA stream associated to I2C4 RX"
+#endif
+
+#if STM32_I2C_USE_I2C4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2C_I2C4_TX_DMA_STREAM, \
+ STM32_I2C4_TX_DMA_MSK)
+#error "invalid DMA stream associated to I2C4 TX"
+#endif
+
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+#endif /* STM32_ADVANCED_DMA */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type representing an I2C address.
+ */
+typedef uint16_t i2caddr_t;
+
+/**
+ * @brief Type of I2C driver condition flags.
+ */
+typedef uint32_t i2cflags_t;
+
+/**
+ * @brief Type of I2C driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief TIMINGR register initialization.
+ * @note Refer to the STM32 reference manual, the values are affected
+ * by the system clock settings in mcuconf.h.
+ */
+ uint32_t timingr;
+ /**
+ * @brief CR1 register initialization.
+ * @note Leave to zero unless you know what you are doing.
+ */
+ uint32_t cr1;
+ /**
+ * @brief CR2 register initialization.
+ * @note Only the ADD10 bit can eventually be specified here.
+ */
+ uint32_t cr2;
+} I2CConfig;
+
+/**
+ * @brief Type of a structure representing an I2C driver.
+ */
+typedef struct I2CDriver I2CDriver;
+
+/**
+ * @brief Structure representing an I2C driver.
+ */
+struct I2CDriver {
+ /**
+ * @brief Driver state.
+ */
+ i2cstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const I2CConfig *config;
+ /**
+ * @brief Error flags.
+ */
+ i2cflags_t errors;
+#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+ mutex_t mutex;
+#endif /* I2C_USE_MUTUAL_EXCLUSION */
+#if defined(I2C_DRIVER_EXT_FIELDS)
+ I2C_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion.
+ */
+ thread_reference_t thread;
+#if (STM32_I2C_USE_DMA == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief RX DMA mode bit mask.
+ */
+ uint32_t rxdmamode;
+ /**
+ * @brief TX DMA mode bit mask.
+ */
+ uint32_t txdmamode;
+ /**
+ * @brief Receive DMA channel.
+ */
+ const stm32_dma_stream_t *dmarx;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const stm32_dma_stream_t *dmatx;
+#else /* STM32_I2C_USE_DMA == FALSE */
+ /**
+ * @brief Pointer to the next TX buffer location.
+ */
+ const uint8_t *txptr;
+ /**
+ * @brief Number of bytes in TX phase.
+ */
+ size_t txbytes;
+ /**
+ * @brief Pointer to the next RX buffer location.
+ */
+ uint8_t *rxptr;
+ /**
+ * @brief Number of bytes in RX phase.
+ */
+ size_t rxbytes;
+#endif /* STM32_I2C_USE_DMA == FALSE */
+ /**
+ * @brief Pointer to the I2Cx registers block.
+ */
+ I2C_TypeDef *i2c;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Get errors from I2C driver.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+#if STM32_I2C_USE_I2C1
+extern I2CDriver I2CD1;
+#endif
+
+#if STM32_I2C_USE_I2C2
+extern I2CDriver I2CD2;
+#endif
+
+#if STM32_I2C_USE_I2C3
+extern I2CDriver I2CD3;
+#endif
+
+#if STM32_I2C_USE_I2C4
+extern I2CDriver I2CD4;
+#endif
+
+#endif /* !defined(__DOXYGEN__) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2c_lld_init(void);
+ void i2c_lld_start(I2CDriver *i2cp);
+ void i2c_lld_stop(I2CDriver *i2cp);
+ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout);
+ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2C */
+
+#endif /* HAL_I2C_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/I2Cv3/driver.mk b/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
index ef55dfdf89..18db3f65aa 100644
--- a/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
+++ b/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
@@ -1,21 +1,21 @@
-ifeq ($(USE_HAL_I2C_FALLBACK),yes)
- # Fallback SW driver.
- ifeq ($(USE_SMART_BUILD),yes)
- ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
- PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
- endif
- else
- PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
- endif
- PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C
-else
- # Default HW driver.
- ifeq ($(USE_SMART_BUILD),yes)
- ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
- PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
- endif
- else
- PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
- endif
- PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3
-endif
+ifeq ($(USE_HAL_I2C_FALLBACK),yes)
+ # Fallback SW driver.
+ ifeq ($(USE_SMART_BUILD),yes)
+ ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
+ PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
+ endif
+ else
+ PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c
+ endif
+ PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C
+else
+ # Default HW driver.
+ ifeq ($(USE_SMART_BUILD),yes)
+ ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),)
+ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
+ endif
+ else
+ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
+ endif
+ PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3
+endif
diff --git a/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c b/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
index 24b1ace93e..6786e9161d 100644
--- a/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
+++ b/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c
@@ -1,1316 +1,1316 @@
-/*
- 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 I2Cv3/hal_i2c_lld.c
- * @brief STM32 I2C subsystem low level driver source.
- *
- * @addtogroup I2C
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_I2C || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if STM32_I2C_USE_DMA == TRUE
-
-#if defined(STM32_I2C_DMA_REQUIRED)
-#define DMAMODE_COMMON \
- (STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | \
- STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE | \
- STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE)
-#endif
-
-#if defined(STM32_I2C_BDMA_REQUIRED)
-#define BDMAMODE_COMMON \
- (STM32_BDMA_CR_PSIZE_BYTE | STM32_BDMA_CR_MSIZE_BYTE | \
- STM32_BDMA_CR_MINC | \
- STM32_BDMA_CR_TEIE | STM32_BDMA_CR_TCIE)
-#endif
-
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if 0
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- }
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-#define I2C_ERROR_MASK \
- ((uint32_t)(I2C_ISR_BERR | I2C_ISR_ARLO | I2C_ISR_OVR | I2C_ISR_PECERR | \
- I2C_ISR_TIMEOUT | I2C_ISR_ALERT))
-
-#define I2C_INT_MASK \
- ((uint32_t)(I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF | \
- I2C_ISR_ADDR | I2C_ISR_RXNE | I2C_ISR_TXIS))
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief I2C1 driver identifier.*/
-#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
-I2CDriver I2CD1;
-#endif
-
-/** @brief I2C2 driver identifier.*/
-#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
-I2CDriver I2CD2;
-#endif
-
-/** @brief I2C3 driver identifier.*/
-#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
-I2CDriver I2CD3;
-#endif
-
-/** @brief I2C4 driver identifier.*/
-#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
-I2CDriver I2CD4;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#if STM32_I2C_USE_DMA == TRUE
-static inline void i2c_lld_start_rx_dma(I2CDriver *i2cp) {
-
-#if STM32_I2C4_USE_BDMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamEnable(i2cp->rx.bdma);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#endif /* STM32_I2C4_USE_BDMA == TRUE */
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamEnable(i2cp->rx.dma);
- }
-#endif
-}
-
-static inline void i2c_lld_start_tx_dma(I2CDriver *i2cp) {
-
-#if STM32_I2C4_USE_BDMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamEnable(i2cp->tx.bdma);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#endif /* STM32_I2C4_USE_BDMA == TRUE */
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamEnable(i2cp->tx.dma);
- }
-#endif
-}
-
-static inline void i2c_lld_stop_rx_dma(I2CDriver *i2cp) {
-
-#if STM32_I2C4_USE_BDMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamDisable(i2cp->rx.bdma);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#endif /* STM32_I2C4_USE_BDMA == TRUE */
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamDisable(i2cp->rx.dma);
- }
-#endif
-}
-
-static inline void i2c_lld_stop_tx_dma(I2CDriver *i2cp) {
-
-#if STM32_I2C4_USE_BDMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamDisable(i2cp->tx.bdma);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#endif /* STM32_I2C4_USE_BDMA == TRUE */
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamDisable(i2cp->tx.dma);
- }
-#endif
-}
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-/**
- * @brief Slave address setup.
- * @note The RW bit is set to zero internally.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- *
- * @notapi
- */
-static void i2c_lld_set_address(I2CDriver *i2cp, i2caddr_t addr) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Address alignment depends on the addressing mode selected.*/
- if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0U)
- dp->CR2 = (uint32_t)addr << 1U;
- else
- dp->CR2 = (uint32_t)addr;
-}
-
-/**
- * @brief I2C RX transfer setup.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_setup_rx_transfer(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- uint32_t reload;
- size_t n;
-
- /* The unit can transfer 255 bytes maximum in a single operation.*/
- n = i2cp->rxbytes;
- if (n > 255U) {
- n = 255U;
- reload = I2C_CR2_RELOAD;
- }
- else {
- reload = 0U;
- }
- i2cp->rxbytes -= n;
-
- /* Configures the CR2 registers with both the calculated and static
- settings.*/
- dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
- I2C_CR2_RD_WRN | (n << 16U) | reload;
-}
-
-/**
- * @brief I2C TX transfer setup.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_setup_tx_transfer(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
- uint32_t reload;
- size_t n;
-
- /* The unit can transfer 255 bytes maximum in a single operation.*/
- n = i2cp->txbytes;
- if (n > 255U) {
- n = 255U;
- reload = I2C_CR2_RELOAD;
- }
- else {
- reload = 0U;
- }
- i2cp->txbytes -= n;
-
- /* Configures the CR2 registers with both the calculated and static
- settings.*/
- dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
- (n << 16U) | reload;
-}
-
-/**
- * @brief Aborts an I2C transaction.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-static void i2c_lld_abort_operation(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- if (dp->CR1 & I2C_CR1_PE) {
- /* Stops the I2C peripheral.*/
- dp->CR1 &= ~I2C_CR1_PE;
- while (dp->CR1 & I2C_CR1_PE)
- dp->CR1 &= ~I2C_CR1_PE;
- dp->CR1 |= I2C_CR1_PE;
- }
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Stops the associated DMA streams.*/
- i2c_lld_stop_rx_dma(i2cp);
- i2c_lld_stop_tx_dma(i2cp);
-#else
- dp->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
-#endif
-}
-
-/**
- * @brief I2C shared ISR code.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] isr content of the ISR register to be decoded
- *
- * @notapi
- */
-static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Special case of a received NACK, the transfer is aborted.*/
- if ((isr & I2C_ISR_NACKF) != 0U) {
-#if STM32_I2C_USE_DMA == TRUE
- /* Stops the associated DMA streams.*/
- i2c_lld_stop_rx_dma(i2cp);
- i2c_lld_stop_tx_dma(i2cp);
-#endif
-
- /* Error flag.*/
- i2cp->errors |= I2C_ACK_FAILURE;
-
- /* Transaction finished sending the STOP.*/
- dp->CR2 |= I2C_CR2_STOP;
-
- /* Make sure no more interrupts.*/
- dp->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_TXIE | I2C_CR1_RXIE);
-
- /* Errors are signaled to the upper layer.*/
- _i2c_wakeup_error_isr(i2cp);
-
- return;
- }
-
-#if STM32_I2C_USE_DMA == FALSE
- /* Handling of data transfer if the DMA mode is disabled.*/
- {
- uint32_t cr1 = dp->CR1;
-
- if (i2cp->state == I2C_ACTIVE_TX) {
- /* Transmission phase.*/
- if (((cr1 &I2C_CR1_TXIE) != 0U) && ((isr & I2C_ISR_TXIS) != 0U)) {
- dp->TXDR = (uint32_t)*i2cp->txptr;
- i2cp->txptr++;
- i2cp->txbytes--;
- if (i2cp->txbytes == 0U) {
- dp->CR1 &= ~I2C_CR1_TXIE;
- }
- }
- }
- else {
- /* Receive phase.*/
- if (((cr1 & I2C_CR1_RXIE) != 0U) && ((isr & I2C_ISR_RXNE) != 0U)) {
- *i2cp->rxptr = (uint8_t)dp->RXDR;
- i2cp->rxptr++;
- i2cp->rxbytes--;
- if (i2cp->rxbytes == 0U) {
- dp->CR1 &= ~I2C_CR1_RXIE;
- }
- }
- }
- }
-#endif
-
- /* Partial transfer handling, restarting the transfer and returning.*/
- if ((isr & I2C_ISR_TCR) != 0U) {
- if (i2cp->state == I2C_ACTIVE_TX) {
- i2c_lld_setup_tx_transfer(i2cp);
- }
- else {
- i2c_lld_setup_rx_transfer(i2cp);
- }
- return;
- }
-
- /* The following condition is true if a transfer phase has been completed.*/
- if ((isr & I2C_ISR_TC) != 0U) {
- if (i2cp->state == I2C_ACTIVE_TX) {
- /* End of the transmit phase.*/
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Disabling TX DMA channel.*/
- i2c_lld_stop_tx_dma(i2cp);
-#endif
-
- /* Starting receive phase if necessary.*/
- if (i2cp->rxbytes > 0U) {
- /* Setting up the peripheral.*/
- i2c_lld_setup_rx_transfer(i2cp);
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Enabling RX DMA.*/
- i2c_lld_start_rx_dma(i2cp);
-#else
- /* RX interrupt enabled.*/
- dp->CR1 |= I2C_CR1_RXIE;
-#endif
-
- /* Starts the read operation.*/
- dp->CR2 |= I2C_CR2_START;
-
- /* State change.*/
- i2cp->state = I2C_ACTIVE_RX;
-
- /* Note, returning because the transaction is not over yet.*/
- return;
- }
- }
- else {
- /* End of the receive phase.*/
-#if STM32_I2C_USE_DMA == TRUE
- /* Disabling RX DMA channel.*/
- i2c_lld_stop_rx_dma(i2cp);
-#endif
- }
-
- /* Transaction finished sending the STOP.*/
- dp->CR2 |= I2C_CR2_STOP;
-
- /* Make sure no more 'Transfer Complete' interrupts.*/
- dp->CR1 &= ~I2C_CR1_TCIE;
-
- /* Normal transaction end.*/
- _i2c_wakeup_isr(i2cp);
- }
-}
-
-/**
- * @brief I2C error handler.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] isr content of the ISR register to be decoded
- *
- * @notapi
- */
-static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t isr) {
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Clears DMA interrupt flags just to be safe.*/
- i2c_lld_stop_rx_dma(i2cp);
- i2c_lld_stop_tx_dma(i2cp);
-#else
- /* Disabling RX and TX interrupts.*/
- i2cp->i2c->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
-#endif
-
- if (isr & I2C_ISR_BERR)
- i2cp->errors |= I2C_BUS_ERROR;
-
- if (isr & I2C_ISR_ARLO)
- i2cp->errors |= I2C_ARBITRATION_LOST;
-
- if (isr & I2C_ISR_OVR)
- i2cp->errors |= I2C_OVERRUN;
-
- if (isr & I2C_ISR_TIMEOUT)
- i2cp->errors |= I2C_TIMEOUT;
-
- /* If some error has been identified then wake the waiting thread.*/
- if (i2cp->errors != I2C_NO_ERROR)
- _i2c_wakeup_error_isr(i2cp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
-#if defined(STM32_I2C1_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C1 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C1_GLOBAL_HANDLER) {
- uint32_t isr = I2CD1.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD1.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD1, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C1_EVENT_HANDLER) && defined(STM32_I2C1_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
- uint32_t isr = I2CD1.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD1.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C1_ERROR_HANDLER) {
- uint32_t isr = I2CD1.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD1.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C1 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
-#if defined(STM32_I2C2_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C2 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C2_GLOBAL_HANDLER) {
- uint32_t isr = I2CD2.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD2.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD2, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C2_EVENT_HANDLER) && defined(STM32_I2C2_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
- uint32_t isr = I2CD2.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD2.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C2_ERROR_HANDLER) {
- uint32_t isr = I2CD2.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD2.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C2 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
-#if defined(STM32_I2C3_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C3 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C3_GLOBAL_HANDLER) {
- uint32_t isr = I2CD3.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD3.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD3, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C3_EVENT_HANDLER) && defined(STM32_I2C3_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
- uint32_t isr = I2CD3.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD3.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C3_ERROR_HANDLER) {
- uint32_t isr = I2CD3.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD3.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C3 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C3 */
-
-#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
-#if defined(STM32_I2C4_GLOBAL_HANDLER) || defined(__DOXYGEN__)
-/**
- * @brief I2C4 event interrupt handler.
- *
- * @notapi
- */
-OSAL_IRQ_HANDLER(STM32_I2C4_GLOBAL_HANDLER) {
- uint32_t isr = I2CD4.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD4.i2c->ICR = isr;
-
- if (isr & I2C_ERROR_MASK)
- i2c_lld_serve_error_interrupt(&I2CD4, isr);
- else if (isr & I2C_INT_MASK)
- i2c_lld_serve_interrupt(&I2CD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#elif defined(STM32_I2C4_EVENT_HANDLER) && defined(STM32_I2C4_ERROR_HANDLER)
-OSAL_IRQ_HANDLER(STM32_I2C4_EVENT_HANDLER) {
- uint32_t isr = I2CD4.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD4.i2c->ICR = isr & I2C_INT_MASK;
-
- i2c_lld_serve_interrupt(&I2CD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-OSAL_IRQ_HANDLER(STM32_I2C4_ERROR_HANDLER) {
- uint32_t isr = I2CD4.i2c->ISR;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Clearing IRQ bits.*/
- I2CD4.i2c->ICR = isr & I2C_ERROR_MASK;
-
- i2c_lld_serve_error_interrupt(&I2CD4, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#else
-#error "I2C4 interrupt handlers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C4 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level I2C driver initialization.
- *
- * @notapi
- */
-void i2c_lld_init(void) {
-
-#if STM32_I2C_USE_I2C1
- i2cObjectInit(&I2CD1);
- I2CD1.thread = NULL;
- I2CD1.i2c = I2C1;
-#if STM32_I2C_USE_DMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- I2CD1.is_bdma = false;
-#endif
- I2CD1.rx.dma = NULL;
- I2CD1.tx.dma = NULL;
-#endif
-#if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
-#elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C1_EVENT_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C1_ERROR_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
-#else
-#error "I2C1 interrupt numbers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2
- i2cObjectInit(&I2CD2);
- I2CD2.thread = NULL;
- I2CD2.i2c = I2C2;
-#if STM32_I2C_USE_DMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- I2CD2.is_bdma = false;
-#endif
- I2CD2.rx.dma = NULL;
- I2CD2.tx.dma = NULL;
-#endif
-#if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
-#elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C2_EVENT_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C2_ERROR_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
-#else
-#error "I2C2 interrupt numbers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3
- i2cObjectInit(&I2CD3);
- I2CD3.thread = NULL;
- I2CD3.i2c = I2C3;
-#if STM32_I2C_USE_DMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- I2CD3.is_bdma = false;
-#endif
- I2CD3.rx.dma = NULL;
- I2CD3.tx.dma = NULL;
-#endif
-#if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C3_GLOBAL_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
-#elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C3_EVENT_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C3_ERROR_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
-#else
-#error "I2C3 interrupt numbers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C3 */
-
-#if STM32_I2C_USE_I2C4
- i2cObjectInit(&I2CD4);
- I2CD4.thread = NULL;
- I2CD4.i2c = I2C4;
-#if STM32_I2C_USE_DMA == TRUE
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
-#if STM32_I2C4_USE_BDMA == TRUE
- I2CD4.is_bdma = true;
- I2CD4.rx.bdma = NULL;
- I2CD4.tx.bdma = NULL;
-#else
- I2CD4.is_bdma = false;
- I2CD4.rx.dma = NULL;
- I2CD4.tx.dma = NULL;
-#endif /* STM32_I2C4_USE_BDMA == TRUE */
-#endif /* defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED) */
-#endif /* STM32_I2C_USE_DMA == TRUE */
-#if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__)
- nvicEnableVector(STM32_I2C4_GLOBAL_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
-#elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER)
- nvicEnableVector(STM32_I2C4_EVENT_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
- nvicEnableVector(STM32_I2C4_ERROR_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
-#else
-#error "I2C4 interrupt numbers not defined"
-#endif
-#endif /* STM32_I2C_USE_I2C4 */
-}
-
-/**
- * @brief Configures and activates the I2C peripheral.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-void i2c_lld_start(I2CDriver *i2cp) {
- I2C_TypeDef *dp = i2cp->i2c;
-
- /* Make sure I2C peripheral is disabled */
- dp->CR1 &= ~I2C_CR1_PE;
-
- /* If in stopped state then enables the I2C and DMA clocks.*/
- if (i2cp->state == I2C_STOP) {
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Common DMA modes.*/
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- i2cp->txdmamode = BDMAMODE_COMMON | STM32_BDMA_CR_DIR_M2P;
- i2cp->rxdmamode = BDMAMODE_COMMON | STM32_BDMA_CR_DIR_P2M;
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- i2cp->txdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_M2P;
- i2cp->rxdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_P2M;
- }
-#endif
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-#if STM32_I2C_USE_I2C1
- if (&I2CD1 == i2cp) {
-
- rccResetI2C1();
- rccEnableI2C1(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
- STM32_I2C_I2C1_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
- i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C1_TX_DMA_STREAM,
- STM32_I2C_I2C1_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
- dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C1_RX);
- dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C1_TX);
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
- }
-#endif /* STM32_I2C_USE_I2C1 */
-
-#if STM32_I2C_USE_I2C2
- if (&I2CD2 == i2cp) {
-
- rccResetI2C2();
- rccEnableI2C2(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
- STM32_I2C_I2C2_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
- i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C2_TX_DMA_STREAM,
- STM32_I2C_I2C2_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
- dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C2_RX);
- dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C2_TX);
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
- }
-#endif /* STM32_I2C_USE_I2C2 */
-
-#if STM32_I2C_USE_I2C3
- if (&I2CD3 == i2cp) {
-
- rccResetI2C3();
- rccEnableI2C3(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
- i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
- STM32_I2C_I2C3_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
- i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C3_TX_DMA_STREAM,
- STM32_I2C_I2C3_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
- dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C3_RX);
- dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C3_TX);
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
- }
-#endif /* STM32_I2C_USE_I2C3 */
-
-#if STM32_I2C_USE_I2C4
- if (&I2CD4 == i2cp) {
-
- rccResetI2C4();
- rccEnableI2C4(true);
-#if STM32_I2C_USE_DMA == TRUE
- {
-#if STM32_I2C4_USE_BDMA == TRUE
- i2cp->rx.bdma = bdmaStreamAllocI(STM32_I2C_I2C4_RX_BDMA_STREAM,
- STM32_I2C_I2C4_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->rx.bdma != NULL, "unable to allocate stream");
- i2cp->tx.bdma = bdmaStreamAllocI(STM32_I2C_I2C4_TX_BDMA_STREAM,
- STM32_I2C_I2C4_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->tx.bdma != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_BDMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_BDMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
- bdmaSetRequestSource(i2cp->rx.bdma, STM32_DMAMUX2_I2C4_RX);
- bdmaSetRequestSource(i2cp->tx.bdma, STM32_DMAMUX2_I2C4_TX);
-#else /* STM32_I2C4_USE_BDMA != TRUE */
- i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C4_RX_DMA_STREAM,
- STM32_I2C_I2C4_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
- i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C4_TX_DMA_STREAM,
- STM32_I2C_I2C4_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
-
- i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
- i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
- dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C4_RX);
- dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C4_TX);
-#endif /* STM32_I2C4_USE_BDMA != TRUE */
- }
-#endif /* STM32_I2C_USE_DMA == TRUE */
- }
-#endif /* STM32_I2C_USE_I2C4 */
- }
-
-#if STM32_I2C_USE_DMA == TRUE
- /* I2C registers pointed by the DMA.*/
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamSetPeripheral(i2cp->rx.bdma, &dp->RXDR);
- bdmaStreamSetPeripheral(i2cp->tx.bdma, &dp->TXDR);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamSetPeripheral(i2cp->rx.dma, &dp->RXDR);
- dmaStreamSetPeripheral(i2cp->tx.dma, &dp->TXDR);
- }
-#endif
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
- /* Reset i2c peripheral, the TCIE bit will be handled separately.*/
- dp->CR1 = i2cp->config->cr1 |
-#if STM32_I2C_USE_DMA == TRUE
- I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN | /* Enable only if using DMA */
-#endif
- I2C_CR1_ERRIE | I2C_CR1_NACKIE;
-
- /* Setup I2C parameters.*/
- dp->TIMINGR = i2cp->config->timingr;
-
- /* Ready to go.*/
- dp->CR1 |= I2C_CR1_PE;
-}
-
-/**
- * @brief Deactivates the I2C peripheral.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-void i2c_lld_stop(I2CDriver *i2cp) {
-
- /* If not in stopped state then disables the I2C clock.*/
- if (i2cp->state != I2C_STOP) {
-
- /* I2C disable.*/
- i2c_lld_abort_operation(i2cp);
-
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamFreeI(i2cp->rx.bdma);
- bdmaStreamFreeI(i2cp->tx.bdma);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamFreeI(i2cp->rx.dma);
- dmaStreamFreeI(i2cp->tx.dma);
- }
-#endif
-
-#if STM32_I2C_USE_I2C1
- if (&I2CD1 == i2cp) {
- rccDisableI2C1();
- }
-#endif
-
-#if STM32_I2C_USE_I2C2
- if (&I2CD2 == i2cp) {
- rccDisableI2C2();
- }
-#endif
-
-#if STM32_I2C_USE_I2C3
- if (&I2CD3 == i2cp) {
- rccDisableI2C3();
- }
-#endif
-
-#if STM32_I2C_USE_I2C4
- if (&I2CD4 == i2cp) {
- rccDisableI2C4();
- }
-#endif
- }
-}
-
-/**
- * @brief Receives data via the I2C bus as master.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- * @param[out] rxbuf pointer to the receive buffer
- * @param[in] rxbytes number of bytes to be received
- * @param[in] timeout the number of ticks before the operation timeouts,
- * the following special values are allowed:
- * - @a TIME_INFINITE no timeout.
- * .
- * @return The operation status.
- * @retval MSG_OK if the function succeeded.
- * @retval MSG_RESET if one or more I2C errors occurred, the errors can
- * be retrieved using @p i2cGetErrors().
- * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
- * timeout the driver must be stopped and restarted
- * because the bus is in an uncertain state.
- *
- * @notapi
- */
-msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout) {
- msg_t msg;
- I2C_TypeDef *dp = i2cp->i2c;
- systime_t start, end;
-
- /* Resetting error flags for this transfer.*/
- i2cp->errors = I2C_NO_ERROR;
-
- /* Releases the lock from high level driver.*/
- osalSysUnlock();
-
- /* Sizes of transfer phases.*/
- i2cp->txbytes = 0U;
- i2cp->rxbytes = rxbytes;
-
-#if STM32_I2C_USE_DMA == TRUE
- /* RX DMA setup.*/
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamSetMode(i2cp->rx.bdma, i2cp->rxdmamode);
- bdmaStreamSetMemory(i2cp->rx.bdma, rxbuf);
- bdmaStreamSetTransactionSize(i2cp->rx.bdma, rxbytes);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamSetMode(i2cp->rx.dma, i2cp->rxdmamode);
- dmaStreamSetMemory0(i2cp->rx.dma, rxbuf);
- dmaStreamSetTransactionSize(i2cp->rx.dma, rxbytes);
- }
-#endif
-#else
- i2cp->rxptr = rxbuf;
-#endif
-
- /* Calculating the time window for the timeout on the busy bus condition.*/
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
-
- /* Waits until BUSY flag is reset or, alternatively, for a timeout
- condition.*/
- while (true) {
- osalSysLock();
-
- /* If the bus is not busy then the operation can continue, note, the
- loop is exited in the locked state.*/
- if ((dp->ISR & I2C_ISR_BUSY) == 0)
- break;
-
- /* If the system time went outside the allowed window then a timeout
- condition is returned.*/
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return MSG_TIMEOUT;
- }
-
- osalSysUnlock();
- }
-
- /* Setting up the slave address.*/
- i2c_lld_set_address(i2cp, addr);
-
- /* Setting up the peripheral.*/
- i2c_lld_setup_rx_transfer(i2cp);
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Enabling RX DMA.*/
- i2c_lld_start_rx_dma(i2cp);
-
- /* Transfer complete interrupt enabled.*/
- dp->CR1 |= I2C_CR1_TCIE;
-#else
-
- /* Transfer complete and RX interrupts enabled.*/
- dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_RXIE;
-#endif
-
- /* Starts the operation.*/
- dp->CR2 |= I2C_CR2_START;
-
- /* Waits for the operation completion or a timeout.*/
- msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
-
- /* In case of a software timeout a STOP is sent as an extreme attempt
- to release the bus and DMA is forcibly disabled.*/
- if (msg == MSG_TIMEOUT) {
- dp->CR2 |= I2C_CR2_STOP;
-#if STM32_I2C_USE_DMA == TRUE
- i2c_lld_stop_rx_dma(i2cp);
-#endif
- }
-
- return msg;
-}
-
-/**
- * @brief Transmits data via the I2C bus as master.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- * @param[in] addr slave device address
- * @param[in] txbuf pointer to the transmit buffer
- * @param[in] txbytes number of bytes to be transmitted
- * @param[out] rxbuf pointer to the receive buffer
- * @param[in] rxbytes number of bytes to be received
- * @param[in] timeout the number of ticks before the operation timeouts,
- * the following special values are allowed:
- * - @a TIME_INFINITE no timeout.
- * .
- * @return The operation status.
- * @retval MSG_OK if the function succeeded.
- * @retval MSG_RESET if one or more I2C errors occurred, the errors can
- * be retrieved using @p i2cGetErrors().
- * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
- * timeout the driver must be stopped and restarted
- * because the bus is in an uncertain state.
- *
- * @notapi
- */
-msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
- const uint8_t *txbuf, size_t txbytes,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout) {
- msg_t msg;
- I2C_TypeDef *dp = i2cp->i2c;
- systime_t start, end;
-
- /* Resetting error flags for this transfer.*/
- i2cp->errors = I2C_NO_ERROR;
-
- /* Releases the lock from high level driver.*/
- osalSysUnlock();
-
- /* Sizes of transfer phases.*/
- i2cp->txbytes = txbytes;
- i2cp->rxbytes = rxbytes;
-
-#if STM32_I2C_USE_DMA == TRUE
- /* TX and RX DMA setup.*/
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- if (i2cp->is_bdma)
-#endif
-#if defined(STM32_I2C_BDMA_REQUIRED)
- {
- bdmaStreamSetMode(i2cp->tx.bdma, i2cp->txdmamode);
- bdmaStreamSetMemory(i2cp->tx.bdma, txbuf);
- bdmaStreamSetTransactionSize(i2cp->tx.bdma, txbytes);
-
- bdmaStreamSetMode(i2cp->rx.bdma, i2cp->rxdmamode);
- bdmaStreamSetMemory(i2cp->rx.bdma, rxbuf);
- bdmaStreamSetTransactionSize(i2cp->rx.bdma, rxbytes);
- }
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_I2C_DMA_REQUIRED)
- {
- dmaStreamSetMode(i2cp->tx.dma, i2cp->txdmamode);
- dmaStreamSetMemory0(i2cp->tx.dma, txbuf);
- dmaStreamSetTransactionSize(i2cp->tx.dma, txbytes);
-
- dmaStreamSetMode(i2cp->rx.dma, i2cp->rxdmamode);
- dmaStreamSetMemory0(i2cp->rx.dma, rxbuf);
- dmaStreamSetTransactionSize(i2cp->rx.dma, rxbytes);
- }
-#endif
-#else
- i2cp->txptr = txbuf;
- i2cp->rxptr = rxbuf;
-#endif
-
- /* Calculating the time window for the timeout on the busy bus condition.*/
- start = osalOsGetSystemTimeX();
- end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
-
- /* Waits until BUSY flag is reset or, alternatively, for a timeout
- condition.*/
- while (true) {
- osalSysLock();
-
- /* If the bus is not busy then the operation can continue, note, the
- loop is exited in the locked state.*/
- if ((dp->ISR & I2C_ISR_BUSY) == 0)
- break;
-
- /* If the system time went outside the allowed window then a timeout
- condition is returned.*/
- if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
- return MSG_TIMEOUT;
- }
-
- osalSysUnlock();
- }
-
- /* Setting up the slave address.*/
- i2c_lld_set_address(i2cp, addr);
-
- /* Preparing the transfer.*/
- i2c_lld_setup_tx_transfer(i2cp);
-
-#if STM32_I2C_USE_DMA == TRUE
- /* Enabling TX DMA.*/
- i2c_lld_start_tx_dma(i2cp);
-
- /* Transfer complete interrupt enabled.*/
- dp->CR1 |= I2C_CR1_TCIE;
-#else
- /* Transfer complete and TX interrupts enabled.*/
- dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_TXIE;
-#endif
-
- /* Starts the operation.*/
- dp->CR2 |= I2C_CR2_START;
-
- /* Waits for the operation completion or a timeout.*/
- msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
-
- /* In case of a software timeout a STOP is sent as an extreme attempt
- to release the bus and DMA is forcibly disabled.*/
- if (msg == MSG_TIMEOUT) {
- dp->CR2 |= I2C_CR2_STOP;
-#if STM32_I2C_USE_DMA == TRUE
- i2c_lld_stop_rx_dma(i2cp);
- i2c_lld_stop_tx_dma(i2cp);
-#endif
- }
-
- return msg;
-}
-
-#endif /* HAL_USE_I2C */
-
-/** @} */
+/*
+ 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 I2Cv3/hal_i2c_lld.c
+ * @brief STM32 I2C subsystem low level driver source.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#if STM32_I2C_USE_DMA == TRUE
+
+#if defined(STM32_I2C_DMA_REQUIRED)
+#define DMAMODE_COMMON \
+ (STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | \
+ STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE | \
+ STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE)
+#endif
+
+#if defined(STM32_I2C_BDMA_REQUIRED)
+#define BDMAMODE_COMMON \
+ (STM32_BDMA_CR_PSIZE_BYTE | STM32_BDMA_CR_MSIZE_BYTE | \
+ STM32_BDMA_CR_MINC | \
+ STM32_BDMA_CR_TEIE | STM32_BDMA_CR_TCIE)
+#endif
+
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if 0
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ }
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+#define I2C_ERROR_MASK \
+ ((uint32_t)(I2C_ISR_BERR | I2C_ISR_ARLO | I2C_ISR_OVR | I2C_ISR_PECERR | \
+ I2C_ISR_TIMEOUT | I2C_ISR_ALERT))
+
+#define I2C_INT_MASK \
+ ((uint32_t)(I2C_ISR_TCR | I2C_ISR_TC | I2C_ISR_STOPF | I2C_ISR_NACKF | \
+ I2C_ISR_ADDR | I2C_ISR_RXNE | I2C_ISR_TXIS))
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief I2C1 driver identifier.*/
+#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
+I2CDriver I2CD1;
+#endif
+
+/** @brief I2C2 driver identifier.*/
+#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
+I2CDriver I2CD2;
+#endif
+
+/** @brief I2C3 driver identifier.*/
+#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
+I2CDriver I2CD3;
+#endif
+
+/** @brief I2C4 driver identifier.*/
+#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
+I2CDriver I2CD4;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#if STM32_I2C_USE_DMA == TRUE
+static inline void i2c_lld_start_rx_dma(I2CDriver *i2cp) {
+
+#if STM32_I2C4_USE_BDMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamEnable(i2cp->rx.bdma);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#endif /* STM32_I2C4_USE_BDMA == TRUE */
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamEnable(i2cp->rx.dma);
+ }
+#endif
+}
+
+static inline void i2c_lld_start_tx_dma(I2CDriver *i2cp) {
+
+#if STM32_I2C4_USE_BDMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamEnable(i2cp->tx.bdma);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#endif /* STM32_I2C4_USE_BDMA == TRUE */
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamEnable(i2cp->tx.dma);
+ }
+#endif
+}
+
+static inline void i2c_lld_stop_rx_dma(I2CDriver *i2cp) {
+
+#if STM32_I2C4_USE_BDMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamDisable(i2cp->rx.bdma);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#endif /* STM32_I2C4_USE_BDMA == TRUE */
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamDisable(i2cp->rx.dma);
+ }
+#endif
+}
+
+static inline void i2c_lld_stop_tx_dma(I2CDriver *i2cp) {
+
+#if STM32_I2C4_USE_BDMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamDisable(i2cp->tx.bdma);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#endif /* STM32_I2C4_USE_BDMA == TRUE */
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamDisable(i2cp->tx.dma);
+ }
+#endif
+}
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+/**
+ * @brief Slave address setup.
+ * @note The RW bit is set to zero internally.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ *
+ * @notapi
+ */
+static void i2c_lld_set_address(I2CDriver *i2cp, i2caddr_t addr) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Address alignment depends on the addressing mode selected.*/
+ if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0U)
+ dp->CR2 = (uint32_t)addr << 1U;
+ else
+ dp->CR2 = (uint32_t)addr;
+}
+
+/**
+ * @brief I2C RX transfer setup.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_setup_rx_transfer(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ uint32_t reload;
+ size_t n;
+
+ /* The unit can transfer 255 bytes maximum in a single operation.*/
+ n = i2cp->rxbytes;
+ if (n > 255U) {
+ n = 255U;
+ reload = I2C_CR2_RELOAD;
+ }
+ else {
+ reload = 0U;
+ }
+ i2cp->rxbytes -= n;
+
+ /* Configures the CR2 registers with both the calculated and static
+ settings.*/
+ dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
+ I2C_CR2_RD_WRN | (n << 16U) | reload;
+}
+
+/**
+ * @brief I2C TX transfer setup.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_setup_tx_transfer(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+ uint32_t reload;
+ size_t n;
+
+ /* The unit can transfer 255 bytes maximum in a single operation.*/
+ n = i2cp->txbytes;
+ if (n > 255U) {
+ n = 255U;
+ reload = I2C_CR2_RELOAD;
+ }
+ else {
+ reload = 0U;
+ }
+ i2cp->txbytes -= n;
+
+ /* Configures the CR2 registers with both the calculated and static
+ settings.*/
+ dp->CR2 = (dp->CR2 & ~(I2C_CR2_NBYTES | I2C_CR2_RELOAD)) | i2cp->config->cr2 |
+ (n << 16U) | reload;
+}
+
+/**
+ * @brief Aborts an I2C transaction.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+static void i2c_lld_abort_operation(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ if (dp->CR1 & I2C_CR1_PE) {
+ /* Stops the I2C peripheral.*/
+ dp->CR1 &= ~I2C_CR1_PE;
+ while (dp->CR1 & I2C_CR1_PE)
+ dp->CR1 &= ~I2C_CR1_PE;
+ dp->CR1 |= I2C_CR1_PE;
+ }
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Stops the associated DMA streams.*/
+ i2c_lld_stop_rx_dma(i2cp);
+ i2c_lld_stop_tx_dma(i2cp);
+#else
+ dp->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
+#endif
+}
+
+/**
+ * @brief I2C shared ISR code.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] isr content of the ISR register to be decoded
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Special case of a received NACK, the transfer is aborted.*/
+ if ((isr & I2C_ISR_NACKF) != 0U) {
+#if STM32_I2C_USE_DMA == TRUE
+ /* Stops the associated DMA streams.*/
+ i2c_lld_stop_rx_dma(i2cp);
+ i2c_lld_stop_tx_dma(i2cp);
+#endif
+
+ /* Error flag.*/
+ i2cp->errors |= I2C_ACK_FAILURE;
+
+ /* Transaction finished sending the STOP.*/
+ dp->CR2 |= I2C_CR2_STOP;
+
+ /* Make sure no more interrupts.*/
+ dp->CR1 &= ~(I2C_CR1_TCIE | I2C_CR1_TXIE | I2C_CR1_RXIE);
+
+ /* Errors are signaled to the upper layer.*/
+ _i2c_wakeup_error_isr(i2cp);
+
+ return;
+ }
+
+#if STM32_I2C_USE_DMA == FALSE
+ /* Handling of data transfer if the DMA mode is disabled.*/
+ {
+ uint32_t cr1 = dp->CR1;
+
+ if (i2cp->state == I2C_ACTIVE_TX) {
+ /* Transmission phase.*/
+ if (((cr1 &I2C_CR1_TXIE) != 0U) && ((isr & I2C_ISR_TXIS) != 0U)) {
+ dp->TXDR = (uint32_t)*i2cp->txptr;
+ i2cp->txptr++;
+ i2cp->txbytes--;
+ if (i2cp->txbytes == 0U) {
+ dp->CR1 &= ~I2C_CR1_TXIE;
+ }
+ }
+ }
+ else {
+ /* Receive phase.*/
+ if (((cr1 & I2C_CR1_RXIE) != 0U) && ((isr & I2C_ISR_RXNE) != 0U)) {
+ *i2cp->rxptr = (uint8_t)dp->RXDR;
+ i2cp->rxptr++;
+ i2cp->rxbytes--;
+ if (i2cp->rxbytes == 0U) {
+ dp->CR1 &= ~I2C_CR1_RXIE;
+ }
+ }
+ }
+ }
+#endif
+
+ /* Partial transfer handling, restarting the transfer and returning.*/
+ if ((isr & I2C_ISR_TCR) != 0U) {
+ if (i2cp->state == I2C_ACTIVE_TX) {
+ i2c_lld_setup_tx_transfer(i2cp);
+ }
+ else {
+ i2c_lld_setup_rx_transfer(i2cp);
+ }
+ return;
+ }
+
+ /* The following condition is true if a transfer phase has been completed.*/
+ if ((isr & I2C_ISR_TC) != 0U) {
+ if (i2cp->state == I2C_ACTIVE_TX) {
+ /* End of the transmit phase.*/
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Disabling TX DMA channel.*/
+ i2c_lld_stop_tx_dma(i2cp);
+#endif
+
+ /* Starting receive phase if necessary.*/
+ if (i2cp->rxbytes > 0U) {
+ /* Setting up the peripheral.*/
+ i2c_lld_setup_rx_transfer(i2cp);
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Enabling RX DMA.*/
+ i2c_lld_start_rx_dma(i2cp);
+#else
+ /* RX interrupt enabled.*/
+ dp->CR1 |= I2C_CR1_RXIE;
+#endif
+
+ /* Starts the read operation.*/
+ dp->CR2 |= I2C_CR2_START;
+
+ /* State change.*/
+ i2cp->state = I2C_ACTIVE_RX;
+
+ /* Note, returning because the transaction is not over yet.*/
+ return;
+ }
+ }
+ else {
+ /* End of the receive phase.*/
+#if STM32_I2C_USE_DMA == TRUE
+ /* Disabling RX DMA channel.*/
+ i2c_lld_stop_rx_dma(i2cp);
+#endif
+ }
+
+ /* Transaction finished sending the STOP.*/
+ dp->CR2 |= I2C_CR2_STOP;
+
+ /* Make sure no more 'Transfer Complete' interrupts.*/
+ dp->CR1 &= ~I2C_CR1_TCIE;
+
+ /* Normal transaction end.*/
+ _i2c_wakeup_isr(i2cp);
+ }
+}
+
+/**
+ * @brief I2C error handler.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] isr content of the ISR register to be decoded
+ *
+ * @notapi
+ */
+static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t isr) {
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Clears DMA interrupt flags just to be safe.*/
+ i2c_lld_stop_rx_dma(i2cp);
+ i2c_lld_stop_tx_dma(i2cp);
+#else
+ /* Disabling RX and TX interrupts.*/
+ i2cp->i2c->CR1 &= ~(I2C_CR1_TXIE | I2C_CR1_RXIE);
+#endif
+
+ if (isr & I2C_ISR_BERR)
+ i2cp->errors |= I2C_BUS_ERROR;
+
+ if (isr & I2C_ISR_ARLO)
+ i2cp->errors |= I2C_ARBITRATION_LOST;
+
+ if (isr & I2C_ISR_OVR)
+ i2cp->errors |= I2C_OVERRUN;
+
+ if (isr & I2C_ISR_TIMEOUT)
+ i2cp->errors |= I2C_TIMEOUT;
+
+ /* If some error has been identified then wake the waiting thread.*/
+ if (i2cp->errors != I2C_NO_ERROR)
+ _i2c_wakeup_error_isr(i2cp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_I2C_USE_I2C1 || defined(__DOXYGEN__)
+#if defined(STM32_I2C1_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C1 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C1_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD1.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD1.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD1, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C1_EVENT_HANDLER) && defined(STM32_I2C1_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
+ uint32_t isr = I2CD1.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD1.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C1_ERROR_HANDLER) {
+ uint32_t isr = I2CD1.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD1.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C1 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2 || defined(__DOXYGEN__)
+#if defined(STM32_I2C2_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C2 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C2_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD2.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD2.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD2, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C2_EVENT_HANDLER) && defined(STM32_I2C2_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
+ uint32_t isr = I2CD2.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD2.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C2_ERROR_HANDLER) {
+ uint32_t isr = I2CD2.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD2.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C2 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3 || defined(__DOXYGEN__)
+#if defined(STM32_I2C3_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C3 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C3_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD3.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD3.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD3, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C3_EVENT_HANDLER) && defined(STM32_I2C3_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
+ uint32_t isr = I2CD3.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD3.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C3_ERROR_HANDLER) {
+ uint32_t isr = I2CD3.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD3.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C3 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C3 */
+
+#if STM32_I2C_USE_I2C4 || defined(__DOXYGEN__)
+#if defined(STM32_I2C4_GLOBAL_HANDLER) || defined(__DOXYGEN__)
+/**
+ * @brief I2C4 event interrupt handler.
+ *
+ * @notapi
+ */
+OSAL_IRQ_HANDLER(STM32_I2C4_GLOBAL_HANDLER) {
+ uint32_t isr = I2CD4.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD4.i2c->ICR = isr;
+
+ if (isr & I2C_ERROR_MASK)
+ i2c_lld_serve_error_interrupt(&I2CD4, isr);
+ else if (isr & I2C_INT_MASK)
+ i2c_lld_serve_interrupt(&I2CD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#elif defined(STM32_I2C4_EVENT_HANDLER) && defined(STM32_I2C4_ERROR_HANDLER)
+OSAL_IRQ_HANDLER(STM32_I2C4_EVENT_HANDLER) {
+ uint32_t isr = I2CD4.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD4.i2c->ICR = isr & I2C_INT_MASK;
+
+ i2c_lld_serve_interrupt(&I2CD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+OSAL_IRQ_HANDLER(STM32_I2C4_ERROR_HANDLER) {
+ uint32_t isr = I2CD4.i2c->ISR;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Clearing IRQ bits.*/
+ I2CD4.i2c->ICR = isr & I2C_ERROR_MASK;
+
+ i2c_lld_serve_error_interrupt(&I2CD4, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#else
+#error "I2C4 interrupt handlers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C4 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2C driver initialization.
+ *
+ * @notapi
+ */
+void i2c_lld_init(void) {
+
+#if STM32_I2C_USE_I2C1
+ i2cObjectInit(&I2CD1);
+ I2CD1.thread = NULL;
+ I2CD1.i2c = I2C1;
+#if STM32_I2C_USE_DMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ I2CD1.is_bdma = false;
+#endif
+ I2CD1.rx.dma = NULL;
+ I2CD1.tx.dma = NULL;
+#endif
+#if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
+#elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C1_EVENT_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C1_ERROR_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY);
+#else
+#error "I2C1 interrupt numbers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2
+ i2cObjectInit(&I2CD2);
+ I2CD2.thread = NULL;
+ I2CD2.i2c = I2C2;
+#if STM32_I2C_USE_DMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ I2CD2.is_bdma = false;
+#endif
+ I2CD2.rx.dma = NULL;
+ I2CD2.tx.dma = NULL;
+#endif
+#if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
+#elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C2_EVENT_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C2_ERROR_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY);
+#else
+#error "I2C2 interrupt numbers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3
+ i2cObjectInit(&I2CD3);
+ I2CD3.thread = NULL;
+ I2CD3.i2c = I2C3;
+#if STM32_I2C_USE_DMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ I2CD3.is_bdma = false;
+#endif
+ I2CD3.rx.dma = NULL;
+ I2CD3.tx.dma = NULL;
+#endif
+#if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C3_GLOBAL_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
+#elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C3_EVENT_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C3_ERROR_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY);
+#else
+#error "I2C3 interrupt numbers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C3 */
+
+#if STM32_I2C_USE_I2C4
+ i2cObjectInit(&I2CD4);
+ I2CD4.thread = NULL;
+ I2CD4.i2c = I2C4;
+#if STM32_I2C_USE_DMA == TRUE
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+#if STM32_I2C4_USE_BDMA == TRUE
+ I2CD4.is_bdma = true;
+ I2CD4.rx.bdma = NULL;
+ I2CD4.tx.bdma = NULL;
+#else
+ I2CD4.is_bdma = false;
+ I2CD4.rx.dma = NULL;
+ I2CD4.tx.dma = NULL;
+#endif /* STM32_I2C4_USE_BDMA == TRUE */
+#endif /* defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED) */
+#endif /* STM32_I2C_USE_DMA == TRUE */
+#if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__)
+ nvicEnableVector(STM32_I2C4_GLOBAL_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
+#elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER)
+ nvicEnableVector(STM32_I2C4_EVENT_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
+ nvicEnableVector(STM32_I2C4_ERROR_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY);
+#else
+#error "I2C4 interrupt numbers not defined"
+#endif
+#endif /* STM32_I2C_USE_I2C4 */
+}
+
+/**
+ * @brief Configures and activates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_start(I2CDriver *i2cp) {
+ I2C_TypeDef *dp = i2cp->i2c;
+
+ /* Make sure I2C peripheral is disabled */
+ dp->CR1 &= ~I2C_CR1_PE;
+
+ /* If in stopped state then enables the I2C and DMA clocks.*/
+ if (i2cp->state == I2C_STOP) {
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Common DMA modes.*/
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ i2cp->txdmamode = BDMAMODE_COMMON | STM32_BDMA_CR_DIR_M2P;
+ i2cp->rxdmamode = BDMAMODE_COMMON | STM32_BDMA_CR_DIR_P2M;
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ i2cp->txdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_M2P;
+ i2cp->rxdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_P2M;
+ }
+#endif
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+#if STM32_I2C_USE_I2C1
+ if (&I2CD1 == i2cp) {
+
+ rccResetI2C1();
+ rccEnableI2C1(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM,
+ STM32_I2C_I2C1_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
+ i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C1_TX_DMA_STREAM,
+ STM32_I2C_I2C1_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY);
+ dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C1_RX);
+ dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C1_TX);
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+ }
+#endif /* STM32_I2C_USE_I2C1 */
+
+#if STM32_I2C_USE_I2C2
+ if (&I2CD2 == i2cp) {
+
+ rccResetI2C2();
+ rccEnableI2C2(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM,
+ STM32_I2C_I2C2_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
+ i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C2_TX_DMA_STREAM,
+ STM32_I2C_I2C2_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY);
+ dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C2_RX);
+ dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C2_TX);
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+ }
+#endif /* STM32_I2C_USE_I2C2 */
+
+#if STM32_I2C_USE_I2C3
+ if (&I2CD3 == i2cp) {
+
+ rccResetI2C3();
+ rccEnableI2C3(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+ i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM,
+ STM32_I2C_I2C3_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
+ i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C3_TX_DMA_STREAM,
+ STM32_I2C_I2C3_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY);
+ dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C3_RX);
+ dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C3_TX);
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+ }
+#endif /* STM32_I2C_USE_I2C3 */
+
+#if STM32_I2C_USE_I2C4
+ if (&I2CD4 == i2cp) {
+
+ rccResetI2C4();
+ rccEnableI2C4(true);
+#if STM32_I2C_USE_DMA == TRUE
+ {
+#if STM32_I2C4_USE_BDMA == TRUE
+ i2cp->rx.bdma = bdmaStreamAllocI(STM32_I2C_I2C4_RX_BDMA_STREAM,
+ STM32_I2C_I2C4_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->rx.bdma != NULL, "unable to allocate stream");
+ i2cp->tx.bdma = bdmaStreamAllocI(STM32_I2C_I2C4_TX_BDMA_STREAM,
+ STM32_I2C_I2C4_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->tx.bdma != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_BDMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_BDMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
+ bdmaSetRequestSource(i2cp->rx.bdma, STM32_DMAMUX2_I2C4_RX);
+ bdmaSetRequestSource(i2cp->tx.bdma, STM32_DMAMUX2_I2C4_TX);
+#else /* STM32_I2C4_USE_BDMA != TRUE */
+ i2cp->rx.dma = dmaStreamAllocI(STM32_I2C_I2C4_RX_DMA_STREAM,
+ STM32_I2C_I2C4_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->rx.dma != NULL, "unable to allocate stream");
+ i2cp->tx.dma = dmaStreamAllocI(STM32_I2C_I2C4_TX_DMA_STREAM,
+ STM32_I2C_I2C4_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(i2cp->tx.dma != NULL, "unable to allocate stream");
+
+ i2cp->rxdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
+ i2cp->txdmamode |= STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY);
+ dmaSetRequestSource(i2cp->rx.dma, STM32_DMAMUX1_I2C4_RX);
+ dmaSetRequestSource(i2cp->tx.dma, STM32_DMAMUX1_I2C4_TX);
+#endif /* STM32_I2C4_USE_BDMA != TRUE */
+ }
+#endif /* STM32_I2C_USE_DMA == TRUE */
+ }
+#endif /* STM32_I2C_USE_I2C4 */
+ }
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* I2C registers pointed by the DMA.*/
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamSetPeripheral(i2cp->rx.bdma, &dp->RXDR);
+ bdmaStreamSetPeripheral(i2cp->tx.bdma, &dp->TXDR);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamSetPeripheral(i2cp->rx.dma, &dp->RXDR);
+ dmaStreamSetPeripheral(i2cp->tx.dma, &dp->TXDR);
+ }
+#endif
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+ /* Reset i2c peripheral, the TCIE bit will be handled separately.*/
+ dp->CR1 = i2cp->config->cr1 |
+#if STM32_I2C_USE_DMA == TRUE
+ I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN | /* Enable only if using DMA */
+#endif
+ I2C_CR1_ERRIE | I2C_CR1_NACKIE;
+
+ /* Setup I2C parameters.*/
+ dp->TIMINGR = i2cp->config->timingr;
+
+ /* Ready to go.*/
+ dp->CR1 |= I2C_CR1_PE;
+}
+
+/**
+ * @brief Deactivates the I2C peripheral.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+void i2c_lld_stop(I2CDriver *i2cp) {
+
+ /* If not in stopped state then disables the I2C clock.*/
+ if (i2cp->state != I2C_STOP) {
+
+ /* I2C disable.*/
+ i2c_lld_abort_operation(i2cp);
+
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamFreeI(i2cp->rx.bdma);
+ bdmaStreamFreeI(i2cp->tx.bdma);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamFreeI(i2cp->rx.dma);
+ dmaStreamFreeI(i2cp->tx.dma);
+ }
+#endif
+
+#if STM32_I2C_USE_I2C1
+ if (&I2CD1 == i2cp) {
+ rccDisableI2C1();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C2
+ if (&I2CD2 == i2cp) {
+ rccDisableI2C2();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C3
+ if (&I2CD3 == i2cp) {
+ rccDisableI2C3();
+ }
+#endif
+
+#if STM32_I2C_USE_I2C4
+ if (&I2CD4 == i2cp) {
+ rccDisableI2C4();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Receives data via the I2C bus as master.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval MSG_OK if the function succeeded.
+ * @retval MSG_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout) {
+ msg_t msg;
+ I2C_TypeDef *dp = i2cp->i2c;
+ systime_t start, end;
+
+ /* Resetting error flags for this transfer.*/
+ i2cp->errors = I2C_NO_ERROR;
+
+ /* Releases the lock from high level driver.*/
+ osalSysUnlock();
+
+ /* Sizes of transfer phases.*/
+ i2cp->txbytes = 0U;
+ i2cp->rxbytes = rxbytes;
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* RX DMA setup.*/
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamSetMode(i2cp->rx.bdma, i2cp->rxdmamode);
+ bdmaStreamSetMemory(i2cp->rx.bdma, rxbuf);
+ bdmaStreamSetTransactionSize(i2cp->rx.bdma, rxbytes);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamSetMode(i2cp->rx.dma, i2cp->rxdmamode);
+ dmaStreamSetMemory0(i2cp->rx.dma, rxbuf);
+ dmaStreamSetTransactionSize(i2cp->rx.dma, rxbytes);
+ }
+#endif
+#else
+ i2cp->rxptr = rxbuf;
+#endif
+
+ /* Calculating the time window for the timeout on the busy bus condition.*/
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
+
+ /* Waits until BUSY flag is reset or, alternatively, for a timeout
+ condition.*/
+ while (true) {
+ osalSysLock();
+
+ /* If the bus is not busy then the operation can continue, note, the
+ loop is exited in the locked state.*/
+ if ((dp->ISR & I2C_ISR_BUSY) == 0)
+ break;
+
+ /* If the system time went outside the allowed window then a timeout
+ condition is returned.*/
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return MSG_TIMEOUT;
+ }
+
+ osalSysUnlock();
+ }
+
+ /* Setting up the slave address.*/
+ i2c_lld_set_address(i2cp, addr);
+
+ /* Setting up the peripheral.*/
+ i2c_lld_setup_rx_transfer(i2cp);
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Enabling RX DMA.*/
+ i2c_lld_start_rx_dma(i2cp);
+
+ /* Transfer complete interrupt enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE;
+#else
+
+ /* Transfer complete and RX interrupts enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_RXIE;
+#endif
+
+ /* Starts the operation.*/
+ dp->CR2 |= I2C_CR2_START;
+
+ /* Waits for the operation completion or a timeout.*/
+ msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
+
+ /* In case of a software timeout a STOP is sent as an extreme attempt
+ to release the bus and DMA is forcibly disabled.*/
+ if (msg == MSG_TIMEOUT) {
+ dp->CR2 |= I2C_CR2_STOP;
+#if STM32_I2C_USE_DMA == TRUE
+ i2c_lld_stop_rx_dma(i2cp);
+#endif
+ }
+
+ return msg;
+}
+
+/**
+ * @brief Transmits data via the I2C bus as master.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ * @param[in] addr slave device address
+ * @param[in] txbuf pointer to the transmit buffer
+ * @param[in] txbytes number of bytes to be transmitted
+ * @param[out] rxbuf pointer to the receive buffer
+ * @param[in] rxbytes number of bytes to be received
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The operation status.
+ * @retval MSG_OK if the function succeeded.
+ * @retval MSG_RESET if one or more I2C errors occurred, the errors can
+ * be retrieved using @p i2cGetErrors().
+ * @retval MSG_TIMEOUT if a timeout occurred before operation end. After a
+ * timeout the driver must be stopped and restarted
+ * because the bus is in an uncertain state.
+ *
+ * @notapi
+ */
+msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout) {
+ msg_t msg;
+ I2C_TypeDef *dp = i2cp->i2c;
+ systime_t start, end;
+
+ /* Resetting error flags for this transfer.*/
+ i2cp->errors = I2C_NO_ERROR;
+
+ /* Releases the lock from high level driver.*/
+ osalSysUnlock();
+
+ /* Sizes of transfer phases.*/
+ i2cp->txbytes = txbytes;
+ i2cp->rxbytes = rxbytes;
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* TX and RX DMA setup.*/
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ if (i2cp->is_bdma)
+#endif
+#if defined(STM32_I2C_BDMA_REQUIRED)
+ {
+ bdmaStreamSetMode(i2cp->tx.bdma, i2cp->txdmamode);
+ bdmaStreamSetMemory(i2cp->tx.bdma, txbuf);
+ bdmaStreamSetTransactionSize(i2cp->tx.bdma, txbytes);
+
+ bdmaStreamSetMode(i2cp->rx.bdma, i2cp->rxdmamode);
+ bdmaStreamSetMemory(i2cp->rx.bdma, rxbuf);
+ bdmaStreamSetTransactionSize(i2cp->rx.bdma, rxbytes);
+ }
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_I2C_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_I2C_DMA_REQUIRED)
+ {
+ dmaStreamSetMode(i2cp->tx.dma, i2cp->txdmamode);
+ dmaStreamSetMemory0(i2cp->tx.dma, txbuf);
+ dmaStreamSetTransactionSize(i2cp->tx.dma, txbytes);
+
+ dmaStreamSetMode(i2cp->rx.dma, i2cp->rxdmamode);
+ dmaStreamSetMemory0(i2cp->rx.dma, rxbuf);
+ dmaStreamSetTransactionSize(i2cp->rx.dma, rxbytes);
+ }
+#endif
+#else
+ i2cp->txptr = txbuf;
+ i2cp->rxptr = rxbuf;
+#endif
+
+ /* Calculating the time window for the timeout on the busy bus condition.*/
+ start = osalOsGetSystemTimeX();
+ end = osalTimeAddX(start, OSAL_MS2I(STM32_I2C_BUSY_TIMEOUT));
+
+ /* Waits until BUSY flag is reset or, alternatively, for a timeout
+ condition.*/
+ while (true) {
+ osalSysLock();
+
+ /* If the bus is not busy then the operation can continue, note, the
+ loop is exited in the locked state.*/
+ if ((dp->ISR & I2C_ISR_BUSY) == 0)
+ break;
+
+ /* If the system time went outside the allowed window then a timeout
+ condition is returned.*/
+ if (!osalTimeIsInRangeX(osalOsGetSystemTimeX(), start, end)) {
+ return MSG_TIMEOUT;
+ }
+
+ osalSysUnlock();
+ }
+
+ /* Setting up the slave address.*/
+ i2c_lld_set_address(i2cp, addr);
+
+ /* Preparing the transfer.*/
+ i2c_lld_setup_tx_transfer(i2cp);
+
+#if STM32_I2C_USE_DMA == TRUE
+ /* Enabling TX DMA.*/
+ i2c_lld_start_tx_dma(i2cp);
+
+ /* Transfer complete interrupt enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE;
+#else
+ /* Transfer complete and TX interrupts enabled.*/
+ dp->CR1 |= I2C_CR1_TCIE | I2C_CR1_TXIE;
+#endif
+
+ /* Starts the operation.*/
+ dp->CR2 |= I2C_CR2_START;
+
+ /* Waits for the operation completion or a timeout.*/
+ msg = osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
+
+ /* In case of a software timeout a STOP is sent as an extreme attempt
+ to release the bus and DMA is forcibly disabled.*/
+ if (msg == MSG_TIMEOUT) {
+ dp->CR2 |= I2C_CR2_STOP;
+#if STM32_I2C_USE_DMA == TRUE
+ i2c_lld_stop_rx_dma(i2cp);
+ i2c_lld_stop_tx_dma(i2cp);
+#endif
+ }
+
+ return msg;
+}
+
+#endif /* HAL_USE_I2C */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.h
index ee29a4e0c1..6d443d63f7 100644
--- a/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.h
+++ b/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.h
@@ -1,603 +1,603 @@
-/*
- 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 I2Cv3/hal_i2c_lld.h
- * @brief STM32 I2C subsystem low level driver header.
- *
- * @addtogroup I2C
- * @{
- */
-
-#ifndef HAL_I2C_LLD_H
-#define HAL_I2C_LLD_H
-
-#if HAL_USE_I2C || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name TIMINGR register definitions
- * @{
- */
-#define STM32_TIMINGR_PRESC_MASK (15U << 28)
-#define STM32_TIMINGR_PRESC(n) ((n) << 28)
-#define STM32_TIMINGR_SCLDEL_MASK (15U << 20)
-#define STM32_TIMINGR_SCLDEL(n) ((n) << 20)
-#define STM32_TIMINGR_SDADEL_MASK (15U << 16)
-#define STM32_TIMINGR_SDADEL(n) ((n) << 16)
-#define STM32_TIMINGR_SCLH_MASK (255U << 8)
-#define STM32_TIMINGR_SCLH(n) ((n) << 8)
-#define STM32_TIMINGR_SCLL_MASK (255U << 0)
-#define STM32_TIMINGR_SCLL(n) ((n) << 0)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief I2C1 driver enable switch.
- * @details If set to @p TRUE the support for I2C1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C1 FALSE
-#endif
-
-/**
- * @brief I2C2 driver enable switch.
- * @details If set to @p TRUE the support for I2C2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C2 FALSE
-#endif
-
-/**
- * @brief I2C3 driver enable switch.
- * @details If set to @p TRUE the support for I2C3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C3 FALSE
-#endif
-
-/**
- * @brief I2C4 driver enable switch.
- * @details If set to @p TRUE the support for I2C4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_I2C_USE_I2C4) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_I2C4 FALSE
-#endif
-
-/**
- * @brief I2C timeout on busy condition in milliseconds.
- */
-#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_I2C_BUSY_TIMEOUT 50
-#endif
-
-/**
- * @brief I2C1 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C2 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C3 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2C4 interrupt priority level setting.
- */
-#if !defined(STM32_I2C_I2C4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C4_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief DMA use switch.
- */
-#if !defined(STM32_I2C_USE_DMA) || defined(__DOXYGEN__)
-#define STM32_I2C_USE_DMA TRUE
-#endif
-
-/**
- * @brief I2C1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_I2C_I2C4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2C_I2C4_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2C DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Registry checks.*/
-#if !defined(STM32_HAS_I2C1)
-#error "STM32_HAS_I2C1 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_I2C2)
-#error "STM32_HAS_I2C2 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_I2C3)
-#error "STM32_HAS_I2C3 not defined in registry"
-#endif
-
-#if !defined(STM32_HAS_I2C4)
-#error "STM32_HAS_I2C4 not defined in registry"
-#endif
-
-#if !defined(STM32_I2C4_USE_BDMA)
-#error "STM32_I2C4_USE_BDMA not defined in registry"
-#endif
-
-/** @brief error checks */
-#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
-#error "I2C1 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
-#error "I2C2 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
-#error "I2C3 not present in the selected device"
-#endif
-
-#if STM32_I2C_USE_I2C4 && !STM32_HAS_I2C4
-#error "I2C4 not present in the selected device"
-#endif
-
-#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && !STM32_I2C_USE_I2C3 && \
- !STM32_I2C_USE_I2C4
-#error "I2C driver activated but no I2C peripheral assigned"
-#endif
-
-#if STM32_I2C_USE_I2C1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C1"
-#endif
-
-#if STM32_I2C_USE_I2C2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C2"
-#endif
-
-#if STM32_I2C_USE_I2C3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C3"
-#endif
-
-#if STM32_I2C_USE_I2C4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to I2C4"
-#endif
-
-#if STM32_I2C_USE_DMA == TRUE
-
-#if STM32_I2C_USE_I2C1
-#if !defined(STM32_I2C_I2C1_RX_DMA_STREAM)
-#error "STM32_I2C_I2C1_RX_DMA_STREAM not defined"
-#endif
-
-#if !defined(STM32_I2C_I2C1_TX_DMA_STREAM)
-#error "STM32_I2C_I2C1_TX_DMA_STREAM not defined"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C1 RX"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C1 TX"
-#endif
-
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C1"
-#endif
-#endif
-
-#if STM32_I2C_USE_I2C2
-#if !defined(STM32_I2C_I2C2_RX_DMA_STREAM)
-#error "STM32_I2C_I2C2_RX_DMA_STREAM not defined"
-#endif
-
-#if !defined(STM32_I2C_I2C2_TX_DMA_STREAM)
-#error "STM32_I2C_I2C2_TX_DMA_STREAM not defined"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C2 RX"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C2 TX"
-#endif
-
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C2"
-#endif
-#endif
-
-#if STM32_I2C_USE_I2C3
-#if !defined(STM32_I2C_I2C3_RX_DMA_STREAM)
-#error "STM32_I2C_I2C3_RX_DMA_STREAM not defined"
-#endif
-
-#if !defined(STM32_I2C_I2C3_TX_DMA_STREAM)
-#error "STM32_I2C_I2C3_TX_DMA_STREAM not defined"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C3 RX"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C3 TX"
-#endif
-
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C3"
-#endif
-#endif
-
-#if STM32_I2C_USE_I2C4
-#if STM32_I2C4_USE_BDMA
-
-#if !defined(STM32_I2C_I2C4_RX_BDMA_STREAM)
-#error "STM32_I2C_I2C4_RX_BDMA_STREAM not defined"
-#endif
-
-#if !defined(STM32_I2C_I2C4_TX_BDMA_STREAM)
-#error "STM32_I2C_I2C4_TX_BDMA_STREAM not defined"
-#endif
-
-#if !STM32_BDMA_IS_VALID_STREAM(STM32_I2C_I2C4_RX_BDMA_STREAM)
-#error "Invalid BDMA stream assigned to I2C4 RX"
-#endif
-
-#if !STM32_BDMA_IS_VALID_STREAM(STM32_I2C_I2C4_TX_BDMA_STREAM)
-#error "Invalid BDMA stream assigned to I2C4 TX"
-#endif
-
-#if !STM32_BDMA_IS_VALID_PRIORITY(STM32_I2C_I2C4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C4"
-#endif
-
-#else /* !STM32_I2C4_USE_BDMA */
-
-#if !defined(STM32_I2C_I2C4_RX_DMA_STREAM)
-#error "STM32_I2C_I2C4_RX_DMA_STREAM not defined"
-#endif
-
-#if !defined(STM32_I2C_I2C4_TX_DMA_STREAM)
-#error "STM32_I2C_I2C4_TX_DMA_STREAM not defined"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C4_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C4 RX"
-#endif
-
-#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C4_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to I2C4 TX"
-#endif
-
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to I2C4"
-#endif
-
-#endif /* !STM32_I2C4_USE_BDMA */
-#endif /* STM32_I2C_USE_I2C4 */
-
-#if STM32_I2C4_USE_BDMA == TRUE
-
-#if STM32_I2C_USE_I2C1 || STM32_I2C_USE_I2C2 || STM32_I2C_USE_I2C3
-#define STM32_I2C_DMA_REQUIRED
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-#endif
-
-#if STM32_I2C_USE_I2C4
-#define STM32_I2C_BDMA_REQUIRED
-#if !defined(STM32_BDMA_REQUIRED)
-#define STM32_BDMA_REQUIRED
-#endif
-#endif
-#else /* STM32_I2C4_USE_BDMA != TRUE */
-
-#if STM32_I2C_USE_I2C1 || STM32_I2C_USE_I2C2 || STM32_I2C_USE_I2C3 || STM32_I2C_USE_I2C4
-#define STM32_I2C_DMA_REQUIRED
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-#endif
-
-#endif /* STM32_I2C4_USE_BDMA != TRUE */
-
-#endif /* STM32_I2C_USE_DMA == TRUE */
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type representing an I2C address.
- */
-typedef uint16_t i2caddr_t;
-
-/**
- * @brief Type of I2C driver condition flags.
- */
-typedef uint32_t i2cflags_t;
-
-/**
- * @brief Type of I2C driver configuration structure.
- */
-typedef struct {
- /**
- * @brief TIMINGR register initialization.
- * @note Refer to the STM32 reference manual, the values are affected
- * by the system clock settings in mcuconf.h.
- */
- uint32_t timingr;
- /**
- * @brief CR1 register initialization.
- * @note Leave to zero unless you know what you are doing.
- */
- uint32_t cr1;
- /**
- * @brief CR2 register initialization.
- * @note Only the ADD10 bit can eventually be specified here.
- */
- uint32_t cr2;
-} I2CConfig;
-
-/**
- * @brief Type of a structure representing an I2C driver.
- */
-typedef struct I2CDriver I2CDriver;
-
-/**
- * @brief Structure representing an I2C driver.
- */
-struct I2CDriver {
- /**
- * @brief Driver state.
- */
- i2cstate_t state;
- /**
- * @brief Current configuration data.
- */
- const I2CConfig *config;
- /**
- * @brief Error flags.
- */
- i2cflags_t errors;
-#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
- mutex_t mutex;
-#endif /* I2C_USE_MUTUAL_EXCLUSION */
-#if defined(I2C_DRIVER_EXT_FIELDS)
- I2C_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion.
- */
- thread_reference_t thread;
- /**
- * @brief Number of bytes in TX phase.
- */
- size_t txbytes;
- /**
- * @brief Number of bytes in RX phase.
- */
- size_t rxbytes;
-#if (STM32_I2C_USE_DMA == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief RX DMA mode bit mask.
- */
- uint32_t rxdmamode;
- /**
- * @brief TX DMA mode bit mask.
- */
- uint32_t txdmamode;
-#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_BDMA_REQUIRED)
- /**
- * @brief DMA type for this instance.
- */
- bool is_bdma;
-#endif
- /**
- * @brief Union of the RX DMA streams.
- */
- union {
-#if defined(STM32_I2C_DMA_REQUIRED) || defined(__DOXYGEN__)
- /**
- * @brief Receive DMA stream.
- */
- const stm32_dma_stream_t *dma;
-#endif
-#if (STM32_I2C4_USE_BDMA == TRUE) || defined(__DOXYGEN__)
-#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__)
- /**
- * @brief Receive BDMA stream.
- */
- const stm32_bdma_stream_t *bdma;
-#endif
-#endif
- } rx;
- /**
- * @brief Union of the TX DMA streams.
- */
- union {
-#if defined(STM32_I2C_DMA_REQUIRED) || defined(__DOXYGEN__)
- /**
- * @brief Transmit DMA stream.
- */
- const stm32_dma_stream_t *dma;
-#endif
-#if (STM32_I2C4_USE_BDMA == TRUE) || defined(__DOXYGEN__)
-#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__)
- /**
- * @brief Transmit DMA stream.
- */
- const stm32_bdma_stream_t *bdma;
-#endif
-#endif
- } tx;
-#else /* STM32_I2C_USE_DMA == FALSE */
- /**
- * @brief Pointer to the next TX buffer location.
- */
- const uint8_t *txptr;
- /**
- * @brief Pointer to the next RX buffer location.
- */
- uint8_t *rxptr;
-#endif /* STM32_I2C_USE_DMA == FALSE */
- /**
- * @brief Pointer to the I2Cx registers block.
- */
- I2C_TypeDef *i2c;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Get errors from I2C driver.
- *
- * @param[in] i2cp pointer to the @p I2CDriver object
- *
- * @notapi
- */
-#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-#if STM32_I2C_USE_I2C1
-extern I2CDriver I2CD1;
-#endif
-
-#if STM32_I2C_USE_I2C2
-extern I2CDriver I2CD2;
-#endif
-
-#if STM32_I2C_USE_I2C3
-extern I2CDriver I2CD3;
-#endif
-
-#if STM32_I2C_USE_I2C4
-extern I2CDriver I2CD4;
-#endif
-
-#endif /* !defined(__DOXYGEN__) */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void i2c_lld_init(void);
- void i2c_lld_start(I2CDriver *i2cp);
- void i2c_lld_stop(I2CDriver *i2cp);
- msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
- const uint8_t *txbuf, size_t txbytes,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout);
- msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
- uint8_t *rxbuf, size_t rxbytes,
- sysinterval_t timeout);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_I2C */
-
-#endif /* HAL_I2C_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 I2Cv3/hal_i2c_lld.h
+ * @brief STM32 I2C subsystem low level driver header.
+ *
+ * @addtogroup I2C
+ * @{
+ */
+
+#ifndef HAL_I2C_LLD_H
+#define HAL_I2C_LLD_H
+
+#if HAL_USE_I2C || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name TIMINGR register definitions
+ * @{
+ */
+#define STM32_TIMINGR_PRESC_MASK (15U << 28)
+#define STM32_TIMINGR_PRESC(n) ((n) << 28)
+#define STM32_TIMINGR_SCLDEL_MASK (15U << 20)
+#define STM32_TIMINGR_SCLDEL(n) ((n) << 20)
+#define STM32_TIMINGR_SDADEL_MASK (15U << 16)
+#define STM32_TIMINGR_SDADEL(n) ((n) << 16)
+#define STM32_TIMINGR_SCLH_MASK (255U << 8)
+#define STM32_TIMINGR_SCLH(n) ((n) << 8)
+#define STM32_TIMINGR_SCLL_MASK (255U << 0)
+#define STM32_TIMINGR_SCLL(n) ((n) << 0)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2C1 driver enable switch.
+ * @details If set to @p TRUE the support for I2C1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C1) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C1 FALSE
+#endif
+
+/**
+ * @brief I2C2 driver enable switch.
+ * @details If set to @p TRUE the support for I2C2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C2) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C2 FALSE
+#endif
+
+/**
+ * @brief I2C3 driver enable switch.
+ * @details If set to @p TRUE the support for I2C3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C3) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C3 FALSE
+#endif
+
+/**
+ * @brief I2C4 driver enable switch.
+ * @details If set to @p TRUE the support for I2C4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_I2C_USE_I2C4) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_I2C4 FALSE
+#endif
+
+/**
+ * @brief I2C timeout on busy condition in milliseconds.
+ */
+#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_I2C_BUSY_TIMEOUT 50
+#endif
+
+/**
+ * @brief I2C1 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C2 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C3 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2C4 interrupt priority level setting.
+ */
+#if !defined(STM32_I2C_I2C4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C4_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief DMA use switch.
+ */
+#if !defined(STM32_I2C_USE_DMA) || defined(__DOXYGEN__)
+#define STM32_I2C_USE_DMA TRUE
+#endif
+
+/**
+ * @brief I2C1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_I2C_I2C4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2C_I2C4_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2C DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_I2C_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Registry checks.*/
+#if !defined(STM32_HAS_I2C1)
+#error "STM32_HAS_I2C1 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_I2C2)
+#error "STM32_HAS_I2C2 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_I2C3)
+#error "STM32_HAS_I2C3 not defined in registry"
+#endif
+
+#if !defined(STM32_HAS_I2C4)
+#error "STM32_HAS_I2C4 not defined in registry"
+#endif
+
+#if !defined(STM32_I2C4_USE_BDMA)
+#error "STM32_I2C4_USE_BDMA not defined in registry"
+#endif
+
+/** @brief error checks */
+#if STM32_I2C_USE_I2C1 && !STM32_HAS_I2C1
+#error "I2C1 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C2 && !STM32_HAS_I2C2
+#error "I2C2 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C3 && !STM32_HAS_I2C3
+#error "I2C3 not present in the selected device"
+#endif
+
+#if STM32_I2C_USE_I2C4 && !STM32_HAS_I2C4
+#error "I2C4 not present in the selected device"
+#endif
+
+#if !STM32_I2C_USE_I2C1 && !STM32_I2C_USE_I2C2 && !STM32_I2C_USE_I2C3 && \
+ !STM32_I2C_USE_I2C4
+#error "I2C driver activated but no I2C peripheral assigned"
+#endif
+
+#if STM32_I2C_USE_I2C1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C1"
+#endif
+
+#if STM32_I2C_USE_I2C2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C2"
+#endif
+
+#if STM32_I2C_USE_I2C3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C3"
+#endif
+
+#if STM32_I2C_USE_I2C4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2C_I2C4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to I2C4"
+#endif
+
+#if STM32_I2C_USE_DMA == TRUE
+
+#if STM32_I2C_USE_I2C1
+#if !defined(STM32_I2C_I2C1_RX_DMA_STREAM)
+#error "STM32_I2C_I2C1_RX_DMA_STREAM not defined"
+#endif
+
+#if !defined(STM32_I2C_I2C1_TX_DMA_STREAM)
+#error "STM32_I2C_I2C1_TX_DMA_STREAM not defined"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C1_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C1 RX"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C1_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C1 TX"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C1"
+#endif
+#endif
+
+#if STM32_I2C_USE_I2C2
+#if !defined(STM32_I2C_I2C2_RX_DMA_STREAM)
+#error "STM32_I2C_I2C2_RX_DMA_STREAM not defined"
+#endif
+
+#if !defined(STM32_I2C_I2C2_TX_DMA_STREAM)
+#error "STM32_I2C_I2C2_TX_DMA_STREAM not defined"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C2_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C2 RX"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C2_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C2 TX"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C2"
+#endif
+#endif
+
+#if STM32_I2C_USE_I2C3
+#if !defined(STM32_I2C_I2C3_RX_DMA_STREAM)
+#error "STM32_I2C_I2C3_RX_DMA_STREAM not defined"
+#endif
+
+#if !defined(STM32_I2C_I2C3_TX_DMA_STREAM)
+#error "STM32_I2C_I2C3_TX_DMA_STREAM not defined"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C3_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C3 RX"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C3_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C3 TX"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C3"
+#endif
+#endif
+
+#if STM32_I2C_USE_I2C4
+#if STM32_I2C4_USE_BDMA
+
+#if !defined(STM32_I2C_I2C4_RX_BDMA_STREAM)
+#error "STM32_I2C_I2C4_RX_BDMA_STREAM not defined"
+#endif
+
+#if !defined(STM32_I2C_I2C4_TX_BDMA_STREAM)
+#error "STM32_I2C_I2C4_TX_BDMA_STREAM not defined"
+#endif
+
+#if !STM32_BDMA_IS_VALID_STREAM(STM32_I2C_I2C4_RX_BDMA_STREAM)
+#error "Invalid BDMA stream assigned to I2C4 RX"
+#endif
+
+#if !STM32_BDMA_IS_VALID_STREAM(STM32_I2C_I2C4_TX_BDMA_STREAM)
+#error "Invalid BDMA stream assigned to I2C4 TX"
+#endif
+
+#if !STM32_BDMA_IS_VALID_PRIORITY(STM32_I2C_I2C4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C4"
+#endif
+
+#else /* !STM32_I2C4_USE_BDMA */
+
+#if !defined(STM32_I2C_I2C4_RX_DMA_STREAM)
+#error "STM32_I2C_I2C4_RX_DMA_STREAM not defined"
+#endif
+
+#if !defined(STM32_I2C_I2C4_TX_DMA_STREAM)
+#error "STM32_I2C_I2C4_TX_DMA_STREAM not defined"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C4_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C4 RX"
+#endif
+
+#if !STM32_DMA_IS_VALID_STREAM(STM32_I2C_I2C4_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to I2C4 TX"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to I2C4"
+#endif
+
+#endif /* !STM32_I2C4_USE_BDMA */
+#endif /* STM32_I2C_USE_I2C4 */
+
+#if STM32_I2C4_USE_BDMA == TRUE
+
+#if STM32_I2C_USE_I2C1 || STM32_I2C_USE_I2C2 || STM32_I2C_USE_I2C3
+#define STM32_I2C_DMA_REQUIRED
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+#endif
+
+#if STM32_I2C_USE_I2C4
+#define STM32_I2C_BDMA_REQUIRED
+#if !defined(STM32_BDMA_REQUIRED)
+#define STM32_BDMA_REQUIRED
+#endif
+#endif
+#else /* STM32_I2C4_USE_BDMA != TRUE */
+
+#if STM32_I2C_USE_I2C1 || STM32_I2C_USE_I2C2 || STM32_I2C_USE_I2C3 || STM32_I2C_USE_I2C4
+#define STM32_I2C_DMA_REQUIRED
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+#endif
+
+#endif /* STM32_I2C4_USE_BDMA != TRUE */
+
+#endif /* STM32_I2C_USE_DMA == TRUE */
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type representing an I2C address.
+ */
+typedef uint16_t i2caddr_t;
+
+/**
+ * @brief Type of I2C driver condition flags.
+ */
+typedef uint32_t i2cflags_t;
+
+/**
+ * @brief Type of I2C driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief TIMINGR register initialization.
+ * @note Refer to the STM32 reference manual, the values are affected
+ * by the system clock settings in mcuconf.h.
+ */
+ uint32_t timingr;
+ /**
+ * @brief CR1 register initialization.
+ * @note Leave to zero unless you know what you are doing.
+ */
+ uint32_t cr1;
+ /**
+ * @brief CR2 register initialization.
+ * @note Only the ADD10 bit can eventually be specified here.
+ */
+ uint32_t cr2;
+} I2CConfig;
+
+/**
+ * @brief Type of a structure representing an I2C driver.
+ */
+typedef struct I2CDriver I2CDriver;
+
+/**
+ * @brief Structure representing an I2C driver.
+ */
+struct I2CDriver {
+ /**
+ * @brief Driver state.
+ */
+ i2cstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const I2CConfig *config;
+ /**
+ * @brief Error flags.
+ */
+ i2cflags_t errors;
+#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+ mutex_t mutex;
+#endif /* I2C_USE_MUTUAL_EXCLUSION */
+#if defined(I2C_DRIVER_EXT_FIELDS)
+ I2C_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion.
+ */
+ thread_reference_t thread;
+ /**
+ * @brief Number of bytes in TX phase.
+ */
+ size_t txbytes;
+ /**
+ * @brief Number of bytes in RX phase.
+ */
+ size_t rxbytes;
+#if (STM32_I2C_USE_DMA == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief RX DMA mode bit mask.
+ */
+ uint32_t rxdmamode;
+ /**
+ * @brief TX DMA mode bit mask.
+ */
+ uint32_t txdmamode;
+#if defined(STM32_I2C_DMA_REQUIRED) && defined(STM32_BDMA_REQUIRED)
+ /**
+ * @brief DMA type for this instance.
+ */
+ bool is_bdma;
+#endif
+ /**
+ * @brief Union of the RX DMA streams.
+ */
+ union {
+#if defined(STM32_I2C_DMA_REQUIRED) || defined(__DOXYGEN__)
+ /**
+ * @brief Receive DMA stream.
+ */
+ const stm32_dma_stream_t *dma;
+#endif
+#if (STM32_I2C4_USE_BDMA == TRUE) || defined(__DOXYGEN__)
+#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__)
+ /**
+ * @brief Receive BDMA stream.
+ */
+ const stm32_bdma_stream_t *bdma;
+#endif
+#endif
+ } rx;
+ /**
+ * @brief Union of the TX DMA streams.
+ */
+ union {
+#if defined(STM32_I2C_DMA_REQUIRED) || defined(__DOXYGEN__)
+ /**
+ * @brief Transmit DMA stream.
+ */
+ const stm32_dma_stream_t *dma;
+#endif
+#if (STM32_I2C4_USE_BDMA == TRUE) || defined(__DOXYGEN__)
+#if defined(STM32_BDMA_REQUIRED) || defined(__DOXYGEN__)
+ /**
+ * @brief Transmit DMA stream.
+ */
+ const stm32_bdma_stream_t *bdma;
+#endif
+#endif
+ } tx;
+#else /* STM32_I2C_USE_DMA == FALSE */
+ /**
+ * @brief Pointer to the next TX buffer location.
+ */
+ const uint8_t *txptr;
+ /**
+ * @brief Pointer to the next RX buffer location.
+ */
+ uint8_t *rxptr;
+#endif /* STM32_I2C_USE_DMA == FALSE */
+ /**
+ * @brief Pointer to the I2Cx registers block.
+ */
+ I2C_TypeDef *i2c;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Get errors from I2C driver.
+ *
+ * @param[in] i2cp pointer to the @p I2CDriver object
+ *
+ * @notapi
+ */
+#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+#if STM32_I2C_USE_I2C1
+extern I2CDriver I2CD1;
+#endif
+
+#if STM32_I2C_USE_I2C2
+extern I2CDriver I2CD2;
+#endif
+
+#if STM32_I2C_USE_I2C3
+extern I2CDriver I2CD3;
+#endif
+
+#if STM32_I2C_USE_I2C4
+extern I2CDriver I2CD4;
+#endif
+
+#endif /* !defined(__DOXYGEN__) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2c_lld_init(void);
+ void i2c_lld_start(I2CDriver *i2cp);
+ void i2c_lld_stop(I2CDriver *i2cp);
+ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ const uint8_t *txbuf, size_t txbytes,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout);
+ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
+ uint8_t *rxbuf, size_t rxbytes,
+ sysinterval_t timeout);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2C */
+
+#endif /* HAL_I2C_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/MACv1/driver.mk b/os/hal/ports/STM32/LLD/MACv1/driver.mk
index 2964178c18..f0a8938e47 100644
--- a/os/hal/ports/STM32/LLD/MACv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/MACv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_MAC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_MAC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv1
diff --git a/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c b/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
index 232fb0ec7e..907f509157 100644
--- a/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
+++ b/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.c
@@ -1,763 +1,763 @@
-/*
- 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 MACv1/hal_mac_lld.c
- * @brief STM32 low level MAC driver code.
- *
- * @addtogroup MAC
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_MAC || defined(__DOXYGEN__)
-
-#include "hal_mii.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define BUFFER_SIZE ((((STM32_MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4)
-
-/* Fixing inconsistencies in ST headers.*/
-#if !defined(ETH_MACMIIAR_CR_Div102) && defined(ETH_MACMIIAR_CR_DIV102)
-#define ETH_MACMIIAR_CR_Div102 ETH_MACMIIAR_CR_DIV102
-#endif
-#if !defined(ETH_MACMIIAR_CR_Div62) && defined(ETH_MACMIIAR_CR_DIV62)
-#define ETH_MACMIIAR_CR_Div62 ETH_MACMIIAR_CR_DIV62
-#endif
-#if !defined(ETH_MACMIIAR_CR_Div42) && defined(ETH_MACMIIAR_CR_DIV42)
-#define ETH_MACMIIAR_CR_Div42 ETH_MACMIIAR_CR_DIV42
-#endif
-#if !defined(ETH_MACMIIAR_CR_Div26) && defined(ETH_MACMIIAR_CR_DIV26)
-#define ETH_MACMIIAR_CR_Div26 ETH_MACMIIAR_CR_DIV26
-#endif
-#if !defined(ETH_MACMIIAR_CR_Div16) && defined(ETH_MACMIIAR_CR_DIV16)
-#define ETH_MACMIIAR_CR_Div16 ETH_MACMIIAR_CR_DIV16
-#endif
-
-/* MII divider optimal value.*/
-#if (STM32_HCLK >= 150000000)
-#define MACMIIDR_CR ETH_MACMIIAR_CR_Div102
-#elif (STM32_HCLK >= 100000000)
-#define MACMIIDR_CR ETH_MACMIIAR_CR_Div62
-#elif (STM32_HCLK >= 60000000)
-#define MACMIIDR_CR ETH_MACMIIAR_CR_Div42
-#elif (STM32_HCLK >= 35000000)
-#define MACMIIDR_CR ETH_MACMIIAR_CR_Div26
-#elif (STM32_HCLK >= 20000000)
-#define MACMIIDR_CR ETH_MACMIIAR_CR_Div16
-#else
-#error "STM32_HCLK below minimum frequency for ETH operations (20MHz)"
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief Ethernet driver 1.
- */
-MACDriver ETHD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint8_t default_mac_address[] = {0xAA, 0x55, 0x13,
- 0x37, 0x01, 0x10};
-
-static stm32_eth_rx_descriptor_t __eth_rd[STM32_MAC_RECEIVE_BUFFERS];
-static stm32_eth_tx_descriptor_t __eth_td[STM32_MAC_TRANSMIT_BUFFERS];
-
-static uint32_t __eth_rb[STM32_MAC_RECEIVE_BUFFERS][BUFFER_SIZE];
-static uint32_t __eth_tb[STM32_MAC_TRANSMIT_BUFFERS][BUFFER_SIZE];
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Writes a PHY register.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[in] reg register number
- * @param[in] value new register value
- *
- * @notapi
- */
-void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) {
-
- ETH->MACMIIDR = value;
- ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR |
- ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
- while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0)
- ;
-}
-
-/**
- * @brief Reads a PHY register.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[in] reg register number
- *
- * @return The PHY register content.
- *
- * @notapi
- */
-uint32_t mii_read(MACDriver *macp, uint32_t reg) {
-
- ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR | ETH_MACMIIAR_MB;
- while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0)
- ;
- return ETH->MACMIIDR;
-}
-
-#if !defined(BOARD_PHY_ADDRESS)
-/**
- * @brief PHY address detection.
- *
- * @param[in] macp pointer to the @p MACDriver object
- */
-static void mii_find_phy(MACDriver *macp) {
- uint32_t i;
-
-#if STM32_MAC_PHY_TIMEOUT > 0
- unsigned n = STM32_MAC_PHY_TIMEOUT;
- do {
-#endif
- for (i = 0U; i <= 31U; i++) {
- macp->phyaddr = i << 11U;
- ETH->MACMIIDR = (i << 6U) | MACMIIDR_CR;
- if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16U)) &&
- ((mii_read(macp, MII_PHYSID2) & 0xFFF0U) == (BOARD_PHY_ID & 0xFFF0U))) {
- return;
- }
- }
-#if STM32_MAC_PHY_TIMEOUT > 0
- n--;
- } while (n > 0U);
-#endif
- /* Wrong or defective board.*/
- osalSysHalt("MAC failure");
-}
-#endif
-
-/**
- * @brief MAC address setup.
- *
- * @param[in] p pointer to a six bytes buffer containing the MAC
- * address
- */
-static void mac_lld_set_address(const uint8_t *p) {
-
- /* MAC address configuration, only a single address comparator is used,
- hash table not used.*/
- ETH->MACA0HR = ((uint32_t)p[5] << 8) |
- ((uint32_t)p[4] << 0);
- ETH->MACA0LR = ((uint32_t)p[3] << 24) |
- ((uint32_t)p[2] << 16) |
- ((uint32_t)p[1] << 8) |
- ((uint32_t)p[0] << 0);
- ETH->MACA1HR = 0x0000FFFF;
- ETH->MACA1LR = 0xFFFFFFFF;
- ETH->MACA2HR = 0x0000FFFF;
- ETH->MACA2LR = 0xFFFFFFFF;
- ETH->MACA3HR = 0x0000FFFF;
- ETH->MACA3LR = 0xFFFFFFFF;
- ETH->MACHTHR = 0;
- ETH->MACHTLR = 0;
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-OSAL_IRQ_HANDLER(STM32_ETH_HANDLER) {
- uint32_t dmasr;
-
- OSAL_IRQ_PROLOGUE();
-
- dmasr = ETH->DMASR;
- ETH->DMASR = dmasr; /* Clear status bits.*/
-
- if (dmasr & ETH_DMASR_RS) {
- /* Data Received.*/
- osalSysLockFromISR();
- osalThreadDequeueAllI(ÐD1.rdqueue, MSG_RESET);
-#if MAC_USE_EVENTS
- osalEventBroadcastFlagsI(ÐD1.rdevent, 0);
-#endif
- osalSysUnlockFromISR();
- }
-
- if (dmasr & ETH_DMASR_TS) {
- /* Data Transmitted.*/
- osalSysLockFromISR();
- osalThreadDequeueAllI(ÐD1.tdqueue, MSG_RESET);
- osalSysUnlockFromISR();
- }
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level MAC initialization.
- *
- * @notapi
- */
-void mac_lld_init(void) {
- unsigned i;
-
- macObjectInit(ÐD1);
- ETHD1.link_up = false;
-
- /* Descriptor tables are initialized in chained mode, note that the first
- word is not initialized here but in mac_lld_start().*/
- for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++) {
- __eth_rd[i].rdes1 = STM32_RDES1_RCH | STM32_MAC_BUFFERS_SIZE;
- __eth_rd[i].rdes2 = (uint32_t)__eth_rb[i];
- __eth_rd[i].rdes3 = (uint32_t)&__eth_rd[(i + 1) % STM32_MAC_RECEIVE_BUFFERS];
- }
- for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++) {
- __eth_td[i].tdes1 = 0;
- __eth_td[i].tdes2 = (uint32_t)__eth_tb[i];
- __eth_td[i].tdes3 = (uint32_t)&__eth_td[(i + 1) % STM32_MAC_TRANSMIT_BUFFERS];
- }
-
- /* Selection of the RMII or MII mode based on info exported by board.h.*/
-#if defined(STM32F10X_CL)
-#if defined(BOARD_PHY_RMII)
- AFIO->MAPR |= AFIO_MAPR_MII_RMII_SEL;
-#else
- AFIO->MAPR &= ~AFIO_MAPR_MII_RMII_SEL;
-#endif
-#elif defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX)
-#if defined(BOARD_PHY_RMII)
- SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
-#else
- SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL;
-#endif
-#else
-#error "unsupported STM32 platform for MAC driver"
-#endif
-
- /* Reset of the MAC core.*/
- rccResetETH();
-
- /* MAC clocks temporary activation.*/
- rccEnableETH(true);
-
- /* PHY address setup.*/
-#if defined(BOARD_PHY_ADDRESS)
- ETHD1.phyaddr = BOARD_PHY_ADDRESS << 11;
-#else
- mii_find_phy(ÐD1);
-#endif
-
-#if defined(BOARD_PHY_RESET)
- /* PHY board-specific reset procedure.*/
- BOARD_PHY_RESET();
-#else
- /* PHY soft reset procedure.*/
- mii_write(ÐD1, MII_BMCR, BMCR_RESET);
-#if defined(BOARD_PHY_RESET_DELAY)
- osalSysPolledDelayX(BOARD_PHY_RESET_DELAY);
-#endif
- while (mii_read(ÐD1, MII_BMCR) & BMCR_RESET)
- ;
-#endif
-
-#if STM32_MAC_ETH1_CHANGE_PHY_STATE
- /* PHY in power down mode until the driver will be started.*/
- mii_write(ÐD1, MII_BMCR, mii_read(ÐD1, MII_BMCR) | BMCR_PDOWN);
-#endif
-
- /* MAC clocks stopped again.*/
- rccDisableETH();
-}
-
-/**
- * @brief Configures and activates the MAC peripheral.
- *
- * @param[in] macp pointer to the @p MACDriver object
- *
- * @notapi
- */
-void mac_lld_start(MACDriver *macp) {
- unsigned i;
-
- /* Resets the state of all descriptors.*/
- for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++)
- __eth_rd[i].rdes0 = STM32_RDES0_OWN;
- macp->rxptr = (stm32_eth_rx_descriptor_t *)__eth_rd;
- for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++)
- __eth_td[i].tdes0 = STM32_TDES0_TCH;
- macp->txptr = (stm32_eth_tx_descriptor_t *)__eth_td;
-
- /* MAC clocks activation and commanded reset procedure.*/
- rccEnableETH(true);
-#if defined(STM32_MAC_DMABMR_SR)
- ETH->DMABMR |= ETH_DMABMR_SR;
- while (ETH->DMABMR & ETH_DMABMR_SR)
- ;
-#endif
-
- /* ISR vector enabled.*/
- nvicEnableVector(STM32_ETH_NUMBER, STM32_MAC_ETH1_IRQ_PRIORITY);
-
-#if STM32_MAC_ETH1_CHANGE_PHY_STATE
- /* PHY in power up mode.*/
- mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) & ~BMCR_PDOWN);
-#endif
-
- /* MAC configuration.*/
- ETH->MACFFR = 0;
- ETH->MACFCR = 0;
- ETH->MACVLANTR = 0;
-
- /* MAC address setup.*/
- if (macp->config->mac_address == NULL)
- mac_lld_set_address(default_mac_address);
- else
- mac_lld_set_address(macp->config->mac_address);
-
- /* Transmitter and receiver enabled.
- Note that the complete setup of the MAC is performed when the link
- status is detected.*/
-#if STM32_MAC_IP_CHECKSUM_OFFLOAD
- ETH->MACCR = ETH_MACCR_IPCO | ETH_MACCR_RE | ETH_MACCR_TE;
-#else
- ETH->MACCR = ETH_MACCR_RE | ETH_MACCR_TE;
-#endif
-
- /* MMC configuration:
- Disable all MMC interrupts.*/
- ETH->MMCRIMR = ETH_MMCRIMR_RFCEM | ETH_MMCRIMR_RFAEM | ETH_MMCRIMR_RGUFM;
- ETH->MMCTIMR = ETH_MMCTIMR_TGFSCM | ETH_MMCTIMR_TGFMSCM | ETH_MMCTIMR_TGFM;
-
- /* DMA configuration:
- Descriptor chains pointers.*/
- ETH->DMARDLAR = (uint32_t)__eth_rd;
- ETH->DMATDLAR = (uint32_t)__eth_td;
-
- /* Enabling required interrupt sources.*/
- ETH->DMASR = ETH->DMASR;
- ETH->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE;
-
- /* DMA general settings.*/
- ETH->DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_RDP_1Beat | ETH_DMABMR_PBL_1Beat;
-
- /* Check because errata on some devices. There should be no need to
- disable flushing because the TXFIFO should be empty on macStart().*/
-#if !defined(STM32_MAC_DISABLE_TX_FLUSH)
- /* Transmit FIFO flush.*/
- ETH->DMAOMR = ETH_DMAOMR_FTF;
- while (ETH->DMAOMR & ETH_DMAOMR_FTF)
- ;
-#endif
-
- /* DMA final configuration and start.*/
- ETH->DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_TSF |
- ETH_DMAOMR_ST | ETH_DMAOMR_SR;
-}
-
-/**
- * @brief Deactivates the MAC peripheral.
- *
- * @param[in] macp pointer to the @p MACDriver object
- *
- * @notapi
- */
-void mac_lld_stop(MACDriver *macp) {
-
- if (macp->state != MAC_STOP) {
-#if STM32_MAC_ETH1_CHANGE_PHY_STATE
- /* PHY in power down mode until the driver will be restarted.*/
- mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) | BMCR_PDOWN);
-#endif
-
- /* MAC and DMA stopped.*/
- ETH->MACCR = 0;
- ETH->DMAOMR = 0;
- ETH->DMAIER = 0;
- ETH->DMASR = ETH->DMASR;
-
- /* MAC clocks stopped.*/
- rccDisableETH();
-
- /* ISR vector disabled.*/
- nvicDisableVector(STM32_ETH_NUMBER);
- }
-}
-
-/**
- * @brief Returns a transmission descriptor.
- * @details One of the available transmission descriptors is locked and
- * returned.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
- * @return The operation status.
- * @retval MSG_OK the descriptor has been obtained.
- * @retval MSG_TIMEOUT descriptor not available.
- *
- * @notapi
- */
-msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
- MACTransmitDescriptor *tdp) {
- stm32_eth_tx_descriptor_t *tdes;
-
- if (!macp->link_up)
- return MSG_TIMEOUT;
-
- /* Get Current TX descriptor.*/
- tdes = macp->txptr;
-
- /* Ensure that descriptor isn't owned by the Ethernet DMA or locked by
- another thread.*/
- if (tdes->tdes0 & (STM32_TDES0_OWN | STM32_TDES0_LOCKED)) {
- return MSG_TIMEOUT;
- }
-
- /* Marks the current descriptor as locked using a reserved bit.*/
- tdes->tdes0 |= STM32_TDES0_LOCKED;
-
- /* Next TX descriptor to use.*/
- macp->txptr = (stm32_eth_tx_descriptor_t *)tdes->tdes3;
-
- /* Set the buffer size and configuration.*/
- tdp->offset = 0;
- tdp->size = STM32_MAC_BUFFERS_SIZE;
- tdp->physdesc = tdes;
-
- return MSG_OK;
-}
-
-/**
- * @brief Releases a transmit descriptor and starts the transmission of the
- * enqueued data as a single frame.
- *
- * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
- *
- * @notapi
- */
-void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
-
- osalDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN),
- "attempt to release descriptor already owned by DMA");
-
- osalSysLock();
-
- /* Unlocks the descriptor and returns it to the DMA engine.*/
- tdp->physdesc->tdes1 = tdp->offset;
- tdp->physdesc->tdes0 = STM32_TDES0_CIC(STM32_MAC_IP_CHECKSUM_OFFLOAD) |
- STM32_TDES0_IC | STM32_TDES0_LS | STM32_TDES0_FS |
- STM32_TDES0_TCH | STM32_TDES0_OWN;
-
- /* Wait for the write to tdes0 to go through before resuming the DMA.*/
- __DSB();
-
- /* If the DMA engine is stalled then a restart request is issued.*/
- if ((ETH->DMASR & ETH_DMASR_TPS) == ETH_DMASR_TPS_Suspended) {
- ETH->DMASR = ETH_DMASR_TBUS;
- ETH->DMATPDR = ETH_DMASR_TBUS; /* Any value is OK.*/
- }
-
- osalSysUnlock();
-}
-
-/**
- * @brief Returns a receive descriptor.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
- * @return The operation status.
- * @retval MSG_OK the descriptor has been obtained.
- * @retval MSG_TIMEOUT descriptor not available.
- *
- * @notapi
- */
-msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
- MACReceiveDescriptor *rdp) {
- stm32_eth_rx_descriptor_t *rdes;
-
- /* Get Current RX descriptor.*/
- rdes = macp->rxptr;
-
- /* Iterates through received frames until a valid one is found, invalid
- frames are discarded.*/
- while (!(rdes->rdes0 & STM32_RDES0_OWN)) {
- if (!(rdes->rdes0 & (STM32_RDES0_AFM | STM32_RDES0_ES))
-#if STM32_MAC_IP_CHECKSUM_OFFLOAD
- && (rdes->rdes0 & STM32_RDES0_FT)
- && !(rdes->rdes0 & (STM32_RDES0_IPHCE | STM32_RDES0_PCE))
-#endif
- && (rdes->rdes0 & STM32_RDES0_FS) && (rdes->rdes0 & STM32_RDES0_LS)) {
- /* Found a valid one.*/
- rdp->offset = 0;
- rdp->size = ((rdes->rdes0 & STM32_RDES0_FL_MASK) >> 16) - 4;
- rdp->physdesc = rdes;
- macp->rxptr = (stm32_eth_rx_descriptor_t *)rdes->rdes3;
-
- return MSG_OK;
- }
- /* Invalid frame found, purging.*/
- rdes->rdes0 = STM32_RDES0_OWN;
- rdes = (stm32_eth_rx_descriptor_t *)rdes->rdes3;
- }
-
- /* Next descriptor to check.*/
- macp->rxptr = rdes;
-
- return MSG_TIMEOUT;
-}
-
-/**
- * @brief Releases a receive descriptor.
- * @details The descriptor and its buffer are made available for more incoming
- * frames.
- *
- * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
- *
- * @notapi
- */
-void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
-
- osalDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN),
- "attempt to release descriptor already owned by DMA");
-
- osalSysLock();
-
- /* Give buffer back to the Ethernet DMA.*/
- rdp->physdesc->rdes0 = STM32_RDES0_OWN;
-
- /* Wait for the write to rdes0 to go through before resuming the DMA.*/
- __DSB();
-
- /* If the DMA engine is stalled then a restart request is issued.*/
- if ((ETH->DMASR & ETH_DMASR_RPS) == ETH_DMASR_RPS_Suspended) {
- ETH->DMASR = ETH_DMASR_RBUS;
- ETH->DMARPDR = ETH_DMASR_RBUS; /* Any value is OK.*/
- }
-
- osalSysUnlock();
-}
-
-/**
- * @brief Updates and returns the link status.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @return The link status.
- * @retval true if the link is active.
- * @retval false if the link is down.
- *
- * @notapi
- */
-bool mac_lld_poll_link_status(MACDriver *macp) {
- uint32_t maccr, bmsr, bmcr;
-
- maccr = ETH->MACCR;
-
- /* PHY CR and SR registers read.*/
- (void)mii_read(macp, MII_BMSR);
- bmsr = mii_read(macp, MII_BMSR);
- bmcr = mii_read(macp, MII_BMCR);
-
- /* Check on auto-negotiation mode.*/
- if (bmcr & BMCR_ANENABLE) {
- uint32_t lpa;
-
- /* Auto-negotiation must be finished without faults and link established.*/
- if ((bmsr & (BMSR_LSTATUS | BMSR_RFAULT | BMSR_ANEGCOMPLETE)) !=
- (BMSR_LSTATUS | BMSR_ANEGCOMPLETE))
- return macp->link_up = false;
-
- /* Auto-negotiation enabled, checks the LPA register.*/
- lpa = mii_read(macp, MII_LPA);
-
- /* Check on link speed.*/
- if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
- maccr |= ETH_MACCR_FES;
- else
- maccr &= ~ETH_MACCR_FES;
-
- /* Check on link mode.*/
- if (lpa & (LPA_10FULL | LPA_100FULL))
- maccr |= ETH_MACCR_DM;
- else
- maccr &= ~ETH_MACCR_DM;
- }
- else {
- /* Link must be established.*/
- if (!(bmsr & BMSR_LSTATUS))
- return macp->link_up = false;
-
- /* Check on link speed.*/
- if (bmcr & BMCR_SPEED100)
- maccr |= ETH_MACCR_FES;
- else
- maccr &= ~ETH_MACCR_FES;
-
- /* Check on link mode.*/
- if (bmcr & BMCR_FULLDPLX)
- maccr |= ETH_MACCR_DM;
- else
- maccr &= ~ETH_MACCR_DM;
- }
-
- /* Changes the mode in the MAC.*/
- ETH->MACCR = maccr;
-
- /* Returns the link status.*/
- return macp->link_up = true;
-}
-
-/**
- * @brief Writes to a transmit descriptor's stream.
- *
- * @param[in] tdp pointer to a @p MACTransmitDescriptor structure
- * @param[in] buf pointer to the buffer containing the data to be
- * written
- * @param[in] size number of bytes to be written
- * @return The number of bytes written into the descriptor's
- * stream, this value can be less than the amount
- * specified in the parameter @p size if the maximum
- * frame size is reached.
- *
- * @notapi
- */
-size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
- uint8_t *buf,
- size_t size) {
-
- osalDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN),
- "attempt to write descriptor already owned by DMA");
-
- if (size > tdp->size - tdp->offset)
- size = tdp->size - tdp->offset;
-
- if (size > 0) {
- memcpy((uint8_t *)(tdp->physdesc->tdes2) + tdp->offset, buf, size);
- tdp->offset += size;
- }
- return size;
-}
-
-/**
- * @brief Reads from a receive descriptor's stream.
- *
- * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
- * @param[in] buf pointer to the buffer that will receive the read data
- * @param[in] size number of bytes to be read
- * @return The number of bytes read from the descriptor's
- * stream, this value can be less than the amount
- * specified in the parameter @p size if there are
- * no more bytes to read.
- *
- * @notapi
- */
-size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
- uint8_t *buf,
- size_t size) {
-
- osalDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN),
- "attempt to read descriptor already owned by DMA");
-
- if (size > rdp->size - rdp->offset)
- size = rdp->size - rdp->offset;
-
- if (size > 0) {
- memcpy(buf, (uint8_t *)(rdp->physdesc->rdes2) + rdp->offset, size);
- rdp->offset += size;
- }
- return size;
-}
-
-#if MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
-/**
- * @brief Returns a pointer to the next transmit buffer in the descriptor
- * chain.
- * @note The API guarantees that enough buffers can be requested to fill
- * a whole frame.
- *
- * @param[in] tdp pointer to a @p MACTransmitDescriptor structure
- * @param[in] size size of the requested buffer. Specify the frame size
- * on the first call then scale the value down subtracting
- * the amount of data already copied into the previous
- * buffers.
- * @param[out] sizep pointer to variable receiving the buffer size, it is
- * zero when the last buffer has already been returned.
- * Note that a returned size lower than the amount
- * requested means that more buffers must be requested
- * in order to fill the frame data entirely.
- * @return Pointer to the returned buffer.
- * @retval NULL if the buffer chain has been entirely scanned.
- *
- * @notapi
- */
-uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp,
- size_t size,
- size_t *sizep) {
-
- if (tdp->offset == 0) {
- *sizep = tdp->size;
- tdp->offset = size;
- return (uint8_t *)tdp->physdesc->tdes2;
- }
- *sizep = 0;
- return NULL;
-}
-
-/**
- * @brief Returns a pointer to the next receive buffer in the descriptor
- * chain.
- * @note The API guarantees that the descriptor chain contains a whole
- * frame.
- *
- * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
- * @param[out] sizep pointer to variable receiving the buffer size, it is
- * zero when the last buffer has already been returned.
- * @return Pointer to the returned buffer.
- * @retval NULL if the buffer chain has been entirely scanned.
- *
- * @notapi
- */
-const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp,
- size_t *sizep) {
-
- if (rdp->size > 0) {
- *sizep = rdp->size;
- rdp->offset = rdp->size;
- rdp->size = 0;
- return (uint8_t *)rdp->physdesc->rdes2;
- }
- *sizep = 0;
- return NULL;
-}
-#endif /* MAC_USE_ZERO_COPY */
-
-#endif /* HAL_USE_MAC */
-
-/** @} */
+/*
+ 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 MACv1/hal_mac_lld.c
+ * @brief STM32 low level MAC driver code.
+ *
+ * @addtogroup MAC
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_MAC || defined(__DOXYGEN__)
+
+#include "hal_mii.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define BUFFER_SIZE ((((STM32_MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4)
+
+/* Fixing inconsistencies in ST headers.*/
+#if !defined(ETH_MACMIIAR_CR_Div102) && defined(ETH_MACMIIAR_CR_DIV102)
+#define ETH_MACMIIAR_CR_Div102 ETH_MACMIIAR_CR_DIV102
+#endif
+#if !defined(ETH_MACMIIAR_CR_Div62) && defined(ETH_MACMIIAR_CR_DIV62)
+#define ETH_MACMIIAR_CR_Div62 ETH_MACMIIAR_CR_DIV62
+#endif
+#if !defined(ETH_MACMIIAR_CR_Div42) && defined(ETH_MACMIIAR_CR_DIV42)
+#define ETH_MACMIIAR_CR_Div42 ETH_MACMIIAR_CR_DIV42
+#endif
+#if !defined(ETH_MACMIIAR_CR_Div26) && defined(ETH_MACMIIAR_CR_DIV26)
+#define ETH_MACMIIAR_CR_Div26 ETH_MACMIIAR_CR_DIV26
+#endif
+#if !defined(ETH_MACMIIAR_CR_Div16) && defined(ETH_MACMIIAR_CR_DIV16)
+#define ETH_MACMIIAR_CR_Div16 ETH_MACMIIAR_CR_DIV16
+#endif
+
+/* MII divider optimal value.*/
+#if (STM32_HCLK >= 150000000)
+#define MACMIIDR_CR ETH_MACMIIAR_CR_Div102
+#elif (STM32_HCLK >= 100000000)
+#define MACMIIDR_CR ETH_MACMIIAR_CR_Div62
+#elif (STM32_HCLK >= 60000000)
+#define MACMIIDR_CR ETH_MACMIIAR_CR_Div42
+#elif (STM32_HCLK >= 35000000)
+#define MACMIIDR_CR ETH_MACMIIAR_CR_Div26
+#elif (STM32_HCLK >= 20000000)
+#define MACMIIDR_CR ETH_MACMIIAR_CR_Div16
+#else
+#error "STM32_HCLK below minimum frequency for ETH operations (20MHz)"
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Ethernet driver 1.
+ */
+MACDriver ETHD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const uint8_t default_mac_address[] = {0xAA, 0x55, 0x13,
+ 0x37, 0x01, 0x10};
+
+static stm32_eth_rx_descriptor_t __eth_rd[STM32_MAC_RECEIVE_BUFFERS];
+static stm32_eth_tx_descriptor_t __eth_td[STM32_MAC_TRANSMIT_BUFFERS];
+
+static uint32_t __eth_rb[STM32_MAC_RECEIVE_BUFFERS][BUFFER_SIZE];
+static uint32_t __eth_tb[STM32_MAC_TRANSMIT_BUFFERS][BUFFER_SIZE];
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Writes a PHY register.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[in] reg register number
+ * @param[in] value new register value
+ *
+ * @notapi
+ */
+void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) {
+
+ ETH->MACMIIDR = value;
+ ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR |
+ ETH_MACMIIAR_MW | ETH_MACMIIAR_MB;
+ while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0)
+ ;
+}
+
+/**
+ * @brief Reads a PHY register.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[in] reg register number
+ *
+ * @return The PHY register content.
+ *
+ * @notapi
+ */
+uint32_t mii_read(MACDriver *macp, uint32_t reg) {
+
+ ETH->MACMIIAR = macp->phyaddr | (reg << 6) | MACMIIDR_CR | ETH_MACMIIAR_MB;
+ while ((ETH->MACMIIAR & ETH_MACMIIAR_MB) != 0)
+ ;
+ return ETH->MACMIIDR;
+}
+
+#if !defined(BOARD_PHY_ADDRESS)
+/**
+ * @brief PHY address detection.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ */
+static void mii_find_phy(MACDriver *macp) {
+ uint32_t i;
+
+#if STM32_MAC_PHY_TIMEOUT > 0
+ unsigned n = STM32_MAC_PHY_TIMEOUT;
+ do {
+#endif
+ for (i = 0U; i <= 31U; i++) {
+ macp->phyaddr = i << 11U;
+ ETH->MACMIIDR = (i << 6U) | MACMIIDR_CR;
+ if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16U)) &&
+ ((mii_read(macp, MII_PHYSID2) & 0xFFF0U) == (BOARD_PHY_ID & 0xFFF0U))) {
+ return;
+ }
+ }
+#if STM32_MAC_PHY_TIMEOUT > 0
+ n--;
+ } while (n > 0U);
+#endif
+ /* Wrong or defective board.*/
+ osalSysHalt("MAC failure");
+}
+#endif
+
+/**
+ * @brief MAC address setup.
+ *
+ * @param[in] p pointer to a six bytes buffer containing the MAC
+ * address
+ */
+static void mac_lld_set_address(const uint8_t *p) {
+
+ /* MAC address configuration, only a single address comparator is used,
+ hash table not used.*/
+ ETH->MACA0HR = ((uint32_t)p[5] << 8) |
+ ((uint32_t)p[4] << 0);
+ ETH->MACA0LR = ((uint32_t)p[3] << 24) |
+ ((uint32_t)p[2] << 16) |
+ ((uint32_t)p[1] << 8) |
+ ((uint32_t)p[0] << 0);
+ ETH->MACA1HR = 0x0000FFFF;
+ ETH->MACA1LR = 0xFFFFFFFF;
+ ETH->MACA2HR = 0x0000FFFF;
+ ETH->MACA2LR = 0xFFFFFFFF;
+ ETH->MACA3HR = 0x0000FFFF;
+ ETH->MACA3LR = 0xFFFFFFFF;
+ ETH->MACHTHR = 0;
+ ETH->MACHTLR = 0;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+OSAL_IRQ_HANDLER(STM32_ETH_HANDLER) {
+ uint32_t dmasr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmasr = ETH->DMASR;
+ ETH->DMASR = dmasr; /* Clear status bits.*/
+
+ if (dmasr & ETH_DMASR_RS) {
+ /* Data Received.*/
+ osalSysLockFromISR();
+ osalThreadDequeueAllI(ÐD1.rdqueue, MSG_RESET);
+#if MAC_USE_EVENTS
+ osalEventBroadcastFlagsI(ÐD1.rdevent, 0);
+#endif
+ osalSysUnlockFromISR();
+ }
+
+ if (dmasr & ETH_DMASR_TS) {
+ /* Data Transmitted.*/
+ osalSysLockFromISR();
+ osalThreadDequeueAllI(ÐD1.tdqueue, MSG_RESET);
+ osalSysUnlockFromISR();
+ }
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level MAC initialization.
+ *
+ * @notapi
+ */
+void mac_lld_init(void) {
+ unsigned i;
+
+ macObjectInit(ÐD1);
+ ETHD1.link_up = false;
+
+ /* Descriptor tables are initialized in chained mode, note that the first
+ word is not initialized here but in mac_lld_start().*/
+ for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++) {
+ __eth_rd[i].rdes1 = STM32_RDES1_RCH | STM32_MAC_BUFFERS_SIZE;
+ __eth_rd[i].rdes2 = (uint32_t)__eth_rb[i];
+ __eth_rd[i].rdes3 = (uint32_t)&__eth_rd[(i + 1) % STM32_MAC_RECEIVE_BUFFERS];
+ }
+ for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++) {
+ __eth_td[i].tdes1 = 0;
+ __eth_td[i].tdes2 = (uint32_t)__eth_tb[i];
+ __eth_td[i].tdes3 = (uint32_t)&__eth_td[(i + 1) % STM32_MAC_TRANSMIT_BUFFERS];
+ }
+
+ /* Selection of the RMII or MII mode based on info exported by board.h.*/
+#if defined(STM32F10X_CL)
+#if defined(BOARD_PHY_RMII)
+ AFIO->MAPR |= AFIO_MAPR_MII_RMII_SEL;
+#else
+ AFIO->MAPR &= ~AFIO_MAPR_MII_RMII_SEL;
+#endif
+#elif defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX)
+#if defined(BOARD_PHY_RMII)
+ SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
+#else
+ SYSCFG->PMC &= ~SYSCFG_PMC_MII_RMII_SEL;
+#endif
+#else
+#error "unsupported STM32 platform for MAC driver"
+#endif
+
+ /* Reset of the MAC core.*/
+ rccResetETH();
+
+ /* MAC clocks temporary activation.*/
+ rccEnableETH(true);
+
+ /* PHY address setup.*/
+#if defined(BOARD_PHY_ADDRESS)
+ ETHD1.phyaddr = BOARD_PHY_ADDRESS << 11;
+#else
+ mii_find_phy(ÐD1);
+#endif
+
+#if defined(BOARD_PHY_RESET)
+ /* PHY board-specific reset procedure.*/
+ BOARD_PHY_RESET();
+#else
+ /* PHY soft reset procedure.*/
+ mii_write(ÐD1, MII_BMCR, BMCR_RESET);
+#if defined(BOARD_PHY_RESET_DELAY)
+ osalSysPolledDelayX(BOARD_PHY_RESET_DELAY);
+#endif
+ while (mii_read(ÐD1, MII_BMCR) & BMCR_RESET)
+ ;
+#endif
+
+#if STM32_MAC_ETH1_CHANGE_PHY_STATE
+ /* PHY in power down mode until the driver will be started.*/
+ mii_write(ÐD1, MII_BMCR, mii_read(ÐD1, MII_BMCR) | BMCR_PDOWN);
+#endif
+
+ /* MAC clocks stopped again.*/
+ rccDisableETH();
+}
+
+/**
+ * @brief Configures and activates the MAC peripheral.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ *
+ * @notapi
+ */
+void mac_lld_start(MACDriver *macp) {
+ unsigned i;
+
+ /* Resets the state of all descriptors.*/
+ for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++)
+ __eth_rd[i].rdes0 = STM32_RDES0_OWN;
+ macp->rxptr = (stm32_eth_rx_descriptor_t *)__eth_rd;
+ for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++)
+ __eth_td[i].tdes0 = STM32_TDES0_TCH;
+ macp->txptr = (stm32_eth_tx_descriptor_t *)__eth_td;
+
+ /* MAC clocks activation and commanded reset procedure.*/
+ rccEnableETH(true);
+#if defined(STM32_MAC_DMABMR_SR)
+ ETH->DMABMR |= ETH_DMABMR_SR;
+ while (ETH->DMABMR & ETH_DMABMR_SR)
+ ;
+#endif
+
+ /* ISR vector enabled.*/
+ nvicEnableVector(STM32_ETH_NUMBER, STM32_MAC_ETH1_IRQ_PRIORITY);
+
+#if STM32_MAC_ETH1_CHANGE_PHY_STATE
+ /* PHY in power up mode.*/
+ mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) & ~BMCR_PDOWN);
+#endif
+
+ /* MAC configuration.*/
+ ETH->MACFFR = 0;
+ ETH->MACFCR = 0;
+ ETH->MACVLANTR = 0;
+
+ /* MAC address setup.*/
+ if (macp->config->mac_address == NULL)
+ mac_lld_set_address(default_mac_address);
+ else
+ mac_lld_set_address(macp->config->mac_address);
+
+ /* Transmitter and receiver enabled.
+ Note that the complete setup of the MAC is performed when the link
+ status is detected.*/
+#if STM32_MAC_IP_CHECKSUM_OFFLOAD
+ ETH->MACCR = ETH_MACCR_IPCO | ETH_MACCR_RE | ETH_MACCR_TE;
+#else
+ ETH->MACCR = ETH_MACCR_RE | ETH_MACCR_TE;
+#endif
+
+ /* MMC configuration:
+ Disable all MMC interrupts.*/
+ ETH->MMCRIMR = ETH_MMCRIMR_RFCEM | ETH_MMCRIMR_RFAEM | ETH_MMCRIMR_RGUFM;
+ ETH->MMCTIMR = ETH_MMCTIMR_TGFSCM | ETH_MMCTIMR_TGFMSCM | ETH_MMCTIMR_TGFM;
+
+ /* DMA configuration:
+ Descriptor chains pointers.*/
+ ETH->DMARDLAR = (uint32_t)__eth_rd;
+ ETH->DMATDLAR = (uint32_t)__eth_td;
+
+ /* Enabling required interrupt sources.*/
+ ETH->DMASR = ETH->DMASR;
+ ETH->DMAIER = ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE;
+
+ /* DMA general settings.*/
+ ETH->DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_RDP_1Beat | ETH_DMABMR_PBL_1Beat;
+
+ /* Check because errata on some devices. There should be no need to
+ disable flushing because the TXFIFO should be empty on macStart().*/
+#if !defined(STM32_MAC_DISABLE_TX_FLUSH)
+ /* Transmit FIFO flush.*/
+ ETH->DMAOMR = ETH_DMAOMR_FTF;
+ while (ETH->DMAOMR & ETH_DMAOMR_FTF)
+ ;
+#endif
+
+ /* DMA final configuration and start.*/
+ ETH->DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_TSF |
+ ETH_DMAOMR_ST | ETH_DMAOMR_SR;
+}
+
+/**
+ * @brief Deactivates the MAC peripheral.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ *
+ * @notapi
+ */
+void mac_lld_stop(MACDriver *macp) {
+
+ if (macp->state != MAC_STOP) {
+#if STM32_MAC_ETH1_CHANGE_PHY_STATE
+ /* PHY in power down mode until the driver will be restarted.*/
+ mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) | BMCR_PDOWN);
+#endif
+
+ /* MAC and DMA stopped.*/
+ ETH->MACCR = 0;
+ ETH->DMAOMR = 0;
+ ETH->DMAIER = 0;
+ ETH->DMASR = ETH->DMASR;
+
+ /* MAC clocks stopped.*/
+ rccDisableETH();
+
+ /* ISR vector disabled.*/
+ nvicDisableVector(STM32_ETH_NUMBER);
+ }
+}
+
+/**
+ * @brief Returns a transmission descriptor.
+ * @details One of the available transmission descriptors is locked and
+ * returned.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
+ * @return The operation status.
+ * @retval MSG_OK the descriptor has been obtained.
+ * @retval MSG_TIMEOUT descriptor not available.
+ *
+ * @notapi
+ */
+msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
+ MACTransmitDescriptor *tdp) {
+ stm32_eth_tx_descriptor_t *tdes;
+
+ if (!macp->link_up)
+ return MSG_TIMEOUT;
+
+ /* Get Current TX descriptor.*/
+ tdes = macp->txptr;
+
+ /* Ensure that descriptor isn't owned by the Ethernet DMA or locked by
+ another thread.*/
+ if (tdes->tdes0 & (STM32_TDES0_OWN | STM32_TDES0_LOCKED)) {
+ return MSG_TIMEOUT;
+ }
+
+ /* Marks the current descriptor as locked using a reserved bit.*/
+ tdes->tdes0 |= STM32_TDES0_LOCKED;
+
+ /* Next TX descriptor to use.*/
+ macp->txptr = (stm32_eth_tx_descriptor_t *)tdes->tdes3;
+
+ /* Set the buffer size and configuration.*/
+ tdp->offset = 0;
+ tdp->size = STM32_MAC_BUFFERS_SIZE;
+ tdp->physdesc = tdes;
+
+ return MSG_OK;
+}
+
+/**
+ * @brief Releases a transmit descriptor and starts the transmission of the
+ * enqueued data as a single frame.
+ *
+ * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
+ *
+ * @notapi
+ */
+void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
+
+ osalDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN),
+ "attempt to release descriptor already owned by DMA");
+
+ osalSysLock();
+
+ /* Unlocks the descriptor and returns it to the DMA engine.*/
+ tdp->physdesc->tdes1 = tdp->offset;
+ tdp->physdesc->tdes0 = STM32_TDES0_CIC(STM32_MAC_IP_CHECKSUM_OFFLOAD) |
+ STM32_TDES0_IC | STM32_TDES0_LS | STM32_TDES0_FS |
+ STM32_TDES0_TCH | STM32_TDES0_OWN;
+
+ /* Wait for the write to tdes0 to go through before resuming the DMA.*/
+ __DSB();
+
+ /* If the DMA engine is stalled then a restart request is issued.*/
+ if ((ETH->DMASR & ETH_DMASR_TPS) == ETH_DMASR_TPS_Suspended) {
+ ETH->DMASR = ETH_DMASR_TBUS;
+ ETH->DMATPDR = ETH_DMASR_TBUS; /* Any value is OK.*/
+ }
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Returns a receive descriptor.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
+ * @return The operation status.
+ * @retval MSG_OK the descriptor has been obtained.
+ * @retval MSG_TIMEOUT descriptor not available.
+ *
+ * @notapi
+ */
+msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
+ MACReceiveDescriptor *rdp) {
+ stm32_eth_rx_descriptor_t *rdes;
+
+ /* Get Current RX descriptor.*/
+ rdes = macp->rxptr;
+
+ /* Iterates through received frames until a valid one is found, invalid
+ frames are discarded.*/
+ while (!(rdes->rdes0 & STM32_RDES0_OWN)) {
+ if (!(rdes->rdes0 & (STM32_RDES0_AFM | STM32_RDES0_ES))
+#if STM32_MAC_IP_CHECKSUM_OFFLOAD
+ && (rdes->rdes0 & STM32_RDES0_FT)
+ && !(rdes->rdes0 & (STM32_RDES0_IPHCE | STM32_RDES0_PCE))
+#endif
+ && (rdes->rdes0 & STM32_RDES0_FS) && (rdes->rdes0 & STM32_RDES0_LS)) {
+ /* Found a valid one.*/
+ rdp->offset = 0;
+ rdp->size = ((rdes->rdes0 & STM32_RDES0_FL_MASK) >> 16) - 4;
+ rdp->physdesc = rdes;
+ macp->rxptr = (stm32_eth_rx_descriptor_t *)rdes->rdes3;
+
+ return MSG_OK;
+ }
+ /* Invalid frame found, purging.*/
+ rdes->rdes0 = STM32_RDES0_OWN;
+ rdes = (stm32_eth_rx_descriptor_t *)rdes->rdes3;
+ }
+
+ /* Next descriptor to check.*/
+ macp->rxptr = rdes;
+
+ return MSG_TIMEOUT;
+}
+
+/**
+ * @brief Releases a receive descriptor.
+ * @details The descriptor and its buffer are made available for more incoming
+ * frames.
+ *
+ * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
+ *
+ * @notapi
+ */
+void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
+
+ osalDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN),
+ "attempt to release descriptor already owned by DMA");
+
+ osalSysLock();
+
+ /* Give buffer back to the Ethernet DMA.*/
+ rdp->physdesc->rdes0 = STM32_RDES0_OWN;
+
+ /* Wait for the write to rdes0 to go through before resuming the DMA.*/
+ __DSB();
+
+ /* If the DMA engine is stalled then a restart request is issued.*/
+ if ((ETH->DMASR & ETH_DMASR_RPS) == ETH_DMASR_RPS_Suspended) {
+ ETH->DMASR = ETH_DMASR_RBUS;
+ ETH->DMARPDR = ETH_DMASR_RBUS; /* Any value is OK.*/
+ }
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Updates and returns the link status.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @return The link status.
+ * @retval true if the link is active.
+ * @retval false if the link is down.
+ *
+ * @notapi
+ */
+bool mac_lld_poll_link_status(MACDriver *macp) {
+ uint32_t maccr, bmsr, bmcr;
+
+ maccr = ETH->MACCR;
+
+ /* PHY CR and SR registers read.*/
+ (void)mii_read(macp, MII_BMSR);
+ bmsr = mii_read(macp, MII_BMSR);
+ bmcr = mii_read(macp, MII_BMCR);
+
+ /* Check on auto-negotiation mode.*/
+ if (bmcr & BMCR_ANENABLE) {
+ uint32_t lpa;
+
+ /* Auto-negotiation must be finished without faults and link established.*/
+ if ((bmsr & (BMSR_LSTATUS | BMSR_RFAULT | BMSR_ANEGCOMPLETE)) !=
+ (BMSR_LSTATUS | BMSR_ANEGCOMPLETE))
+ return macp->link_up = false;
+
+ /* Auto-negotiation enabled, checks the LPA register.*/
+ lpa = mii_read(macp, MII_LPA);
+
+ /* Check on link speed.*/
+ if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
+ maccr |= ETH_MACCR_FES;
+ else
+ maccr &= ~ETH_MACCR_FES;
+
+ /* Check on link mode.*/
+ if (lpa & (LPA_10FULL | LPA_100FULL))
+ maccr |= ETH_MACCR_DM;
+ else
+ maccr &= ~ETH_MACCR_DM;
+ }
+ else {
+ /* Link must be established.*/
+ if (!(bmsr & BMSR_LSTATUS))
+ return macp->link_up = false;
+
+ /* Check on link speed.*/
+ if (bmcr & BMCR_SPEED100)
+ maccr |= ETH_MACCR_FES;
+ else
+ maccr &= ~ETH_MACCR_FES;
+
+ /* Check on link mode.*/
+ if (bmcr & BMCR_FULLDPLX)
+ maccr |= ETH_MACCR_DM;
+ else
+ maccr &= ~ETH_MACCR_DM;
+ }
+
+ /* Changes the mode in the MAC.*/
+ ETH->MACCR = maccr;
+
+ /* Returns the link status.*/
+ return macp->link_up = true;
+}
+
+/**
+ * @brief Writes to a transmit descriptor's stream.
+ *
+ * @param[in] tdp pointer to a @p MACTransmitDescriptor structure
+ * @param[in] buf pointer to the buffer containing the data to be
+ * written
+ * @param[in] size number of bytes to be written
+ * @return The number of bytes written into the descriptor's
+ * stream, this value can be less than the amount
+ * specified in the parameter @p size if the maximum
+ * frame size is reached.
+ *
+ * @notapi
+ */
+size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
+ uint8_t *buf,
+ size_t size) {
+
+ osalDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN),
+ "attempt to write descriptor already owned by DMA");
+
+ if (size > tdp->size - tdp->offset)
+ size = tdp->size - tdp->offset;
+
+ if (size > 0) {
+ memcpy((uint8_t *)(tdp->physdesc->tdes2) + tdp->offset, buf, size);
+ tdp->offset += size;
+ }
+ return size;
+}
+
+/**
+ * @brief Reads from a receive descriptor's stream.
+ *
+ * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
+ * @param[in] buf pointer to the buffer that will receive the read data
+ * @param[in] size number of bytes to be read
+ * @return The number of bytes read from the descriptor's
+ * stream, this value can be less than the amount
+ * specified in the parameter @p size if there are
+ * no more bytes to read.
+ *
+ * @notapi
+ */
+size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
+ uint8_t *buf,
+ size_t size) {
+
+ osalDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN),
+ "attempt to read descriptor already owned by DMA");
+
+ if (size > rdp->size - rdp->offset)
+ size = rdp->size - rdp->offset;
+
+ if (size > 0) {
+ memcpy(buf, (uint8_t *)(rdp->physdesc->rdes2) + rdp->offset, size);
+ rdp->offset += size;
+ }
+ return size;
+}
+
+#if MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
+/**
+ * @brief Returns a pointer to the next transmit buffer in the descriptor
+ * chain.
+ * @note The API guarantees that enough buffers can be requested to fill
+ * a whole frame.
+ *
+ * @param[in] tdp pointer to a @p MACTransmitDescriptor structure
+ * @param[in] size size of the requested buffer. Specify the frame size
+ * on the first call then scale the value down subtracting
+ * the amount of data already copied into the previous
+ * buffers.
+ * @param[out] sizep pointer to variable receiving the buffer size, it is
+ * zero when the last buffer has already been returned.
+ * Note that a returned size lower than the amount
+ * requested means that more buffers must be requested
+ * in order to fill the frame data entirely.
+ * @return Pointer to the returned buffer.
+ * @retval NULL if the buffer chain has been entirely scanned.
+ *
+ * @notapi
+ */
+uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp,
+ size_t size,
+ size_t *sizep) {
+
+ if (tdp->offset == 0) {
+ *sizep = tdp->size;
+ tdp->offset = size;
+ return (uint8_t *)tdp->physdesc->tdes2;
+ }
+ *sizep = 0;
+ return NULL;
+}
+
+/**
+ * @brief Returns a pointer to the next receive buffer in the descriptor
+ * chain.
+ * @note The API guarantees that the descriptor chain contains a whole
+ * frame.
+ *
+ * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
+ * @param[out] sizep pointer to variable receiving the buffer size, it is
+ * zero when the last buffer has already been returned.
+ * @return Pointer to the returned buffer.
+ * @retval NULL if the buffer chain has been entirely scanned.
+ *
+ * @notapi
+ */
+const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp,
+ size_t *sizep) {
+
+ if (rdp->size > 0) {
+ *sizep = rdp->size;
+ rdp->offset = rdp->size;
+ rdp->size = 0;
+ return (uint8_t *)rdp->physdesc->rdes2;
+ }
+ *sizep = 0;
+ return NULL;
+}
+#endif /* MAC_USE_ZERO_COPY */
+
+#endif /* HAL_USE_MAC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.h b/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.h
index 31ad0164b0..4df08efe41 100644
--- a/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.h
+++ b/os/hal/ports/STM32/LLD/MACv1/hal_mac_lld.h
@@ -1,359 +1,359 @@
-/*
- 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 MACv1/hal_mac_lld.h
- * @brief STM32 low level MAC driver header.
- *
- * @addtogroup MAC
- * @{
- */
-
-#ifndef HAL_MAC_LLD_H
-#define HAL_MAC_LLD_H
-
-#if HAL_USE_MAC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief This implementation supports the zero-copy mode API.
- */
-#define MAC_SUPPORTS_ZERO_COPY TRUE
-
-/**
- * @name RDES0 constants
- * @{
- */
-#define STM32_RDES0_OWN 0x80000000
-#define STM32_RDES0_AFM 0x40000000
-#define STM32_RDES0_FL_MASK 0x3FFF0000
-#define STM32_RDES0_ES 0x00008000
-#define STM32_RDES0_DESERR 0x00004000
-#define STM32_RDES0_SAF 0x00002000
-#define STM32_RDES0_LE 0x00001000
-#define STM32_RDES0_OE 0x00000800
-#define STM32_RDES0_VLAN 0x00000400
-#define STM32_RDES0_FS 0x00000200
-#define STM32_RDES0_LS 0x00000100
-#define STM32_RDES0_IPHCE 0x00000080
-#define STM32_RDES0_LCO 0x00000040
-#define STM32_RDES0_FT 0x00000020
-#define STM32_RDES0_RWT 0x00000010
-#define STM32_RDES0_RE 0x00000008
-#define STM32_RDES0_DE 0x00000004
-#define STM32_RDES0_CE 0x00000002
-#define STM32_RDES0_PCE 0x00000001
-/** @} */
-
-/**
- * @name RDES1 constants
- * @{
- */
-#define STM32_RDES1_DIC 0x80000000
-#define STM32_RDES1_RBS2_MASK 0x1FFF0000
-#define STM32_RDES1_RER 0x00008000
-#define STM32_RDES1_RCH 0x00004000
-#define STM32_RDES1_RBS1_MASK 0x00001FFF
-/** @} */
-
-/**
- * @name TDES0 constants
- * @{
- */
-#define STM32_TDES0_OWN 0x80000000
-#define STM32_TDES0_IC 0x40000000
-#define STM32_TDES0_LS 0x20000000
-#define STM32_TDES0_FS 0x10000000
-#define STM32_TDES0_DC 0x08000000
-#define STM32_TDES0_DP 0x04000000
-#define STM32_TDES0_TTSE 0x02000000
-#define STM32_TDES0_LOCKED 0x01000000 /* NOTE: Pseudo flag. */
-#define STM32_TDES0_CIC_MASK 0x00C00000
-#define STM32_TDES0_CIC(n) ((n) << 22)
-#define STM32_TDES0_TER 0x00200000
-#define STM32_TDES0_TCH 0x00100000
-#define STM32_TDES0_TTSS 0x00020000
-#define STM32_TDES0_IHE 0x00010000
-#define STM32_TDES0_ES 0x00008000
-#define STM32_TDES0_JT 0x00004000
-#define STM32_TDES0_FF 0x00002000
-#define STM32_TDES0_IPE 0x00001000
-#define STM32_TDES0_LCA 0x00000800
-#define STM32_TDES0_NC 0x00000400
-#define STM32_TDES0_LCO 0x00000200
-#define STM32_TDES0_EC 0x00000100
-#define STM32_TDES0_VF 0x00000080
-#define STM32_TDES0_CC_MASK 0x00000078
-#define STM32_TDES0_ED 0x00000004
-#define STM32_TDES0_UF 0x00000002
-#define STM32_TDES0_DB 0x00000001
-/** @} */
-
-/**
- * @name TDES1 constants
- * @{
- */
-#define STM32_TDES1_TBS2_MASK 0x1FFF0000
-#define STM32_TDES1_TBS1_MASK 0x00001FFF
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief Number of available transmit buffers.
- */
-#if !defined(STM32_MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
-#define STM32_MAC_TRANSMIT_BUFFERS 2
-#endif
-
-/**
- * @brief Number of available receive buffers.
- */
-#if !defined(STM32_MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
-#define STM32_MAC_RECEIVE_BUFFERS 4
-#endif
-
-/**
- * @brief Maximum supported frame size.
- */
-#if !defined(STM32_MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
-#define STM32_MAC_BUFFERS_SIZE 1522
-#endif
-
-/**
- * @brief PHY detection timeout.
- * @details Timeout for PHY address detection, the scan for a PHY is performed
- * the specified number of times before invoking the failure handler.
- * This setting applies only if the PHY address is not explicitly
- * set in the board header file using @p BOARD_PHY_ADDRESS. A zero
- * value disables the timeout and a single search is performed.
- */
-#if !defined(STM32_MAC_PHY_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_MAC_PHY_TIMEOUT 100
-#endif
-
-/**
- * @brief Change the PHY power state inside the driver.
- */
-#if !defined(STM32_MAC_ETH1_CHANGE_PHY_STATE) || defined(__DOXYGEN__)
-#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
-#endif
-
-/**
- * @brief ETHD1 interrupt priority level setting.
- */
-#if !defined(STM32_MAC_ETH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_MAC_ETH1_IRQ_PRIORITY 13
-#endif
-
-/**
- * @brief IP checksum offload.
- * @details The following modes are available:
- * - 0 Function disabled.
- * - 1 Only IP header checksum calculation and insertion are enabled.
- * - 2 IP header checksum and payload checksum calculation and
- * insertion are enabled, but pseudo-header checksum is not
- * calculated in hardware.
- * - 3 IP Header checksum and payload checksum calculation and
- * insertion are enabled, and pseudo-header checksum is
- * calculated in hardware.
- * .
- */
-#if !defined(STM32_MAC_IP_CHECKSUM_OFFLOAD) || defined(__DOXYGEN__)
-#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of an STM32 Ethernet receive descriptor.
- */
-typedef struct {
- volatile uint32_t rdes0;
- volatile uint32_t rdes1;
- volatile uint32_t rdes2;
- volatile uint32_t rdes3;
-} stm32_eth_rx_descriptor_t;
-
-/**
- * @brief Type of an STM32 Ethernet transmit descriptor.
- */
-typedef struct {
- volatile uint32_t tdes0;
- volatile uint32_t tdes1;
- volatile uint32_t tdes2;
- volatile uint32_t tdes3;
-} stm32_eth_tx_descriptor_t;
-
-/**
- * @brief Driver configuration structure.
- */
-typedef struct {
- /**
- * @brief MAC address.
- */
- uint8_t *mac_address;
- /* End of the mandatory fields.*/
-} MACConfig;
-
-/**
- * @brief Structure representing a MAC driver.
- */
-struct MACDriver {
- /**
- * @brief Driver state.
- */
- macstate_t state;
- /**
- * @brief Current configuration data.
- */
- const MACConfig *config;
- /**
- * @brief Transmit semaphore.
- */
- threads_queue_t tdqueue;
- /**
- * @brief Receive semaphore.
- */
- threads_queue_t rdqueue;
-#if MAC_USE_EVENTS || defined(__DOXYGEN__)
- /**
- * @brief Receive event.
- */
- event_source_t rdevent;
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Link status flag.
- */
- bool link_up;
- /**
- * @brief PHY address (pre shifted).
- */
- uint32_t phyaddr;
- /**
- * @brief Receive next frame pointer.
- */
- stm32_eth_rx_descriptor_t *rxptr;
- /**
- * @brief Transmit next frame pointer.
- */
- stm32_eth_tx_descriptor_t *txptr;
-};
-
-/**
- * @brief Structure representing a transmit descriptor.
- */
-typedef struct {
- /**
- * @brief Current write offset.
- */
- size_t offset;
- /**
- * @brief Available space size.
- */
- size_t size;
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the physical descriptor.
- */
- stm32_eth_tx_descriptor_t *physdesc;
-} MACTransmitDescriptor;
-
-/**
- * @brief Structure representing a receive descriptor.
- */
-typedef struct {
- /**
- * @brief Current read offset.
- */
- size_t offset;
- /**
- * @brief Available data size.
- */
- size_t size;
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the physical descriptor.
- */
- stm32_eth_rx_descriptor_t *physdesc;
-} MACReceiveDescriptor;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern MACDriver ETHD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void mii_write(MACDriver *macp, uint32_t reg, uint32_t value);
- uint32_t mii_read(MACDriver *macp, uint32_t reg);
- void mac_lld_init(void);
- void mac_lld_start(MACDriver *macp);
- void mac_lld_stop(MACDriver *macp);
- msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
- MACTransmitDescriptor *tdp);
- void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
- msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
- MACReceiveDescriptor *rdp);
- void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
- bool mac_lld_poll_link_status(MACDriver *macp);
- size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
- uint8_t *buf,
- size_t size);
- size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
- uint8_t *buf,
- size_t size);
-#if MAC_USE_ZERO_COPY
- uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp,
- size_t size,
- size_t *sizep);
- const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp,
- size_t *sizep);
-#endif /* MAC_USE_ZERO_COPY */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_MAC */
-
-#endif /* HAL_MAC_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 MACv1/hal_mac_lld.h
+ * @brief STM32 low level MAC driver header.
+ *
+ * @addtogroup MAC
+ * @{
+ */
+
+#ifndef HAL_MAC_LLD_H
+#define HAL_MAC_LLD_H
+
+#if HAL_USE_MAC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief This implementation supports the zero-copy mode API.
+ */
+#define MAC_SUPPORTS_ZERO_COPY TRUE
+
+/**
+ * @name RDES0 constants
+ * @{
+ */
+#define STM32_RDES0_OWN 0x80000000
+#define STM32_RDES0_AFM 0x40000000
+#define STM32_RDES0_FL_MASK 0x3FFF0000
+#define STM32_RDES0_ES 0x00008000
+#define STM32_RDES0_DESERR 0x00004000
+#define STM32_RDES0_SAF 0x00002000
+#define STM32_RDES0_LE 0x00001000
+#define STM32_RDES0_OE 0x00000800
+#define STM32_RDES0_VLAN 0x00000400
+#define STM32_RDES0_FS 0x00000200
+#define STM32_RDES0_LS 0x00000100
+#define STM32_RDES0_IPHCE 0x00000080
+#define STM32_RDES0_LCO 0x00000040
+#define STM32_RDES0_FT 0x00000020
+#define STM32_RDES0_RWT 0x00000010
+#define STM32_RDES0_RE 0x00000008
+#define STM32_RDES0_DE 0x00000004
+#define STM32_RDES0_CE 0x00000002
+#define STM32_RDES0_PCE 0x00000001
+/** @} */
+
+/**
+ * @name RDES1 constants
+ * @{
+ */
+#define STM32_RDES1_DIC 0x80000000
+#define STM32_RDES1_RBS2_MASK 0x1FFF0000
+#define STM32_RDES1_RER 0x00008000
+#define STM32_RDES1_RCH 0x00004000
+#define STM32_RDES1_RBS1_MASK 0x00001FFF
+/** @} */
+
+/**
+ * @name TDES0 constants
+ * @{
+ */
+#define STM32_TDES0_OWN 0x80000000
+#define STM32_TDES0_IC 0x40000000
+#define STM32_TDES0_LS 0x20000000
+#define STM32_TDES0_FS 0x10000000
+#define STM32_TDES0_DC 0x08000000
+#define STM32_TDES0_DP 0x04000000
+#define STM32_TDES0_TTSE 0x02000000
+#define STM32_TDES0_LOCKED 0x01000000 /* NOTE: Pseudo flag. */
+#define STM32_TDES0_CIC_MASK 0x00C00000
+#define STM32_TDES0_CIC(n) ((n) << 22)
+#define STM32_TDES0_TER 0x00200000
+#define STM32_TDES0_TCH 0x00100000
+#define STM32_TDES0_TTSS 0x00020000
+#define STM32_TDES0_IHE 0x00010000
+#define STM32_TDES0_ES 0x00008000
+#define STM32_TDES0_JT 0x00004000
+#define STM32_TDES0_FF 0x00002000
+#define STM32_TDES0_IPE 0x00001000
+#define STM32_TDES0_LCA 0x00000800
+#define STM32_TDES0_NC 0x00000400
+#define STM32_TDES0_LCO 0x00000200
+#define STM32_TDES0_EC 0x00000100
+#define STM32_TDES0_VF 0x00000080
+#define STM32_TDES0_CC_MASK 0x00000078
+#define STM32_TDES0_ED 0x00000004
+#define STM32_TDES0_UF 0x00000002
+#define STM32_TDES0_DB 0x00000001
+/** @} */
+
+/**
+ * @name TDES1 constants
+ * @{
+ */
+#define STM32_TDES1_TBS2_MASK 0x1FFF0000
+#define STM32_TDES1_TBS1_MASK 0x00001FFF
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief Number of available transmit buffers.
+ */
+#if !defined(STM32_MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
+#define STM32_MAC_TRANSMIT_BUFFERS 2
+#endif
+
+/**
+ * @brief Number of available receive buffers.
+ */
+#if !defined(STM32_MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
+#define STM32_MAC_RECEIVE_BUFFERS 4
+#endif
+
+/**
+ * @brief Maximum supported frame size.
+ */
+#if !defined(STM32_MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define STM32_MAC_BUFFERS_SIZE 1522
+#endif
+
+/**
+ * @brief PHY detection timeout.
+ * @details Timeout for PHY address detection, the scan for a PHY is performed
+ * the specified number of times before invoking the failure handler.
+ * This setting applies only if the PHY address is not explicitly
+ * set in the board header file using @p BOARD_PHY_ADDRESS. A zero
+ * value disables the timeout and a single search is performed.
+ */
+#if !defined(STM32_MAC_PHY_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_MAC_PHY_TIMEOUT 100
+#endif
+
+/**
+ * @brief Change the PHY power state inside the driver.
+ */
+#if !defined(STM32_MAC_ETH1_CHANGE_PHY_STATE) || defined(__DOXYGEN__)
+#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
+#endif
+
+/**
+ * @brief ETHD1 interrupt priority level setting.
+ */
+#if !defined(STM32_MAC_ETH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_MAC_ETH1_IRQ_PRIORITY 13
+#endif
+
+/**
+ * @brief IP checksum offload.
+ * @details The following modes are available:
+ * - 0 Function disabled.
+ * - 1 Only IP header checksum calculation and insertion are enabled.
+ * - 2 IP header checksum and payload checksum calculation and
+ * insertion are enabled, but pseudo-header checksum is not
+ * calculated in hardware.
+ * - 3 IP Header checksum and payload checksum calculation and
+ * insertion are enabled, and pseudo-header checksum is
+ * calculated in hardware.
+ * .
+ */
+#if !defined(STM32_MAC_IP_CHECKSUM_OFFLOAD) || defined(__DOXYGEN__)
+#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an STM32 Ethernet receive descriptor.
+ */
+typedef struct {
+ volatile uint32_t rdes0;
+ volatile uint32_t rdes1;
+ volatile uint32_t rdes2;
+ volatile uint32_t rdes3;
+} stm32_eth_rx_descriptor_t;
+
+/**
+ * @brief Type of an STM32 Ethernet transmit descriptor.
+ */
+typedef struct {
+ volatile uint32_t tdes0;
+ volatile uint32_t tdes1;
+ volatile uint32_t tdes2;
+ volatile uint32_t tdes3;
+} stm32_eth_tx_descriptor_t;
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief MAC address.
+ */
+ uint8_t *mac_address;
+ /* End of the mandatory fields.*/
+} MACConfig;
+
+/**
+ * @brief Structure representing a MAC driver.
+ */
+struct MACDriver {
+ /**
+ * @brief Driver state.
+ */
+ macstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const MACConfig *config;
+ /**
+ * @brief Transmit semaphore.
+ */
+ threads_queue_t tdqueue;
+ /**
+ * @brief Receive semaphore.
+ */
+ threads_queue_t rdqueue;
+#if MAC_USE_EVENTS || defined(__DOXYGEN__)
+ /**
+ * @brief Receive event.
+ */
+ event_source_t rdevent;
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Link status flag.
+ */
+ bool link_up;
+ /**
+ * @brief PHY address (pre shifted).
+ */
+ uint32_t phyaddr;
+ /**
+ * @brief Receive next frame pointer.
+ */
+ stm32_eth_rx_descriptor_t *rxptr;
+ /**
+ * @brief Transmit next frame pointer.
+ */
+ stm32_eth_tx_descriptor_t *txptr;
+};
+
+/**
+ * @brief Structure representing a transmit descriptor.
+ */
+typedef struct {
+ /**
+ * @brief Current write offset.
+ */
+ size_t offset;
+ /**
+ * @brief Available space size.
+ */
+ size_t size;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the physical descriptor.
+ */
+ stm32_eth_tx_descriptor_t *physdesc;
+} MACTransmitDescriptor;
+
+/**
+ * @brief Structure representing a receive descriptor.
+ */
+typedef struct {
+ /**
+ * @brief Current read offset.
+ */
+ size_t offset;
+ /**
+ * @brief Available data size.
+ */
+ size_t size;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the physical descriptor.
+ */
+ stm32_eth_rx_descriptor_t *physdesc;
+} MACReceiveDescriptor;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern MACDriver ETHD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void mii_write(MACDriver *macp, uint32_t reg, uint32_t value);
+ uint32_t mii_read(MACDriver *macp, uint32_t reg);
+ void mac_lld_init(void);
+ void mac_lld_start(MACDriver *macp);
+ void mac_lld_stop(MACDriver *macp);
+ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
+ MACTransmitDescriptor *tdp);
+ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
+ msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
+ MACReceiveDescriptor *rdp);
+ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
+ bool mac_lld_poll_link_status(MACDriver *macp);
+ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
+ uint8_t *buf,
+ size_t size);
+ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
+ uint8_t *buf,
+ size_t size);
+#if MAC_USE_ZERO_COPY
+ uint8_t *mac_lld_get_next_transmit_buffer(MACTransmitDescriptor *tdp,
+ size_t size,
+ size_t *sizep);
+ const uint8_t *mac_lld_get_next_receive_buffer(MACReceiveDescriptor *rdp,
+ size_t *sizep);
+#endif /* MAC_USE_ZERO_COPY */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_MAC */
+
+#endif /* HAL_MAC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/MACv2/driver.mk b/os/hal/ports/STM32/LLD/MACv2/driver.mk
index e746dc14b0..c9fc45f13f 100644
--- a/os/hal/ports/STM32/LLD/MACv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/MACv2/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_MAC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_MAC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2
diff --git a/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c b/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
index 1987973c1f..b02303ba10 100644
--- a/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
+++ b/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.c
@@ -1,773 +1,773 @@
-/*
- 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 MACv2/hal_mac_lld.c
- * @brief STM32 low level MAC driver code.
- *
- * @addtogroup MAC
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_MAC || defined(__DOXYGEN__)
-
-#include "hal_mii.h"
-
-/* Fixes for errors in ST headers.*/
-#if ETH_DMADSR_RPS_FETCHING_Pos == 12
-#undef ETH_DMADSR_RPS_FETCHING_Pos
-#define ETH_DMADSR_RPS_FETCHING_Pos (8U)
-#endif
-
-#if ETH_DMADSR_RPS_WAITING_Pos == 12
-#undef ETH_DMADSR_RPS_WAITING_Pos
-#define ETH_DMADSR_RPS_WAITING_Pos (9U)
-#endif
-
-#if ETH_DMADSR_RPS_SUSPENDED_Pos == 14
-#undef ETH_DMADSR_RPS_SUSPENDED_Pos
-#define ETH_DMADSR_RPS_SUSPENDED_Pos (10U)
-#endif
-
-#if ETH_DMADSR_RPS_CLOSING_Pos == 12
-#undef ETH_DMADSR_RPS_CLOSING_Pos
-#define ETH_DMADSR_RPS_CLOSING_Pos (10U)
-#endif
-
-#if ETH_DMADSR_RPS_TIMESTAMP_WR_Pos == 13
-#undef ETH_DMADSR_RPS_TIMESTAMP_WR_Pos
-#undef ETH_DMADSR_RPS_TIMESTAMP_WR_Msk
-#define ETH_DMADSR_RPS_TIMESTAMP_WR_Pos (10U)
-#define ETH_DMADSR_RPS_TIMESTAMP_WR_Msk (0x6UL << ETH_DMADSR_RPS_TIMESTAMP_WR_Pos)
-#endif
-
-#if ETH_DMADSR_RPS_TRANSFERRING_Pos == 12
-#undef ETH_DMADSR_RPS_TRANSFERRING_Pos
-#define ETH_DMADSR_RPS_TRANSFERRING_Pos (10U)
-#endif
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define BUFFER_SIZE ((((STM32_MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4)
-
-/* Fixing inconsistencies in ST headers.*/
-#if !defined(ETH_MACMDIOAR_CR_Div124) && defined(ETH_MACMDIOAR_CR_DIV124)
-#define ETH_MACMDIOAR_CR_Div124 ETH_MACMDIOAR_CR_DIV124
-#endif
-#if !defined(ETH_MACMDIOAR_CR_Div102) && defined(ETH_MACMDIOAR_CR_DIV102)
-#define ETH_MACMDIOAR_CR_Div102 ETH_MACMDIOAR_CR_DIV102
-#endif
-#if !defined(ETH_MACMDIOAR_CR_Div62) && defined(ETH_MACMDIOAR_CR_DIV62)
-#define ETH_MACMDIOAR_CR_Div62 ETH_MACMDIOAR_CR_DIV62
-#endif
-#if !defined(ETH_MACMDIOAR_CR_Div42) && defined(ETH_MACMDIOAR_CR_DIV42)
-#define ETH_MACMDIOAR_CR_Div42 ETH_MACMDIOAR_CR_DIV42
-#endif
-#if !defined(ETH_MACMDIOAR_CR_Div26) && defined(ETH_MACMDIOAR_CR_DIV26)
-#define ETH_MACMDIOAR_CR_Div26 ETH_MACMDIOAR_CR_DIV26
-#endif
-#if !defined(ETH_MACMDIOAR_CR_Div16) && defined(ETH_MACMDIOAR_CR_DIV16)
-#define ETH_MACMDIOAR_CR_Div16 ETH_MACMDIOAR_CR_DIV16
-#endif
-
-/* MII divider optimal value.*/
-#if (STM32_HCLK > 300000000)
-#error "STM32_HCLK above maximum frequency for ETH operations (300MHz)"
-#elif (STM32_HCLK >= 250000000)
-#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div124
-#elif (STM32_HCLK >= 150000000)
-#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div102
-#elif (STM32_HCLK >= 100000000)
-#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div62
-#elif (STM32_HCLK >= 60000000)
-#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div42
-#elif (STM32_HCLK >= 35000000)
-#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div26
-#elif (STM32_HCLK >= 20000000)
-#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div16
-#else
-#error "STM32_HCLK below minimum frequency for ETH operations (20MHz)"
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief Ethernet driver 1.
- */
-MACDriver ETHD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint8_t default_mac_address[] = {0xAA, 0x55, 0x13,
- 0x37, 0x01, 0x10};
-
-static stm32_eth_rx_descriptor_t __eth_rd[STM32_MAC_RECEIVE_BUFFERS]
- __attribute__((aligned(4), __section__(".eth")));
-static stm32_eth_tx_descriptor_t __eth_td[STM32_MAC_TRANSMIT_BUFFERS]
- __attribute__((aligned(4), __section__(".eth")));
-
-static uint32_t __eth_rb[STM32_MAC_RECEIVE_BUFFERS][BUFFER_SIZE]
- __attribute__((aligned(4), __section__(".eth")));
-static uint32_t __eth_tb[STM32_MAC_TRANSMIT_BUFFERS][BUFFER_SIZE]
- __attribute__((aligned(4), __section__(".eth")));
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Writes a PHY register.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[in] reg register number
- * @param[in] value new register value
- *
- * @notapi
- */
-void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) {
-
- ETH->MACMDIODR = value;
- ETH->MACMDIOAR = macp->phyaddr | (reg << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR |
- ETH_MACMDIOAR_MOC_WR | ETH_MACMDIOAR_MB;
- while ((ETH->MACMDIOAR & ETH_MACMDIOAR_MB) != 0)
- ;
-}
-
-/**
- * @brief Reads a PHY register.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[in] reg register number
- *
- * @return The PHY register content.
- *
- * @notapi
- */
-uint32_t mii_read(MACDriver *macp, uint32_t reg) {
-
- ETH->MACMDIOAR = macp->phyaddr | (reg << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR |
- ETH_MACMDIOAR_MOC_RD | ETH_MACMDIOAR_MB;
- while ((ETH->MACMDIOAR & ETH_MACMDIOAR_MB) != 0)
- ;
- return ETH->MACMDIODR;
-}
-
-#if !defined(BOARD_PHY_ADDRESS)
-/**
- * @brief PHY address detection.
- *
- * @param[in] macp pointer to the @p MACDriver object
- */
-static void mii_find_phy(MACDriver *macp) {
- uint32_t i;
-
-#if STM32_MAC_PHY_TIMEOUT > 0
- unsigned n = STM32_MAC_PHY_TIMEOUT;
- do {
-#endif
- for (i = 0U; i <= 31U; i++) {
- macp->phyaddr = i << ETH_MACMDIOAR_PA_Pos;
- ETH->MACMDIOAR = (i << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR;
- ETH->MACMDIODR = (i << ETH_MACMDIODR_RA_Pos) | MACMDIODR_CR;
- if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16U)) &&
- ((mii_read(macp, MII_PHYSID2) & 0xFFF0U) == (BOARD_PHY_ID & 0xFFF0U))) {
- return;
- }
- }
-#if STM32_MAC_PHY_TIMEOUT > 0
- n--;
- } while (n > 0U);
-#endif
- /* Wrong or defective board.*/
- osalSysHalt("MAC failure");
-}
-#endif
-
-/**
- * @brief MAC address setup.
- *
- * @param[in] p pointer to a six bytes buffer containing the MAC
- * address
- */
-static void mac_lld_set_address(const uint8_t *p) {
-
- /* MAC address configuration, only a single address comparator is used,
- hash table not used.*/
- ETH->MACA0HR = ((uint32_t)p[5] << 8) |
- ((uint32_t)p[4] << 0);
- ETH->MACA0LR = ((uint32_t)p[3] << 24) |
- ((uint32_t)p[2] << 16) |
- ((uint32_t)p[1] << 8) |
- ((uint32_t)p[0] << 0);
- ETH->MACA1HR = 0;
- ETH->MACA1LR = 0;
- ETH->MACA2HR = 0;
- ETH->MACA2LR = 0;
- ETH->MACA3HR = 0;
- ETH->MACA3LR = 0;
- ETH->MACHT0R = 0;
- ETH->MACHT1R = 0;
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-OSAL_IRQ_HANDLER(STM32_ETH_HANDLER) {
- uint32_t dmasr;
-
- OSAL_IRQ_PROLOGUE();
-
- dmasr = ETH->DMACSR;
-
- if (dmasr & ETH_DMACSR_RI) {
- /* Data Received.*/
- ETH->DMACSR = ETH_DMACSR_RI;
- ETH->DMACIER &= ~ETH_DMACIER_RIE;
- osalSysLockFromISR();
- osalThreadDequeueAllI(ÐD1.rdqueue, MSG_RESET);
-#if MAC_USE_EVENTS
- osalEventBroadcastFlagsI(ÐD1.rdevent, 0);
-#endif
- osalSysUnlockFromISR();
- }
-
- if (dmasr & ETH_DMACSR_TI) {
- /* Data Transmitted.*/
- ETH->DMACSR = ETH_DMACSR_TI;
- osalSysLockFromISR();
- osalThreadDequeueAllI(ÐD1.tdqueue, MSG_RESET);
- osalSysUnlockFromISR();
- }
-
- ETH->DMACSR |= ETH_DMACSR_NIS;
- ETH->DMACIER = ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE;
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level MAC initialization.
- *
- * @notapi
- */
-void mac_lld_init(void) {
- unsigned i,j;
-
- macObjectInit(ÐD1);
- ETHD1.link_up = false;
-
- /* Descriptor tables are initialized in ring mode, note that the first
- word is not initialized here but in mac_lld_start().*/
- for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++) {
- __eth_rd[i].rdes0 = (uint32_t)__eth_rb[i];
- __eth_rd[i].rdes1 = 0;
- __eth_rd[i].rdes2 = 0;
- __eth_rd[i].rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
- for (j = 0; j < BUFFER_SIZE; j++) {
- __eth_rb[i][j] = 825373492; /* telltale "1234" */
- }
- }
- for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++) {
- __eth_td[i].tdes0 = 0;
- __eth_td[i].tdes1 = 0;
- __eth_td[i].tdes2 = 0;
- __eth_td[i].tdes3 = 0;
- for (j = 0; j < BUFFER_SIZE; j++) {
- __eth_tb[i][j] = 892745528; /* telltale "5678" */
- }
- }
-
- /* Selection of the RMII or MII mode based on info exported by board.h.*/
-#if defined(STM32H7XX)
- SYSCFG->PMCR |= SYSCFG_PMCR_PA1SO;
-#if defined(BOARD_PHY_RMII)
- SYSCFG->PMCR |= SYSCFG_PMCR_EPIS_SEL_2;
- SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_1;
- SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_0;
-#else
- SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_2;
- SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_1;
- SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_0;
-#endif
-#else
-#error "unsupported STM32 platform for MACv2 driver"
-#endif
-
- /* Reset of the MAC core.*/
- rccResetETH();
-
- /* MAC clocks temporary activation.*/
- rccEnableETH(true);
-
- /* PHY address setup.*/
-#if defined(BOARD_PHY_ADDRESS)
- ETHD1.phyaddr = BOARD_PHY_ADDRESS << 11;
-#else
- mii_find_phy(ÐD1);
-#endif
-
-#if defined(BOARD_PHY_RESET)
- /* PHY board-specific reset procedure.*/
- BOARD_PHY_RESET();
-#else
- /* PHY soft reset procedure.*/
- mii_write(ÐD1, MII_BMCR, BMCR_RESET);
-#if defined(BOARD_PHY_RESET_DELAY)
- osalSysPolledDelayX(BOARD_PHY_RESET_DELAY);
-#endif
- while (mii_read(ÐD1, MII_BMCR) & BMCR_RESET)
- ;
-#endif
-
-#if STM32_MAC_ETH1_CHANGE_PHY_STATE
- /* PHY in power down mode until the driver will be started.*/
- mii_write(ÐD1, MII_BMCR, mii_read(ÐD1, MII_BMCR) | BMCR_PDOWN);
-#endif
-
- /* MAC clocks stopped again.*/
- rccDisableETH();
-}
-
-/**
- * @brief Configures and activates the MAC peripheral.
- *
- * @param[in] macp pointer to the @p MACDriver object
- *
- * @notapi
- */
-void mac_lld_start(MACDriver *macp) {
- unsigned i;
-
- /* Resets the state of all descriptors.*/
- for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++)
- __eth_rd[i].rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
- macp->rdindex = 0;
- for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++)
- __eth_td[i].tdes3 = 0;
- macp->tdindex = 0;
-
- /* MAC clocks activation and commanded reset procedure.*/
- rccEnableETH(true);
-
- /* ISR vector enabled.*/
- nvicEnableVector(STM32_ETH_NUMBER, STM32_MAC_ETH1_IRQ_PRIORITY);
-
-#if STM32_MAC_ETH1_CHANGE_PHY_STATE
- /* PHY in power up mode.*/
- mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) & ~BMCR_PDOWN);
-#endif
-
- ETH->DMAMR |= ETH_DMAMR_SWR;
- while (ETH->DMAMR & ETH_DMAMR_SWR)
- ;
-
- /* MAC configuration.*/
- ETH->MACCR = ETH_MACCR_DO;
- ETH->MACPFR = 0;
- ETH->MACTFCR = 0;
- ETH->MACRFCR = 0;
- ETH->MACVTR = 0;
-
- /* MAC address setup.*/
- if (macp->config->mac_address == NULL)
- mac_lld_set_address(default_mac_address);
- else
- mac_lld_set_address(macp->config->mac_address);
-
- /* Transmitter and receiver enabled.
- Note that the complete setup of the MAC is performed when the link
- status is detected.*/
-#if STM32_MAC_IP_CHECKSUM_OFFLOAD
- ETH->MACCR |= ETH_MACCR_IPC | ETH_MACCR_RE | ETH_MACCR_TE;
-#else
- ETH->MACCR |= ETH_MACCR_RE | ETH_MACCR_TE;
-#endif
-
- /* DMA general settings.*/
- ETH->DMASBMR = ETH_DMASBMR_AAL;
- ETH->DMACCR = ETH_DMACCR_DSL_0BIT;
- ETH->DMAMR = ETH_DMAMR_INTM_0 | ETH_DMAMR_PR_8_1 | ETH_DMAMR_TXPR; /* TX:RX 8:1 */
- /* DMA configuration:
- Descriptor rings pointers.*/
- ETH->DMACTDLAR = (uint32_t)&__eth_td[0];
- ETH->DMACTDRLR = STM32_MAC_TRANSMIT_BUFFERS-1;
- ETH->DMACRDLAR = (uint32_t)&__eth_rd[0];
- ETH->DMACRDRLR = STM32_MAC_RECEIVE_BUFFERS-1;
-
- /* Enabling required interrupt sources.*/
- ETH->DMACSR = ETH_DMACSR_NIS;
- ETH->DMACIER = ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE;
-
-
- /* Check because errata on some devices. There should be no need to
- disable flushing because the TXFIFO should be empty on macStart().*/
-#if !defined(STM32_MAC_DISABLE_TX_FLUSH)
- /* Transmit FIFO flush.*/
- ETH->MTLTQOMR = ETH_MTLTQOMR_FTQ;
- while (ETH->MTLTQOMR & ETH_MTLTQOMR_FTQ)
- ;
-#endif
-
- /* DMA final configuration and start.*/
- ETH->MTLRQOMR = ETH_MTLRQOMR_DISTCPEF | ETH_MTLRQOMR_RSF;
- ETH->MTLTQOMR = ETH_MTLTQOMR_TSF;
- ETH->DMACTCR = ETH_DMACTCR_ST | ETH_DMACTCR_TPBL_1PBL;
- ETH->DMACRCR = ETH_DMACRCR_SR | ETH_DMACRCR_RPBL_1PBL
- | (STM32_MAC_BUFFERS_SIZE << ETH_DMACRCR_RBSZ_Pos
- & ETH_DMACRCR_RBSZ);
-}
-
-/**
- * @brief Deactivates the MAC peripheral.
- *
- * @param[in] macp pointer to the @p MACDriver object
- *
- * @notapi
- */
-void mac_lld_stop(MACDriver *macp) {
-
- if (macp->state != MAC_STOP) {
-#if STM32_MAC_ETH1_CHANGE_PHY_STATE
- /* PHY in power down mode until the driver will be restarted.*/
- mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) | BMCR_PDOWN);
-#endif
-
- /* MAC and DMA stopped.*/
- ETH->MACCR = 0;
- ETH->MTLRQOMR = 0;
- ETH->DMACIER = 0;
- ETH->DMACSR = ETH->DMACSR;
-
- /* MAC clocks stopped.*/
- rccDisableETH();
-
- /* ISR vector disabled.*/
- nvicDisableVector(STM32_ETH_NUMBER);
- }
-}
-
-/**
- * @brief Returns a transmission descriptor.
- * @details One of the available transmission descriptors is locked and
- * returned.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
- * @return The operation status.
- * @retval MSG_OK the descriptor has been obtained.
- * @retval MSG_TIMEOUT descriptor not available.
- *
- * @notapi
- */
-msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
- MACTransmitDescriptor *tdp) {
- stm32_eth_tx_descriptor_t *tdes;
-
- if (!macp->link_up)
- return MSG_TIMEOUT;
-
- /* Get Current TX descriptor.*/
- tdes = (stm32_eth_tx_descriptor_t *)&__eth_td[macp->tdindex];
-
- /* Ensure that descriptor isn't owned by the Ethernet DMA or locked by
- another thread.*/
- if ((tdes->tdes3 & (STM32_TDES3_OWN)) | (tdes->tdes1 > 0)) {
- return MSG_TIMEOUT;
- }
-
- tdes->tdes0 = (uint32_t )__eth_tb[macp->tdindex];
- /* Marks the current descriptor as locked using a reserved bit.*/
- /*tdes->tdes0 |= STM32_TDES0_LOCKED; */
- tdes->tdes1++;
-
- /* Next TX descriptor to use.*/
- macp->tdindex++;
- if (macp->tdindex >= STM32_MAC_TRANSMIT_BUFFERS)
- macp->tdindex = 0;
-
- /* Set the buffer size and configuration.*/
- tdp->offset = 0;
- tdp->size = STM32_MAC_BUFFERS_SIZE;
- tdp->physdesc = tdes;
-
- return MSG_OK;
-}
-
-/**
- * @brief Releases a transmit descriptor and starts the transmission of the
- * enqueued data as a single frame.
- *
- * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
- *
- * @notapi
- */
-void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
-
- osalDbgAssert(!(tdp->physdesc->tdes3 & STM32_TDES3_OWN),
- "attempt to release descriptor already owned by DMA");
-
- osalSysLock();
-
- /* Unlocks the descriptor and returns it to the DMA engine.*/
- tdp->physdesc->tdes1 = 0;
- tdp->physdesc->tdes2 = STM32_TDES2_IOC | (tdp->offset & STM32_TDES2_B1L_MASK);
-#if STM32_MAC_IP_CHECKSUM_OFFLOAD
- tdp->physdesc->tdes3 = STM32_TDES3_CIC(STM32_MAC_IP_CHECKSUM_OFFLOAD) |
- STM32_TDES3_LD | STM32_TDES3_FD |
- STM32_TDES3_OWN;
-#else
- tdp->physdesc->tdes3 = STM32_TDES3_LD | STM32_TDES3_FD |
- STM32_TDES3_OWN;
-#endif
-
- /* Wait for the write to tdes3 to go through before resuming the DMA.*/
- __DSB();
-
- /* If the DMA engine is stalled then a restart request is issued.*/
- if ((ETH->DMADSR & ETH_DMADSR_TPS) == ETH_DMADSR_TPS_SUSPENDED) {
- ETH->DMACSR = ETH_DMACSR_TBU;
- }
- ETH->DMACTDTPR = 0;
-
- osalSysUnlock();
-}
-
-/**
- * @brief Returns a receive descriptor.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
- * @return The operation status.
- * @retval MSG_OK the descriptor has been obtained.
- * @retval MSG_TIMEOUT descriptor not available.
- *
- * @notapi
- */
-msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
- MACReceiveDescriptor *rdp) {
- stm32_eth_rx_descriptor_t *rdes;
-
- /* Get Current RX descriptor.*/
- rdes = (stm32_eth_rx_descriptor_t *)&__eth_rd[macp->rdindex];
-
- /* Iterates through received frames until a valid one is found, invalid
- frames are discarded.*/
- while (!(rdes->rdes3 & STM32_RDES3_OWN)) {
- if (!(rdes->rdes3 & STM32_RDES3_ES)
- && !(rdes->rdes2 & STM32_RDES2_DAF)
-#if STM32_MAC_IP_CHECKSUM_OFFLOAD
- && !(rdes->rdes1 & (STM32_RDES1_IPHE | STM32_RDES1_IPCE))
-#endif
- && (rdes->rdes3 & STM32_RDES3_FD) && (rdes->rdes3 & STM32_RDES3_LD)) {
- /* Found a valid one.*/
- rdp->offset = 0;
- rdp->size = (rdes->rdes3 & STM32_RDES3_PL_MASK) -2; /* Lose CRC */
- rdp->physdesc = rdes;
- /* Reposition in ring.*/
- macp->rdindex++;
- if (macp->rdindex >= STM32_MAC_RECEIVE_BUFFERS)
- macp->rdindex = 0;
-
- return MSG_OK;
- }
- /* Invalid frame found, purging.*/
- rdes->rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
- /* Reposition in ring.*/
- }
-
- return MSG_TIMEOUT;
-}
-
-/*
- * @brief Releases a receive descriptor.
- * @details The descriptor and its buffer are made available for more incoming
- * frames.
- *
- * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
- *
- * @notapi
- */
-void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
-
- osalDbgAssert(!(rdp->physdesc->rdes3 & STM32_RDES3_OWN),
- "attempt to release descriptor already owned by DMA");
-
- osalSysLock();
-
- /* Give buffer back to the Ethernet DMA.*/
- rdp->physdesc->rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
-
- /* Wait for the write to rdes3 to go through before resuming the DMA.*/
- __DSB();
-
- /* If the DMA engine is stalled then a restart request is issued.*/
- if ((ETH->DMADSR & ETH_DMADSR_RPS) == ETH_DMADSR_RPS_SUSPENDED) {
- ETH->DMACSR = ETH_DMACSR_RBU;
- }
- ETH->DMACRDTPR = 0;
-
- osalSysUnlock();
-}
-
-/**
- * @brief Updates and returns the link status.
- *
- * @param[in] macp pointer to the @p MACDriver object
- * @return The link status.
- * @retval true if the link is active.
- * @retval false if the link is down.
- *
- * @notapi
- */
-bool mac_lld_poll_link_status(MACDriver *macp) {
- uint32_t maccr, bmsr, bmcr;
-
- maccr = ETH->MACCR;
-
- /* PHY CR and SR registers read.*/
- (void)mii_read(macp, MII_BMSR);
- bmsr = mii_read(macp, MII_BMSR);
- bmcr = mii_read(macp, MII_BMCR);
-
- /* Check on auto-negotiation mode.*/
- if (bmcr & BMCR_ANENABLE) {
- uint32_t lpa;
-
- /* Auto-negotiation must be finished without faults and link established.*/
- if ((bmsr & (BMSR_LSTATUS | BMSR_RFAULT | BMSR_ANEGCOMPLETE)) !=
- (BMSR_LSTATUS | BMSR_ANEGCOMPLETE))
- return macp->link_up = false;
-
- /* Auto-negotiation enabled, checks the LPA register.*/
- lpa = mii_read(macp, MII_LPA);
-
- /* Check on link speed.*/
- if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
- maccr |= ETH_MACCR_FES;
- else
- maccr &= ~ETH_MACCR_FES;
-
- /* Check on link mode.*/
- if (lpa & (LPA_10FULL | LPA_100FULL))
- maccr |= ETH_MACCR_DM;
- else
- maccr &= ~ETH_MACCR_DM;
- }
- else {
- /* Link must be established.*/
- if (!(bmsr & BMSR_LSTATUS))
- return macp->link_up = false;
-
- /* Check on link speed.*/
- if (bmcr & BMCR_SPEED100)
- maccr |= ETH_MACCR_FES;
- else
- maccr &= ~ETH_MACCR_FES;
-
- /* Check on link mode.*/
- if (bmcr & BMCR_FULLDPLX)
- maccr |= ETH_MACCR_DM;
- else
- maccr &= ~ETH_MACCR_DM;
- }
-
- /* Changes the mode in the MAC.*/
- ETH->MACCR = maccr;
-
- /* Returns the link status.*/
- return macp->link_up = true;
-}
-
-/**
- * @brief Writes to a transmit descriptor's stream.
- *
- * @param[in] tdp pointer to a @p MACTransmitDescriptor structure
- * @param[in] buf pointer to the buffer containing the data to be
- * written
- * @param[in] size number of bytes to be written
- * @return The number of bytes written into the descriptor's
- * stream, this value can be less than the amount
- * specified in the parameter @p size if the maximum
- * frame size is reached.
- *
- * @notapi
- */
-size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
- uint8_t *buf,
- size_t size) {
-
- osalDbgAssert(!(tdp->physdesc->tdes3 & STM32_TDES3_OWN),
- "attempt to write descriptor already owned by DMA");
-
- if (size > tdp->size - tdp->offset)
- size = tdp->size - tdp->offset;
-
- if (size > 0) {
- memcpy((uint8_t *)(tdp->physdesc->tdes0) + tdp->offset, buf, size);
- tdp->offset += size;
- }
- return size;
-}
-
-/**
- * @brief Reads from a receive descriptor's stream.
- *
- * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
- * @param[in] buf pointer to the buffer that will receive the read data
- * @param[in] size number of bytes to be read
- * @return The number of bytes read from the descriptor's
- * stream, this value can be less than the amount
- * specified in the parameter @p size if there are
- * no more bytes to read.
- *
- * @notapi
- */
-size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
- uint8_t *buf,
- size_t size) {
-
- osalDbgAssert(!(rdp->physdesc->rdes3 & STM32_RDES3_OWN),
- "attempt to read descriptor already owned by DMA");
-
- if (size > rdp->size - rdp->offset)
- size = rdp->size - rdp->offset;
-
- if (size > 0) {
- cacheBufferInvalidate((uint8_t *)(rdp->physdesc->rdes0) + rdp->offset, size);
- memcpy(buf, (uint8_t *)(rdp->physdesc->rdes0) + rdp->offset, size);
- rdp->offset += size;
- }
- return size;
-}
-
-#endif /* HAL_USE_MAC */
-
-/** @} */
+/*
+ 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 MACv2/hal_mac_lld.c
+ * @brief STM32 low level MAC driver code.
+ *
+ * @addtogroup MAC
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_MAC || defined(__DOXYGEN__)
+
+#include "hal_mii.h"
+
+/* Fixes for errors in ST headers.*/
+#if ETH_DMADSR_RPS_FETCHING_Pos == 12
+#undef ETH_DMADSR_RPS_FETCHING_Pos
+#define ETH_DMADSR_RPS_FETCHING_Pos (8U)
+#endif
+
+#if ETH_DMADSR_RPS_WAITING_Pos == 12
+#undef ETH_DMADSR_RPS_WAITING_Pos
+#define ETH_DMADSR_RPS_WAITING_Pos (9U)
+#endif
+
+#if ETH_DMADSR_RPS_SUSPENDED_Pos == 14
+#undef ETH_DMADSR_RPS_SUSPENDED_Pos
+#define ETH_DMADSR_RPS_SUSPENDED_Pos (10U)
+#endif
+
+#if ETH_DMADSR_RPS_CLOSING_Pos == 12
+#undef ETH_DMADSR_RPS_CLOSING_Pos
+#define ETH_DMADSR_RPS_CLOSING_Pos (10U)
+#endif
+
+#if ETH_DMADSR_RPS_TIMESTAMP_WR_Pos == 13
+#undef ETH_DMADSR_RPS_TIMESTAMP_WR_Pos
+#undef ETH_DMADSR_RPS_TIMESTAMP_WR_Msk
+#define ETH_DMADSR_RPS_TIMESTAMP_WR_Pos (10U)
+#define ETH_DMADSR_RPS_TIMESTAMP_WR_Msk (0x6UL << ETH_DMADSR_RPS_TIMESTAMP_WR_Pos)
+#endif
+
+#if ETH_DMADSR_RPS_TRANSFERRING_Pos == 12
+#undef ETH_DMADSR_RPS_TRANSFERRING_Pos
+#define ETH_DMADSR_RPS_TRANSFERRING_Pos (10U)
+#endif
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define BUFFER_SIZE ((((STM32_MAC_BUFFERS_SIZE - 1) | 3) + 1) / 4)
+
+/* Fixing inconsistencies in ST headers.*/
+#if !defined(ETH_MACMDIOAR_CR_Div124) && defined(ETH_MACMDIOAR_CR_DIV124)
+#define ETH_MACMDIOAR_CR_Div124 ETH_MACMDIOAR_CR_DIV124
+#endif
+#if !defined(ETH_MACMDIOAR_CR_Div102) && defined(ETH_MACMDIOAR_CR_DIV102)
+#define ETH_MACMDIOAR_CR_Div102 ETH_MACMDIOAR_CR_DIV102
+#endif
+#if !defined(ETH_MACMDIOAR_CR_Div62) && defined(ETH_MACMDIOAR_CR_DIV62)
+#define ETH_MACMDIOAR_CR_Div62 ETH_MACMDIOAR_CR_DIV62
+#endif
+#if !defined(ETH_MACMDIOAR_CR_Div42) && defined(ETH_MACMDIOAR_CR_DIV42)
+#define ETH_MACMDIOAR_CR_Div42 ETH_MACMDIOAR_CR_DIV42
+#endif
+#if !defined(ETH_MACMDIOAR_CR_Div26) && defined(ETH_MACMDIOAR_CR_DIV26)
+#define ETH_MACMDIOAR_CR_Div26 ETH_MACMDIOAR_CR_DIV26
+#endif
+#if !defined(ETH_MACMDIOAR_CR_Div16) && defined(ETH_MACMDIOAR_CR_DIV16)
+#define ETH_MACMDIOAR_CR_Div16 ETH_MACMDIOAR_CR_DIV16
+#endif
+
+/* MII divider optimal value.*/
+#if (STM32_HCLK > 300000000)
+#error "STM32_HCLK above maximum frequency for ETH operations (300MHz)"
+#elif (STM32_HCLK >= 250000000)
+#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div124
+#elif (STM32_HCLK >= 150000000)
+#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div102
+#elif (STM32_HCLK >= 100000000)
+#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div62
+#elif (STM32_HCLK >= 60000000)
+#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div42
+#elif (STM32_HCLK >= 35000000)
+#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div26
+#elif (STM32_HCLK >= 20000000)
+#define MACMDIODR_CR ETH_MACMDIOAR_CR_Div16
+#else
+#error "STM32_HCLK below minimum frequency for ETH operations (20MHz)"
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Ethernet driver 1.
+ */
+MACDriver ETHD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const uint8_t default_mac_address[] = {0xAA, 0x55, 0x13,
+ 0x37, 0x01, 0x10};
+
+static stm32_eth_rx_descriptor_t __eth_rd[STM32_MAC_RECEIVE_BUFFERS]
+ __attribute__((aligned(4), __section__(".eth")));
+static stm32_eth_tx_descriptor_t __eth_td[STM32_MAC_TRANSMIT_BUFFERS]
+ __attribute__((aligned(4), __section__(".eth")));
+
+static uint32_t __eth_rb[STM32_MAC_RECEIVE_BUFFERS][BUFFER_SIZE]
+ __attribute__((aligned(4), __section__(".eth")));
+static uint32_t __eth_tb[STM32_MAC_TRANSMIT_BUFFERS][BUFFER_SIZE]
+ __attribute__((aligned(4), __section__(".eth")));
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Writes a PHY register.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[in] reg register number
+ * @param[in] value new register value
+ *
+ * @notapi
+ */
+void mii_write(MACDriver *macp, uint32_t reg, uint32_t value) {
+
+ ETH->MACMDIODR = value;
+ ETH->MACMDIOAR = macp->phyaddr | (reg << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR |
+ ETH_MACMDIOAR_MOC_WR | ETH_MACMDIOAR_MB;
+ while ((ETH->MACMDIOAR & ETH_MACMDIOAR_MB) != 0)
+ ;
+}
+
+/**
+ * @brief Reads a PHY register.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[in] reg register number
+ *
+ * @return The PHY register content.
+ *
+ * @notapi
+ */
+uint32_t mii_read(MACDriver *macp, uint32_t reg) {
+
+ ETH->MACMDIOAR = macp->phyaddr | (reg << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR |
+ ETH_MACMDIOAR_MOC_RD | ETH_MACMDIOAR_MB;
+ while ((ETH->MACMDIOAR & ETH_MACMDIOAR_MB) != 0)
+ ;
+ return ETH->MACMDIODR;
+}
+
+#if !defined(BOARD_PHY_ADDRESS)
+/**
+ * @brief PHY address detection.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ */
+static void mii_find_phy(MACDriver *macp) {
+ uint32_t i;
+
+#if STM32_MAC_PHY_TIMEOUT > 0
+ unsigned n = STM32_MAC_PHY_TIMEOUT;
+ do {
+#endif
+ for (i = 0U; i <= 31U; i++) {
+ macp->phyaddr = i << ETH_MACMDIOAR_PA_Pos;
+ ETH->MACMDIOAR = (i << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR;
+ ETH->MACMDIODR = (i << ETH_MACMDIODR_RA_Pos) | MACMDIODR_CR;
+ if ((mii_read(macp, MII_PHYSID1) == (BOARD_PHY_ID >> 16U)) &&
+ ((mii_read(macp, MII_PHYSID2) & 0xFFF0U) == (BOARD_PHY_ID & 0xFFF0U))) {
+ return;
+ }
+ }
+#if STM32_MAC_PHY_TIMEOUT > 0
+ n--;
+ } while (n > 0U);
+#endif
+ /* Wrong or defective board.*/
+ osalSysHalt("MAC failure");
+}
+#endif
+
+/**
+ * @brief MAC address setup.
+ *
+ * @param[in] p pointer to a six bytes buffer containing the MAC
+ * address
+ */
+static void mac_lld_set_address(const uint8_t *p) {
+
+ /* MAC address configuration, only a single address comparator is used,
+ hash table not used.*/
+ ETH->MACA0HR = ((uint32_t)p[5] << 8) |
+ ((uint32_t)p[4] << 0);
+ ETH->MACA0LR = ((uint32_t)p[3] << 24) |
+ ((uint32_t)p[2] << 16) |
+ ((uint32_t)p[1] << 8) |
+ ((uint32_t)p[0] << 0);
+ ETH->MACA1HR = 0;
+ ETH->MACA1LR = 0;
+ ETH->MACA2HR = 0;
+ ETH->MACA2LR = 0;
+ ETH->MACA3HR = 0;
+ ETH->MACA3LR = 0;
+ ETH->MACHT0R = 0;
+ ETH->MACHT1R = 0;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+OSAL_IRQ_HANDLER(STM32_ETH_HANDLER) {
+ uint32_t dmasr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ dmasr = ETH->DMACSR;
+
+ if (dmasr & ETH_DMACSR_RI) {
+ /* Data Received.*/
+ ETH->DMACSR = ETH_DMACSR_RI;
+ ETH->DMACIER &= ~ETH_DMACIER_RIE;
+ osalSysLockFromISR();
+ osalThreadDequeueAllI(ÐD1.rdqueue, MSG_RESET);
+#if MAC_USE_EVENTS
+ osalEventBroadcastFlagsI(ÐD1.rdevent, 0);
+#endif
+ osalSysUnlockFromISR();
+ }
+
+ if (dmasr & ETH_DMACSR_TI) {
+ /* Data Transmitted.*/
+ ETH->DMACSR = ETH_DMACSR_TI;
+ osalSysLockFromISR();
+ osalThreadDequeueAllI(ÐD1.tdqueue, MSG_RESET);
+ osalSysUnlockFromISR();
+ }
+
+ ETH->DMACSR |= ETH_DMACSR_NIS;
+ ETH->DMACIER = ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE;
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level MAC initialization.
+ *
+ * @notapi
+ */
+void mac_lld_init(void) {
+ unsigned i,j;
+
+ macObjectInit(ÐD1);
+ ETHD1.link_up = false;
+
+ /* Descriptor tables are initialized in ring mode, note that the first
+ word is not initialized here but in mac_lld_start().*/
+ for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++) {
+ __eth_rd[i].rdes0 = (uint32_t)__eth_rb[i];
+ __eth_rd[i].rdes1 = 0;
+ __eth_rd[i].rdes2 = 0;
+ __eth_rd[i].rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
+ for (j = 0; j < BUFFER_SIZE; j++) {
+ __eth_rb[i][j] = 825373492; /* telltale "1234" */
+ }
+ }
+ for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++) {
+ __eth_td[i].tdes0 = 0;
+ __eth_td[i].tdes1 = 0;
+ __eth_td[i].tdes2 = 0;
+ __eth_td[i].tdes3 = 0;
+ for (j = 0; j < BUFFER_SIZE; j++) {
+ __eth_tb[i][j] = 892745528; /* telltale "5678" */
+ }
+ }
+
+ /* Selection of the RMII or MII mode based on info exported by board.h.*/
+#if defined(STM32H7XX)
+ SYSCFG->PMCR |= SYSCFG_PMCR_PA1SO;
+#if defined(BOARD_PHY_RMII)
+ SYSCFG->PMCR |= SYSCFG_PMCR_EPIS_SEL_2;
+ SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_1;
+ SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_0;
+#else
+ SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_2;
+ SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_1;
+ SYSCFG->PMCR &= ~SYSCFG_PMCR_EPIS_SEL_0;
+#endif
+#else
+#error "unsupported STM32 platform for MACv2 driver"
+#endif
+
+ /* Reset of the MAC core.*/
+ rccResetETH();
+
+ /* MAC clocks temporary activation.*/
+ rccEnableETH(true);
+
+ /* PHY address setup.*/
+#if defined(BOARD_PHY_ADDRESS)
+ ETHD1.phyaddr = BOARD_PHY_ADDRESS << 11;
+#else
+ mii_find_phy(ÐD1);
+#endif
+
+#if defined(BOARD_PHY_RESET)
+ /* PHY board-specific reset procedure.*/
+ BOARD_PHY_RESET();
+#else
+ /* PHY soft reset procedure.*/
+ mii_write(ÐD1, MII_BMCR, BMCR_RESET);
+#if defined(BOARD_PHY_RESET_DELAY)
+ osalSysPolledDelayX(BOARD_PHY_RESET_DELAY);
+#endif
+ while (mii_read(ÐD1, MII_BMCR) & BMCR_RESET)
+ ;
+#endif
+
+#if STM32_MAC_ETH1_CHANGE_PHY_STATE
+ /* PHY in power down mode until the driver will be started.*/
+ mii_write(ÐD1, MII_BMCR, mii_read(ÐD1, MII_BMCR) | BMCR_PDOWN);
+#endif
+
+ /* MAC clocks stopped again.*/
+ rccDisableETH();
+}
+
+/**
+ * @brief Configures and activates the MAC peripheral.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ *
+ * @notapi
+ */
+void mac_lld_start(MACDriver *macp) {
+ unsigned i;
+
+ /* Resets the state of all descriptors.*/
+ for (i = 0; i < STM32_MAC_RECEIVE_BUFFERS; i++)
+ __eth_rd[i].rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
+ macp->rdindex = 0;
+ for (i = 0; i < STM32_MAC_TRANSMIT_BUFFERS; i++)
+ __eth_td[i].tdes3 = 0;
+ macp->tdindex = 0;
+
+ /* MAC clocks activation and commanded reset procedure.*/
+ rccEnableETH(true);
+
+ /* ISR vector enabled.*/
+ nvicEnableVector(STM32_ETH_NUMBER, STM32_MAC_ETH1_IRQ_PRIORITY);
+
+#if STM32_MAC_ETH1_CHANGE_PHY_STATE
+ /* PHY in power up mode.*/
+ mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) & ~BMCR_PDOWN);
+#endif
+
+ ETH->DMAMR |= ETH_DMAMR_SWR;
+ while (ETH->DMAMR & ETH_DMAMR_SWR)
+ ;
+
+ /* MAC configuration.*/
+ ETH->MACCR = ETH_MACCR_DO;
+ ETH->MACPFR = 0;
+ ETH->MACTFCR = 0;
+ ETH->MACRFCR = 0;
+ ETH->MACVTR = 0;
+
+ /* MAC address setup.*/
+ if (macp->config->mac_address == NULL)
+ mac_lld_set_address(default_mac_address);
+ else
+ mac_lld_set_address(macp->config->mac_address);
+
+ /* Transmitter and receiver enabled.
+ Note that the complete setup of the MAC is performed when the link
+ status is detected.*/
+#if STM32_MAC_IP_CHECKSUM_OFFLOAD
+ ETH->MACCR |= ETH_MACCR_IPC | ETH_MACCR_RE | ETH_MACCR_TE;
+#else
+ ETH->MACCR |= ETH_MACCR_RE | ETH_MACCR_TE;
+#endif
+
+ /* DMA general settings.*/
+ ETH->DMASBMR = ETH_DMASBMR_AAL;
+ ETH->DMACCR = ETH_DMACCR_DSL_0BIT;
+ ETH->DMAMR = ETH_DMAMR_INTM_0 | ETH_DMAMR_PR_8_1 | ETH_DMAMR_TXPR; /* TX:RX 8:1 */
+ /* DMA configuration:
+ Descriptor rings pointers.*/
+ ETH->DMACTDLAR = (uint32_t)&__eth_td[0];
+ ETH->DMACTDRLR = STM32_MAC_TRANSMIT_BUFFERS-1;
+ ETH->DMACRDLAR = (uint32_t)&__eth_rd[0];
+ ETH->DMACRDRLR = STM32_MAC_RECEIVE_BUFFERS-1;
+
+ /* Enabling required interrupt sources.*/
+ ETH->DMACSR = ETH_DMACSR_NIS;
+ ETH->DMACIER = ETH_DMACIER_NIE | ETH_DMACIER_RIE | ETH_DMACIER_TIE;
+
+
+ /* Check because errata on some devices. There should be no need to
+ disable flushing because the TXFIFO should be empty on macStart().*/
+#if !defined(STM32_MAC_DISABLE_TX_FLUSH)
+ /* Transmit FIFO flush.*/
+ ETH->MTLTQOMR = ETH_MTLTQOMR_FTQ;
+ while (ETH->MTLTQOMR & ETH_MTLTQOMR_FTQ)
+ ;
+#endif
+
+ /* DMA final configuration and start.*/
+ ETH->MTLRQOMR = ETH_MTLRQOMR_DISTCPEF | ETH_MTLRQOMR_RSF;
+ ETH->MTLTQOMR = ETH_MTLTQOMR_TSF;
+ ETH->DMACTCR = ETH_DMACTCR_ST | ETH_DMACTCR_TPBL_1PBL;
+ ETH->DMACRCR = ETH_DMACRCR_SR | ETH_DMACRCR_RPBL_1PBL
+ | (STM32_MAC_BUFFERS_SIZE << ETH_DMACRCR_RBSZ_Pos
+ & ETH_DMACRCR_RBSZ);
+}
+
+/**
+ * @brief Deactivates the MAC peripheral.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ *
+ * @notapi
+ */
+void mac_lld_stop(MACDriver *macp) {
+
+ if (macp->state != MAC_STOP) {
+#if STM32_MAC_ETH1_CHANGE_PHY_STATE
+ /* PHY in power down mode until the driver will be restarted.*/
+ mii_write(macp, MII_BMCR, mii_read(macp, MII_BMCR) | BMCR_PDOWN);
+#endif
+
+ /* MAC and DMA stopped.*/
+ ETH->MACCR = 0;
+ ETH->MTLRQOMR = 0;
+ ETH->DMACIER = 0;
+ ETH->DMACSR = ETH->DMACSR;
+
+ /* MAC clocks stopped.*/
+ rccDisableETH();
+
+ /* ISR vector disabled.*/
+ nvicDisableVector(STM32_ETH_NUMBER);
+ }
+}
+
+/**
+ * @brief Returns a transmission descriptor.
+ * @details One of the available transmission descriptors is locked and
+ * returned.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[out] tdp pointer to a @p MACTransmitDescriptor structure
+ * @return The operation status.
+ * @retval MSG_OK the descriptor has been obtained.
+ * @retval MSG_TIMEOUT descriptor not available.
+ *
+ * @notapi
+ */
+msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
+ MACTransmitDescriptor *tdp) {
+ stm32_eth_tx_descriptor_t *tdes;
+
+ if (!macp->link_up)
+ return MSG_TIMEOUT;
+
+ /* Get Current TX descriptor.*/
+ tdes = (stm32_eth_tx_descriptor_t *)&__eth_td[macp->tdindex];
+
+ /* Ensure that descriptor isn't owned by the Ethernet DMA or locked by
+ another thread.*/
+ if ((tdes->tdes3 & (STM32_TDES3_OWN)) | (tdes->tdes1 > 0)) {
+ return MSG_TIMEOUT;
+ }
+
+ tdes->tdes0 = (uint32_t )__eth_tb[macp->tdindex];
+ /* Marks the current descriptor as locked using a reserved bit.*/
+ /*tdes->tdes0 |= STM32_TDES0_LOCKED; */
+ tdes->tdes1++;
+
+ /* Next TX descriptor to use.*/
+ macp->tdindex++;
+ if (macp->tdindex >= STM32_MAC_TRANSMIT_BUFFERS)
+ macp->tdindex = 0;
+
+ /* Set the buffer size and configuration.*/
+ tdp->offset = 0;
+ tdp->size = STM32_MAC_BUFFERS_SIZE;
+ tdp->physdesc = tdes;
+
+ return MSG_OK;
+}
+
+/**
+ * @brief Releases a transmit descriptor and starts the transmission of the
+ * enqueued data as a single frame.
+ *
+ * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
+ *
+ * @notapi
+ */
+void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
+
+ osalDbgAssert(!(tdp->physdesc->tdes3 & STM32_TDES3_OWN),
+ "attempt to release descriptor already owned by DMA");
+
+ osalSysLock();
+
+ /* Unlocks the descriptor and returns it to the DMA engine.*/
+ tdp->physdesc->tdes1 = 0;
+ tdp->physdesc->tdes2 = STM32_TDES2_IOC | (tdp->offset & STM32_TDES2_B1L_MASK);
+#if STM32_MAC_IP_CHECKSUM_OFFLOAD
+ tdp->physdesc->tdes3 = STM32_TDES3_CIC(STM32_MAC_IP_CHECKSUM_OFFLOAD) |
+ STM32_TDES3_LD | STM32_TDES3_FD |
+ STM32_TDES3_OWN;
+#else
+ tdp->physdesc->tdes3 = STM32_TDES3_LD | STM32_TDES3_FD |
+ STM32_TDES3_OWN;
+#endif
+
+ /* Wait for the write to tdes3 to go through before resuming the DMA.*/
+ __DSB();
+
+ /* If the DMA engine is stalled then a restart request is issued.*/
+ if ((ETH->DMADSR & ETH_DMADSR_TPS) == ETH_DMADSR_TPS_SUSPENDED) {
+ ETH->DMACSR = ETH_DMACSR_TBU;
+ }
+ ETH->DMACTDTPR = 0;
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Returns a receive descriptor.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @param[out] rdp pointer to a @p MACReceiveDescriptor structure
+ * @return The operation status.
+ * @retval MSG_OK the descriptor has been obtained.
+ * @retval MSG_TIMEOUT descriptor not available.
+ *
+ * @notapi
+ */
+msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
+ MACReceiveDescriptor *rdp) {
+ stm32_eth_rx_descriptor_t *rdes;
+
+ /* Get Current RX descriptor.*/
+ rdes = (stm32_eth_rx_descriptor_t *)&__eth_rd[macp->rdindex];
+
+ /* Iterates through received frames until a valid one is found, invalid
+ frames are discarded.*/
+ while (!(rdes->rdes3 & STM32_RDES3_OWN)) {
+ if (!(rdes->rdes3 & STM32_RDES3_ES)
+ && !(rdes->rdes2 & STM32_RDES2_DAF)
+#if STM32_MAC_IP_CHECKSUM_OFFLOAD
+ && !(rdes->rdes1 & (STM32_RDES1_IPHE | STM32_RDES1_IPCE))
+#endif
+ && (rdes->rdes3 & STM32_RDES3_FD) && (rdes->rdes3 & STM32_RDES3_LD)) {
+ /* Found a valid one.*/
+ rdp->offset = 0;
+ rdp->size = (rdes->rdes3 & STM32_RDES3_PL_MASK) -2; /* Lose CRC */
+ rdp->physdesc = rdes;
+ /* Reposition in ring.*/
+ macp->rdindex++;
+ if (macp->rdindex >= STM32_MAC_RECEIVE_BUFFERS)
+ macp->rdindex = 0;
+
+ return MSG_OK;
+ }
+ /* Invalid frame found, purging.*/
+ rdes->rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
+ /* Reposition in ring.*/
+ }
+
+ return MSG_TIMEOUT;
+}
+
+/*
+ * @brief Releases a receive descriptor.
+ * @details The descriptor and its buffer are made available for more incoming
+ * frames.
+ *
+ * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
+ *
+ * @notapi
+ */
+void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
+
+ osalDbgAssert(!(rdp->physdesc->rdes3 & STM32_RDES3_OWN),
+ "attempt to release descriptor already owned by DMA");
+
+ osalSysLock();
+
+ /* Give buffer back to the Ethernet DMA.*/
+ rdp->physdesc->rdes3 = STM32_RDES3_OWN | STM32_RDES3_IOC | STM32_RDES3_BUF1V;
+
+ /* Wait for the write to rdes3 to go through before resuming the DMA.*/
+ __DSB();
+
+ /* If the DMA engine is stalled then a restart request is issued.*/
+ if ((ETH->DMADSR & ETH_DMADSR_RPS) == ETH_DMADSR_RPS_SUSPENDED) {
+ ETH->DMACSR = ETH_DMACSR_RBU;
+ }
+ ETH->DMACRDTPR = 0;
+
+ osalSysUnlock();
+}
+
+/**
+ * @brief Updates and returns the link status.
+ *
+ * @param[in] macp pointer to the @p MACDriver object
+ * @return The link status.
+ * @retval true if the link is active.
+ * @retval false if the link is down.
+ *
+ * @notapi
+ */
+bool mac_lld_poll_link_status(MACDriver *macp) {
+ uint32_t maccr, bmsr, bmcr;
+
+ maccr = ETH->MACCR;
+
+ /* PHY CR and SR registers read.*/
+ (void)mii_read(macp, MII_BMSR);
+ bmsr = mii_read(macp, MII_BMSR);
+ bmcr = mii_read(macp, MII_BMCR);
+
+ /* Check on auto-negotiation mode.*/
+ if (bmcr & BMCR_ANENABLE) {
+ uint32_t lpa;
+
+ /* Auto-negotiation must be finished without faults and link established.*/
+ if ((bmsr & (BMSR_LSTATUS | BMSR_RFAULT | BMSR_ANEGCOMPLETE)) !=
+ (BMSR_LSTATUS | BMSR_ANEGCOMPLETE))
+ return macp->link_up = false;
+
+ /* Auto-negotiation enabled, checks the LPA register.*/
+ lpa = mii_read(macp, MII_LPA);
+
+ /* Check on link speed.*/
+ if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
+ maccr |= ETH_MACCR_FES;
+ else
+ maccr &= ~ETH_MACCR_FES;
+
+ /* Check on link mode.*/
+ if (lpa & (LPA_10FULL | LPA_100FULL))
+ maccr |= ETH_MACCR_DM;
+ else
+ maccr &= ~ETH_MACCR_DM;
+ }
+ else {
+ /* Link must be established.*/
+ if (!(bmsr & BMSR_LSTATUS))
+ return macp->link_up = false;
+
+ /* Check on link speed.*/
+ if (bmcr & BMCR_SPEED100)
+ maccr |= ETH_MACCR_FES;
+ else
+ maccr &= ~ETH_MACCR_FES;
+
+ /* Check on link mode.*/
+ if (bmcr & BMCR_FULLDPLX)
+ maccr |= ETH_MACCR_DM;
+ else
+ maccr &= ~ETH_MACCR_DM;
+ }
+
+ /* Changes the mode in the MAC.*/
+ ETH->MACCR = maccr;
+
+ /* Returns the link status.*/
+ return macp->link_up = true;
+}
+
+/**
+ * @brief Writes to a transmit descriptor's stream.
+ *
+ * @param[in] tdp pointer to a @p MACTransmitDescriptor structure
+ * @param[in] buf pointer to the buffer containing the data to be
+ * written
+ * @param[in] size number of bytes to be written
+ * @return The number of bytes written into the descriptor's
+ * stream, this value can be less than the amount
+ * specified in the parameter @p size if the maximum
+ * frame size is reached.
+ *
+ * @notapi
+ */
+size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
+ uint8_t *buf,
+ size_t size) {
+
+ osalDbgAssert(!(tdp->physdesc->tdes3 & STM32_TDES3_OWN),
+ "attempt to write descriptor already owned by DMA");
+
+ if (size > tdp->size - tdp->offset)
+ size = tdp->size - tdp->offset;
+
+ if (size > 0) {
+ memcpy((uint8_t *)(tdp->physdesc->tdes0) + tdp->offset, buf, size);
+ tdp->offset += size;
+ }
+ return size;
+}
+
+/**
+ * @brief Reads from a receive descriptor's stream.
+ *
+ * @param[in] rdp pointer to a @p MACReceiveDescriptor structure
+ * @param[in] buf pointer to the buffer that will receive the read data
+ * @param[in] size number of bytes to be read
+ * @return The number of bytes read from the descriptor's
+ * stream, this value can be less than the amount
+ * specified in the parameter @p size if there are
+ * no more bytes to read.
+ *
+ * @notapi
+ */
+size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
+ uint8_t *buf,
+ size_t size) {
+
+ osalDbgAssert(!(rdp->physdesc->rdes3 & STM32_RDES3_OWN),
+ "attempt to read descriptor already owned by DMA");
+
+ if (size > rdp->size - rdp->offset)
+ size = rdp->size - rdp->offset;
+
+ if (size > 0) {
+ cacheBufferInvalidate((uint8_t *)(rdp->physdesc->rdes0) + rdp->offset, size);
+ memcpy(buf, (uint8_t *)(rdp->physdesc->rdes0) + rdp->offset, size);
+ rdp->offset += size;
+ }
+ return size;
+}
+
+#endif /* HAL_USE_MAC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.h b/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.h
index d756205d24..37c3340c93 100644
--- a/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.h
+++ b/os/hal/ports/STM32/LLD/MACv2/hal_mac_lld.h
@@ -1,368 +1,368 @@
-/*
- 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 MACv2/hal_mac_lld.h
- * @brief STM32 low level MAC driver header.
- *
- * @addtogroup MAC
- * @{
- */
-
-#ifndef HAL_MAC_LLD_H
-#define HAL_MAC_LLD_H
-
-#if HAL_USE_MAC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief This implementation does not support the zero-copy mode API.
- */
-#define MAC_SUPPORTS_ZERO_COPY FALSE
-
-/**
- * @name RDES1 constants
- * @{
- */
-#define STM32_RDES1_OPC_MASK 0xFFFF0000
-#define STM32_RDES1_TD 0x00008000
-#define STM32_RDES1_TSA 0x00004000
-#define STM32_RDES1_PV 0x00002000
-#define STM32_RDES1_PFT 0x00001000
-#define STM32_RDES1_PMT_MASK 0x00000F00
-#define STM32_RDES1_IPCE 0x00000080
-#define STM32_RDES1_IPCB 0x00000040
-#define STM32_RDES1_IPV6 0x00000020
-#define STM32_RDES1_IPV4 0x00000010
-#define STM32_RDES1_IPHE 0x00000008
-#define STM32_RDES1_PT_MASK 0x00000007
-/** @} */
-
-/**
- * @name RDES2 constants
- * @{
- */
-#define STM32_RDES2_L3L4FM_MASK 0xE0000000
-#define STM32_RDES2_L4FM 0x01000000
-#define STM32_RDES2_L3FM 0x00800000
-#define STM32_RDES2_MADRM_MASK 0x007F8000
-#define STM32_RDES2_HF 0x00004000
-#define STM32_RDES2_DAF 0x00002000
-#define STM32_RDES2_SAF 0x00001000
-#define STM32_RDES2_VF 0x00000800
-#define STM32_RDES2_RES1 0x00000780
-#define STM32_RDES2_ARPNR 0x00000040
-#define STM32_RDES2_RES2 0x0000003F
-/** @} */
-
-/**
- * @name RDES3 constants
- * @{
- */
-#define STM32_RDES3_OWN 0x80000000
-#define STM32_RDES3_IOC 0x40000000 /* Read */
-#define STM32_RDES3_CTXT 0x40000000 /* Write */
-#define STM32_RDES3_FD 0x20000000
-#define STM32_RDES3_LD 0x10000000
-#define STM32_RDES3_RS2V 0x08000000
-#define STM32_RDES3_RS1V 0x04000000
-#define STM32_RDES3_BUF2V 0x02000000 /* Read */
-#define STM32_RDES3_RS0V 0x02000000 /* Write */
-#define STM32_RDES3_BUF1V 0x01000000 /* Read */
-#define STM32_RDES3_CE 0x01000000 /* Write */
-#define STM32_RDES3_GP 0x00800000
-#define STM32_RDES3_RWT 0x00400000
-#define STM32_RDES3_OE 0x00200000
-#define STM32_RDES3_RE 0x00100000
-#define STM32_RDES3_DE 0x00080000
-#define STM32_RDES3_LT_MASK 0x00070000
-#define STM32_RDES3_ES 0x00008000
-#define STM32_RDES3_PL_MASK 0x00007FFF
-/** @} */
-
-/**
- * @name TDES2 constants
- * @{
- */
-#define STM32_TDES2_IOC 0x80000000
-#define STM32_TDES2_TTSE 0x40000000
-#define STM32_TDES2_B2L_MASK 0x3FFF0000
-#define STM32_TDES2_VTIR_MASK 0x0000C000
-#define STM32_TDES2_VTIR(n) ((n) << 14)
-#define STM32_TDES2_B1L_MASK 0x00003FFF
-/** @} */
-
-/**
- * @name TDES3 constants
- * @{
- */
-#define STM32_TDES3_OWN 0x80000000
-#define STM32_TDES3_CTXT 0x40000000
-#define STM32_TDES3_FD 0x20000000
-#define STM32_TDES3_LD 0x10000000
-#define STM32_TDES3_CPC_MASK 0x0C000000
-#define STM32_TDES3_CPC(n) ((n) << 26)
-#define STM32_TDES3_SAIC_MASK 0x03800000
-#define STM32_TDES3_SAIC(n) ((n) << 23)
-#define STM32_TDES3_THL_MASK 0x00780000
-#define STM32_TDES3_THL(n) ((n) << 19)
-#define STM32_TDES3_TSE 0x00040000
-#define STM32_TDES3_CIC_MASK 0x00030000
-#define STM32_TDES3_CIC(n) ((n) << 16)
-#define STM32_TDES3_TPL 0x00008000
-#define STM32_TDES3_FL 0x00007FFF
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief Number of available transmit buffers.
- */
-#if !defined(STM32_MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
-#define STM32_MAC_TRANSMIT_BUFFERS 4
-#endif
-
-/**
- * @brief Number of available receive buffers.
- */
-#if !defined(STM32_MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
-#define STM32_MAC_RECEIVE_BUFFERS 4
-#endif
-
-/**
- * @brief Maximum supported frame size.
- */
-#if !defined(STM32_MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
-#define STM32_MAC_BUFFERS_SIZE 1524
-#endif
-
-/**
- * @brief PHY detection timeout.
- * @details Timeout for PHY address detection, the scan for a PHY is performed
- * the specified number of times before invoking the failure handler.
- * This setting applies only if the PHY address is not explicitly
- * set in the board header file using @p BOARD_PHY_ADDRESS. A zero
- * value disables the timeout and a single search is performed.
- */
-#if !defined(STM32_MAC_PHY_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_MAC_PHY_TIMEOUT 100
-#endif
-
-/**
- * @brief Change the PHY power state inside the driver.
- */
-#if !defined(STM32_MAC_ETH1_CHANGE_PHY_STATE) || defined(__DOXYGEN__)
-#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
-#endif
-
-/**
- * @brief ETHD1 interrupt priority level setting.
- */
-#if !defined(STM32_MAC_ETH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_MAC_ETH1_IRQ_PRIORITY 13
-#endif
-
-/**
- * @brief IP checksum offload.
- * @details The following modes are available:
- * - 0 Function disabled.
- * - 1 Only IP header checksum calculation and insertion are enabled.
- * - 2 IP header checksum and payload checksum calculation and
- * insertion are enabled, but pseudo-header checksum is not
- * calculated in hardware.
- * - 3 IP Header checksum and payload checksum calculation and
- * insertion are enabled, and pseudo-header checksum is
- * calculated in hardware.
- * .
- */
-#if !defined(STM32_MAC_IP_CHECKSUM_OFFLOAD) || defined(__DOXYGEN__)
-#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of an STM32 Ethernet receive descriptor.
- */
-typedef struct {
- volatile uint32_t rdes0;
- volatile uint32_t rdes1;
- volatile uint32_t rdes2;
- volatile uint32_t rdes3;
-} stm32_eth_rx_descriptor_t;
-
-/**
- * @brief Type of an STM32 Ethernet transmit descriptor.
- */
-typedef struct {
- volatile uint32_t tdes0;
- volatile uint32_t tdes1;
- volatile uint32_t tdes2;
- volatile uint32_t tdes3;
-} stm32_eth_tx_descriptor_t;
-
-/**
- * @brief Driver configuration structure.
- */
-typedef struct {
- /**
- * @brief MAC address.
- */
- uint8_t *mac_address;
- /* End of the mandatory fields.*/
-} MACConfig;
-
-/**
- * @brief Structure representing a MAC driver.
- */
-struct MACDriver {
- /**
- * @brief Driver state.
- */
- macstate_t state;
- /**
- * @brief Current configuration data.
- */
- const MACConfig *config;
- /**
- * @brief Transmit semaphore.
- */
- threads_queue_t tdqueue;
- /**
- * @brief Receive semaphore.
- */
- threads_queue_t rdqueue;
-#if MAC_USE_EVENTS || defined(__DOXYGEN__)
- /**
- * @brief Receive event.
- */
- event_source_t rdevent;
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Link status flag.
- */
- bool link_up;
- /**
- * @brief PHY address (pre shifted).
- */
- uint32_t phyaddr;
- /**
- * @brief Receive next frame index.
- */
- uint16_t rdindex;
- /**
- * @brief Transmit next frame index.
- */
- uint16_t tdindex;
-};
-
-/**
- * @brief Structure representing a transmit descriptor.
- */
-typedef struct {
- /**
- * @brief Current write offset.
- */
- size_t offset;
- /**
- * @brief Available space size.
- */
- size_t size;
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the physical descriptor.
- */
- stm32_eth_tx_descriptor_t *physdesc;
-} MACTransmitDescriptor;
-
-/**
- * @brief Structure representing a receive descriptor.
- */
-typedef struct {
- /**
- * @brief Current read offset.
- */
- size_t offset;
- /**
- * @brief Available data size.
- */
- size_t size;
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the physical descriptor.
- */
- stm32_eth_rx_descriptor_t *physdesc;
-} MACReceiveDescriptor;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern MACDriver ETHD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void mii_write(MACDriver *macp, uint32_t reg, uint32_t value);
- uint32_t mii_read(MACDriver *macp, uint32_t reg);
- void mac_lld_init(void);
- void mac_lld_start(MACDriver *macp);
- void mac_lld_stop(MACDriver *macp);
- msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
- MACTransmitDescriptor *tdp);
- void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
- msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
- MACReceiveDescriptor *rdp);
- void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
- bool mac_lld_poll_link_status(MACDriver *macp);
- size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
- uint8_t *buf,
- size_t size);
- size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
- uint8_t *buf,
- size_t size);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_MAC */
-
-#endif /* HAL_MAC_LLD_H */
-
-/** @} */
+/*
+ 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 MACv2/hal_mac_lld.h
+ * @brief STM32 low level MAC driver header.
+ *
+ * @addtogroup MAC
+ * @{
+ */
+
+#ifndef HAL_MAC_LLD_H
+#define HAL_MAC_LLD_H
+
+#if HAL_USE_MAC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief This implementation does not support the zero-copy mode API.
+ */
+#define MAC_SUPPORTS_ZERO_COPY FALSE
+
+/**
+ * @name RDES1 constants
+ * @{
+ */
+#define STM32_RDES1_OPC_MASK 0xFFFF0000
+#define STM32_RDES1_TD 0x00008000
+#define STM32_RDES1_TSA 0x00004000
+#define STM32_RDES1_PV 0x00002000
+#define STM32_RDES1_PFT 0x00001000
+#define STM32_RDES1_PMT_MASK 0x00000F00
+#define STM32_RDES1_IPCE 0x00000080
+#define STM32_RDES1_IPCB 0x00000040
+#define STM32_RDES1_IPV6 0x00000020
+#define STM32_RDES1_IPV4 0x00000010
+#define STM32_RDES1_IPHE 0x00000008
+#define STM32_RDES1_PT_MASK 0x00000007
+/** @} */
+
+/**
+ * @name RDES2 constants
+ * @{
+ */
+#define STM32_RDES2_L3L4FM_MASK 0xE0000000
+#define STM32_RDES2_L4FM 0x01000000
+#define STM32_RDES2_L3FM 0x00800000
+#define STM32_RDES2_MADRM_MASK 0x007F8000
+#define STM32_RDES2_HF 0x00004000
+#define STM32_RDES2_DAF 0x00002000
+#define STM32_RDES2_SAF 0x00001000
+#define STM32_RDES2_VF 0x00000800
+#define STM32_RDES2_RES1 0x00000780
+#define STM32_RDES2_ARPNR 0x00000040
+#define STM32_RDES2_RES2 0x0000003F
+/** @} */
+
+/**
+ * @name RDES3 constants
+ * @{
+ */
+#define STM32_RDES3_OWN 0x80000000
+#define STM32_RDES3_IOC 0x40000000 /* Read */
+#define STM32_RDES3_CTXT 0x40000000 /* Write */
+#define STM32_RDES3_FD 0x20000000
+#define STM32_RDES3_LD 0x10000000
+#define STM32_RDES3_RS2V 0x08000000
+#define STM32_RDES3_RS1V 0x04000000
+#define STM32_RDES3_BUF2V 0x02000000 /* Read */
+#define STM32_RDES3_RS0V 0x02000000 /* Write */
+#define STM32_RDES3_BUF1V 0x01000000 /* Read */
+#define STM32_RDES3_CE 0x01000000 /* Write */
+#define STM32_RDES3_GP 0x00800000
+#define STM32_RDES3_RWT 0x00400000
+#define STM32_RDES3_OE 0x00200000
+#define STM32_RDES3_RE 0x00100000
+#define STM32_RDES3_DE 0x00080000
+#define STM32_RDES3_LT_MASK 0x00070000
+#define STM32_RDES3_ES 0x00008000
+#define STM32_RDES3_PL_MASK 0x00007FFF
+/** @} */
+
+/**
+ * @name TDES2 constants
+ * @{
+ */
+#define STM32_TDES2_IOC 0x80000000
+#define STM32_TDES2_TTSE 0x40000000
+#define STM32_TDES2_B2L_MASK 0x3FFF0000
+#define STM32_TDES2_VTIR_MASK 0x0000C000
+#define STM32_TDES2_VTIR(n) ((n) << 14)
+#define STM32_TDES2_B1L_MASK 0x00003FFF
+/** @} */
+
+/**
+ * @name TDES3 constants
+ * @{
+ */
+#define STM32_TDES3_OWN 0x80000000
+#define STM32_TDES3_CTXT 0x40000000
+#define STM32_TDES3_FD 0x20000000
+#define STM32_TDES3_LD 0x10000000
+#define STM32_TDES3_CPC_MASK 0x0C000000
+#define STM32_TDES3_CPC(n) ((n) << 26)
+#define STM32_TDES3_SAIC_MASK 0x03800000
+#define STM32_TDES3_SAIC(n) ((n) << 23)
+#define STM32_TDES3_THL_MASK 0x00780000
+#define STM32_TDES3_THL(n) ((n) << 19)
+#define STM32_TDES3_TSE 0x00040000
+#define STM32_TDES3_CIC_MASK 0x00030000
+#define STM32_TDES3_CIC(n) ((n) << 16)
+#define STM32_TDES3_TPL 0x00008000
+#define STM32_TDES3_FL 0x00007FFF
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief Number of available transmit buffers.
+ */
+#if !defined(STM32_MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
+#define STM32_MAC_TRANSMIT_BUFFERS 4
+#endif
+
+/**
+ * @brief Number of available receive buffers.
+ */
+#if !defined(STM32_MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
+#define STM32_MAC_RECEIVE_BUFFERS 4
+#endif
+
+/**
+ * @brief Maximum supported frame size.
+ */
+#if !defined(STM32_MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define STM32_MAC_BUFFERS_SIZE 1524
+#endif
+
+/**
+ * @brief PHY detection timeout.
+ * @details Timeout for PHY address detection, the scan for a PHY is performed
+ * the specified number of times before invoking the failure handler.
+ * This setting applies only if the PHY address is not explicitly
+ * set in the board header file using @p BOARD_PHY_ADDRESS. A zero
+ * value disables the timeout and a single search is performed.
+ */
+#if !defined(STM32_MAC_PHY_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_MAC_PHY_TIMEOUT 100
+#endif
+
+/**
+ * @brief Change the PHY power state inside the driver.
+ */
+#if !defined(STM32_MAC_ETH1_CHANGE_PHY_STATE) || defined(__DOXYGEN__)
+#define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE
+#endif
+
+/**
+ * @brief ETHD1 interrupt priority level setting.
+ */
+#if !defined(STM32_MAC_ETH1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_MAC_ETH1_IRQ_PRIORITY 13
+#endif
+
+/**
+ * @brief IP checksum offload.
+ * @details The following modes are available:
+ * - 0 Function disabled.
+ * - 1 Only IP header checksum calculation and insertion are enabled.
+ * - 2 IP header checksum and payload checksum calculation and
+ * insertion are enabled, but pseudo-header checksum is not
+ * calculated in hardware.
+ * - 3 IP Header checksum and payload checksum calculation and
+ * insertion are enabled, and pseudo-header checksum is
+ * calculated in hardware.
+ * .
+ */
+#if !defined(STM32_MAC_IP_CHECKSUM_OFFLOAD) || defined(__DOXYGEN__)
+#define STM32_MAC_IP_CHECKSUM_OFFLOAD 0
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an STM32 Ethernet receive descriptor.
+ */
+typedef struct {
+ volatile uint32_t rdes0;
+ volatile uint32_t rdes1;
+ volatile uint32_t rdes2;
+ volatile uint32_t rdes3;
+} stm32_eth_rx_descriptor_t;
+
+/**
+ * @brief Type of an STM32 Ethernet transmit descriptor.
+ */
+typedef struct {
+ volatile uint32_t tdes0;
+ volatile uint32_t tdes1;
+ volatile uint32_t tdes2;
+ volatile uint32_t tdes3;
+} stm32_eth_tx_descriptor_t;
+
+/**
+ * @brief Driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief MAC address.
+ */
+ uint8_t *mac_address;
+ /* End of the mandatory fields.*/
+} MACConfig;
+
+/**
+ * @brief Structure representing a MAC driver.
+ */
+struct MACDriver {
+ /**
+ * @brief Driver state.
+ */
+ macstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const MACConfig *config;
+ /**
+ * @brief Transmit semaphore.
+ */
+ threads_queue_t tdqueue;
+ /**
+ * @brief Receive semaphore.
+ */
+ threads_queue_t rdqueue;
+#if MAC_USE_EVENTS || defined(__DOXYGEN__)
+ /**
+ * @brief Receive event.
+ */
+ event_source_t rdevent;
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Link status flag.
+ */
+ bool link_up;
+ /**
+ * @brief PHY address (pre shifted).
+ */
+ uint32_t phyaddr;
+ /**
+ * @brief Receive next frame index.
+ */
+ uint16_t rdindex;
+ /**
+ * @brief Transmit next frame index.
+ */
+ uint16_t tdindex;
+};
+
+/**
+ * @brief Structure representing a transmit descriptor.
+ */
+typedef struct {
+ /**
+ * @brief Current write offset.
+ */
+ size_t offset;
+ /**
+ * @brief Available space size.
+ */
+ size_t size;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the physical descriptor.
+ */
+ stm32_eth_tx_descriptor_t *physdesc;
+} MACTransmitDescriptor;
+
+/**
+ * @brief Structure representing a receive descriptor.
+ */
+typedef struct {
+ /**
+ * @brief Current read offset.
+ */
+ size_t offset;
+ /**
+ * @brief Available data size.
+ */
+ size_t size;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the physical descriptor.
+ */
+ stm32_eth_rx_descriptor_t *physdesc;
+} MACReceiveDescriptor;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern MACDriver ETHD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void mii_write(MACDriver *macp, uint32_t reg, uint32_t value);
+ uint32_t mii_read(MACDriver *macp, uint32_t reg);
+ void mac_lld_init(void);
+ void mac_lld_start(MACDriver *macp);
+ void mac_lld_stop(MACDriver *macp);
+ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
+ MACTransmitDescriptor *tdp);
+ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
+ msg_t mac_lld_get_receive_descriptor(MACDriver *macp,
+ MACReceiveDescriptor *rdp);
+ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
+ bool mac_lld_poll_link_status(MACDriver *macp);
+ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
+ uint8_t *buf,
+ size_t size);
+ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
+ uint8_t *buf,
+ size_t size);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_MAC */
+
+#endif /* HAL_MAC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/MDMAv1/driver.mk b/os/hal/ports/STM32/LLD/MDMAv1/driver.mk
index d10e2add0a..710647fe72 100644
--- a/os/hal/ports/STM32/LLD/MDMAv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/MDMAv1/driver.mk
@@ -1,2 +1,2 @@
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.c
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MDMAv1
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.c
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/MDMAv1
diff --git a/os/hal/ports/STM32/LLD/MDMAv1/notes.txt b/os/hal/ports/STM32/LLD/MDMAv1/notes.txt
index a092556a64..5d16ff1961 100644
--- a/os/hal/ports/STM32/LLD/MDMAv1/notes.txt
+++ b/os/hal/ports/STM32/LLD/MDMAv1/notes.txt
@@ -1,11 +1,11 @@
-STM32 MDMAv1 driver.
-
-Driver capability:
-
-- The driver supports the STM32 complex MDMA controller found on H7
- sub-family.
-
-The file registry must export:
-
-STM32_MDMA_CHn_HANDLER - Vector name for channel "n" (0..15).
-STM32_MDMA_CHn_NUMBER - Vector number for channel "n" (0..15).
+STM32 MDMAv1 driver.
+
+Driver capability:
+
+- The driver supports the STM32 complex MDMA controller found on H7
+ sub-family.
+
+The file registry must export:
+
+STM32_MDMA_CHn_HANDLER - Vector name for channel "n" (0..15).
+STM32_MDMA_CHn_NUMBER - Vector number for channel "n" (0..15).
diff --git a/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.c b/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.c
index 2a41ec3b75..fe870fcdad 100644
--- a/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.c
+++ b/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.c
@@ -1,355 +1,355 @@
-/*
- 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 MDMAv1/stm32_mdma.c
- * @brief MDMA helper driver code.
- *
- * @addtogroup STM32_MDMA
- * @details MDMA sharing helper driver. In the STM32 the MDMA channels are a
- * shared resource, this driver allows to allocate and free MDMA
- * STM32 at runtime in order to allow all the other device
- * drivers to coordinate the access to the resource.
- * @note The MDMA ISR handlers are all declared into this module because
- * sharing, the various device drivers can associate a callback to
- * ISRs when allocating channels.
- * @{
- */
-
-#include "hal.h"
-
-/* The following macro is only defined if some driver requiring MDMA services
- has been enabled.*/
-#if defined(STM32_MDMA_REQUIRED) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief Global MDMA-related data structures.
- */
-static struct {
- /**
- * @brief Mask of the allocated channels.
- */
- uint32_t allocated_mask;
- /**
- * @brief MDMA IRQ redirectors.
- */
- stm32_mdma_channel_t channels[STM32_MDMA_CHANNELS];
-} mdma;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static void mdma_serve_interrupt(const stm32_mdma_channel_t *mdmachp) {
- uint32_t flags;
-
- flags = mdmachp->channel->CISR;
- mdmachp->channel->CIFCR = flags;
- if (mdmachp->func != NULL) {
- mdmachp->func(mdmachp->param, flags);
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/**
- * @brief MDMA shared interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_MDMA_HANDLER) {
- uint32_t gisr = MDMA->GISR0;
- OSAL_IRQ_PROLOGUE();
-
- if ((gisr & (1U << 0)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[0]);
- }
-
- if ((gisr & (1U << 1)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[1]);
- }
-
- if ((gisr & (1U << 2)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[2]);
- }
-
- if ((gisr & (1U << 3)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[3]);
- }
-
- if ((gisr & (1U << 4)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[4]);
- }
-
- if ((gisr & (1U << 5)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[5]);
- }
-
- if ((gisr & (1U << 6)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[6]);
- }
-
- if ((gisr & (1U << 7)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[7]);
- }
-
- if ((gisr & (1U << 8)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[8]);
- }
-
- if ((gisr & (1U << 9)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[9]);
- }
-
- if ((gisr & (1U << 10)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[10]);
- }
-
- if ((gisr & (1U << 11)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[11]);
- }
-
- if ((gisr & (1U << 12)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[12]);
- }
-
- if ((gisr & (1U << 13)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[13]);
- }
-
- if ((gisr & (1U << 14)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[14]);
- }
-
- if ((gisr & (1U << 15)) != 0U) {
- mdma_serve_interrupt(&mdma.channels[15]);
- }
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 MDMA helper initialization.
- *
- * @init
- */
-void mdmaInit(void) {
- static MDMA_Channel_TypeDef * const channels[STM32_MDMA_CHANNELS] = {
- MDMA_Channel0, MDMA_Channel1, MDMA_Channel2, MDMA_Channel3,
- MDMA_Channel4, MDMA_Channel5, MDMA_Channel6, MDMA_Channel7,
- MDMA_Channel8, MDMA_Channel9, MDMA_Channel10, MDMA_Channel11,
- MDMA_Channel12, MDMA_Channel13, MDMA_Channel14, MDMA_Channel15
- };
- unsigned i;
-
- mdma.allocated_mask = 0U;
- for (i = 0U; i < STM32_MDMA_CHANNELS; i++) {
- MDMA_Channel_TypeDef *cp = channels[i];
- mdma.channels[i].channel = cp;
- mdma.channels[i].func = NULL;
- mdma.channels[i].channel->CCR = STM32_MDMA_CCR_RESET_VALUE;
- mdma.channels[i].channel->CTCR = STM32_MDMA_CTCR_RESET_VALUE;
- mdma.channels[i].channel->CIFCR = STM32_MDMA_CIFCR_CTEIF |
- STM32_MDMA_CIFCR_CBRTIF |
- STM32_MDMA_CIFCR_CBRTIF |
- STM32_MDMA_CIFCR_CCTCIF |
- STM32_MDMA_CIFCR_CTEIF;
- }
-}
-
-/**
- * @brief Allocates an MDMA channel.
- * @details The channel is allocated and, if required, the MDMA clock enabled.
- * The function also enables the IRQ vector associated to the channel
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific channel or:
- * - @p STM32_MDMA_CHANNEL_ID_ANY for any channel.
- * .
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_mdma_channel_t
- * structure.
- * @retval NULL if a/the channel is not available.
- *
- * @iclass
- */
-const stm32_mdma_channel_t *mdmaChannelAllocI(uint32_t id,
- stm32_mdmaisr_t func,
- void *param) {
- uint32_t i, startid, endid;
-
- osalDbgCheckClassI();
-
- if (id < STM32_MDMA_CHANNELS) {
- startid = id;
- endid = id;
- }
- else if (id == STM32_MDMA_CHANNEL_ID_ANY) {
- startid = 0U;
- endid = STM32_MDMA_CHANNELS - 1U;
- }
- else {
- osalDbgCheck(false);
- return NULL;
- }
-
- for (i = startid; i <= endid; i++) {
- uint32_t mask = (1U << i);
- if ((mdma.allocated_mask & mask) == 0U) {
- stm32_mdma_channel_t *mdmachp = &mdma.channels[i];
-
- /* Installs the MDMA handler.*/
- mdma.allocated_mask |= mask;
- mdmachp->func = func;
- mdmachp->param = param;
-
- /* Enabling MDMA clocks required by the current channels set.*/
- if (mdma.allocated_mask != 0U) {
- rccEnableMDMA(true);
- }
-
- return mdmachp;
- }
- }
-
- return NULL;
-}
-
-/**
- * @brief Allocates a MDMA channel.
- * @details The channel is allocated and, if required, the MDMA clock enabled.
- * The function also enables the IRQ vector associated to the channel
- * and initializes its priority.
- *
- * @param[in] id numeric identifiers of a specific channel or:
- * - @p STM32_MDMA_CHANNEL_ID_ANY for any channel.
- * .
- * @param[in] func handling function pointer, can be @p NULL
- * @param[in] param a parameter to be passed to the handling function
- * @return Pointer to the allocated @p stm32_mdma_channel_t
- * structure.
- * @retval NULL if a/the channel is not available.
- *
- * @api
- */
-const stm32_mdma_channel_t *mdmaChannelAlloc(uint32_t id,
- stm32_mdmaisr_t func,
- void *param) {
- const stm32_mdma_channel_t *mdmachp;
-
- osalSysLock();
- mdmachp = mdmaChannelAllocI(id, func, param);
- osalSysUnlock();
-
- return mdmachp;
-}
-
-/**
- * @brief Releases a MDMA channel.
- * @details The channel is freed and, if required, the MDMA clock disabled.
- * Trying to release a unallocated channel is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- *
- * @iclass
- */
-void mdmaChannelFreeI(const stm32_mdma_channel_t *mdmachp) {
- uint32_t channel = mdmachp - mdma.channels;
- osalDbgCheck(mdmachp != NULL);
-
- /* Check if the channels is not taken.*/
- osalDbgAssert((mdma.allocated_mask & (1U << channel)) != 0U,
- "not allocated");
-
- /* Marks the channel as not allocated.*/
- mdma.allocated_mask &= ~(1U << channel);
-
- /* Shutting down clocks that are no more required, if any.*/
- if (mdma.allocated_mask == 0U) {
- rccDisableMDMA();
- }
-}
-
-/**
- * @brief Releases a MDMA channel.
- * @details The channel is freed and, if required, the MDMA clock disabled.
- * Trying to release a unallocated channel is an illegal operation
- * and is trapped if assertions are enabled.
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- *
- * @api
- */
-void mdmaChannelFree(const stm32_mdma_channel_t *mdmachp) {
-
- osalSysLock();
- mdmaChannelFreeI(mdmachp);
- osalSysUnlock();
-}
-
-/**
- * @brief MDMA stream disable.
- * @details The function disables the specified stream, waits for the disable
- * operation to complete and then clears any pending interrupt.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- *
- * @xclass
- */
-void mdmaChannelDisableX(const stm32_mdma_channel_t *mdmachp) {
- uint32_t ccr = mdmachp->channel->CCR;
-
- /* Clearing CCR regardless of previous state.*/
- mdmachp->channel->CCR &= ~(STM32_MDMA_CCR_TCIE | STM32_MDMA_CCR_BTIE |
- STM32_MDMA_CCR_BRTIE | STM32_MDMA_CCR_CTCIE |
- STM32_MDMA_CCR_TEIE | STM32_MDMA_CCR_EN);
-
- /* If the channel was enabled then waiting for ongoing operations
- to finish.*/
- if ((ccr & STM32_MDMA_CCR_EN) != 0U) {
- while (((mdmachp)->channel->CISR & STM32_MDMA_CISR_CTCIF) == 0U)
- ;
- }
-
- /* Clearing IRQ sources.*/
- mdmaChannelClearInterruptX(mdmachp);
-}
-
-#endif /* defined(STM32_MDMA_REQUIRED) */
-
-/** @} */
+/*
+ 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 MDMAv1/stm32_mdma.c
+ * @brief MDMA helper driver code.
+ *
+ * @addtogroup STM32_MDMA
+ * @details MDMA sharing helper driver. In the STM32 the MDMA channels are a
+ * shared resource, this driver allows to allocate and free MDMA
+ * STM32 at runtime in order to allow all the other device
+ * drivers to coordinate the access to the resource.
+ * @note The MDMA ISR handlers are all declared into this module because
+ * sharing, the various device drivers can associate a callback to
+ * ISRs when allocating channels.
+ * @{
+ */
+
+#include "hal.h"
+
+/* The following macro is only defined if some driver requiring MDMA services
+ has been enabled.*/
+#if defined(STM32_MDMA_REQUIRED) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Global MDMA-related data structures.
+ */
+static struct {
+ /**
+ * @brief Mask of the allocated channels.
+ */
+ uint32_t allocated_mask;
+ /**
+ * @brief MDMA IRQ redirectors.
+ */
+ stm32_mdma_channel_t channels[STM32_MDMA_CHANNELS];
+} mdma;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+static void mdma_serve_interrupt(const stm32_mdma_channel_t *mdmachp) {
+ uint32_t flags;
+
+ flags = mdmachp->channel->CISR;
+ mdmachp->channel->CIFCR = flags;
+ if (mdmachp->func != NULL) {
+ mdmachp->func(mdmachp->param, flags);
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief MDMA shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_MDMA_HANDLER) {
+ uint32_t gisr = MDMA->GISR0;
+ OSAL_IRQ_PROLOGUE();
+
+ if ((gisr & (1U << 0)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[0]);
+ }
+
+ if ((gisr & (1U << 1)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[1]);
+ }
+
+ if ((gisr & (1U << 2)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[2]);
+ }
+
+ if ((gisr & (1U << 3)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[3]);
+ }
+
+ if ((gisr & (1U << 4)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[4]);
+ }
+
+ if ((gisr & (1U << 5)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[5]);
+ }
+
+ if ((gisr & (1U << 6)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[6]);
+ }
+
+ if ((gisr & (1U << 7)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[7]);
+ }
+
+ if ((gisr & (1U << 8)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[8]);
+ }
+
+ if ((gisr & (1U << 9)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[9]);
+ }
+
+ if ((gisr & (1U << 10)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[10]);
+ }
+
+ if ((gisr & (1U << 11)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[11]);
+ }
+
+ if ((gisr & (1U << 12)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[12]);
+ }
+
+ if ((gisr & (1U << 13)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[13]);
+ }
+
+ if ((gisr & (1U << 14)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[14]);
+ }
+
+ if ((gisr & (1U << 15)) != 0U) {
+ mdma_serve_interrupt(&mdma.channels[15]);
+ }
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 MDMA helper initialization.
+ *
+ * @init
+ */
+void mdmaInit(void) {
+ static MDMA_Channel_TypeDef * const channels[STM32_MDMA_CHANNELS] = {
+ MDMA_Channel0, MDMA_Channel1, MDMA_Channel2, MDMA_Channel3,
+ MDMA_Channel4, MDMA_Channel5, MDMA_Channel6, MDMA_Channel7,
+ MDMA_Channel8, MDMA_Channel9, MDMA_Channel10, MDMA_Channel11,
+ MDMA_Channel12, MDMA_Channel13, MDMA_Channel14, MDMA_Channel15
+ };
+ unsigned i;
+
+ mdma.allocated_mask = 0U;
+ for (i = 0U; i < STM32_MDMA_CHANNELS; i++) {
+ MDMA_Channel_TypeDef *cp = channels[i];
+ mdma.channels[i].channel = cp;
+ mdma.channels[i].func = NULL;
+ mdma.channels[i].channel->CCR = STM32_MDMA_CCR_RESET_VALUE;
+ mdma.channels[i].channel->CTCR = STM32_MDMA_CTCR_RESET_VALUE;
+ mdma.channels[i].channel->CIFCR = STM32_MDMA_CIFCR_CTEIF |
+ STM32_MDMA_CIFCR_CBRTIF |
+ STM32_MDMA_CIFCR_CBRTIF |
+ STM32_MDMA_CIFCR_CCTCIF |
+ STM32_MDMA_CIFCR_CTEIF;
+ }
+}
+
+/**
+ * @brief Allocates an MDMA channel.
+ * @details The channel is allocated and, if required, the MDMA clock enabled.
+ * The function also enables the IRQ vector associated to the channel
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific channel or:
+ * - @p STM32_MDMA_CHANNEL_ID_ANY for any channel.
+ * .
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_mdma_channel_t
+ * structure.
+ * @retval NULL if a/the channel is not available.
+ *
+ * @iclass
+ */
+const stm32_mdma_channel_t *mdmaChannelAllocI(uint32_t id,
+ stm32_mdmaisr_t func,
+ void *param) {
+ uint32_t i, startid, endid;
+
+ osalDbgCheckClassI();
+
+ if (id < STM32_MDMA_CHANNELS) {
+ startid = id;
+ endid = id;
+ }
+ else if (id == STM32_MDMA_CHANNEL_ID_ANY) {
+ startid = 0U;
+ endid = STM32_MDMA_CHANNELS - 1U;
+ }
+ else {
+ osalDbgCheck(false);
+ return NULL;
+ }
+
+ for (i = startid; i <= endid; i++) {
+ uint32_t mask = (1U << i);
+ if ((mdma.allocated_mask & mask) == 0U) {
+ stm32_mdma_channel_t *mdmachp = &mdma.channels[i];
+
+ /* Installs the MDMA handler.*/
+ mdma.allocated_mask |= mask;
+ mdmachp->func = func;
+ mdmachp->param = param;
+
+ /* Enabling MDMA clocks required by the current channels set.*/
+ if (mdma.allocated_mask != 0U) {
+ rccEnableMDMA(true);
+ }
+
+ return mdmachp;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Allocates a MDMA channel.
+ * @details The channel is allocated and, if required, the MDMA clock enabled.
+ * The function also enables the IRQ vector associated to the channel
+ * and initializes its priority.
+ *
+ * @param[in] id numeric identifiers of a specific channel or:
+ * - @p STM32_MDMA_CHANNEL_ID_ANY for any channel.
+ * .
+ * @param[in] func handling function pointer, can be @p NULL
+ * @param[in] param a parameter to be passed to the handling function
+ * @return Pointer to the allocated @p stm32_mdma_channel_t
+ * structure.
+ * @retval NULL if a/the channel is not available.
+ *
+ * @api
+ */
+const stm32_mdma_channel_t *mdmaChannelAlloc(uint32_t id,
+ stm32_mdmaisr_t func,
+ void *param) {
+ const stm32_mdma_channel_t *mdmachp;
+
+ osalSysLock();
+ mdmachp = mdmaChannelAllocI(id, func, param);
+ osalSysUnlock();
+
+ return mdmachp;
+}
+
+/**
+ * @brief Releases a MDMA channel.
+ * @details The channel is freed and, if required, the MDMA clock disabled.
+ * Trying to release a unallocated channel is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ *
+ * @iclass
+ */
+void mdmaChannelFreeI(const stm32_mdma_channel_t *mdmachp) {
+ uint32_t channel = mdmachp - mdma.channels;
+ osalDbgCheck(mdmachp != NULL);
+
+ /* Check if the channels is not taken.*/
+ osalDbgAssert((mdma.allocated_mask & (1U << channel)) != 0U,
+ "not allocated");
+
+ /* Marks the channel as not allocated.*/
+ mdma.allocated_mask &= ~(1U << channel);
+
+ /* Shutting down clocks that are no more required, if any.*/
+ if (mdma.allocated_mask == 0U) {
+ rccDisableMDMA();
+ }
+}
+
+/**
+ * @brief Releases a MDMA channel.
+ * @details The channel is freed and, if required, the MDMA clock disabled.
+ * Trying to release a unallocated channel is an illegal operation
+ * and is trapped if assertions are enabled.
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ *
+ * @api
+ */
+void mdmaChannelFree(const stm32_mdma_channel_t *mdmachp) {
+
+ osalSysLock();
+ mdmaChannelFreeI(mdmachp);
+ osalSysUnlock();
+}
+
+/**
+ * @brief MDMA stream disable.
+ * @details The function disables the specified stream, waits for the disable
+ * operation to complete and then clears any pending interrupt.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ *
+ * @xclass
+ */
+void mdmaChannelDisableX(const stm32_mdma_channel_t *mdmachp) {
+ uint32_t ccr = mdmachp->channel->CCR;
+
+ /* Clearing CCR regardless of previous state.*/
+ mdmachp->channel->CCR &= ~(STM32_MDMA_CCR_TCIE | STM32_MDMA_CCR_BTIE |
+ STM32_MDMA_CCR_BRTIE | STM32_MDMA_CCR_CTCIE |
+ STM32_MDMA_CCR_TEIE | STM32_MDMA_CCR_EN);
+
+ /* If the channel was enabled then waiting for ongoing operations
+ to finish.*/
+ if ((ccr & STM32_MDMA_CCR_EN) != 0U) {
+ while (((mdmachp)->channel->CISR & STM32_MDMA_CISR_CTCIF) == 0U)
+ ;
+ }
+
+ /* Clearing IRQ sources.*/
+ mdmaChannelClearInterruptX(mdmachp);
+}
+
+#endif /* defined(STM32_MDMA_REQUIRED) */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.h b/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.h
index bdc8bbbf98..8fcaf131a1 100644
--- a/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.h
+++ b/os/hal/ports/STM32/LLD/MDMAv1/stm32_mdma.h
@@ -1,462 +1,462 @@
-/*
- 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 MDMAv1/stm32_mdma.h
- * @brief MDMA helper driver header.
- *
- * @addtogroup STM32_MDMA
- * @{
- */
-
-#ifndef STM32_MDMA_H
-#define STM32_MDMA_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Total number of MDMA streams.
- */
-#define STM32_MDMA_CHANNELS 16U
-
-/**
- * @brief Mask of the ISR bits passed to the MDMA callback functions.
- */
-#define STM32_MDMA_ISR_MASK 0x1FU
-
-/**
- * @brief Checks if a MDMA priority is within the valid range.
- * @param[in] prio MDMA priority
- *
- * @retval The check result.
- * @retval false invalid MDMA priority.
- * @retval true correct MDMA priority.
- */
-#define STM32_MDMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
-
-/**
- * @brief Checks if a MDMA channel id is within the valid range.
- *
- * @param[in] id MDMA channel id
- * @retval The check result.
- * @retval false invalid MDMA channel.
- * @retval true correct MDMA channel.
- */
-#define STM32_MDMA_IS_VALID_CHANNEL(id) (((id) >= 0U) && \
- ((id) <= STM32_MDMA_CHANNELS))
-
-/**
- * @brief Special stream identifier
- */
-#define STM32_MDMA_CHANNEL_ID_ANY STM32_MDMA_CHANNELS
-
-/**
- * @name CISR register constants
- * @{
- */
-#define STM32_MDMA_CISR_TEIF (1U << 0)
-#define STM32_MDMA_CISR_CTCIF (1U << 1)
-#define STM32_MDMA_CISR_BRTIF (1U << 2)
-#define STM32_MDMA_CISR_BTIF (1U << 3)
-#define STM32_MDMA_CISR_TCIF (1U << 4)
-#define STM32_MDMA_CISR_CRQA (1U << 16)
-/** @} */
-
-/**
- * @name CIFCR register constants
- * @{
- */
-#define STM32_MDMA_CIFCR_CTEIF (1U << 0)
-#define STM32_MDMA_CIFCR_CCTCIF (1U << 1)
-#define STM32_MDMA_CIFCR_CBRTIF (1U << 2)
-#define STM32_MDMA_CIFCR_CBTIF (1U << 3)
-#define STM32_MDMA_CIFCR_CTCIF (1U << 4)
-/** @} */
-
-/**
- * @name CESR register constants
- * @{
- */
-#define STM32_MDMA_CESR_TEA_MASK (127U << 0)
-#define STM32_MDMA_CESR_TED (1U << 7)
-#define STM32_MDMA_CESR_TELD (1U << 8)
-#define STM32_MDMA_CESR_TEMD (1U << 9)
-#define STM32_MDMA_CESR_ASE (1U << 10)
-#define STM32_MDMA_CESR_BSE (1U << 11)
-/** @} */
-
-/**
- * @name CCR register constants
- * @{
- */
-#define STM32_MDMA_CCR_RESET_VALUE 0x00000000U
-#define STM32_MDMA_CCR_EN (1U << 0)
-#define STM32_MDMA_CCR_TEIE (1U << 1)
-#define STM32_MDMA_CCR_CTCIE (1U << 2)
-#define STM32_MDMA_CCR_BRTIE (1U << 3)
-#define STM32_MDMA_CCR_BTIE (1U << 4)
-#define STM32_MDMA_CCR_TCIE (1U << 5)
-#define STM32_MDMA_CCR_PL_MASK (3U << 6)
-#define STM32_MDMA_CCR_PL(n) ((n) << 6)
-#define STM32_MDMA_CCR_BEX (1U << 12)
-#define STM32_MDMA_CCR_HEX (1U << 13)
-#define STM32_MDMA_CCR_WEX (1U << 14)
-#define STM32_MDMA_CCR_SWRQ (1U << 16)
-/** @} */
-
-/**
- * @name CTCR register constants
- * @{
- */
-#define STM32_MDMA_CTCR_RESET_VALUE 0x00000000U
-
-#define STM32_MDMA_CTCR_SINC_MASK (3U << 0)
-#define STM32_MDMA_CTCR_SINC(n) ((n) << 0)
-#define STM32_MDMA_CTCR_SINC_FIXED STM32_MDMA_CTCR_SINC(0U)
-#define STM32_MDMA_CTCR_SINC_INC STM32_MDMA_CTCR_SINC(2U)
-#define STM32_MDMA_CTCR_SINC_DEC STM32_MDMA_CTCR_SINC(3U)
-
-#define STM32_MDMA_CTCR_DINC_MASK (3U << 2)
-#define STM32_MDMA_CTCR_DINC(n) ((n) << 2)
-#define STM32_MDMA_CTCR_DINC_FIXED STM32_MDMA_CTCR_DINC(0U)
-#define STM32_MDMA_CTCR_DINC_INC STM32_MDMA_CTCR_DINC(2U)
-#define STM32_MDMA_CTCR_DINC_DEC STM32_MDMA_CTCR_DINC(3U)
-
-#define STM32_MDMA_CTCR_SSIZE_MASK (3U << 4)
-#define STM32_MDMA_CTCR_SSIZE(n) ((n) << 4)
-#define STM32_MDMA_CTCR_SSIZE_BYTE STM32_MDMA_CTCR_SSIZE(0U)
-#define STM32_MDMA_CTCR_SSIZE_HALF STM32_MDMA_CTCR_SSIZE(1U)
-#define STM32_MDMA_CTCR_SSIZE_WORD STM32_MDMA_CTCR_SSIZE(2U)
-#define STM32_MDMA_CTCR_SSIZE_DWORD STM32_MDMA_CTCR_SSIZE(3U)
-
-#define STM32_MDMA_CTCR_DSIZE_MASK (3U << 6)
-#define STM32_MDMA_CTCR_DSIZE(n) ((n) << 6)
-#define STM32_MDMA_CTCR_DSIZE_BYTE STM32_MDMA_CTCR_DSIZE(0U)
-#define STM32_MDMA_CTCR_DSIZE_HALF STM32_MDMA_CTCR_DSIZE(1U)
-#define STM32_MDMA_CTCR_DSIZE_WORD STM32_MDMA_CTCR_DSIZE(2U)
-#define STM32_MDMA_CTCR_DSIZE_DWORD STM32_MDMA_CTCR_DSIZE(3U)
-
-#define STM32_MDMA_CTCR_SINCOS_MASK (3U << 8)
-#define STM32_MDMA_CTCR_SINCOS(n) ((n) << 8)
-#define STM32_MDMA_CTCR_SINCOS_BYTE STM32_MDMA_CTCR_SINCOS(0U)
-#define STM32_MDMA_CTCR_SINCOS_HALF STM32_MDMA_CTCR_SINCOS(1U)
-#define STM32_MDMA_CTCR_SINCOS_WORD STM32_MDMA_CTCR_SINCOS(2U)
-#define STM32_MDMA_CTCR_SINCOS_DWORD STM32_MDMA_CTCR_SINCOS(3U)
-
-#define STM32_MDMA_CTCR_DINCOS_MASK (3U << 10)
-#define STM32_MDMA_CTCR_DINCOS(n) ((n) << 10)
-#define STM32_MDMA_CTCR_DINCOS_BYTE STM32_MDMA_CTCR_DINCOS(0U)
-#define STM32_MDMA_CTCR_DINCOS_HALF STM32_MDMA_CTCR_DINCOS(1U)
-#define STM32_MDMA_CTCR_DINCOS_WORD STM32_MDMA_CTCR_DINCOS(2U)
-#define STM32_MDMA_CTCR_DINCOS_DWORD STM32_MDMA_CTCR_DINCOS(3U)
-
-#define STM32_MDMA_CTCR_SBURST_MASK (7U << 12)
-#define STM32_MDMA_CTCR_SBURST(n) ((n) << 12)
-#define STM32_MDMA_CTCR_SBURST_1 STM32_MDMA_CTCR_SBURST(0U)
-#define STM32_MDMA_CTCR_SBURST_2 STM32_MDMA_CTCR_SBURST(1U)
-#define STM32_MDMA_CTCR_SBURST_4 STM32_MDMA_CTCR_SBURST(2U)
-#define STM32_MDMA_CTCR_SBURST_8 STM32_MDMA_CTCR_SBURST(3U)
-#define STM32_MDMA_CTCR_SBURST_16 STM32_MDMA_CTCR_SBURST(4U)
-#define STM32_MDMA_CTCR_SBURST_32 STM32_MDMA_CTCR_SBURST(5U)
-#define STM32_MDMA_CTCR_SBURST_64 STM32_MDMA_CTCR_SBURST(6U)
-#define STM32_MDMA_CTCR_SBURST_128 STM32_MDMA_CTCR_SBURST(7U)
-
-#define STM32_MDMA_CTCR_DBURST_MASK (7U << 15)
-#define STM32_MDMA_CTCR_DBURST(n) ((n) << 15)
-#define STM32_MDMA_CTCR_DBURST_1 STM32_MDMA_CTCR_DBURST(0U)
-#define STM32_MDMA_CTCR_DBURST_2 STM32_MDMA_CTCR_DBURST(1U)
-#define STM32_MDMA_CTCR_DBURST_4 STM32_MDMA_CTCR_DBURST(2U)
-#define STM32_MDMA_CTCR_DBURST_8 STM32_MDMA_CTCR_DBURST(3U)
-#define STM32_MDMA_CTCR_DBURST_16 STM32_MDMA_CTCR_DBURST(4U)
-#define STM32_MDMA_CTCR_DBURST_32 STM32_MDMA_CTCR_DBURST(5U)
-#define STM32_MDMA_CTCR_DBURST_64 STM32_MDMA_CTCR_DBURST(6U)
-#define STM32_MDMA_CTCR_DBURST_128 STM32_MDMA_CTCR_DBURST(7U)
-
-#define STM32_MDMA_CTCR_TLEN_MASK (127U << 18)
-#define STM32_MDMA_CTCR_TLEN(n) ((n) << 18)
-
-#define STM32_MDMA_CTCR_PKE (1U << 25)
-
-#define STM32_MDMA_CTCR_PAM_MASK (3U << 26)
-#define STM32_MDMA_CTCR_PAM(n) ((n) << 26)
-#define STM32_MDMA_CTCR_PAM_RIGHT STM32_MDMA_CTCR_PAM(0U)
-#define STM32_MDMA_CTCR_PAM_RIGHT_SE STM32_MDMA_CTCR_PAM(1U)
-#define STM32_MDMA_CTCR_PAM_LEFT STM32_MDMA_CTCR_PAM(2U)
-
-#define STM32_MDMA_CTCR_TRGM_MASK (3U << 28)
-#define STM32_MDMA_CTCR_TRGM(n) ((n) << 28)
-#define STM32_MDMA_CTCR_TRGM_BUFFER STM32_MDMA_CTCR_TRGM(0U)
-#define STM32_MDMA_CTCR_TRGM_BLOCK STM32_MDMA_CTCR_TRGM(1U)
-#define STM32_MDMA_CTCR_TRGM_REP_BLOCK STM32_MDMA_CTCR_TRGM(2U)
-#define STM32_MDMA_CTCR_TRGM_WHOLE STM32_MDMA_CTCR_TRGM(3U)
-
-#define STM32_MDMA_CTCR_SWRM (1U << 30)
-
-#define STM32_MDMA_CTCR_BWM_MASK (1U << 31)
-#define STM32_MDMA_CTCR_BWM_NON_BUFF (0U << 31)
-#define STM32_MDMA_CTCR_BWM_BUFF (1U << 31)
-/** @} */
-
-/**
- * @name BNDTR register constants
- * @{
- */
-#define STM32_MDMA_CBNDTR_BNDT_MASK (0x1FFFFU << 0)
-#define STM32_MDMA_CBNDTR_BNDT(n) ((n) << 0)
-#define STM32_MDMA_CBNDTR_BRSUM (1U << 18)
-#define STM32_MDMA_CBNDTR_BRDUM (1U << 19)
-#define STM32_MDMA_CBNDTR_BRC_MASK (0xFFFU << 20)
-#define STM32_MDMA_CBNDTR_BRC(n) ((n) << 20)
-/** @} */
-
-/**
- * @name CBRUR register constants
- * @{
- */
-#define STM32_MDMA_CBRUR_SUV_MASK (0xFFFFU << 0)
-#define STM32_MDMA_CBRUR_SUV(n) ((n) << 0)
-#define STM32_MDMA_CBRUR_DUV_MASK (0xFFFFU << 16)
-#define STM32_MDMA_CBRUR_DUV(n) ((n) << 16)
-/** @} */
-
-/**
- * @name CTBR register constants
- * @{
- */
-#define STM32_MDMA_CTBR_TSEL_MASK (0x3FU << 0)
-#define STM32_MDMA_CTBR_TSEL(n) ((n) << 0)
-#define STM32_MDMA_CTBR_TSEL_SBUS (1U << 16)
-#define STM32_MDMA_CTBR_TSEL_DBUS (1U << 17)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_MDMA_HANDLER)
-#error "STM32_MDMA_HANDLER missing in registry"
-#endif
-
-#if !defined(STM32_MDMA_NUMBER)
-#error "STM32_MDMA_NUMBER missing in registry"
-#endif
-
-/* Priority settings checks.*/
-#if !defined(STM32_IRQ_MDMA_PRIORITY)
-#error "STM32_IRQ_MDMA_PRIORITY not defined in mcuconf.h"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_MDMA_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_MDMA_PRIORITY"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 MDMA ISR function type.
- *
- * @param[in] p parameter for the registered function
- * @param[in] flags content of the CISR register
- */
-typedef void (*stm32_mdmaisr_t)(void *p, uint32_t flags);
-
-/**
- * @brief STM32 MDMA stream descriptor structure.
- */
-typedef struct {
- /**
- * @brief Associated MDMA channel.
- */
- MDMA_Channel_TypeDef *channel;
- /**
- * @brief MDMA callback function.
- */
- stm32_mdmaisr_t func;
- /**
- * @brief MDMA callback parameter.
- */
- void *param;
-} stm32_mdma_channel_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @name Macro Functions
- * @{
- */
-/**
- * @brief Associates a source address to a MDMA stream.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- * @param[in] addr value to be written in the CSAR register
- *
- * @xclass
- */
-#define mdmaChannelSetSourceX(mdmachp, addr) do { \
- (mdmachp)->channel->CSAR = (uint32_t)(addr); \
-} while (0)
-
-/**
- * @brief Associates a memory destination to a MDMA stream.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- * @param[in] addr value to be written in the CDAR register
- *
- * @xclass
- */
-#define mdmaChannelSetDestinationX(mdmachp, addr) do { \
- (mdmachp)->channel->CDAR = (uint32_t)(addr); \
-} while (0)
-
-/**
- * @brief Sets parameters related to the transaction size.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- * @param[in] size number of bytes per block
- * @param[in] n number of blocks repetitions
- * @param[in] opt other option bits for the CBNDTR register
- *
- * @xclass
- */
-#define mdmaChannelSetTransactionSizeX(mdmachp, size, n, opt) do { \
- (mdmachp)->channel->CBNDTR = (uint32_t)STM32_MDMA_CBNDTR_BNDT(size) | \
- (uint32_t)STM32_MDMA_CBNDTR_BRC(n) | \
- (uint32_t)opt; \
-} while (0)
-
-/**
- * @brief Programs the stream mode settings.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- * @param[in] ctcr value to be written in the CTCR register
- * @param[in] ccr value to be written in the CCR register
- *
- * @xclass
- */
-#define mdmaChannelSetModeX(mdmachp, ctcr, ccr) do { \
- (mdmachp)->channel->CTCR = (uint32_t)(ctcr); \
- (mdmachp)->channel->CCR = (uint32_t)(ccr); \
-} while (0)
-
-/**
- * @brief Programs the trigger mode settings.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- * @param[in] tsel value to be written in the CTBR register
- *
- * @xclass
- */
-#define mdmaChannelSetTrigModeX(mdmachp, tsel) do { \
- (mdmachp)->channel->CTBR = STM32_MDMA_CTBR_TSEL(tsel); \
-} while (0)
-
-/**
- * @brief MDMA stream enable.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- *
- * @xclass
- */
-#define mdmaChannelEnableX(mdmachp) do { \
- (mdmachp)->channel->CCR |= STM32_MDMA_CCR_EN; \
-} while (0)
-
-/**
- * @brief Channel enable check.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- */
-#define mdmaChannelIsEnabled(mdmachp) \
- (((mdmachp)->channel->CCR & STM32_MDMA_CCR_EN) != 0U)
-
-/**
- * @brief MDMA stream interrupt sources clear.
- * @pre The stream must have been allocated using @p mdmaChannelAlloc().
- * @post After use the stream can be released using @p mdmaChannelFree().
- *
- * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
- *
- * @xclass
- */
-#define mdmaChannelClearInterruptX(mdmachp) do { \
- (mdmachp)->channel->CIFCR = (STM32_MDMA_CIFCR_CTEIF | \
- STM32_MDMA_CIFCR_CBRTIF | \
- STM32_MDMA_CIFCR_CBRTIF | \
- STM32_MDMA_CIFCR_CCTCIF | \
- STM32_MDMA_CIFCR_CTEIF); \
-} while (0)
-
-/**
- * @brief MDMA IRQ enable.
- */
-#define mdma_irq_init() \
- nvicEnableVector(STM32_MDMA_NUMBER, STM32_IRQ_MDMA_PRIORITY)
-
-/**
- * @brief MDMA IRQ disable.
- */
-#define mdma_irq_deinit() \
- nvicDisableVector(STM32_MDMA_NUMBER)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void mdmaInit(void);
- const stm32_mdma_channel_t *mdmaChannelAllocI(uint32_t id,
- stm32_mdmaisr_t func,
- void *param);
- const stm32_mdma_channel_t *mdmaChannelAlloc(uint32_t id,
- stm32_mdmaisr_t func,
- void *param);
- void mdmaChannelFreeI(const stm32_mdma_channel_t *mdmachp);
- void mdmaChannelFree(const stm32_mdma_channel_t *mdmachp);
- void mdmaChannelDisableX(const stm32_mdma_channel_t *mdmachp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_MDMA_H */
-
-/** @} */
+/*
+ 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 MDMAv1/stm32_mdma.h
+ * @brief MDMA helper driver header.
+ *
+ * @addtogroup STM32_MDMA
+ * @{
+ */
+
+#ifndef STM32_MDMA_H
+#define STM32_MDMA_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Total number of MDMA streams.
+ */
+#define STM32_MDMA_CHANNELS 16U
+
+/**
+ * @brief Mask of the ISR bits passed to the MDMA callback functions.
+ */
+#define STM32_MDMA_ISR_MASK 0x1FU
+
+/**
+ * @brief Checks if a MDMA priority is within the valid range.
+ * @param[in] prio MDMA priority
+ *
+ * @retval The check result.
+ * @retval false invalid MDMA priority.
+ * @retval true correct MDMA priority.
+ */
+#define STM32_MDMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
+
+/**
+ * @brief Checks if a MDMA channel id is within the valid range.
+ *
+ * @param[in] id MDMA channel id
+ * @retval The check result.
+ * @retval false invalid MDMA channel.
+ * @retval true correct MDMA channel.
+ */
+#define STM32_MDMA_IS_VALID_CHANNEL(id) (((id) >= 0U) && \
+ ((id) <= STM32_MDMA_CHANNELS))
+
+/**
+ * @brief Special stream identifier
+ */
+#define STM32_MDMA_CHANNEL_ID_ANY STM32_MDMA_CHANNELS
+
+/**
+ * @name CISR register constants
+ * @{
+ */
+#define STM32_MDMA_CISR_TEIF (1U << 0)
+#define STM32_MDMA_CISR_CTCIF (1U << 1)
+#define STM32_MDMA_CISR_BRTIF (1U << 2)
+#define STM32_MDMA_CISR_BTIF (1U << 3)
+#define STM32_MDMA_CISR_TCIF (1U << 4)
+#define STM32_MDMA_CISR_CRQA (1U << 16)
+/** @} */
+
+/**
+ * @name CIFCR register constants
+ * @{
+ */
+#define STM32_MDMA_CIFCR_CTEIF (1U << 0)
+#define STM32_MDMA_CIFCR_CCTCIF (1U << 1)
+#define STM32_MDMA_CIFCR_CBRTIF (1U << 2)
+#define STM32_MDMA_CIFCR_CBTIF (1U << 3)
+#define STM32_MDMA_CIFCR_CTCIF (1U << 4)
+/** @} */
+
+/**
+ * @name CESR register constants
+ * @{
+ */
+#define STM32_MDMA_CESR_TEA_MASK (127U << 0)
+#define STM32_MDMA_CESR_TED (1U << 7)
+#define STM32_MDMA_CESR_TELD (1U << 8)
+#define STM32_MDMA_CESR_TEMD (1U << 9)
+#define STM32_MDMA_CESR_ASE (1U << 10)
+#define STM32_MDMA_CESR_BSE (1U << 11)
+/** @} */
+
+/**
+ * @name CCR register constants
+ * @{
+ */
+#define STM32_MDMA_CCR_RESET_VALUE 0x00000000U
+#define STM32_MDMA_CCR_EN (1U << 0)
+#define STM32_MDMA_CCR_TEIE (1U << 1)
+#define STM32_MDMA_CCR_CTCIE (1U << 2)
+#define STM32_MDMA_CCR_BRTIE (1U << 3)
+#define STM32_MDMA_CCR_BTIE (1U << 4)
+#define STM32_MDMA_CCR_TCIE (1U << 5)
+#define STM32_MDMA_CCR_PL_MASK (3U << 6)
+#define STM32_MDMA_CCR_PL(n) ((n) << 6)
+#define STM32_MDMA_CCR_BEX (1U << 12)
+#define STM32_MDMA_CCR_HEX (1U << 13)
+#define STM32_MDMA_CCR_WEX (1U << 14)
+#define STM32_MDMA_CCR_SWRQ (1U << 16)
+/** @} */
+
+/**
+ * @name CTCR register constants
+ * @{
+ */
+#define STM32_MDMA_CTCR_RESET_VALUE 0x00000000U
+
+#define STM32_MDMA_CTCR_SINC_MASK (3U << 0)
+#define STM32_MDMA_CTCR_SINC(n) ((n) << 0)
+#define STM32_MDMA_CTCR_SINC_FIXED STM32_MDMA_CTCR_SINC(0U)
+#define STM32_MDMA_CTCR_SINC_INC STM32_MDMA_CTCR_SINC(2U)
+#define STM32_MDMA_CTCR_SINC_DEC STM32_MDMA_CTCR_SINC(3U)
+
+#define STM32_MDMA_CTCR_DINC_MASK (3U << 2)
+#define STM32_MDMA_CTCR_DINC(n) ((n) << 2)
+#define STM32_MDMA_CTCR_DINC_FIXED STM32_MDMA_CTCR_DINC(0U)
+#define STM32_MDMA_CTCR_DINC_INC STM32_MDMA_CTCR_DINC(2U)
+#define STM32_MDMA_CTCR_DINC_DEC STM32_MDMA_CTCR_DINC(3U)
+
+#define STM32_MDMA_CTCR_SSIZE_MASK (3U << 4)
+#define STM32_MDMA_CTCR_SSIZE(n) ((n) << 4)
+#define STM32_MDMA_CTCR_SSIZE_BYTE STM32_MDMA_CTCR_SSIZE(0U)
+#define STM32_MDMA_CTCR_SSIZE_HALF STM32_MDMA_CTCR_SSIZE(1U)
+#define STM32_MDMA_CTCR_SSIZE_WORD STM32_MDMA_CTCR_SSIZE(2U)
+#define STM32_MDMA_CTCR_SSIZE_DWORD STM32_MDMA_CTCR_SSIZE(3U)
+
+#define STM32_MDMA_CTCR_DSIZE_MASK (3U << 6)
+#define STM32_MDMA_CTCR_DSIZE(n) ((n) << 6)
+#define STM32_MDMA_CTCR_DSIZE_BYTE STM32_MDMA_CTCR_DSIZE(0U)
+#define STM32_MDMA_CTCR_DSIZE_HALF STM32_MDMA_CTCR_DSIZE(1U)
+#define STM32_MDMA_CTCR_DSIZE_WORD STM32_MDMA_CTCR_DSIZE(2U)
+#define STM32_MDMA_CTCR_DSIZE_DWORD STM32_MDMA_CTCR_DSIZE(3U)
+
+#define STM32_MDMA_CTCR_SINCOS_MASK (3U << 8)
+#define STM32_MDMA_CTCR_SINCOS(n) ((n) << 8)
+#define STM32_MDMA_CTCR_SINCOS_BYTE STM32_MDMA_CTCR_SINCOS(0U)
+#define STM32_MDMA_CTCR_SINCOS_HALF STM32_MDMA_CTCR_SINCOS(1U)
+#define STM32_MDMA_CTCR_SINCOS_WORD STM32_MDMA_CTCR_SINCOS(2U)
+#define STM32_MDMA_CTCR_SINCOS_DWORD STM32_MDMA_CTCR_SINCOS(3U)
+
+#define STM32_MDMA_CTCR_DINCOS_MASK (3U << 10)
+#define STM32_MDMA_CTCR_DINCOS(n) ((n) << 10)
+#define STM32_MDMA_CTCR_DINCOS_BYTE STM32_MDMA_CTCR_DINCOS(0U)
+#define STM32_MDMA_CTCR_DINCOS_HALF STM32_MDMA_CTCR_DINCOS(1U)
+#define STM32_MDMA_CTCR_DINCOS_WORD STM32_MDMA_CTCR_DINCOS(2U)
+#define STM32_MDMA_CTCR_DINCOS_DWORD STM32_MDMA_CTCR_DINCOS(3U)
+
+#define STM32_MDMA_CTCR_SBURST_MASK (7U << 12)
+#define STM32_MDMA_CTCR_SBURST(n) ((n) << 12)
+#define STM32_MDMA_CTCR_SBURST_1 STM32_MDMA_CTCR_SBURST(0U)
+#define STM32_MDMA_CTCR_SBURST_2 STM32_MDMA_CTCR_SBURST(1U)
+#define STM32_MDMA_CTCR_SBURST_4 STM32_MDMA_CTCR_SBURST(2U)
+#define STM32_MDMA_CTCR_SBURST_8 STM32_MDMA_CTCR_SBURST(3U)
+#define STM32_MDMA_CTCR_SBURST_16 STM32_MDMA_CTCR_SBURST(4U)
+#define STM32_MDMA_CTCR_SBURST_32 STM32_MDMA_CTCR_SBURST(5U)
+#define STM32_MDMA_CTCR_SBURST_64 STM32_MDMA_CTCR_SBURST(6U)
+#define STM32_MDMA_CTCR_SBURST_128 STM32_MDMA_CTCR_SBURST(7U)
+
+#define STM32_MDMA_CTCR_DBURST_MASK (7U << 15)
+#define STM32_MDMA_CTCR_DBURST(n) ((n) << 15)
+#define STM32_MDMA_CTCR_DBURST_1 STM32_MDMA_CTCR_DBURST(0U)
+#define STM32_MDMA_CTCR_DBURST_2 STM32_MDMA_CTCR_DBURST(1U)
+#define STM32_MDMA_CTCR_DBURST_4 STM32_MDMA_CTCR_DBURST(2U)
+#define STM32_MDMA_CTCR_DBURST_8 STM32_MDMA_CTCR_DBURST(3U)
+#define STM32_MDMA_CTCR_DBURST_16 STM32_MDMA_CTCR_DBURST(4U)
+#define STM32_MDMA_CTCR_DBURST_32 STM32_MDMA_CTCR_DBURST(5U)
+#define STM32_MDMA_CTCR_DBURST_64 STM32_MDMA_CTCR_DBURST(6U)
+#define STM32_MDMA_CTCR_DBURST_128 STM32_MDMA_CTCR_DBURST(7U)
+
+#define STM32_MDMA_CTCR_TLEN_MASK (127U << 18)
+#define STM32_MDMA_CTCR_TLEN(n) ((n) << 18)
+
+#define STM32_MDMA_CTCR_PKE (1U << 25)
+
+#define STM32_MDMA_CTCR_PAM_MASK (3U << 26)
+#define STM32_MDMA_CTCR_PAM(n) ((n) << 26)
+#define STM32_MDMA_CTCR_PAM_RIGHT STM32_MDMA_CTCR_PAM(0U)
+#define STM32_MDMA_CTCR_PAM_RIGHT_SE STM32_MDMA_CTCR_PAM(1U)
+#define STM32_MDMA_CTCR_PAM_LEFT STM32_MDMA_CTCR_PAM(2U)
+
+#define STM32_MDMA_CTCR_TRGM_MASK (3U << 28)
+#define STM32_MDMA_CTCR_TRGM(n) ((n) << 28)
+#define STM32_MDMA_CTCR_TRGM_BUFFER STM32_MDMA_CTCR_TRGM(0U)
+#define STM32_MDMA_CTCR_TRGM_BLOCK STM32_MDMA_CTCR_TRGM(1U)
+#define STM32_MDMA_CTCR_TRGM_REP_BLOCK STM32_MDMA_CTCR_TRGM(2U)
+#define STM32_MDMA_CTCR_TRGM_WHOLE STM32_MDMA_CTCR_TRGM(3U)
+
+#define STM32_MDMA_CTCR_SWRM (1U << 30)
+
+#define STM32_MDMA_CTCR_BWM_MASK (1U << 31)
+#define STM32_MDMA_CTCR_BWM_NON_BUFF (0U << 31)
+#define STM32_MDMA_CTCR_BWM_BUFF (1U << 31)
+/** @} */
+
+/**
+ * @name BNDTR register constants
+ * @{
+ */
+#define STM32_MDMA_CBNDTR_BNDT_MASK (0x1FFFFU << 0)
+#define STM32_MDMA_CBNDTR_BNDT(n) ((n) << 0)
+#define STM32_MDMA_CBNDTR_BRSUM (1U << 18)
+#define STM32_MDMA_CBNDTR_BRDUM (1U << 19)
+#define STM32_MDMA_CBNDTR_BRC_MASK (0xFFFU << 20)
+#define STM32_MDMA_CBNDTR_BRC(n) ((n) << 20)
+/** @} */
+
+/**
+ * @name CBRUR register constants
+ * @{
+ */
+#define STM32_MDMA_CBRUR_SUV_MASK (0xFFFFU << 0)
+#define STM32_MDMA_CBRUR_SUV(n) ((n) << 0)
+#define STM32_MDMA_CBRUR_DUV_MASK (0xFFFFU << 16)
+#define STM32_MDMA_CBRUR_DUV(n) ((n) << 16)
+/** @} */
+
+/**
+ * @name CTBR register constants
+ * @{
+ */
+#define STM32_MDMA_CTBR_TSEL_MASK (0x3FU << 0)
+#define STM32_MDMA_CTBR_TSEL(n) ((n) << 0)
+#define STM32_MDMA_CTBR_TSEL_SBUS (1U << 16)
+#define STM32_MDMA_CTBR_TSEL_DBUS (1U << 17)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_MDMA_HANDLER)
+#error "STM32_MDMA_HANDLER missing in registry"
+#endif
+
+#if !defined(STM32_MDMA_NUMBER)
+#error "STM32_MDMA_NUMBER missing in registry"
+#endif
+
+/* Priority settings checks.*/
+#if !defined(STM32_IRQ_MDMA_PRIORITY)
+#error "STM32_IRQ_MDMA_PRIORITY not defined in mcuconf.h"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_MDMA_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_MDMA_PRIORITY"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 MDMA ISR function type.
+ *
+ * @param[in] p parameter for the registered function
+ * @param[in] flags content of the CISR register
+ */
+typedef void (*stm32_mdmaisr_t)(void *p, uint32_t flags);
+
+/**
+ * @brief STM32 MDMA stream descriptor structure.
+ */
+typedef struct {
+ /**
+ * @brief Associated MDMA channel.
+ */
+ MDMA_Channel_TypeDef *channel;
+ /**
+ * @brief MDMA callback function.
+ */
+ stm32_mdmaisr_t func;
+ /**
+ * @brief MDMA callback parameter.
+ */
+ void *param;
+} stm32_mdma_channel_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Associates a source address to a MDMA stream.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ * @param[in] addr value to be written in the CSAR register
+ *
+ * @xclass
+ */
+#define mdmaChannelSetSourceX(mdmachp, addr) do { \
+ (mdmachp)->channel->CSAR = (uint32_t)(addr); \
+} while (0)
+
+/**
+ * @brief Associates a memory destination to a MDMA stream.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ * @param[in] addr value to be written in the CDAR register
+ *
+ * @xclass
+ */
+#define mdmaChannelSetDestinationX(mdmachp, addr) do { \
+ (mdmachp)->channel->CDAR = (uint32_t)(addr); \
+} while (0)
+
+/**
+ * @brief Sets parameters related to the transaction size.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ * @param[in] size number of bytes per block
+ * @param[in] n number of blocks repetitions
+ * @param[in] opt other option bits for the CBNDTR register
+ *
+ * @xclass
+ */
+#define mdmaChannelSetTransactionSizeX(mdmachp, size, n, opt) do { \
+ (mdmachp)->channel->CBNDTR = (uint32_t)STM32_MDMA_CBNDTR_BNDT(size) | \
+ (uint32_t)STM32_MDMA_CBNDTR_BRC(n) | \
+ (uint32_t)opt; \
+} while (0)
+
+/**
+ * @brief Programs the stream mode settings.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ * @param[in] ctcr value to be written in the CTCR register
+ * @param[in] ccr value to be written in the CCR register
+ *
+ * @xclass
+ */
+#define mdmaChannelSetModeX(mdmachp, ctcr, ccr) do { \
+ (mdmachp)->channel->CTCR = (uint32_t)(ctcr); \
+ (mdmachp)->channel->CCR = (uint32_t)(ccr); \
+} while (0)
+
+/**
+ * @brief Programs the trigger mode settings.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ * @param[in] tsel value to be written in the CTBR register
+ *
+ * @xclass
+ */
+#define mdmaChannelSetTrigModeX(mdmachp, tsel) do { \
+ (mdmachp)->channel->CTBR = STM32_MDMA_CTBR_TSEL(tsel); \
+} while (0)
+
+/**
+ * @brief MDMA stream enable.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ *
+ * @xclass
+ */
+#define mdmaChannelEnableX(mdmachp) do { \
+ (mdmachp)->channel->CCR |= STM32_MDMA_CCR_EN; \
+} while (0)
+
+/**
+ * @brief Channel enable check.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ */
+#define mdmaChannelIsEnabled(mdmachp) \
+ (((mdmachp)->channel->CCR & STM32_MDMA_CCR_EN) != 0U)
+
+/**
+ * @brief MDMA stream interrupt sources clear.
+ * @pre The stream must have been allocated using @p mdmaChannelAlloc().
+ * @post After use the stream can be released using @p mdmaChannelFree().
+ *
+ * @param[in] mdmachp pointer to a stm32_mdma_channel_t structure
+ *
+ * @xclass
+ */
+#define mdmaChannelClearInterruptX(mdmachp) do { \
+ (mdmachp)->channel->CIFCR = (STM32_MDMA_CIFCR_CTEIF | \
+ STM32_MDMA_CIFCR_CBRTIF | \
+ STM32_MDMA_CIFCR_CBRTIF | \
+ STM32_MDMA_CIFCR_CCTCIF | \
+ STM32_MDMA_CIFCR_CTEIF); \
+} while (0)
+
+/**
+ * @brief MDMA IRQ enable.
+ */
+#define mdma_irq_init() \
+ nvicEnableVector(STM32_MDMA_NUMBER, STM32_IRQ_MDMA_PRIORITY)
+
+/**
+ * @brief MDMA IRQ disable.
+ */
+#define mdma_irq_deinit() \
+ nvicDisableVector(STM32_MDMA_NUMBER)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void mdmaInit(void);
+ const stm32_mdma_channel_t *mdmaChannelAllocI(uint32_t id,
+ stm32_mdmaisr_t func,
+ void *param);
+ const stm32_mdma_channel_t *mdmaChannelAlloc(uint32_t id,
+ stm32_mdmaisr_t func,
+ void *param);
+ void mdmaChannelFreeI(const stm32_mdma_channel_t *mdmachp);
+ void mdmaChannelFree(const stm32_mdma_channel_t *mdmachp);
+ void mdmaChannelDisableX(const stm32_mdma_channel_t *mdmachp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_MDMA_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/OCTOSPIv1/driver.mk b/os/hal/ports/STM32/LLD/OCTOSPIv1/driver.mk
index 987220b5a4..527bf5469c 100644
--- a/os/hal/ports/STM32/LLD/OCTOSPIv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/OCTOSPIv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1
diff --git a/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c b/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
index 4b78488ddf..a91284ccb7 100644
--- a/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
+++ b/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.c
@@ -1,470 +1,470 @@
-/*
- 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 OCTOSPIv1/hal_wspi_lld.c
- * @brief STM32 WSPI subsystem low level driver source.
- *
- * @addtogroup WSPI
- * @{
- */
-
-#include "hal.h"
-
-#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* Workarounds for bugs in ST headers.*/
-#if !defined(OCTOSPI_FCR_CTOF) && defined(OCTOSPI_FCR_TOF)
-#define OCTOSPI_FCR_CTOF OCTOSPI_FCR_TOF
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief OCTOSPI1 driver identifier.*/
-#if STM32_WSPI_USE_OCTOSPI1 || defined(__DOXYGEN__)
-WSPIDriver WSPID1;
-#endif
-
-/** @brief OCTOSPI2 driver identifier.*/
-#if STM32_WSPI_USE_OCTOSPI2 || defined(__DOXYGEN__)
-WSPIDriver WSPID2;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Waits for completion of previous operation.
- */
-static inline void wspi_lld_sync(WSPIDriver *wspip) {
-
- while ((wspip->ospi->SR & OCTOSPI_SR_BUSY) != 0U) {
- }
-}
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void wspi_lld_serve_dma_interrupt(WSPIDriver *wspip, uint32_t flags) {
-
- (void)wspip;
- (void)flags;
-
- /* DMA errors handling.*/
-#if defined(STM32_WSPI_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_WSPI_DMA_ERROR_HOOK(wspip);
- }
-#endif
-}
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- */
-static void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
-
- /* Portable WSPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _wspi_isr_code(wspip);
-
- /* Stop everything, we need to give DMA enough time to complete the ongoing
- operation. Race condition hidden here.*/
- while (dmaStreamGetTransactionSize(wspip->dma) > 0U)
- ;
- dmaStreamDisable(wspip->dma);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_WSPI_USE_OCTOSPI1 || defined(__DOXYGEN__)
-#if !defined(STM32_OCTOSPI1_SUPPRESS_ISR)
-#if !defined(STM32_OCTOSPI1_HANDLER)
-#error "STM32_OCTOSPI1_HANDLER not defined"
-#endif
-/**
- * @brief STM32_OCTOSPI1_HANDLER interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_OCTOSPI1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- OCTOSPI1->FCR = OCTOSPI_FCR_CTEF | OCTOSPI_FCR_CTCF |
- OCTOSPI_FCR_CSMF | OCTOSPI_FCR_CTOF;
-
- wspi_lld_serve_interrupt(&WSPID1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_OCTOSPI1_SUPPRESS_ISR) */
-#endif /* STM32_WSPI_USE_OCTOSPI1 */
-
-#if STM32_WSPI_USE_OCTOSPI2 || defined(__DOXYGEN__)
-#if !defined(STM32_OCTOSPI2_SUPPRESS_ISR)
-#if !defined(STM32_OCTOSPI2_HANDLER)
-#error "STM32_OCTOSPI2_HANDLER not defined"
-#endif
-/**
- * @brief STM32_OCTOSPI2_HANDLER interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_OCTOSPI2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- OCTOSPI2->FCR = OCTOSPI_FCR_CTEF | OCTOSPI_FCR_CTCF |
- OCTOSPI_FCR_CSMF | OCTOSPI_FCR_CTOF;
-
- wspi_lld_serve_interrupt(&WSPID2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_OCTOSPI2_SUPPRESS_ISR) */
-#endif /* STM32_WSPI_USE_OCTOSPI2 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level WSPI driver initialization.
- *
- * @notapi
- */
-void wspi_lld_init(void) {
-
-#if STM32_WSPI_USE_OCTOSPI1
- wspiObjectInit(&WSPID1);
- WSPID1.ospi = OCTOSPI1;
- WSPID1.dma = NULL;
- WSPID1.dmamode = STM32_DMA_CR_CHSEL(OCTOSPI1_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_WSPI_OCTOSPI1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_BYTE |
- STM32_DMA_CR_MSIZE_BYTE |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- nvicEnableVector(STM32_OCTOSPI1_NUMBER, STM32_WSPI_OCTOSPI1_IRQ_PRIORITY);
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2
- wspiObjectInit(&WSPID2);
- WSPID2.ospi = OCTOSPI2;
- WSPID2.dma = NULL;
- WSPID2.dmamode = STM32_DMA_CR_CHSEL(OCTOSPI2_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_WSPI_OCTOSPI2_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_BYTE |
- STM32_DMA_CR_MSIZE_BYTE |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- nvicEnableVector(STM32_OCTOSPI2_NUMBER, STM32_WSPI_OCTOSPI2_IRQ_PRIORITY);
-#endif
-}
-
-/**
- * @brief Configures and activates the WSPI peripheral.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_start(WSPIDriver *wspip) {
-
- /* If in stopped state then full initialization.*/
- if (wspip->state == WSPI_STOP) {
-#if STM32_WSPI_USE_OCTOSPI1
- if (&WSPID1 == wspip) {
- wspip->dma = dmaStreamAllocI(STM32_WSPI_OCTOSPI1_DMA_STREAM,
- STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)wspi_lld_serve_dma_interrupt,
- (void *)wspip);
- osalDbgAssert(wspip->dma != NULL, "unable to allocate stream");
- rccEnableOCTOSPI1(true);
- dmaSetRequestSource(wspip->dma, STM32_DMAMUX1_OCTOSPI1);
- }
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2
- if (&WSPID2 == wspip) {
- wspip->dma = dmaStreamAllocI(STM32_WSPI_OCTOSPI2_DMA_STREAM,
- STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)wspi_lld_serve_dma_interrupt,
- (void *)wspip);
- osalDbgAssert(wspip->dma != NULL, "unable to allocate stream");
- rccEnableOCTOSPI2(true);
- dmaSetRequestSource(wspip->dma, STM32_DMAMUX1_OCTOSPI2);
- }
-#endif
-
- /* Common initializations.*/
- dmaStreamSetPeripheral(wspip->dma, &wspip->ospi->DR);
- }
-
- /* WSPI setup and enable.*/
- wspip->ospi->DCR1 = wspip->config->dcr1;
- wspip->ospi->DCR2 = wspip->config->dcr2 |
- STM32_DCR2_PRESCALER(STM32_WSPI_OCTOSPI1_PRESCALER_VALUE - 1U);
- wspip->ospi->DCR3 = wspip->config->dcr3;
- wspip->ospi->CR = OCTOSPI_CR_TCIE | OCTOSPI_CR_DMAEN | OCTOSPI_CR_EN;
- wspip->ospi->FCR = OCTOSPI_FCR_CTEF | OCTOSPI_FCR_CTCF |
- OCTOSPI_FCR_CSMF | OCTOSPI_FCR_CTOF;
-}
-
-/**
- * @brief Deactivates the WSPI peripheral.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_stop(WSPIDriver *wspip) {
-
- /* Waiting for the previous operation to complete, if any.*/
- wspi_lld_sync(wspip);
-
- /* If in ready state then disables the OCTOSPI clock.*/
- if (wspip->state == WSPI_READY) {
-
- /* WSPI disable.*/
- wspip->ospi->CR = 0U;
-
- /* Releasing the DMA.*/
- dmaStreamFreeI(wspip->dma);
- wspip->dma = NULL;
-
- /* Stopping involved clocks.*/
-#if STM32_WSPI_USE_OCTOSPI1
- if (&WSPID1 == wspip) {
- rccDisableOCTOSPI1();
- }
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2
- if (&WSPID2 == wspip) {
- rccDisableOCTOSPI2();
- }
-#endif
- }
-}
-
-/**
- * @brief Sends a command without data phase.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- *
- * @notapi
- */
-void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) {
-
-#if 0 //STM32_USE_STM32_D1_WORKAROUND == TRUE
- /* If it is a command without address and alternate phases then the command
- is sent as an alternate byte, the command phase is suppressed.*/
- if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) {
- /* The command mode field is copied in the alternate mode field. All
- other fields are not used in this scenario.*/
- wspip->ospi->DLR = 0U;
- wspip->ospi->ABR = cmdp->cmd;
- wspip->ospi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U;
- return;
- }
-#endif
- wspip->ospi->CR &= ~OCTOSPI_CR_FMODE;
- wspip->ospi->DLR = 0U;
- wspip->ospi->TCR = cmdp->dummy;
- wspip->ospi->CCR = cmdp->cfg;
- wspip->ospi->ABR = cmdp->alt;
- wspip->ospi->IR = cmdp->cmd;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->ospi->AR = cmdp->addr;
- }
-
- /* Waiting for the previous operation to complete.*/
- wspi_lld_sync(wspip);
-}
-
-/**
- * @brief Sends a command with data over the WSPI bus.
- * @post At the end of the operation the configured callback is invoked.
- * @note If using DTR in 8 lines mode then the following restrictions
- * apply:
- * - Command size must be 0, 2 or 4 bytes.
- * - Address must be even.
- * - Alternate bytes size must be 0, 2 or 4 bytes.
- * - Data size must be a multiple of two.
- * .
- * There is no check on the above conditions in order to keep the
- * code efficient.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[in] n number of bytes to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, const uint8_t *txbuf) {
-
- dmaStreamSetMemory0(wspip->dma, txbuf);
- dmaStreamSetTransactionSize(wspip->dma, n);
- dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_M2P);
-
- wspip->ospi->CR &= ~OCTOSPI_CR_FMODE;
- wspip->ospi->DLR = n - 1U;
- wspip->ospi->TCR = cmdp->dummy;
- wspip->ospi->CCR = cmdp->cfg;
- wspip->ospi->ABR = cmdp->alt;
- wspip->ospi->IR = cmdp->cmd;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->ospi->AR = cmdp->addr;
- }
-
- dmaStreamEnable(wspip->dma);
-}
-
-/**
- * @brief Sends a command then receives data over the WSPI bus.
- * @post At the end of the operation the configured callback is invoked.
- * @note If using DTR in 8 lines mode then the following restrictions
- * apply:
- * - Command size must be 0, 2 or 4 bytes.
- * - Address must be even.
- * - Alternate bytes size must be 0, 2 or 4 bytes.
- * - Data size must be a multiple of two.
- * .
- * There is no check on the above conditions in order to keep the
- * code efficient.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[in] n number of bytes to send
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, uint8_t *rxbuf) {
-
- dmaStreamSetMemory0(wspip->dma, rxbuf);
- dmaStreamSetTransactionSize(wspip->dma, n);
- dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_P2M);
-
- wspip->ospi->CR = (wspip->ospi->CR & ~OCTOSPI_CR_FMODE) | OCTOSPI_CR_FMODE_0;
- wspip->ospi->DLR = n - 1U;
- wspip->ospi->TCR = cmdp->dummy;
- wspip->ospi->CCR = cmdp->cfg;
- wspip->ospi->ABR = cmdp->alt;
- wspip->ospi->IR = cmdp->cmd;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->ospi->AR = cmdp->addr;
- }
-
- dmaStreamEnable(wspip->dma);
-}
-
-#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Maps in memory space a WSPI flash device.
- * @pre The memory flash device must be initialized appropriately
- * before mapping it in memory space.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[out] addrp pointer to the memory start address of the mapped
- * flash or @p NULL
- *
- * @notapi
- */
-void wspi_lld_map_flash(WSPIDriver *wspip,
- const wspi_command_t *cmdp,
- uint8_t **addrp) {
-
- /* Starting memory mapped mode using the passed parameters.*/
- wspip->ospi->CR = OCTOSPI_CR_FMODE_1 | OCTOSPI_CR_FMODE_0 | OCTOSPI_CR_EN;
- wspip->ospi->TCR = cmdp->dummy;
- wspip->ospi->CCR = cmdp->cfg;
- wspip->ospi->IR = cmdp->cmd;
- wspip->ospi->ABR = 0U;
- wspip->ospi->AR = 0U;
- wspip->ospi->WTCR = 0U;
- wspip->ospi->WCCR = 0U;
- wspip->ospi->WIR = 0U;
- wspip->ospi->WABR = 0U;
-
- /* Mapped flash absolute base address.*/
-#if STM32_WSPI_USE_OCTOSPI1
- if (&WSPID1 == wspip) {
- if (addrp != NULL) {
- *addrp = (uint8_t *)0x90000000U;
- }
- }
-#endif
-#if STM32_WSPI_USE_OCTOSPI2
- if (&WSPID2 == wspip) {
- if (addrp != NULL) {
- *addrp = (uint8_t *)0x70000000U;
- }
- }
-#endif
-}
-
-/**
- * @brief Unmaps from memory space a WSPI flash device.
- * @post The memory flash device must be re-initialized for normal
- * commands exchange.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_unmap_flash(WSPIDriver *wspip) {
-
- /* Aborting memory mapped mode.*/
- wspip->ospi->CR |= OCTOSPI_CR_ABORT;
- while ((wspip->ospi->CR & OCTOSPI_CR_ABORT) != 0U) {
- }
-
- /* Disabling memory mapped mode and re-enabling DMA and IRQs.*/
- wspip->ospi->CR = OCTOSPI_CR_TCIE | OCTOSPI_CR_DMAEN | OCTOSPI_CR_EN;
-}
-#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
-
-#endif /* HAL_USE_WSPI */
-
-/** @} */
+/*
+ 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 OCTOSPIv1/hal_wspi_lld.c
+ * @brief STM32 WSPI subsystem low level driver source.
+ *
+ * @addtogroup WSPI
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* Workarounds for bugs in ST headers.*/
+#if !defined(OCTOSPI_FCR_CTOF) && defined(OCTOSPI_FCR_TOF)
+#define OCTOSPI_FCR_CTOF OCTOSPI_FCR_TOF
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief OCTOSPI1 driver identifier.*/
+#if STM32_WSPI_USE_OCTOSPI1 || defined(__DOXYGEN__)
+WSPIDriver WSPID1;
+#endif
+
+/** @brief OCTOSPI2 driver identifier.*/
+#if STM32_WSPI_USE_OCTOSPI2 || defined(__DOXYGEN__)
+WSPIDriver WSPID2;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Waits for completion of previous operation.
+ */
+static inline void wspi_lld_sync(WSPIDriver *wspip) {
+
+ while ((wspip->ospi->SR & OCTOSPI_SR_BUSY) != 0U) {
+ }
+}
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void wspi_lld_serve_dma_interrupt(WSPIDriver *wspip, uint32_t flags) {
+
+ (void)wspip;
+ (void)flags;
+
+ /* DMA errors handling.*/
+#if defined(STM32_WSPI_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_WSPI_DMA_ERROR_HOOK(wspip);
+ }
+#endif
+}
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ */
+static void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
+
+ /* Portable WSPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _wspi_isr_code(wspip);
+
+ /* Stop everything, we need to give DMA enough time to complete the ongoing
+ operation. Race condition hidden here.*/
+ while (dmaStreamGetTransactionSize(wspip->dma) > 0U)
+ ;
+ dmaStreamDisable(wspip->dma);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_WSPI_USE_OCTOSPI1 || defined(__DOXYGEN__)
+#if !defined(STM32_OCTOSPI1_SUPPRESS_ISR)
+#if !defined(STM32_OCTOSPI1_HANDLER)
+#error "STM32_OCTOSPI1_HANDLER not defined"
+#endif
+/**
+ * @brief STM32_OCTOSPI1_HANDLER interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_OCTOSPI1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ OCTOSPI1->FCR = OCTOSPI_FCR_CTEF | OCTOSPI_FCR_CTCF |
+ OCTOSPI_FCR_CSMF | OCTOSPI_FCR_CTOF;
+
+ wspi_lld_serve_interrupt(&WSPID1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_OCTOSPI1_SUPPRESS_ISR) */
+#endif /* STM32_WSPI_USE_OCTOSPI1 */
+
+#if STM32_WSPI_USE_OCTOSPI2 || defined(__DOXYGEN__)
+#if !defined(STM32_OCTOSPI2_SUPPRESS_ISR)
+#if !defined(STM32_OCTOSPI2_HANDLER)
+#error "STM32_OCTOSPI2_HANDLER not defined"
+#endif
+/**
+ * @brief STM32_OCTOSPI2_HANDLER interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_OCTOSPI2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ OCTOSPI2->FCR = OCTOSPI_FCR_CTEF | OCTOSPI_FCR_CTCF |
+ OCTOSPI_FCR_CSMF | OCTOSPI_FCR_CTOF;
+
+ wspi_lld_serve_interrupt(&WSPID2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_OCTOSPI2_SUPPRESS_ISR) */
+#endif /* STM32_WSPI_USE_OCTOSPI2 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level WSPI driver initialization.
+ *
+ * @notapi
+ */
+void wspi_lld_init(void) {
+
+#if STM32_WSPI_USE_OCTOSPI1
+ wspiObjectInit(&WSPID1);
+ WSPID1.ospi = OCTOSPI1;
+ WSPID1.dma = NULL;
+ WSPID1.dmamode = STM32_DMA_CR_CHSEL(OCTOSPI1_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_WSPI_OCTOSPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_BYTE |
+ STM32_DMA_CR_MSIZE_BYTE |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ nvicEnableVector(STM32_OCTOSPI1_NUMBER, STM32_WSPI_OCTOSPI1_IRQ_PRIORITY);
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2
+ wspiObjectInit(&WSPID2);
+ WSPID2.ospi = OCTOSPI2;
+ WSPID2.dma = NULL;
+ WSPID2.dmamode = STM32_DMA_CR_CHSEL(OCTOSPI2_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_WSPI_OCTOSPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_BYTE |
+ STM32_DMA_CR_MSIZE_BYTE |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ nvicEnableVector(STM32_OCTOSPI2_NUMBER, STM32_WSPI_OCTOSPI2_IRQ_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Configures and activates the WSPI peripheral.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_start(WSPIDriver *wspip) {
+
+ /* If in stopped state then full initialization.*/
+ if (wspip->state == WSPI_STOP) {
+#if STM32_WSPI_USE_OCTOSPI1
+ if (&WSPID1 == wspip) {
+ wspip->dma = dmaStreamAllocI(STM32_WSPI_OCTOSPI1_DMA_STREAM,
+ STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)wspi_lld_serve_dma_interrupt,
+ (void *)wspip);
+ osalDbgAssert(wspip->dma != NULL, "unable to allocate stream");
+ rccEnableOCTOSPI1(true);
+ dmaSetRequestSource(wspip->dma, STM32_DMAMUX1_OCTOSPI1);
+ }
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2
+ if (&WSPID2 == wspip) {
+ wspip->dma = dmaStreamAllocI(STM32_WSPI_OCTOSPI2_DMA_STREAM,
+ STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)wspi_lld_serve_dma_interrupt,
+ (void *)wspip);
+ osalDbgAssert(wspip->dma != NULL, "unable to allocate stream");
+ rccEnableOCTOSPI2(true);
+ dmaSetRequestSource(wspip->dma, STM32_DMAMUX1_OCTOSPI2);
+ }
+#endif
+
+ /* Common initializations.*/
+ dmaStreamSetPeripheral(wspip->dma, &wspip->ospi->DR);
+ }
+
+ /* WSPI setup and enable.*/
+ wspip->ospi->DCR1 = wspip->config->dcr1;
+ wspip->ospi->DCR2 = wspip->config->dcr2 |
+ STM32_DCR2_PRESCALER(STM32_WSPI_OCTOSPI1_PRESCALER_VALUE - 1U);
+ wspip->ospi->DCR3 = wspip->config->dcr3;
+ wspip->ospi->CR = OCTOSPI_CR_TCIE | OCTOSPI_CR_DMAEN | OCTOSPI_CR_EN;
+ wspip->ospi->FCR = OCTOSPI_FCR_CTEF | OCTOSPI_FCR_CTCF |
+ OCTOSPI_FCR_CSMF | OCTOSPI_FCR_CTOF;
+}
+
+/**
+ * @brief Deactivates the WSPI peripheral.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_stop(WSPIDriver *wspip) {
+
+ /* Waiting for the previous operation to complete, if any.*/
+ wspi_lld_sync(wspip);
+
+ /* If in ready state then disables the OCTOSPI clock.*/
+ if (wspip->state == WSPI_READY) {
+
+ /* WSPI disable.*/
+ wspip->ospi->CR = 0U;
+
+ /* Releasing the DMA.*/
+ dmaStreamFreeI(wspip->dma);
+ wspip->dma = NULL;
+
+ /* Stopping involved clocks.*/
+#if STM32_WSPI_USE_OCTOSPI1
+ if (&WSPID1 == wspip) {
+ rccDisableOCTOSPI1();
+ }
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2
+ if (&WSPID2 == wspip) {
+ rccDisableOCTOSPI2();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Sends a command without data phase.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ *
+ * @notapi
+ */
+void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) {
+
+#if 0 //STM32_USE_STM32_D1_WORKAROUND == TRUE
+ /* If it is a command without address and alternate phases then the command
+ is sent as an alternate byte, the command phase is suppressed.*/
+ if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) {
+ /* The command mode field is copied in the alternate mode field. All
+ other fields are not used in this scenario.*/
+ wspip->ospi->DLR = 0U;
+ wspip->ospi->ABR = cmdp->cmd;
+ wspip->ospi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U;
+ return;
+ }
+#endif
+ wspip->ospi->CR &= ~OCTOSPI_CR_FMODE;
+ wspip->ospi->DLR = 0U;
+ wspip->ospi->TCR = cmdp->dummy;
+ wspip->ospi->CCR = cmdp->cfg;
+ wspip->ospi->ABR = cmdp->alt;
+ wspip->ospi->IR = cmdp->cmd;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->ospi->AR = cmdp->addr;
+ }
+
+ /* Waiting for the previous operation to complete.*/
+ wspi_lld_sync(wspip);
+}
+
+/**
+ * @brief Sends a command with data over the WSPI bus.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note If using DTR in 8 lines mode then the following restrictions
+ * apply:
+ * - Command size must be 0, 2 or 4 bytes.
+ * - Address must be even.
+ * - Alternate bytes size must be 0, 2 or 4 bytes.
+ * - Data size must be a multiple of two.
+ * .
+ * There is no check on the above conditions in order to keep the
+ * code efficient.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[in] n number of bytes to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, const uint8_t *txbuf) {
+
+ dmaStreamSetMemory0(wspip->dma, txbuf);
+ dmaStreamSetTransactionSize(wspip->dma, n);
+ dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_M2P);
+
+ wspip->ospi->CR &= ~OCTOSPI_CR_FMODE;
+ wspip->ospi->DLR = n - 1U;
+ wspip->ospi->TCR = cmdp->dummy;
+ wspip->ospi->CCR = cmdp->cfg;
+ wspip->ospi->ABR = cmdp->alt;
+ wspip->ospi->IR = cmdp->cmd;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->ospi->AR = cmdp->addr;
+ }
+
+ dmaStreamEnable(wspip->dma);
+}
+
+/**
+ * @brief Sends a command then receives data over the WSPI bus.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note If using DTR in 8 lines mode then the following restrictions
+ * apply:
+ * - Command size must be 0, 2 or 4 bytes.
+ * - Address must be even.
+ * - Alternate bytes size must be 0, 2 or 4 bytes.
+ * - Data size must be a multiple of two.
+ * .
+ * There is no check on the above conditions in order to keep the
+ * code efficient.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[in] n number of bytes to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, uint8_t *rxbuf) {
+
+ dmaStreamSetMemory0(wspip->dma, rxbuf);
+ dmaStreamSetTransactionSize(wspip->dma, n);
+ dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_P2M);
+
+ wspip->ospi->CR = (wspip->ospi->CR & ~OCTOSPI_CR_FMODE) | OCTOSPI_CR_FMODE_0;
+ wspip->ospi->DLR = n - 1U;
+ wspip->ospi->TCR = cmdp->dummy;
+ wspip->ospi->CCR = cmdp->cfg;
+ wspip->ospi->ABR = cmdp->alt;
+ wspip->ospi->IR = cmdp->cmd;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->ospi->AR = cmdp->addr;
+ }
+
+ dmaStreamEnable(wspip->dma);
+}
+
+#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Maps in memory space a WSPI flash device.
+ * @pre The memory flash device must be initialized appropriately
+ * before mapping it in memory space.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[out] addrp pointer to the memory start address of the mapped
+ * flash or @p NULL
+ *
+ * @notapi
+ */
+void wspi_lld_map_flash(WSPIDriver *wspip,
+ const wspi_command_t *cmdp,
+ uint8_t **addrp) {
+
+ /* Starting memory mapped mode using the passed parameters.*/
+ wspip->ospi->CR = OCTOSPI_CR_FMODE_1 | OCTOSPI_CR_FMODE_0 | OCTOSPI_CR_EN;
+ wspip->ospi->TCR = cmdp->dummy;
+ wspip->ospi->CCR = cmdp->cfg;
+ wspip->ospi->IR = cmdp->cmd;
+ wspip->ospi->ABR = 0U;
+ wspip->ospi->AR = 0U;
+ wspip->ospi->WTCR = 0U;
+ wspip->ospi->WCCR = 0U;
+ wspip->ospi->WIR = 0U;
+ wspip->ospi->WABR = 0U;
+
+ /* Mapped flash absolute base address.*/
+#if STM32_WSPI_USE_OCTOSPI1
+ if (&WSPID1 == wspip) {
+ if (addrp != NULL) {
+ *addrp = (uint8_t *)0x90000000U;
+ }
+ }
+#endif
+#if STM32_WSPI_USE_OCTOSPI2
+ if (&WSPID2 == wspip) {
+ if (addrp != NULL) {
+ *addrp = (uint8_t *)0x70000000U;
+ }
+ }
+#endif
+}
+
+/**
+ * @brief Unmaps from memory space a WSPI flash device.
+ * @post The memory flash device must be re-initialized for normal
+ * commands exchange.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_unmap_flash(WSPIDriver *wspip) {
+
+ /* Aborting memory mapped mode.*/
+ wspip->ospi->CR |= OCTOSPI_CR_ABORT;
+ while ((wspip->ospi->CR & OCTOSPI_CR_ABORT) != 0U) {
+ }
+
+ /* Disabling memory mapped mode and re-enabling DMA and IRQs.*/
+ wspip->ospi->CR = OCTOSPI_CR_TCIE | OCTOSPI_CR_DMAEN | OCTOSPI_CR_EN;
+}
+#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
+
+#endif /* HAL_USE_WSPI */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.h b/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.h
index 8d990814f6..e91c88ea9a 100644
--- a/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.h
+++ b/os/hal/ports/STM32/LLD/OCTOSPIv1/hal_wspi_lld.h
@@ -1,339 +1,339 @@
-/*
- 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 OCTOSPIv1/hal_wspi_lld.h
- * @brief STM32 WSPI subsystem low level driver header.
- *
- * @addtogroup WSPI
- * @{
- */
-
-#ifndef HAL_WSPI_LLD_H
-#define HAL_WSPI_LLD_H
-
-#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name WSPI implementation capabilities
- * @{
- */
-#define WSPI_SUPPORTS_MEMMAP TRUE
-#define WSPI_DEFAULT_CFG_MASKS TRUE
-/** @} */
-
-/**
- * @name DCR1 register options
- * @{
- */
-#define STM32_DCR1_CK_MODE (1U << 0U)
-#define STM32_DCR1_FRCK_MODE (1U << 1U)
-#define STM32_DCR1_CSHT_MASK (7U << 8U)
-#define STM32_DCR1_CSHT(n) ((n) << 8U)
-#define STM32_DCR1_DEVSIZE_MASK (31U << 16U)
-#define STM32_DCR1_DEVSIZE(n) ((n) << 16U)
-#define STM32_DCR1_MTYP_MASK (7U << 16U)
-#define STM32_DCR1_MTYP(n) ((n) << 24U)
-/** @} */
-
-/**
- * @name DCR2 register options
- * @{
- */
-#define STM32_DCR2_PRESCALER_MASK (255U << 0U)
-#define STM32_DCR2_PRESCALER(n) ((n) << 0U)
-#define STM32_DCR2_WRAPSIZE_MASK (7U << 16U)
-#define STM32_DCR2_WRAPSIZE(n) ((n) << 16U)
-
-/**
- * @name DCR3 register options
- * @{
- */
-#define STM32_DCR3_MAXTRAN_MASK (255U << 0U)
-#define STM32_DCR3_MAXTRAN(n) ((n) << 0U)
-#define STM32_DCR3_CSBOUND_MASK (7U << 16U)
-#define STM32_DCR3_CSBOUND(n) ((n) << 16U)
-
-/**
- * @name DCR4 register options
- * @{
- */
-#define STM32_DCR4_REFRESH_MASK (255U << 0U)
-#define STM32_DCR4_REFRESH(n) ((n) << 0U)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief WSPID1 driver enable switch.
- * @details If set to @p TRUE the support for OCTOSPI1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_WSPI_USE_OCTOSPI1) || defined(__DOXYGEN__)
-#define STM32_WSPI_USE_OCTOSPI1 FALSE
-#endif
-
-/**
- * @brief WSPID2 driver enable switch.
- * @details If set to @p TRUE the support for OCTOSPI2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_WSPI_USE_OCTOSPI2) || defined(__DOXYGEN__)
-#define STM32_WSPI_USE_OCTOSPI2 FALSE
-#endif
-
-/**
- * @brief OCTOSPI1 prescaler setting.
- * @note This is the prescaler divider value 1..256. The maximum frequency
- * varies depending on the STM32 model and operating conditions,
- * find the details in the data sheet.
- */
-#if !defined(STM32_WSPI_OCTOSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI1_PRESCALER_VALUE 1
-#endif
-
-/**
- * @brief OCTOSPI2 prescaler setting.
- * @note This is the prescaler divider value 1..256. The maximum frequency
- * varies depending on the STM32 model and operating conditions,
- * find the details in the data sheet.
- */
-#if !defined(STM32_WSPI_OCTOSPI2_PRESCALER_VALUE) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI2_PRESCALER_VALUE 1
-#endif
-
-/**
- * @brief OCTOSPI1 interrupt priority level setting.
- */
-#if !defined(STM32_WSPI_OCTOSPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief OCTOSPI2 interrupt priority level setting.
- */
-#if !defined(STM32_WSPI_OCTOSPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief OCTOSPI1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_WSPI_OCTOSPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief OCTOSPI2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_WSPI_OCTOSPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief OCTOSPI1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief OCTOSPI2 DMA interrupt priority level setting.
- */
-#if !defined(STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief OCTOSPI DMA error hook.
- */
-#if !defined(STM32_WSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_WSPI_DMA_ERROR_HOOK(wspip) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_OCTOSPI1)
-#define STM32_HAS_OCTOSPI1 FALSE
-#endif
-
-#if !defined(STM32_HAS_OCTOSPI2)
-#define STM32_HAS_OCTOSPI2 FALSE
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI1 && !STM32_HAS_OCTOSPI1
-#error "OCTOSPI1 not present in the selected device"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2 && !STM32_HAS_OCTOSPI2
-#error "OCTOSPI2 not present in the selected device"
-#endif
-
-#if !STM32_WSPI_USE_OCTOSPI1 && !STM32_WSPI_USE_OCTOSPI2
-#error "WSPI driver activated but no OCTOSPI peripheral assigned"
-#endif
-
-/* Check on OCTOSPI prescaler setting.*/
-#if (STM32_WSPI_OCTOSPI1_PRESCALER_VALUE < 1) || \
- (STM32_WSPI_OCTOSPI1_PRESCALER_VALUE > 256)
-#error "STM32_WSPI_OCTOSPI1_PRESCALER_VALUE not within 1..256"
-#endif
-
-#if (STM32_WSPI_OCTOSPI2_PRESCALER_VALUE < 1) || \
- (STM32_WSPI_OCTOSPI2_PRESCALER_VALUE > 256)
-#error "STM32_WSPI_OCTOSPI2_PRESCALER_VALUE not within 1..256"
-#endif
-
-/* Check on IRQ priorities.*/
-#if STM32_WSPI_USE_OCTOSPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to OCTOSPI1"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to OCTOSPI2"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to OCTOSPI1 DMA"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to OCTOSPI2 DMA"
-#endif
-
-/* Check on the presence of the DMA channels settings in mcuconf.h.*/
-#if STM32_WSPI_USE_OCTOSPI1 && !defined(STM32_WSPI_OCTOSPI1_DMA_STREAM)
-#error "OCTOSPI1 DMA stream not defined"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2 && !defined(STM32_WSPI_OCTOSPI2_DMA_STREAM)
-#error "OCTOSPI2 DMA stream not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_WSPI_USE_OCTOSPI1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_WSPI_OCTOSPI1_DMA_STREAM)
-#error "invalid DMA stream associated to OCTOSPI1"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_WSPI_OCTOSPI2_DMA_STREAM)
-#error "invalid DMA stream associated to OCTOSPI2"
-#endif
-
-/* Check on DMA channels priority.*/
-#if STM32_WSPI_USE_OCTOSPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to OCTOSPI1"
-#endif
-
-#if STM32_WSPI_USE_OCTOSPI2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to OCTOSPI2"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the WSPI configuration structure.
- */
-#define wspi_lld_config_fields \
- /* DCR1 register initialization data.*/ \
- uint32_t dcr1; \
- /* DCR2 register initialization data. The prescaler field is internally \
- ORed to this field, leave it to zero.*/ \
- uint32_t dcr2; \
- /* DCR3 register initialization data.*/ \
- uint32_t dcr3; \
- /* DCR4 register initialization data.*/ \
- uint32_t dcr4
-
-/**
- * @brief Low level fields of the WSPI driver structure.
- */
-#define wspi_lld_driver_fields \
- /* Pointer to the OCTOSPIx registers block.*/ \
- OCTOSPI_TypeDef *ospi; \
- /* OCTOSPI DMA stream.*/ \
- const stm32_dma_stream_t *dma; \
- /* OCTOSPI DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if (STM32_WSPI_USE_OCTOSPI1 == TRUE) && !defined(__DOXYGEN__)
-extern WSPIDriver WSPID1;
-#endif
-
-#if (STM32_WSPI_USE_OCTOSPI2 == TRUE) && !defined(__DOXYGEN__)
-extern WSPIDriver WSPID2;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void wspi_lld_init(void);
- void wspi_lld_start(WSPIDriver *wspip);
- void wspi_lld_stop(WSPIDriver *wspip);
- void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp);
- void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, const uint8_t *txbuf);
- void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, uint8_t *rxbuf);
-#if WSPI_SUPPORTS_MEMMAP == TRUE
- void wspi_lld_map_flash(WSPIDriver *wspip,
- const wspi_command_t *cmdp,
- uint8_t **addrp);
- void wspi_lld_unmap_flash(WSPIDriver *wspip);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_WSPI */
-
-#endif /* HAL_WSPI_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 OCTOSPIv1/hal_wspi_lld.h
+ * @brief STM32 WSPI subsystem low level driver header.
+ *
+ * @addtogroup WSPI
+ * @{
+ */
+
+#ifndef HAL_WSPI_LLD_H
+#define HAL_WSPI_LLD_H
+
+#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name WSPI implementation capabilities
+ * @{
+ */
+#define WSPI_SUPPORTS_MEMMAP TRUE
+#define WSPI_DEFAULT_CFG_MASKS TRUE
+/** @} */
+
+/**
+ * @name DCR1 register options
+ * @{
+ */
+#define STM32_DCR1_CK_MODE (1U << 0U)
+#define STM32_DCR1_FRCK_MODE (1U << 1U)
+#define STM32_DCR1_CSHT_MASK (7U << 8U)
+#define STM32_DCR1_CSHT(n) ((n) << 8U)
+#define STM32_DCR1_DEVSIZE_MASK (31U << 16U)
+#define STM32_DCR1_DEVSIZE(n) ((n) << 16U)
+#define STM32_DCR1_MTYP_MASK (7U << 16U)
+#define STM32_DCR1_MTYP(n) ((n) << 24U)
+/** @} */
+
+/**
+ * @name DCR2 register options
+ * @{
+ */
+#define STM32_DCR2_PRESCALER_MASK (255U << 0U)
+#define STM32_DCR2_PRESCALER(n) ((n) << 0U)
+#define STM32_DCR2_WRAPSIZE_MASK (7U << 16U)
+#define STM32_DCR2_WRAPSIZE(n) ((n) << 16U)
+
+/**
+ * @name DCR3 register options
+ * @{
+ */
+#define STM32_DCR3_MAXTRAN_MASK (255U << 0U)
+#define STM32_DCR3_MAXTRAN(n) ((n) << 0U)
+#define STM32_DCR3_CSBOUND_MASK (7U << 16U)
+#define STM32_DCR3_CSBOUND(n) ((n) << 16U)
+
+/**
+ * @name DCR4 register options
+ * @{
+ */
+#define STM32_DCR4_REFRESH_MASK (255U << 0U)
+#define STM32_DCR4_REFRESH(n) ((n) << 0U)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief WSPID1 driver enable switch.
+ * @details If set to @p TRUE the support for OCTOSPI1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_WSPI_USE_OCTOSPI1) || defined(__DOXYGEN__)
+#define STM32_WSPI_USE_OCTOSPI1 FALSE
+#endif
+
+/**
+ * @brief WSPID2 driver enable switch.
+ * @details If set to @p TRUE the support for OCTOSPI2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_WSPI_USE_OCTOSPI2) || defined(__DOXYGEN__)
+#define STM32_WSPI_USE_OCTOSPI2 FALSE
+#endif
+
+/**
+ * @brief OCTOSPI1 prescaler setting.
+ * @note This is the prescaler divider value 1..256. The maximum frequency
+ * varies depending on the STM32 model and operating conditions,
+ * find the details in the data sheet.
+ */
+#if !defined(STM32_WSPI_OCTOSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI1_PRESCALER_VALUE 1
+#endif
+
+/**
+ * @brief OCTOSPI2 prescaler setting.
+ * @note This is the prescaler divider value 1..256. The maximum frequency
+ * varies depending on the STM32 model and operating conditions,
+ * find the details in the data sheet.
+ */
+#if !defined(STM32_WSPI_OCTOSPI2_PRESCALER_VALUE) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI2_PRESCALER_VALUE 1
+#endif
+
+/**
+ * @brief OCTOSPI1 interrupt priority level setting.
+ */
+#if !defined(STM32_WSPI_OCTOSPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief OCTOSPI2 interrupt priority level setting.
+ */
+#if !defined(STM32_WSPI_OCTOSPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief OCTOSPI1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_WSPI_OCTOSPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief OCTOSPI2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_WSPI_OCTOSPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief OCTOSPI1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief OCTOSPI2 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief OCTOSPI DMA error hook.
+ */
+#if !defined(STM32_WSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_WSPI_DMA_ERROR_HOOK(wspip) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_OCTOSPI1)
+#define STM32_HAS_OCTOSPI1 FALSE
+#endif
+
+#if !defined(STM32_HAS_OCTOSPI2)
+#define STM32_HAS_OCTOSPI2 FALSE
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI1 && !STM32_HAS_OCTOSPI1
+#error "OCTOSPI1 not present in the selected device"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2 && !STM32_HAS_OCTOSPI2
+#error "OCTOSPI2 not present in the selected device"
+#endif
+
+#if !STM32_WSPI_USE_OCTOSPI1 && !STM32_WSPI_USE_OCTOSPI2
+#error "WSPI driver activated but no OCTOSPI peripheral assigned"
+#endif
+
+/* Check on OCTOSPI prescaler setting.*/
+#if (STM32_WSPI_OCTOSPI1_PRESCALER_VALUE < 1) || \
+ (STM32_WSPI_OCTOSPI1_PRESCALER_VALUE > 256)
+#error "STM32_WSPI_OCTOSPI1_PRESCALER_VALUE not within 1..256"
+#endif
+
+#if (STM32_WSPI_OCTOSPI2_PRESCALER_VALUE < 1) || \
+ (STM32_WSPI_OCTOSPI2_PRESCALER_VALUE > 256)
+#error "STM32_WSPI_OCTOSPI2_PRESCALER_VALUE not within 1..256"
+#endif
+
+/* Check on IRQ priorities.*/
+#if STM32_WSPI_USE_OCTOSPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to OCTOSPI1"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to OCTOSPI2"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to OCTOSPI1 DMA"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI2_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to OCTOSPI2 DMA"
+#endif
+
+/* Check on the presence of the DMA channels settings in mcuconf.h.*/
+#if STM32_WSPI_USE_OCTOSPI1 && !defined(STM32_WSPI_OCTOSPI1_DMA_STREAM)
+#error "OCTOSPI1 DMA stream not defined"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2 && !defined(STM32_WSPI_OCTOSPI2_DMA_STREAM)
+#error "OCTOSPI2 DMA stream not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_WSPI_USE_OCTOSPI1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_WSPI_OCTOSPI1_DMA_STREAM)
+#error "invalid DMA stream associated to OCTOSPI1"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_WSPI_OCTOSPI2_DMA_STREAM)
+#error "invalid DMA stream associated to OCTOSPI2"
+#endif
+
+/* Check on DMA channels priority.*/
+#if STM32_WSPI_USE_OCTOSPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to OCTOSPI1"
+#endif
+
+#if STM32_WSPI_USE_OCTOSPI2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_WSPI_OCTOSPI2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to OCTOSPI2"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the WSPI configuration structure.
+ */
+#define wspi_lld_config_fields \
+ /* DCR1 register initialization data.*/ \
+ uint32_t dcr1; \
+ /* DCR2 register initialization data. The prescaler field is internally \
+ ORed to this field, leave it to zero.*/ \
+ uint32_t dcr2; \
+ /* DCR3 register initialization data.*/ \
+ uint32_t dcr3; \
+ /* DCR4 register initialization data.*/ \
+ uint32_t dcr4
+
+/**
+ * @brief Low level fields of the WSPI driver structure.
+ */
+#define wspi_lld_driver_fields \
+ /* Pointer to the OCTOSPIx registers block.*/ \
+ OCTOSPI_TypeDef *ospi; \
+ /* OCTOSPI DMA stream.*/ \
+ const stm32_dma_stream_t *dma; \
+ /* OCTOSPI DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if (STM32_WSPI_USE_OCTOSPI1 == TRUE) && !defined(__DOXYGEN__)
+extern WSPIDriver WSPID1;
+#endif
+
+#if (STM32_WSPI_USE_OCTOSPI2 == TRUE) && !defined(__DOXYGEN__)
+extern WSPIDriver WSPID2;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void wspi_lld_init(void);
+ void wspi_lld_start(WSPIDriver *wspip);
+ void wspi_lld_stop(WSPIDriver *wspip);
+ void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp);
+ void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, const uint8_t *txbuf);
+ void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, uint8_t *rxbuf);
+#if WSPI_SUPPORTS_MEMMAP == TRUE
+ void wspi_lld_map_flash(WSPIDriver *wspip,
+ const wspi_command_t *cmdp,
+ uint8_t **addrp);
+ void wspi_lld_unmap_flash(WSPIDriver *wspip);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_WSPI */
+
+#endif /* HAL_WSPI_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/OTGv1/driver.mk b/os/hal/ports/STM32/LLD/OTGv1/driver.mk
index 197c1d281d..16250123ba 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/OTGv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1
diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
index 76f7c320b8..75d23c569a 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
+++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.c
@@ -1,1264 +1,1264 @@
-/*
- 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 OTGv1/hal_usb_lld.c
- * @brief STM32 USB subsystem low level driver source.
- *
- * @addtogroup USB
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_USB || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define TRDT_VALUE_FS 5
-#define TRDT_VALUE_HS 9
-
-#define EP0_MAX_INSIZE 64
-#define EP0_MAX_OUTSIZE 64
-
-#if STM32_OTG_STEPPING == 1
-#if defined(BOARD_OTG_NOVBUSSENS)
-#define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | \
- GCCFG_VBUSBSEN | GCCFG_PWRDWN)
-#else
-#define GCCFG_INIT_VALUE (GCCFG_VBUSASEN | GCCFG_VBUSBSEN | \
- GCCFG_PWRDWN)
-#endif
-
-#elif STM32_OTG_STEPPING == 2
-#if defined(BOARD_OTG_NOVBUSSENS)
-#define GCCFG_INIT_VALUE GCCFG_PWRDWN
-#else
-#define GCCFG_INIT_VALUE (GCCFG_VBDEN | GCCFG_PWRDWN)
-#endif
-
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief OTG_FS driver identifier.*/
-#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__)
-USBDriver USBD1;
-#endif
-
-/** @brief OTG_HS driver identifier.*/
-#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__)
-USBDriver USBD2;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief EP0 state.
- * @note It is an union because IN and OUT endpoints are never used at the
- * same time for EP0.
- */
-static union {
- /**
- * @brief IN EP0 state.
- */
- USBInEndpointState in;
- /**
- * @brief OUT EP0 state.
- */
- USBOutEndpointState out;
-} ep0_state;
-
-/**
- * @brief Buffer for the EP0 setup packets.
- */
-static uint8_t ep0setup_buffer[8];
-
-/**
- * @brief EP0 initialization structure.
- */
-static const USBEndpointConfig ep0config = {
- USB_EP_MODE_TYPE_CTRL,
- _usb_ep0setup,
- _usb_ep0in,
- _usb_ep0out,
- 0x40,
- 0x40,
- &ep0_state.in,
- &ep0_state.out,
- 1,
- ep0setup_buffer
-};
-
-#if STM32_USB_USE_OTG1
-static const stm32_otg_params_t fsparams = {
- STM32_USB_OTG1_RX_FIFO_SIZE / 4,
- STM32_OTG1_FIFO_MEM_SIZE,
- STM32_OTG1_ENDPOINTS
-};
-#endif
-
-#if STM32_USB_USE_OTG2
-static const stm32_otg_params_t hsparams = {
- STM32_USB_OTG2_RX_FIFO_SIZE / 4,
- STM32_OTG2_FIFO_MEM_SIZE,
- STM32_OTG2_ENDPOINTS
-};
-#endif
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static void otg_core_reset(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
-
- /* Wait AHB idle condition.*/
- while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0)
- ;
-
- /* Core reset and delay of at least 3 PHY cycles.*/
- otgp->GRSTCTL = GRSTCTL_CSRST;
- osalSysPolledDelayX(12);
- while ((otgp->GRSTCTL & GRSTCTL_CSRST) != 0)
- ;
-
- osalSysPolledDelayX(18);
-
- /* Wait AHB idle condition again.*/
- while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0)
- ;
-}
-
-static void otg_disable_ep(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
- unsigned i;
-
- for (i = 0; i <= usbp->otgparams->num_endpoints; i++) {
-
- if ((otgp->ie[i].DIEPCTL & DIEPCTL_EPENA) != 0U) {
- otgp->ie[i].DIEPCTL |= DIEPCTL_EPDIS;
- }
-
- if ((otgp->oe[i].DOEPCTL & DIEPCTL_EPENA) != 0U) {
- otgp->oe[i].DOEPCTL |= DIEPCTL_EPDIS;
- }
-
- otgp->ie[i].DIEPINT = 0xFFFFFFFF;
- otgp->oe[i].DOEPINT = 0xFFFFFFFF;
- }
- otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0);
-}
-
-static void otg_rxfifo_flush(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
-
- otgp->GRSTCTL = GRSTCTL_RXFFLSH;
- while ((otgp->GRSTCTL & GRSTCTL_RXFFLSH) != 0)
- ;
- /* Wait for 3 PHY Clocks.*/
- osalSysPolledDelayX(18);
-}
-
-static void otg_txfifo_flush(USBDriver *usbp, uint32_t fifo) {
- stm32_otg_t *otgp = usbp->otg;
-
- otgp->GRSTCTL = GRSTCTL_TXFNUM(fifo) | GRSTCTL_TXFFLSH;
- while ((otgp->GRSTCTL & GRSTCTL_TXFFLSH) != 0)
- ;
- /* Wait for 3 PHY Clocks.*/
- osalSysPolledDelayX(18);
-}
-
-/**
- * @brief Resets the FIFO RAM memory allocator.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-static void otg_ram_reset(USBDriver *usbp) {
-
- usbp->pmnext = usbp->otgparams->rx_fifo_size;
-}
-
-/**
- * @brief Allocates a block from the FIFO RAM memory.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] size size of the packet buffer to allocate in words
- *
- * @notapi
- */
-static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) {
- uint32_t next;
-
- next = usbp->pmnext;
- usbp->pmnext += size;
- osalDbgAssert(usbp->pmnext <= usbp->otgparams->otg_ram_size,
- "OTG FIFO memory overflow");
- return next;
-}
-
-/**
- * @brief Writes to a TX FIFO.
- *
- * @param[in] fifop pointer to the FIFO register
- * @param[in] buf buffer where to copy the endpoint data
- * @param[in] n maximum number of bytes to copy
- *
- * @notapi
- */
-static void otg_fifo_write_from_buffer(volatile uint32_t *fifop,
- const uint8_t *buf,
- size_t n) {
-
- osalDbgAssert(n > 0, "is zero");
-
- while (true) {
- *fifop = *((uint32_t *)buf);
- if (n <= 4) {
- break;
- }
- n -= 4;
- buf += 4;
- }
-}
-
-/**
- * @brief Reads a packet from the RXFIFO.
- *
- * @param[in] fifop pointer to the FIFO register
- * @param[out] buf buffer where to copy the endpoint data
- * @param[in] n number of bytes to pull from the FIFO
- * @param[in] max number of bytes to copy into the buffer
- *
- * @notapi
- */
-static void otg_fifo_read_to_buffer(volatile uint32_t *fifop,
- uint8_t *buf,
- size_t n,
- size_t max) {
- uint32_t w = 0;
- size_t i = 0;
-
- while (i < n) {
- if ((i & 3) == 0) {
- w = *fifop;
- }
- if (i < max) {
- *buf++ = (uint8_t)w;
- w >>= 8;
- }
- i++;
- }
-}
-
-/**
- * @brief Incoming packets handler.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-static void otg_rxfifo_handler(USBDriver *usbp) {
- uint32_t sts, cnt, ep;
-
- /* Popping the event word out of the RX FIFO.*/
- sts = usbp->otg->GRXSTSP;
-
- /* Event details.*/
- cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
- ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
-
- switch (sts & GRXSTSP_PKTSTS_MASK) {
- case GRXSTSP_SETUP_DATA:
- otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf,
- cnt, 8);
- break;
- case GRXSTSP_SETUP_COMP:
- break;
- case GRXSTSP_OUT_DATA:
- otg_fifo_read_to_buffer(usbp->otg->FIFO[0],
- usbp->epc[ep]->out_state->rxbuf,
- cnt,
- usbp->epc[ep]->out_state->rxsize -
- usbp->epc[ep]->out_state->rxcnt);
- usbp->epc[ep]->out_state->rxbuf += cnt;
- usbp->epc[ep]->out_state->rxcnt += cnt;
- break;
- case GRXSTSP_OUT_COMP:
- break;
- case GRXSTSP_OUT_GLOBAL_NAK:
- break;
- default:
- break;
- }
-}
-
-/**
- * @brief Outgoing packets handler.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-static bool otg_txfifo_handler(USBDriver *usbp, usbep_t ep) {
-
- /* The TXFIFO is filled until there is space and data to be transmitted.*/
- while (true) {
- uint32_t n;
-
- /* Transaction end condition.*/
- if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) {
-#if 1
- usbp->otg->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep);
-#endif
- return true;
- }
-
- /* Number of bytes remaining in current transaction.*/
- n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt;
- if (n > usbp->epc[ep]->in_maxsize)
- n = usbp->epc[ep]->in_maxsize;
-
- /* Checks if in the TXFIFO there is enough space to accommodate the
- next packet.*/
- if (((usbp->otg->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n)
- return false;
-
-#if STM32_USB_OTGFIFO_FILL_BASEPRI
- __set_BASEPRI(CORTEX_PRIO_MASK(STM32_USB_OTGFIFO_FILL_BASEPRI));
-#endif
- otg_fifo_write_from_buffer(usbp->otg->FIFO[ep],
- usbp->epc[ep]->in_state->txbuf,
- n);
- usbp->epc[ep]->in_state->txbuf += n;
- usbp->epc[ep]->in_state->txcnt += n;
-#if STM32_USB_OTGFIFO_FILL_BASEPRI
- __set_BASEPRI(0);
-#endif
- }
-}
-
-/**
- * @brief Generic endpoint IN handler.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-static void otg_epin_handler(USBDriver *usbp, usbep_t ep) {
- stm32_otg_t *otgp = usbp->otg;
- uint32_t epint = otgp->ie[ep].DIEPINT;
-
- otgp->ie[ep].DIEPINT = epint;
-
- if (epint & DIEPINT_TOC) {
- /* Timeouts not handled yet, not sure how to handle.*/
- }
- if ((epint & DIEPINT_XFRC) && (otgp->DIEPMSK & DIEPMSK_XFRCM)) {
- /* Transmit transfer complete.*/
- USBInEndpointState *isp = usbp->epc[ep]->in_state;
-
- if (isp->txsize < isp->totsize) {
- /* In case the transaction covered only part of the total transfer
- then another transaction is immediately started in order to
- cover the remaining.*/
- isp->txsize = isp->totsize - isp->txsize;
- isp->txcnt = 0;
- osalSysLockFromISR();
- usb_lld_start_in(usbp, ep);
- osalSysUnlockFromISR();
- }
- else {
- /* End on IN transfer.*/
- _usb_isr_invoke_in_cb(usbp, ep);
- }
- }
- if ((epint & DIEPINT_TXFE) &&
- (otgp->DIEPEMPMSK & DIEPEMPMSK_INEPTXFEM(ep))) {
- /* TX FIFO empty or emptying.*/
- otg_txfifo_handler(usbp, ep);
- }
-}
-
-/**
- * @brief Generic endpoint OUT handler.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
- stm32_otg_t *otgp = usbp->otg;
- uint32_t epint = otgp->oe[ep].DOEPINT;
-
- /* Resets all EP IRQ sources.*/
- otgp->oe[ep].DOEPINT = epint;
-
- if ((epint & DOEPINT_STUP) && (otgp->DOEPMSK & DOEPMSK_STUPM)) {
- /* Setup packets handling, setup packets are handled using a
- specific callback.*/
- _usb_isr_invoke_setup_cb(usbp, ep);
- }
-
- if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) {
- USBOutEndpointState *osp;
-
- /* OUT state structure pointer for this endpoint.*/
- osp = usbp->epc[ep]->out_state;
-
- /* EP0 requires special handling.*/
- if (ep == 0) {
-
-#if defined(STM32_OTG_SEQUENCE_WORKAROUND)
- /* If an OUT transaction end interrupt is processed while the state
- machine is not in an OUT state then it is ignored, this is caused
- on some devices (L4) apparently injecting spurious data complete
- words in the RX FIFO.*/
- if ((usbp->ep0state & USB_OUT_STATE) == 0)
- return;
-#endif
-
- /* In case the transaction covered only part of the total transfer
- then another transaction is immediately started in order to
- cover the remaining.*/
- if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
- (osp->rxsize < osp->totsize)) {
- osp->rxsize = osp->totsize - osp->rxsize;
- osp->rxcnt = 0;
- osalSysLockFromISR();
- usb_lld_start_out(usbp, ep);
- osalSysUnlockFromISR();
- return;
- }
- }
-
- /* End on OUT transfer.*/
- _usb_isr_invoke_out_cb(usbp, ep);
- }
-}
-
-/**
- * @brief Isochronous IN transfer failed handler.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-static void otg_isoc_in_failed_handler(USBDriver *usbp) {
- usbep_t ep;
- stm32_otg_t *otgp = usbp->otg;
-
- for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) {
- if (((otgp->ie[ep].DIEPCTL & DIEPCTL_EPTYP_MASK) == DIEPCTL_EPTYP_ISO) &&
- ((otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) != 0)) {
- /* Endpoint enabled -> ISOC IN transfer failed.*/
- /* Disable endpoint.*/
- otgp->ie[ep].DIEPCTL |= (DIEPCTL_EPDIS | DIEPCTL_SNAK);
- while (otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA)
- ;
-
- /* Flush FIFO.*/
- otg_txfifo_flush(usbp, ep);
-
- /* Prepare data for next frame.*/
- _usb_isr_invoke_in_cb(usbp, ep);
- }
- }
-}
-
-/**
- * @brief Isochronous OUT transfer failed handler.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-static void otg_isoc_out_failed_handler(USBDriver *usbp) {
- usbep_t ep;
- stm32_otg_t *otgp = usbp->otg;
-
- for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) {
- if (((otgp->oe[ep].DOEPCTL & DOEPCTL_EPTYP_MASK) == DOEPCTL_EPTYP_ISO) &&
- ((otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) != 0)) {
-#if 0
- /* Endpoint enabled -> ISOC OUT transfer failed.*/
- /* Disable endpoint.*/
- /* CHTODO:: Core stucks here */
- otgp->oe[ep].DOEPCTL |= (DOEPCTL_EPDIS | DOEPCTL_SNAK);
- while (otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA)
- ;
-#endif
- /* Prepare transfer for next frame.*/
- _usb_isr_invoke_out_cb(usbp, ep);
- }
- }
-}
-
-/**
- * @brief OTG shared ISR.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-static void usb_lld_serve_interrupt(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
- uint32_t sts, src;
-
- sts = otgp->GINTSTS;
- sts &= otgp->GINTMSK;
- otgp->GINTSTS = sts;
-
- /* Reset interrupt handling.*/
- if (sts & GINTSTS_USBRST) {
- /* Default reset action.*/
- _usb_reset(usbp);
-
- /* Preventing execution of more handlers, the core has been reset.*/
- return;
- }
-
- /* Wake-up handling.*/
- if (sts & GINTSTS_WKUPINT) {
- /* If clocks are gated off, turn them back on (may be the case if
- coming out of suspend mode).*/
- if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) {
- /* Set to zero to un-gate the USB core clocks.*/
- otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK);
- }
-
- /* Clear the Remote Wake-up Signaling.*/
- otgp->DCTL &= ~DCTL_RWUSIG;
-
- _usb_wakeup(usbp);
- }
-
- /* Suspend handling.*/
- if (sts & GINTSTS_USBSUSP) {
- /* Stopping all ongoing transfers.*/
- otg_disable_ep(usbp);
-
- /* Default suspend action.*/
- _usb_suspend(usbp);
- }
-
- /* Enumeration done.*/
- if (sts & GINTSTS_ENUMDNE) {
- /* Full or High speed timing selection.*/
- if ((otgp->DSTS & DSTS_ENUMSPD_MASK) == DSTS_ENUMSPD_HS_480) {
- otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) |
- GUSBCFG_TRDT(TRDT_VALUE_HS);
- }
- else {
- otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) |
- GUSBCFG_TRDT(TRDT_VALUE_FS);
- }
- }
-
- /* SOF interrupt handling.*/
- if (sts & GINTSTS_SOF) {
- _usb_isr_invoke_sof_cb(usbp);
- }
-
- /* Isochronous IN failed handling */
- if (sts & GINTSTS_IISOIXFR) {
- otg_isoc_in_failed_handler(usbp);
- }
-
- /* Isochronous OUT failed handling */
- if (sts & GINTSTS_IISOOXFR) {
- otg_isoc_out_failed_handler(usbp);
- }
-
- /* Performing the whole FIFO emptying in the ISR, it is advised to keep
- this IRQ at a very low priority level.*/
- if ((sts & GINTSTS_RXFLVL) != 0U) {
- otg_rxfifo_handler(usbp);
- }
-
- /* IN/OUT endpoints event handling.*/
- src = otgp->DAINT;
- if (sts & GINTSTS_OEPINT) {
- if (src & (1 << 16))
- otg_epout_handler(usbp, 0);
- if (src & (1 << 17))
- otg_epout_handler(usbp, 1);
- if (src & (1 << 18))
- otg_epout_handler(usbp, 2);
- if (src & (1 << 19))
- otg_epout_handler(usbp, 3);
-#if USB_MAX_ENDPOINTS >= 4
- if (src & (1 << 20))
- otg_epout_handler(usbp, 4);
-#endif
-#if USB_MAX_ENDPOINTS >= 5
- if (src & (1 << 21))
- otg_epout_handler(usbp, 5);
-#endif
-#if USB_MAX_ENDPOINTS >= 6
- if (src & (1 << 22))
- otg_epout_handler(usbp, 6);
-#endif
-#if USB_MAX_ENDPOINTS >= 7
- if (src & (1 << 23))
- otg_epout_handler(usbp, 7);
-#endif
-#if USB_MAX_ENDPOINTS >= 8
- if (src & (1 << 24))
- otg_epout_handler(usbp, 8);
-#endif
- }
- if (sts & GINTSTS_IEPINT) {
- if (src & (1 << 0))
- otg_epin_handler(usbp, 0);
- if (src & (1 << 1))
- otg_epin_handler(usbp, 1);
- if (src & (1 << 2))
- otg_epin_handler(usbp, 2);
- if (src & (1 << 3))
- otg_epin_handler(usbp, 3);
-#if USB_MAX_ENDPOINTS >= 4
- if (src & (1 << 4))
- otg_epin_handler(usbp, 4);
-#endif
-#if USB_MAX_ENDPOINTS >= 5
- if (src & (1 << 5))
- otg_epin_handler(usbp, 5);
-#endif
-#if USB_MAX_ENDPOINTS >= 6
- if (src & (1 << 6))
- otg_epin_handler(usbp, 6);
-#endif
-#if USB_MAX_ENDPOINTS >= 7
- if (src & (1 << 7))
- otg_epin_handler(usbp, 7);
-#endif
-#if USB_MAX_ENDPOINTS >= 8
- if (src & (1 << 8))
- otg_epin_handler(usbp, 8);
-#endif
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__)
-/**
- * @brief OTG1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_OTG1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- usb_lld_serve_interrupt(&USBD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__)
-/**
- * @brief OTG2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_OTG2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- usb_lld_serve_interrupt(&USBD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level USB driver initialization.
- *
- * @notapi
- */
-void usb_lld_init(void) {
-
- /* Driver initialization.*/
-#if STM32_USB_USE_OTG1
- usbObjectInit(&USBD1);
- USBD1.otg = OTG_FS;
- USBD1.otgparams = &fsparams;
-
-#endif
-
-#if STM32_USB_USE_OTG2
- usbObjectInit(&USBD2);
- USBD2.otg = OTG_HS;
- USBD2.otgparams = &hsparams;
-#endif
-}
-
-/**
- * @brief Configures and activates the USB peripheral.
- * @note Starting the OTG cell can be a slow operation carried out with
- * interrupts disabled, perform it before starting time-critical
- * operations.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_start(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
-
- if (usbp->state == USB_STOP) {
- /* Clock activation.*/
-
-#if STM32_USB_USE_OTG1
- if (&USBD1 == usbp) {
- /* OTG FS clock enable and reset.*/
- rccEnableOTG_FS(true);
- rccResetOTG_FS();
-
- /* Enables IRQ vector.*/
- nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY);
-
- /* - Forced device mode.
- - USB turn-around time = TRDT_VALUE_FS.
- - Full Speed 1.1 PHY.*/
- otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) |
- GUSBCFG_PHYSEL;
-
- /* 48MHz 1.1 PHY.*/
- otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11;
- }
-#endif
-
-#if STM32_USB_USE_OTG2
- if (&USBD2 == usbp) {
- /* OTG HS clock enable and reset.*/
- rccEnableOTG_HS(true);
- rccResetOTG_HS();
-
- /* ULPI clock is managed depending on the presence of an external
- PHY.*/
-#if defined(BOARD_OTG2_USES_ULPI)
- rccEnableOTG_HSULPI(true);
-#else
- /* Workaround for the problem described here:
- http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798.*/
- rccDisableOTG_HSULPI();
-#endif
-
- /* Enables IRQ vector.*/
- nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY);
-
- /* - Forced device mode.
- - USB turn-around time = TRDT_VALUE_HS or TRDT_VALUE_FS.*/
-#if defined(BOARD_OTG2_USES_ULPI)
- /* High speed ULPI PHY.*/
- otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_HS) |
- GUSBCFG_SRPCAP | GUSBCFG_HNPCAP;
-#else
- otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) |
- GUSBCFG_PHYSEL;
-#endif
-
-#if defined(BOARD_OTG2_USES_ULPI)
-#if STM32_USE_USB_OTG2_HS
- /* USB 2.0 High Speed PHY in HS mode.*/
- otgp->DCFG = 0x02200000 | DCFG_DSPD_HS;
-#else
- /* USB 2.0 High Speed PHY in FS mode.*/
- otgp->DCFG = 0x02200000 | DCFG_DSPD_HS_FS;
-#endif
-#else
- /* 48MHz 1.1 PHY.*/
- otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11;
-#endif
- }
-#endif
-
- /* PHY enabled.*/
- otgp->PCGCCTL = 0;
-
- /* VBUS sensing and transceiver enabled.*/
- otgp->GOTGCTL = GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL;
-
-#if defined(BOARD_OTG2_USES_ULPI)
-#if STM32_USB_USE_OTG1
- if (&USBD1 == usbp) {
- otgp->GCCFG = GCCFG_INIT_VALUE;
- }
-#endif
-
-#if STM32_USB_USE_OTG2
- if (&USBD2 == usbp) {
- otgp->GCCFG = 0;
- }
-#endif
-#else
- otgp->GCCFG = GCCFG_INIT_VALUE;
-#endif
-
- /* Soft core reset.*/
- otg_core_reset(usbp);
-
- /* Interrupts on TXFIFOs half empty.*/
- otgp->GAHBCFG = 0;
-
- /* Endpoints re-initialization.*/
- otg_disable_ep(usbp);
-
- /* Clear all pending Device Interrupts, only the USB Reset interrupt
- is required initially.*/
- otgp->DIEPMSK = 0;
- otgp->DOEPMSK = 0;
- otgp->DAINTMSK = 0;
- if (usbp->config->sof_cb == NULL)
- otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM |
- GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM |
- GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM;
- else
- otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM |
- GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM |
- GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM |
- GINTMSK_SOFM;
-
- /* Clears all pending IRQs, if any. */
- otgp->GINTSTS = 0xFFFFFFFF;
-
- /* Global interrupts enable.*/
- otgp->GAHBCFG |= GAHBCFG_GINTMSK;
- }
-}
-
-/**
- * @brief Deactivates the USB peripheral.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_stop(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
-
- /* If in ready state then disables the USB clock.*/
- if (usbp->state != USB_STOP) {
-
- /* Disabling all endpoints in case the driver has been stopped while
- active.*/
- otg_disable_ep(usbp);
-
- otgp->DAINTMSK = 0;
- otgp->GAHBCFG = 0;
- otgp->GCCFG = 0;
-
-#if STM32_USB_USE_OTG1
- if (&USBD1 == usbp) {
- nvicDisableVector(STM32_OTG1_NUMBER);
- rccDisableOTG_FS();
- }
-#endif
-
-#if STM32_USB_USE_OTG2
- if (&USBD2 == usbp) {
- nvicDisableVector(STM32_OTG2_NUMBER);
- rccDisableOTG_HS();
-#if defined(BOARD_OTG2_USES_ULPI)
- rccDisableOTG_HSULPI()
-#endif
- }
-#endif
- }
-}
-
-/**
- * @brief USB low level reset routine.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_reset(USBDriver *usbp) {
- unsigned i;
- stm32_otg_t *otgp = usbp->otg;
-
- /* Flush the Tx FIFO.*/
- otg_txfifo_flush(usbp, 0);
-
- /* Endpoint interrupts all disabled and cleared.*/
- otgp->DIEPEMPMSK = 0;
- otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0);
-
- /* All endpoints in NAK mode, interrupts cleared.*/
- for (i = 0; i <= usbp->otgparams->num_endpoints; i++) {
- otgp->ie[i].DIEPCTL = DIEPCTL_SNAK;
- otgp->oe[i].DOEPCTL = DOEPCTL_SNAK;
- otgp->ie[i].DIEPINT = 0xFFFFFFFF;
- otgp->oe[i].DOEPINT = 0xFFFFFFFF;
- }
-
- /* Resets the FIFO memory allocator.*/
- otg_ram_reset(usbp);
-
- /* Receive FIFO size initialization, the address is always zero.*/
- otgp->GRXFSIZ = usbp->otgparams->rx_fifo_size;
- otg_rxfifo_flush(usbp);
-
- /* Resets the device address to zero.*/
- otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0);
-
- /* Enables also EP-related interrupt sources.*/
- otgp->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM;
- otgp->DIEPMSK = DIEPMSK_TOCM | DIEPMSK_XFRCM;
- otgp->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM;
-
- /* EP0 initialization, it is a special case.*/
- usbp->epc[0] = &ep0config;
- otgp->oe[0].DOEPTSIZ = DOEPTSIZ_STUPCNT(3);
- otgp->oe[0].DOEPCTL = DOEPCTL_SD0PID | DOEPCTL_USBAEP | DOEPCTL_EPTYP_CTRL |
- DOEPCTL_MPSIZ(ep0config.out_maxsize);
- otgp->ie[0].DIEPTSIZ = 0;
- otgp->ie[0].DIEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL |
- DIEPCTL_TXFNUM(0) | DIEPCTL_MPSIZ(ep0config.in_maxsize);
- otgp->DIEPTXF0 = DIEPTXF_INEPTXFD(ep0config.in_maxsize / 4) |
- DIEPTXF_INEPTXSA(otg_ram_alloc(usbp,
- ep0config.in_maxsize / 4));
-}
-
-/**
- * @brief Sets the USB address.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_set_address(USBDriver *usbp) {
- stm32_otg_t *otgp = usbp->otg;
-
- otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(usbp->address);
-}
-
-/**
- * @brief Enables an endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
- uint32_t ctl, fsize;
- stm32_otg_t *otgp = usbp->otg;
-
- /* IN and OUT common parameters.*/
- switch (usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) {
- case USB_EP_MODE_TYPE_CTRL:
- ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL;
- break;
- case USB_EP_MODE_TYPE_ISOC:
- ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_ISO;
- break;
- case USB_EP_MODE_TYPE_BULK:
- ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_BULK;
- break;
- case USB_EP_MODE_TYPE_INTR:
- ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_INTR;
- break;
- default:
- return;
- }
-
- /* OUT endpoint activation or deactivation.*/
- otgp->oe[ep].DOEPTSIZ = 0;
- if (usbp->epc[ep]->out_state != NULL) {
- otgp->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize);
- otgp->DAINTMSK |= DAINTMSK_OEPM(ep);
- }
- else {
- otgp->oe[ep].DOEPCTL &= ~DOEPCTL_USBAEP;
- otgp->DAINTMSK &= ~DAINTMSK_OEPM(ep);
- }
-
- /* IN endpoint activation or deactivation.*/
- otgp->ie[ep].DIEPTSIZ = 0;
- if (usbp->epc[ep]->in_state != NULL) {
- /* FIFO allocation for the IN endpoint.*/
- fsize = usbp->epc[ep]->in_maxsize / 4;
- if (usbp->epc[ep]->in_multiplier > 1)
- fsize *= usbp->epc[ep]->in_multiplier;
- otgp->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) |
- DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize));
- otg_txfifo_flush(usbp, ep);
-
- otgp->ie[ep].DIEPCTL = ctl |
- DIEPCTL_TXFNUM(ep) |
- DIEPCTL_MPSIZ(usbp->epc[ep]->in_maxsize);
- otgp->DAINTMSK |= DAINTMSK_IEPM(ep);
- }
- else {
- otgp->DIEPTXF[ep - 1] = 0x02000400; /* Reset value.*/
- otg_txfifo_flush(usbp, ep);
- otgp->ie[ep].DIEPCTL &= ~DIEPCTL_USBAEP;
- otgp->DAINTMSK &= ~DAINTMSK_IEPM(ep);
- }
-}
-
-/**
- * @brief Disables all the active endpoints except the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_disable_endpoints(USBDriver *usbp) {
-
- /* Resets the FIFO memory allocator.*/
- otg_ram_reset(usbp);
-
- /* Disabling all endpoints.*/
- otg_disable_ep(usbp);
-}
-
-/**
- * @brief Returns the status of an OUT endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @return The endpoint status.
- * @retval EP_STATUS_DISABLED The endpoint is not active.
- * @retval EP_STATUS_STALLED The endpoint is stalled.
- * @retval EP_STATUS_ACTIVE The endpoint is active.
- *
- * @notapi
- */
-usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
- uint32_t ctl;
-
- (void)usbp;
-
- ctl = usbp->otg->oe[ep].DOEPCTL;
- if (!(ctl & DOEPCTL_USBAEP))
- return EP_STATUS_DISABLED;
- if (ctl & DOEPCTL_STALL)
- return EP_STATUS_STALLED;
- return EP_STATUS_ACTIVE;
-}
-
-/**
- * @brief Returns the status of an IN endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @return The endpoint status.
- * @retval EP_STATUS_DISABLED The endpoint is not active.
- * @retval EP_STATUS_STALLED The endpoint is stalled.
- * @retval EP_STATUS_ACTIVE The endpoint is active.
- *
- * @notapi
- */
-usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
- uint32_t ctl;
-
- (void)usbp;
-
- ctl = usbp->otg->ie[ep].DIEPCTL;
- if (!(ctl & DIEPCTL_USBAEP))
- return EP_STATUS_DISABLED;
- if (ctl & DIEPCTL_STALL)
- return EP_STATUS_STALLED;
- return EP_STATUS_ACTIVE;
-}
-
-/**
- * @brief Reads a setup packet from the dedicated packet buffer.
- * @details This function must be invoked in the context of the @p setup_cb
- * callback in order to read the received setup packet.
- * @pre In order to use this function the endpoint must have been
- * initialized as a control endpoint.
- * @post The endpoint is ready to accept another packet.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @param[out] buf buffer where to copy the packet data
- *
- * @notapi
- */
-void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
-
- memcpy(buf, usbp->epc[ep]->setup_buf, 8);
-}
-
-/**
- * @brief Starts a receive operation on an OUT endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
- uint32_t pcnt, rxsize;
- USBOutEndpointState *osp = usbp->epc[ep]->out_state;
-
- /* Transfer initialization.*/
- osp->totsize = osp->rxsize;
- if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE))
- osp->rxsize = EP0_MAX_OUTSIZE;
-
- /* Transaction size is rounded to a multiple of packet size because the
- following requirement in the RM:
- "For OUT transfers, the transfer size field in the endpoint's transfer
- size register must be a multiple of the maximum packet size of the
- endpoint, adjusted to the Word boundary".*/
- pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1U) /
- usbp->epc[ep]->out_maxsize;
- rxsize = (pcnt * usbp->epc[ep]->out_maxsize + 3U) & 0xFFFFFFFCU;
-
- /*Setting up transaction parameters in DOEPTSIZ.*/
- usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
- DOEPTSIZ_XFRSIZ(rxsize);
-
- /* Special case of isochronous endpoint.*/
- if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
- /* Odd/even bit toggling for isochronous endpoint.*/
- if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
- usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SEVNFRM;
- else
- usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM;
- }
-
- /* Starting operation.*/
- usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK;
-}
-
-/**
- * @brief Starts a transmit operation on an IN endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
- USBInEndpointState *isp = usbp->epc[ep]->in_state;
-
- /* Transfer initialization.*/
- isp->totsize = isp->txsize;
- if (isp->txsize == 0) {
- /* Special case, sending zero size packet.*/
- usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
- }
- else {
- if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE))
- isp->txsize = EP0_MAX_INSIZE;
-
- /* Normal case.*/
- uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) /
- usbp->epc[ep]->in_maxsize;
- /* CHTODO: Support more than one packet per frame for isochronous transfers.*/
- usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) |
- DIEPTSIZ_XFRSIZ(isp->txsize);
- }
-
- /* Special case of isochronous endpoint.*/
- if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
- /* Odd/even bit toggling.*/
- if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
- usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SEVNFRM;
- else
- usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM;
- }
-
- /* Starting operation.*/
- usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
- usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep);
-}
-
-/**
- * @brief Brings an OUT endpoint in the stalled state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
-
- usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_STALL;
-}
-
-/**
- * @brief Brings an IN endpoint in the stalled state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
-
- usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_STALL;
-}
-
-/**
- * @brief Brings an OUT endpoint in the active state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
-
- usbp->otg->oe[ep].DOEPCTL &= ~DOEPCTL_STALL;
-}
-
-/**
- * @brief Brings an IN endpoint in the active state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
-
- usbp->otg->ie[ep].DIEPCTL &= ~DIEPCTL_STALL;
-}
-
-#endif /* HAL_USE_USB */
-
-/** @} */
+/*
+ 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 OTGv1/hal_usb_lld.c
+ * @brief STM32 USB subsystem low level driver source.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define TRDT_VALUE_FS 5
+#define TRDT_VALUE_HS 9
+
+#define EP0_MAX_INSIZE 64
+#define EP0_MAX_OUTSIZE 64
+
+#if STM32_OTG_STEPPING == 1
+#if defined(BOARD_OTG_NOVBUSSENS)
+#define GCCFG_INIT_VALUE (GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | \
+ GCCFG_VBUSBSEN | GCCFG_PWRDWN)
+#else
+#define GCCFG_INIT_VALUE (GCCFG_VBUSASEN | GCCFG_VBUSBSEN | \
+ GCCFG_PWRDWN)
+#endif
+
+#elif STM32_OTG_STEPPING == 2
+#if defined(BOARD_OTG_NOVBUSSENS)
+#define GCCFG_INIT_VALUE GCCFG_PWRDWN
+#else
+#define GCCFG_INIT_VALUE (GCCFG_VBDEN | GCCFG_PWRDWN)
+#endif
+
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief OTG_FS driver identifier.*/
+#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__)
+USBDriver USBD1;
+#endif
+
+/** @brief OTG_HS driver identifier.*/
+#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__)
+USBDriver USBD2;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief EP0 state.
+ * @note It is an union because IN and OUT endpoints are never used at the
+ * same time for EP0.
+ */
+static union {
+ /**
+ * @brief IN EP0 state.
+ */
+ USBInEndpointState in;
+ /**
+ * @brief OUT EP0 state.
+ */
+ USBOutEndpointState out;
+} ep0_state;
+
+/**
+ * @brief Buffer for the EP0 setup packets.
+ */
+static uint8_t ep0setup_buffer[8];
+
+/**
+ * @brief EP0 initialization structure.
+ */
+static const USBEndpointConfig ep0config = {
+ USB_EP_MODE_TYPE_CTRL,
+ _usb_ep0setup,
+ _usb_ep0in,
+ _usb_ep0out,
+ 0x40,
+ 0x40,
+ &ep0_state.in,
+ &ep0_state.out,
+ 1,
+ ep0setup_buffer
+};
+
+#if STM32_USB_USE_OTG1
+static const stm32_otg_params_t fsparams = {
+ STM32_USB_OTG1_RX_FIFO_SIZE / 4,
+ STM32_OTG1_FIFO_MEM_SIZE,
+ STM32_OTG1_ENDPOINTS
+};
+#endif
+
+#if STM32_USB_USE_OTG2
+static const stm32_otg_params_t hsparams = {
+ STM32_USB_OTG2_RX_FIFO_SIZE / 4,
+ STM32_OTG2_FIFO_MEM_SIZE,
+ STM32_OTG2_ENDPOINTS
+};
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+static void otg_core_reset(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+
+ /* Wait AHB idle condition.*/
+ while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0)
+ ;
+
+ /* Core reset and delay of at least 3 PHY cycles.*/
+ otgp->GRSTCTL = GRSTCTL_CSRST;
+ osalSysPolledDelayX(12);
+ while ((otgp->GRSTCTL & GRSTCTL_CSRST) != 0)
+ ;
+
+ osalSysPolledDelayX(18);
+
+ /* Wait AHB idle condition again.*/
+ while ((otgp->GRSTCTL & GRSTCTL_AHBIDL) == 0)
+ ;
+}
+
+static void otg_disable_ep(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+ unsigned i;
+
+ for (i = 0; i <= usbp->otgparams->num_endpoints; i++) {
+
+ if ((otgp->ie[i].DIEPCTL & DIEPCTL_EPENA) != 0U) {
+ otgp->ie[i].DIEPCTL |= DIEPCTL_EPDIS;
+ }
+
+ if ((otgp->oe[i].DOEPCTL & DIEPCTL_EPENA) != 0U) {
+ otgp->oe[i].DOEPCTL |= DIEPCTL_EPDIS;
+ }
+
+ otgp->ie[i].DIEPINT = 0xFFFFFFFF;
+ otgp->oe[i].DOEPINT = 0xFFFFFFFF;
+ }
+ otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0);
+}
+
+static void otg_rxfifo_flush(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+
+ otgp->GRSTCTL = GRSTCTL_RXFFLSH;
+ while ((otgp->GRSTCTL & GRSTCTL_RXFFLSH) != 0)
+ ;
+ /* Wait for 3 PHY Clocks.*/
+ osalSysPolledDelayX(18);
+}
+
+static void otg_txfifo_flush(USBDriver *usbp, uint32_t fifo) {
+ stm32_otg_t *otgp = usbp->otg;
+
+ otgp->GRSTCTL = GRSTCTL_TXFNUM(fifo) | GRSTCTL_TXFFLSH;
+ while ((otgp->GRSTCTL & GRSTCTL_TXFFLSH) != 0)
+ ;
+ /* Wait for 3 PHY Clocks.*/
+ osalSysPolledDelayX(18);
+}
+
+/**
+ * @brief Resets the FIFO RAM memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void otg_ram_reset(USBDriver *usbp) {
+
+ usbp->pmnext = usbp->otgparams->rx_fifo_size;
+}
+
+/**
+ * @brief Allocates a block from the FIFO RAM memory.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] size size of the packet buffer to allocate in words
+ *
+ * @notapi
+ */
+static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) {
+ uint32_t next;
+
+ next = usbp->pmnext;
+ usbp->pmnext += size;
+ osalDbgAssert(usbp->pmnext <= usbp->otgparams->otg_ram_size,
+ "OTG FIFO memory overflow");
+ return next;
+}
+
+/**
+ * @brief Writes to a TX FIFO.
+ *
+ * @param[in] fifop pointer to the FIFO register
+ * @param[in] buf buffer where to copy the endpoint data
+ * @param[in] n maximum number of bytes to copy
+ *
+ * @notapi
+ */
+static void otg_fifo_write_from_buffer(volatile uint32_t *fifop,
+ const uint8_t *buf,
+ size_t n) {
+
+ osalDbgAssert(n > 0, "is zero");
+
+ while (true) {
+ *fifop = *((uint32_t *)buf);
+ if (n <= 4) {
+ break;
+ }
+ n -= 4;
+ buf += 4;
+ }
+}
+
+/**
+ * @brief Reads a packet from the RXFIFO.
+ *
+ * @param[in] fifop pointer to the FIFO register
+ * @param[out] buf buffer where to copy the endpoint data
+ * @param[in] n number of bytes to pull from the FIFO
+ * @param[in] max number of bytes to copy into the buffer
+ *
+ * @notapi
+ */
+static void otg_fifo_read_to_buffer(volatile uint32_t *fifop,
+ uint8_t *buf,
+ size_t n,
+ size_t max) {
+ uint32_t w = 0;
+ size_t i = 0;
+
+ while (i < n) {
+ if ((i & 3) == 0) {
+ w = *fifop;
+ }
+ if (i < max) {
+ *buf++ = (uint8_t)w;
+ w >>= 8;
+ }
+ i++;
+ }
+}
+
+/**
+ * @brief Incoming packets handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void otg_rxfifo_handler(USBDriver *usbp) {
+ uint32_t sts, cnt, ep;
+
+ /* Popping the event word out of the RX FIFO.*/
+ sts = usbp->otg->GRXSTSP;
+
+ /* Event details.*/
+ cnt = (sts & GRXSTSP_BCNT_MASK) >> GRXSTSP_BCNT_OFF;
+ ep = (sts & GRXSTSP_EPNUM_MASK) >> GRXSTSP_EPNUM_OFF;
+
+ switch (sts & GRXSTSP_PKTSTS_MASK) {
+ case GRXSTSP_SETUP_DATA:
+ otg_fifo_read_to_buffer(usbp->otg->FIFO[0], usbp->epc[ep]->setup_buf,
+ cnt, 8);
+ break;
+ case GRXSTSP_SETUP_COMP:
+ break;
+ case GRXSTSP_OUT_DATA:
+ otg_fifo_read_to_buffer(usbp->otg->FIFO[0],
+ usbp->epc[ep]->out_state->rxbuf,
+ cnt,
+ usbp->epc[ep]->out_state->rxsize -
+ usbp->epc[ep]->out_state->rxcnt);
+ usbp->epc[ep]->out_state->rxbuf += cnt;
+ usbp->epc[ep]->out_state->rxcnt += cnt;
+ break;
+ case GRXSTSP_OUT_COMP:
+ break;
+ case GRXSTSP_OUT_GLOBAL_NAK:
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Outgoing packets handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static bool otg_txfifo_handler(USBDriver *usbp, usbep_t ep) {
+
+ /* The TXFIFO is filled until there is space and data to be transmitted.*/
+ while (true) {
+ uint32_t n;
+
+ /* Transaction end condition.*/
+ if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) {
+#if 1
+ usbp->otg->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep);
+#endif
+ return true;
+ }
+
+ /* Number of bytes remaining in current transaction.*/
+ n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt;
+ if (n > usbp->epc[ep]->in_maxsize)
+ n = usbp->epc[ep]->in_maxsize;
+
+ /* Checks if in the TXFIFO there is enough space to accommodate the
+ next packet.*/
+ if (((usbp->otg->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n)
+ return false;
+
+#if STM32_USB_OTGFIFO_FILL_BASEPRI
+ __set_BASEPRI(CORTEX_PRIO_MASK(STM32_USB_OTGFIFO_FILL_BASEPRI));
+#endif
+ otg_fifo_write_from_buffer(usbp->otg->FIFO[ep],
+ usbp->epc[ep]->in_state->txbuf,
+ n);
+ usbp->epc[ep]->in_state->txbuf += n;
+ usbp->epc[ep]->in_state->txcnt += n;
+#if STM32_USB_OTGFIFO_FILL_BASEPRI
+ __set_BASEPRI(0);
+#endif
+ }
+}
+
+/**
+ * @brief Generic endpoint IN handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static void otg_epin_handler(USBDriver *usbp, usbep_t ep) {
+ stm32_otg_t *otgp = usbp->otg;
+ uint32_t epint = otgp->ie[ep].DIEPINT;
+
+ otgp->ie[ep].DIEPINT = epint;
+
+ if (epint & DIEPINT_TOC) {
+ /* Timeouts not handled yet, not sure how to handle.*/
+ }
+ if ((epint & DIEPINT_XFRC) && (otgp->DIEPMSK & DIEPMSK_XFRCM)) {
+ /* Transmit transfer complete.*/
+ USBInEndpointState *isp = usbp->epc[ep]->in_state;
+
+ if (isp->txsize < isp->totsize) {
+ /* In case the transaction covered only part of the total transfer
+ then another transaction is immediately started in order to
+ cover the remaining.*/
+ isp->txsize = isp->totsize - isp->txsize;
+ isp->txcnt = 0;
+ osalSysLockFromISR();
+ usb_lld_start_in(usbp, ep);
+ osalSysUnlockFromISR();
+ }
+ else {
+ /* End on IN transfer.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ }
+ if ((epint & DIEPINT_TXFE) &&
+ (otgp->DIEPEMPMSK & DIEPEMPMSK_INEPTXFEM(ep))) {
+ /* TX FIFO empty or emptying.*/
+ otg_txfifo_handler(usbp, ep);
+ }
+}
+
+/**
+ * @brief Generic endpoint OUT handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
+ stm32_otg_t *otgp = usbp->otg;
+ uint32_t epint = otgp->oe[ep].DOEPINT;
+
+ /* Resets all EP IRQ sources.*/
+ otgp->oe[ep].DOEPINT = epint;
+
+ if ((epint & DOEPINT_STUP) && (otgp->DOEPMSK & DOEPMSK_STUPM)) {
+ /* Setup packets handling, setup packets are handled using a
+ specific callback.*/
+ _usb_isr_invoke_setup_cb(usbp, ep);
+ }
+
+ if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) {
+ USBOutEndpointState *osp;
+
+ /* OUT state structure pointer for this endpoint.*/
+ osp = usbp->epc[ep]->out_state;
+
+ /* EP0 requires special handling.*/
+ if (ep == 0) {
+
+#if defined(STM32_OTG_SEQUENCE_WORKAROUND)
+ /* If an OUT transaction end interrupt is processed while the state
+ machine is not in an OUT state then it is ignored, this is caused
+ on some devices (L4) apparently injecting spurious data complete
+ words in the RX FIFO.*/
+ if ((usbp->ep0state & USB_OUT_STATE) == 0)
+ return;
+#endif
+
+ /* In case the transaction covered only part of the total transfer
+ then another transaction is immediately started in order to
+ cover the remaining.*/
+ if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
+ (osp->rxsize < osp->totsize)) {
+ osp->rxsize = osp->totsize - osp->rxsize;
+ osp->rxcnt = 0;
+ osalSysLockFromISR();
+ usb_lld_start_out(usbp, ep);
+ osalSysUnlockFromISR();
+ return;
+ }
+ }
+
+ /* End on OUT transfer.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+}
+
+/**
+ * @brief Isochronous IN transfer failed handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void otg_isoc_in_failed_handler(USBDriver *usbp) {
+ usbep_t ep;
+ stm32_otg_t *otgp = usbp->otg;
+
+ for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) {
+ if (((otgp->ie[ep].DIEPCTL & DIEPCTL_EPTYP_MASK) == DIEPCTL_EPTYP_ISO) &&
+ ((otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA) != 0)) {
+ /* Endpoint enabled -> ISOC IN transfer failed.*/
+ /* Disable endpoint.*/
+ otgp->ie[ep].DIEPCTL |= (DIEPCTL_EPDIS | DIEPCTL_SNAK);
+ while (otgp->ie[ep].DIEPCTL & DIEPCTL_EPENA)
+ ;
+
+ /* Flush FIFO.*/
+ otg_txfifo_flush(usbp, ep);
+
+ /* Prepare data for next frame.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ }
+}
+
+/**
+ * @brief Isochronous OUT transfer failed handler.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void otg_isoc_out_failed_handler(USBDriver *usbp) {
+ usbep_t ep;
+ stm32_otg_t *otgp = usbp->otg;
+
+ for (ep = 0; ep <= usbp->otgparams->num_endpoints; ep++) {
+ if (((otgp->oe[ep].DOEPCTL & DOEPCTL_EPTYP_MASK) == DOEPCTL_EPTYP_ISO) &&
+ ((otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA) != 0)) {
+#if 0
+ /* Endpoint enabled -> ISOC OUT transfer failed.*/
+ /* Disable endpoint.*/
+ /* CHTODO:: Core stucks here */
+ otgp->oe[ep].DOEPCTL |= (DOEPCTL_EPDIS | DOEPCTL_SNAK);
+ while (otgp->oe[ep].DOEPCTL & DOEPCTL_EPENA)
+ ;
+#endif
+ /* Prepare transfer for next frame.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ }
+}
+
+/**
+ * @brief OTG shared ISR.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+static void usb_lld_serve_interrupt(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+ uint32_t sts, src;
+
+ sts = otgp->GINTSTS;
+ sts &= otgp->GINTMSK;
+ otgp->GINTSTS = sts;
+
+ /* Reset interrupt handling.*/
+ if (sts & GINTSTS_USBRST) {
+ /* Default reset action.*/
+ _usb_reset(usbp);
+
+ /* Preventing execution of more handlers, the core has been reset.*/
+ return;
+ }
+
+ /* Wake-up handling.*/
+ if (sts & GINTSTS_WKUPINT) {
+ /* If clocks are gated off, turn them back on (may be the case if
+ coming out of suspend mode).*/
+ if (otgp->PCGCCTL & (PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK)) {
+ /* Set to zero to un-gate the USB core clocks.*/
+ otgp->PCGCCTL &= ~(PCGCCTL_STPPCLK | PCGCCTL_GATEHCLK);
+ }
+
+ /* Clear the Remote Wake-up Signaling.*/
+ otgp->DCTL &= ~DCTL_RWUSIG;
+
+ _usb_wakeup(usbp);
+ }
+
+ /* Suspend handling.*/
+ if (sts & GINTSTS_USBSUSP) {
+ /* Stopping all ongoing transfers.*/
+ otg_disable_ep(usbp);
+
+ /* Default suspend action.*/
+ _usb_suspend(usbp);
+ }
+
+ /* Enumeration done.*/
+ if (sts & GINTSTS_ENUMDNE) {
+ /* Full or High speed timing selection.*/
+ if ((otgp->DSTS & DSTS_ENUMSPD_MASK) == DSTS_ENUMSPD_HS_480) {
+ otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) |
+ GUSBCFG_TRDT(TRDT_VALUE_HS);
+ }
+ else {
+ otgp->GUSBCFG = (otgp->GUSBCFG & ~(GUSBCFG_TRDT_MASK)) |
+ GUSBCFG_TRDT(TRDT_VALUE_FS);
+ }
+ }
+
+ /* SOF interrupt handling.*/
+ if (sts & GINTSTS_SOF) {
+ _usb_isr_invoke_sof_cb(usbp);
+ }
+
+ /* Isochronous IN failed handling */
+ if (sts & GINTSTS_IISOIXFR) {
+ otg_isoc_in_failed_handler(usbp);
+ }
+
+ /* Isochronous OUT failed handling */
+ if (sts & GINTSTS_IISOOXFR) {
+ otg_isoc_out_failed_handler(usbp);
+ }
+
+ /* Performing the whole FIFO emptying in the ISR, it is advised to keep
+ this IRQ at a very low priority level.*/
+ if ((sts & GINTSTS_RXFLVL) != 0U) {
+ otg_rxfifo_handler(usbp);
+ }
+
+ /* IN/OUT endpoints event handling.*/
+ src = otgp->DAINT;
+ if (sts & GINTSTS_OEPINT) {
+ if (src & (1 << 16))
+ otg_epout_handler(usbp, 0);
+ if (src & (1 << 17))
+ otg_epout_handler(usbp, 1);
+ if (src & (1 << 18))
+ otg_epout_handler(usbp, 2);
+ if (src & (1 << 19))
+ otg_epout_handler(usbp, 3);
+#if USB_MAX_ENDPOINTS >= 4
+ if (src & (1 << 20))
+ otg_epout_handler(usbp, 4);
+#endif
+#if USB_MAX_ENDPOINTS >= 5
+ if (src & (1 << 21))
+ otg_epout_handler(usbp, 5);
+#endif
+#if USB_MAX_ENDPOINTS >= 6
+ if (src & (1 << 22))
+ otg_epout_handler(usbp, 6);
+#endif
+#if USB_MAX_ENDPOINTS >= 7
+ if (src & (1 << 23))
+ otg_epout_handler(usbp, 7);
+#endif
+#if USB_MAX_ENDPOINTS >= 8
+ if (src & (1 << 24))
+ otg_epout_handler(usbp, 8);
+#endif
+ }
+ if (sts & GINTSTS_IEPINT) {
+ if (src & (1 << 0))
+ otg_epin_handler(usbp, 0);
+ if (src & (1 << 1))
+ otg_epin_handler(usbp, 1);
+ if (src & (1 << 2))
+ otg_epin_handler(usbp, 2);
+ if (src & (1 << 3))
+ otg_epin_handler(usbp, 3);
+#if USB_MAX_ENDPOINTS >= 4
+ if (src & (1 << 4))
+ otg_epin_handler(usbp, 4);
+#endif
+#if USB_MAX_ENDPOINTS >= 5
+ if (src & (1 << 5))
+ otg_epin_handler(usbp, 5);
+#endif
+#if USB_MAX_ENDPOINTS >= 6
+ if (src & (1 << 6))
+ otg_epin_handler(usbp, 6);
+#endif
+#if USB_MAX_ENDPOINTS >= 7
+ if (src & (1 << 7))
+ otg_epin_handler(usbp, 7);
+#endif
+#if USB_MAX_ENDPOINTS >= 8
+ if (src & (1 << 8))
+ otg_epin_handler(usbp, 8);
+#endif
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_OTG1 || defined(__DOXYGEN__)
+/**
+ * @brief OTG1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_OTG1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ usb_lld_serve_interrupt(&USBD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_USB_USE_OTG2 || defined(__DOXYGEN__)
+/**
+ * @brief OTG2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_OTG2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ usb_lld_serve_interrupt(&USBD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level USB driver initialization.
+ *
+ * @notapi
+ */
+void usb_lld_init(void) {
+
+ /* Driver initialization.*/
+#if STM32_USB_USE_OTG1
+ usbObjectInit(&USBD1);
+ USBD1.otg = OTG_FS;
+ USBD1.otgparams = &fsparams;
+
+#endif
+
+#if STM32_USB_USE_OTG2
+ usbObjectInit(&USBD2);
+ USBD2.otg = OTG_HS;
+ USBD2.otgparams = &hsparams;
+#endif
+}
+
+/**
+ * @brief Configures and activates the USB peripheral.
+ * @note Starting the OTG cell can be a slow operation carried out with
+ * interrupts disabled, perform it before starting time-critical
+ * operations.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_start(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+
+ if (usbp->state == USB_STOP) {
+ /* Clock activation.*/
+
+#if STM32_USB_USE_OTG1
+ if (&USBD1 == usbp) {
+ /* OTG FS clock enable and reset.*/
+ rccEnableOTG_FS(true);
+ rccResetOTG_FS();
+
+ /* Enables IRQ vector.*/
+ nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY);
+
+ /* - Forced device mode.
+ - USB turn-around time = TRDT_VALUE_FS.
+ - Full Speed 1.1 PHY.*/
+ otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) |
+ GUSBCFG_PHYSEL;
+
+ /* 48MHz 1.1 PHY.*/
+ otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11;
+ }
+#endif
+
+#if STM32_USB_USE_OTG2
+ if (&USBD2 == usbp) {
+ /* OTG HS clock enable and reset.*/
+ rccEnableOTG_HS(true);
+ rccResetOTG_HS();
+
+ /* ULPI clock is managed depending on the presence of an external
+ PHY.*/
+#if defined(BOARD_OTG2_USES_ULPI)
+ rccEnableOTG_HSULPI(true);
+#else
+ /* Workaround for the problem described here:
+ http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798.*/
+ rccDisableOTG_HSULPI();
+#endif
+
+ /* Enables IRQ vector.*/
+ nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY);
+
+ /* - Forced device mode.
+ - USB turn-around time = TRDT_VALUE_HS or TRDT_VALUE_FS.*/
+#if defined(BOARD_OTG2_USES_ULPI)
+ /* High speed ULPI PHY.*/
+ otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_HS) |
+ GUSBCFG_SRPCAP | GUSBCFG_HNPCAP;
+#else
+ otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE_FS) |
+ GUSBCFG_PHYSEL;
+#endif
+
+#if defined(BOARD_OTG2_USES_ULPI)
+#if STM32_USE_USB_OTG2_HS
+ /* USB 2.0 High Speed PHY in HS mode.*/
+ otgp->DCFG = 0x02200000 | DCFG_DSPD_HS;
+#else
+ /* USB 2.0 High Speed PHY in FS mode.*/
+ otgp->DCFG = 0x02200000 | DCFG_DSPD_HS_FS;
+#endif
+#else
+ /* 48MHz 1.1 PHY.*/
+ otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11;
+#endif
+ }
+#endif
+
+ /* PHY enabled.*/
+ otgp->PCGCCTL = 0;
+
+ /* VBUS sensing and transceiver enabled.*/
+ otgp->GOTGCTL = GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL;
+
+#if defined(BOARD_OTG2_USES_ULPI)
+#if STM32_USB_USE_OTG1
+ if (&USBD1 == usbp) {
+ otgp->GCCFG = GCCFG_INIT_VALUE;
+ }
+#endif
+
+#if STM32_USB_USE_OTG2
+ if (&USBD2 == usbp) {
+ otgp->GCCFG = 0;
+ }
+#endif
+#else
+ otgp->GCCFG = GCCFG_INIT_VALUE;
+#endif
+
+ /* Soft core reset.*/
+ otg_core_reset(usbp);
+
+ /* Interrupts on TXFIFOs half empty.*/
+ otgp->GAHBCFG = 0;
+
+ /* Endpoints re-initialization.*/
+ otg_disable_ep(usbp);
+
+ /* Clear all pending Device Interrupts, only the USB Reset interrupt
+ is required initially.*/
+ otgp->DIEPMSK = 0;
+ otgp->DOEPMSK = 0;
+ otgp->DAINTMSK = 0;
+ if (usbp->config->sof_cb == NULL)
+ otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM |
+ GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM |
+ GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM;
+ else
+ otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM | GINTMSK_USBSUSPM |
+ GINTMSK_ESUSPM | GINTMSK_SRQM | GINTMSK_WKUM |
+ GINTMSK_IISOIXFRM | GINTMSK_IISOOXFRM |
+ GINTMSK_SOFM;
+
+ /* Clears all pending IRQs, if any. */
+ otgp->GINTSTS = 0xFFFFFFFF;
+
+ /* Global interrupts enable.*/
+ otgp->GAHBCFG |= GAHBCFG_GINTMSK;
+ }
+}
+
+/**
+ * @brief Deactivates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_stop(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+
+ /* If in ready state then disables the USB clock.*/
+ if (usbp->state != USB_STOP) {
+
+ /* Disabling all endpoints in case the driver has been stopped while
+ active.*/
+ otg_disable_ep(usbp);
+
+ otgp->DAINTMSK = 0;
+ otgp->GAHBCFG = 0;
+ otgp->GCCFG = 0;
+
+#if STM32_USB_USE_OTG1
+ if (&USBD1 == usbp) {
+ nvicDisableVector(STM32_OTG1_NUMBER);
+ rccDisableOTG_FS();
+ }
+#endif
+
+#if STM32_USB_USE_OTG2
+ if (&USBD2 == usbp) {
+ nvicDisableVector(STM32_OTG2_NUMBER);
+ rccDisableOTG_HS();
+#if defined(BOARD_OTG2_USES_ULPI)
+ rccDisableOTG_HSULPI()
+#endif
+ }
+#endif
+ }
+}
+
+/**
+ * @brief USB low level reset routine.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_reset(USBDriver *usbp) {
+ unsigned i;
+ stm32_otg_t *otgp = usbp->otg;
+
+ /* Flush the Tx FIFO.*/
+ otg_txfifo_flush(usbp, 0);
+
+ /* Endpoint interrupts all disabled and cleared.*/
+ otgp->DIEPEMPMSK = 0;
+ otgp->DAINTMSK = DAINTMSK_OEPM(0) | DAINTMSK_IEPM(0);
+
+ /* All endpoints in NAK mode, interrupts cleared.*/
+ for (i = 0; i <= usbp->otgparams->num_endpoints; i++) {
+ otgp->ie[i].DIEPCTL = DIEPCTL_SNAK;
+ otgp->oe[i].DOEPCTL = DOEPCTL_SNAK;
+ otgp->ie[i].DIEPINT = 0xFFFFFFFF;
+ otgp->oe[i].DOEPINT = 0xFFFFFFFF;
+ }
+
+ /* Resets the FIFO memory allocator.*/
+ otg_ram_reset(usbp);
+
+ /* Receive FIFO size initialization, the address is always zero.*/
+ otgp->GRXFSIZ = usbp->otgparams->rx_fifo_size;
+ otg_rxfifo_flush(usbp);
+
+ /* Resets the device address to zero.*/
+ otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(0);
+
+ /* Enables also EP-related interrupt sources.*/
+ otgp->GINTMSK |= GINTMSK_RXFLVLM | GINTMSK_OEPM | GINTMSK_IEPM;
+ otgp->DIEPMSK = DIEPMSK_TOCM | DIEPMSK_XFRCM;
+ otgp->DOEPMSK = DOEPMSK_STUPM | DOEPMSK_XFRCM;
+
+ /* EP0 initialization, it is a special case.*/
+ usbp->epc[0] = &ep0config;
+ otgp->oe[0].DOEPTSIZ = DOEPTSIZ_STUPCNT(3);
+ otgp->oe[0].DOEPCTL = DOEPCTL_SD0PID | DOEPCTL_USBAEP | DOEPCTL_EPTYP_CTRL |
+ DOEPCTL_MPSIZ(ep0config.out_maxsize);
+ otgp->ie[0].DIEPTSIZ = 0;
+ otgp->ie[0].DIEPCTL = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL |
+ DIEPCTL_TXFNUM(0) | DIEPCTL_MPSIZ(ep0config.in_maxsize);
+ otgp->DIEPTXF0 = DIEPTXF_INEPTXFD(ep0config.in_maxsize / 4) |
+ DIEPTXF_INEPTXSA(otg_ram_alloc(usbp,
+ ep0config.in_maxsize / 4));
+}
+
+/**
+ * @brief Sets the USB address.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_set_address(USBDriver *usbp) {
+ stm32_otg_t *otgp = usbp->otg;
+
+ otgp->DCFG = (otgp->DCFG & ~DCFG_DAD_MASK) | DCFG_DAD(usbp->address);
+}
+
+/**
+ * @brief Enables an endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
+ uint32_t ctl, fsize;
+ stm32_otg_t *otgp = usbp->otg;
+
+ /* IN and OUT common parameters.*/
+ switch (usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) {
+ case USB_EP_MODE_TYPE_CTRL:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_CTRL;
+ break;
+ case USB_EP_MODE_TYPE_ISOC:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_ISO;
+ break;
+ case USB_EP_MODE_TYPE_BULK:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_BULK;
+ break;
+ case USB_EP_MODE_TYPE_INTR:
+ ctl = DIEPCTL_SD0PID | DIEPCTL_USBAEP | DIEPCTL_EPTYP_INTR;
+ break;
+ default:
+ return;
+ }
+
+ /* OUT endpoint activation or deactivation.*/
+ otgp->oe[ep].DOEPTSIZ = 0;
+ if (usbp->epc[ep]->out_state != NULL) {
+ otgp->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize);
+ otgp->DAINTMSK |= DAINTMSK_OEPM(ep);
+ }
+ else {
+ otgp->oe[ep].DOEPCTL &= ~DOEPCTL_USBAEP;
+ otgp->DAINTMSK &= ~DAINTMSK_OEPM(ep);
+ }
+
+ /* IN endpoint activation or deactivation.*/
+ otgp->ie[ep].DIEPTSIZ = 0;
+ if (usbp->epc[ep]->in_state != NULL) {
+ /* FIFO allocation for the IN endpoint.*/
+ fsize = usbp->epc[ep]->in_maxsize / 4;
+ if (usbp->epc[ep]->in_multiplier > 1)
+ fsize *= usbp->epc[ep]->in_multiplier;
+ otgp->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) |
+ DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize));
+ otg_txfifo_flush(usbp, ep);
+
+ otgp->ie[ep].DIEPCTL = ctl |
+ DIEPCTL_TXFNUM(ep) |
+ DIEPCTL_MPSIZ(usbp->epc[ep]->in_maxsize);
+ otgp->DAINTMSK |= DAINTMSK_IEPM(ep);
+ }
+ else {
+ otgp->DIEPTXF[ep - 1] = 0x02000400; /* Reset value.*/
+ otg_txfifo_flush(usbp, ep);
+ otgp->ie[ep].DIEPCTL &= ~DIEPCTL_USBAEP;
+ otgp->DAINTMSK &= ~DAINTMSK_IEPM(ep);
+ }
+}
+
+/**
+ * @brief Disables all the active endpoints except the endpoint zero.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_disable_endpoints(USBDriver *usbp) {
+
+ /* Resets the FIFO memory allocator.*/
+ otg_ram_reset(usbp);
+
+ /* Disabling all endpoints.*/
+ otg_disable_ep(usbp);
+}
+
+/**
+ * @brief Returns the status of an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
+ uint32_t ctl;
+
+ (void)usbp;
+
+ ctl = usbp->otg->oe[ep].DOEPCTL;
+ if (!(ctl & DOEPCTL_USBAEP))
+ return EP_STATUS_DISABLED;
+ if (ctl & DOEPCTL_STALL)
+ return EP_STATUS_STALLED;
+ return EP_STATUS_ACTIVE;
+}
+
+/**
+ * @brief Returns the status of an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
+ uint32_t ctl;
+
+ (void)usbp;
+
+ ctl = usbp->otg->ie[ep].DIEPCTL;
+ if (!(ctl & DIEPCTL_USBAEP))
+ return EP_STATUS_DISABLED;
+ if (ctl & DIEPCTL_STALL)
+ return EP_STATUS_STALLED;
+ return EP_STATUS_ACTIVE;
+}
+
+/**
+ * @brief Reads a setup packet from the dedicated packet buffer.
+ * @details This function must be invoked in the context of the @p setup_cb
+ * callback in order to read the received setup packet.
+ * @pre In order to use this function the endpoint must have been
+ * initialized as a control endpoint.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ *
+ * @notapi
+ */
+void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
+
+ memcpy(buf, usbp->epc[ep]->setup_buf, 8);
+}
+
+/**
+ * @brief Starts a receive operation on an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
+ uint32_t pcnt, rxsize;
+ USBOutEndpointState *osp = usbp->epc[ep]->out_state;
+
+ /* Transfer initialization.*/
+ osp->totsize = osp->rxsize;
+ if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE))
+ osp->rxsize = EP0_MAX_OUTSIZE;
+
+ /* Transaction size is rounded to a multiple of packet size because the
+ following requirement in the RM:
+ "For OUT transfers, the transfer size field in the endpoint's transfer
+ size register must be a multiple of the maximum packet size of the
+ endpoint, adjusted to the Word boundary".*/
+ pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1U) /
+ usbp->epc[ep]->out_maxsize;
+ rxsize = (pcnt * usbp->epc[ep]->out_maxsize + 3U) & 0xFFFFFFFCU;
+
+ /*Setting up transaction parameters in DOEPTSIZ.*/
+ usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
+ DOEPTSIZ_XFRSIZ(rxsize);
+
+ /* Special case of isochronous endpoint.*/
+ if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
+ /* Odd/even bit toggling for isochronous endpoint.*/
+ if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SEVNFRM;
+ else
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM;
+ }
+
+ /* Starting operation.*/
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK;
+}
+
+/**
+ * @brief Starts a transmit operation on an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
+ USBInEndpointState *isp = usbp->epc[ep]->in_state;
+
+ /* Transfer initialization.*/
+ isp->totsize = isp->txsize;
+ if (isp->txsize == 0) {
+ /* Special case, sending zero size packet.*/
+ usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
+ }
+ else {
+ if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE))
+ isp->txsize = EP0_MAX_INSIZE;
+
+ /* Normal case.*/
+ uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) /
+ usbp->epc[ep]->in_maxsize;
+ /* CHTODO: Support more than one packet per frame for isochronous transfers.*/
+ usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) |
+ DIEPTSIZ_XFRSIZ(isp->txsize);
+ }
+
+ /* Special case of isochronous endpoint.*/
+ if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
+ /* Odd/even bit toggling.*/
+ if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
+ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SEVNFRM;
+ else
+ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM;
+ }
+
+ /* Starting operation.*/
+ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
+ usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep);
+}
+
+/**
+ * @brief Brings an OUT endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
+
+ usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_STALL;
+}
+
+/**
+ * @brief Brings an IN endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
+
+ usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_STALL;
+}
+
+/**
+ * @brief Brings an OUT endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
+
+ usbp->otg->oe[ep].DOEPCTL &= ~DOEPCTL_STALL;
+}
+
+/**
+ * @brief Brings an IN endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
+
+ usbp->otg->ie[ep].DIEPCTL &= ~DIEPCTL_STALL;
+}
+
+#endif /* HAL_USE_USB */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h
index 4d7ae15935..1ccdeae2a5 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h
+++ b/os/hal/ports/STM32/LLD/OTGv1/hal_usb_lld.h
@@ -1,604 +1,604 @@
-/*
- 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 OTGv1/hal_usb_lld.h
- * @brief STM32 USB subsystem low level driver header.
- *
- * @addtogroup USB
- * @{
- */
-
-#ifndef HAL_USB_LLD_H
-#define HAL_USB_LLD_H
-
-#if HAL_USE_USB || defined(__DOXYGEN__)
-
-#include "stm32_otg.h"
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Status stage handling method.
- */
-#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
-
-/**
- * @brief The address can be changed immediately upon packet reception.
- */
-#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS
-
-/**
- * @brief Method for set address acknowledge.
- */
-#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @brief OTG1 driver enable switch.
- * @details If set to @p TRUE the support for OTG_FS is included.
- * @note The default is @p FALSE
- */
-#if !defined(STM32_USB_USE_OTG1) || defined(__DOXYGEN__)
-#define STM32_USB_USE_OTG1 FALSE
-#endif
-
-/**
- * @brief OTG2 driver enable switch.
- * @details If set to @p TRUE the support for OTG_HS is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_USB_USE_OTG2) || defined(__DOXYGEN__)
-#define STM32_USB_USE_OTG2 FALSE
-#endif
-
-/**
- * @brief OTG1 interrupt priority level setting.
- */
-#if !defined(STM32_USB_OTG1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_USB_OTG1_IRQ_PRIORITY 14
-#endif
-
-/**
- * @brief OTG2 interrupt priority level setting.
- */
-#if !defined(STM32_USB_OTG2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_USB_OTG2_IRQ_PRIORITY 14
-#endif
-
-/**
- * @brief OTG1 RX shared FIFO size.
- * @note Must be a multiple of 4.
- */
-#if !defined(STM32_USB_OTG1_RX_FIFO_SIZE) || defined(__DOXYGEN__)
-#define STM32_USB_OTG1_RX_FIFO_SIZE 512
-#endif
-
-/**
- * @brief OTG2 RX shared FIFO size.
- * @note Must be a multiple of 4.
- */
-#if !defined(STM32_USB_OTG2_RX_FIFO_SIZE) || defined(__DOXYGEN__)
-#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
-#endif
-
-/**
- * @brief Enables HS mode on OTG2 else FS mode.
- * @note The default is @p TRUE.
- * @note Has effect only if @p BOARD_OTG2_USES_ULPI is defined.
- */
-#if !defined(STM32_USE_USB_OTG2_HS) || defined(__DOXYGEN__)
-#define STM32_USE_USB_OTG2_HS TRUE
-#endif
-
-/**
- * @brief Exception priority level during TXFIFOs operations.
- * @note Because an undocumented silicon behavior the operation of
- * copying a packet into a TXFIFO must not be interrupted by
- * any other operation on the OTG peripheral.
- * This parameter represents the priority mask during copy
- * operations. The default value only allows to call USB
- * functions from callbacks invoked from USB ISR handlers.
- * If you need to invoke USB functions from other handlers
- * then raise this priority mast to the same level of the
- * handler you need to use.
- * @note The value zero means disabled, when disabled calling USB
- * functions is only safe from thread level or from USB
- * callbacks.
- */
-#if !defined(STM32_USB_OTGFIFO_FILL_BASEPRI) || defined(__DOXYGEN__)
-#define STM32_USB_OTGFIFO_FILL_BASEPRI 0
-#endif
-
-/**
- * @brief Host wake-up procedure duration.
- */
-#if !defined(STM32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
-#define STM32_USB_HOST_WAKEUP_DURATION 2
-#endif
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Registry checks.*/
-#if !defined(STM32_OTG_STEPPING)
-#error "STM32_OTG_STEPPING not defined in registry"
-#endif
-
-#if (STM32_OTG_STEPPING < 1) || (STM32_OTG_STEPPING > 2)
-#error "unsupported STM32_OTG_STEPPING"
-#endif
-
-#if !defined(STM32_HAS_OTG1) || !defined(STM32_HAS_OTG2)
-#error "STM32_HAS_OTGx not defined in registry"
-#endif
-
-#if STM32_HAS_OTG1 && !defined(STM32_OTG1_ENDPOINTS)
-#error "STM32_OTG1_ENDPOINTS not defined in registry"
-#endif
-
-#if STM32_HAS_OTG2 && !defined(STM32_OTG2_ENDPOINTS)
-#error "STM32_OTG2_ENDPOINTS not defined in registry"
-#endif
-
-#if STM32_HAS_OTG1 && !defined(STM32_OTG1_FIFO_MEM_SIZE)
-#error "STM32_OTG1_FIFO_MEM_SIZE not defined in registry"
-#endif
-
-#if STM32_HAS_OTG2 && !defined(STM32_OTG2_FIFO_MEM_SIZE)
-#error "STM32_OTG2_FIFO_MEM_SIZE not defined in registry"
-#endif
-
-#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_HANDLER)) || \
- (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_HANDLER))
-#error "STM32_OTGx_HANDLER not defined in registry"
-#endif
-
-#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_NUMBER)) || \
- (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_NUMBER))
-#error "STM32_OTGx_NUMBER not defined in registry"
-#endif
-
-/**
- * @brief Maximum endpoint address.
- */
-#if (STM32_HAS_OTG2 && STM32_USB_USE_OTG2) || defined(__DOXYGEN__)
-#if (STM32_OTG1_ENDPOINTS < STM32_OTG2_ENDPOINTS) || defined(__DOXYGEN__)
-#define USB_MAX_ENDPOINTS STM32_OTG2_ENDPOINTS
-#else
-#define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS
-#endif
-#else
-#define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS
-#endif
-
-#if STM32_USB_USE_OTG1 && !STM32_HAS_OTG1
-#error "OTG1 not present in the selected device"
-#endif
-
-#if STM32_USB_USE_OTG2 && !STM32_HAS_OTG2
-#error "OTG2 not present in the selected device"
-#endif
-
-#if !STM32_USB_USE_OTG1 && !STM32_USB_USE_OTG2
-#error "USB driver activated but no USB peripheral assigned"
-#endif
-
-#if STM32_USB_USE_OTG1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to OTG1"
-#endif
-
-#if STM32_USB_USE_OTG2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to OTG2"
-#endif
-
-#if (STM32_USB_OTG1_RX_FIFO_SIZE & 3) != 0
-#error "OTG1 RX FIFO size must be a multiple of 4"
-#endif
-
-#if (STM32_USB_OTG2_RX_FIFO_SIZE & 3) != 0
-#error "OTG2 RX FIFO size must be a multiple of 4"
-#endif
-
-#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX)
-#define STM32_USBCLK STM32_PLL48CLK
-#elif defined(STM32F10X_CL)
-#define STM32_USBCLK STM32_OTGFSCLK
-#elif defined(STM32L4XX) || defined(STM32L4XXP)
-#define STM32_USBCLK STM32_48CLK
-#elif defined(STM32H7XX)
-/* Defines directly STM32_USBCLK.*/
-#define rccEnableOTG_FS rccEnableUSB2_OTG_FS
-#define rccDisableOTG_FS rccDisableUSB2_OTG_FS
-#define rccResetOTG_FS rccResetUSB2_OTG_FS
-#define rccEnableOTG_HS rccEnableUSB1_OTG_HS
-#define rccDisableOTG_HS rccDisableUSB1_OTG_HS
-#define rccResetOTG_HS rccResetUSB1_OTG_HS
-#define rccEnableOTG_HSULPI rccEnableUSB1_HSULPI
-#define rccDisableOTG_HSULPI rccDisableUSB1_HSULPI
-#else
-#error "unsupported STM32 platform for OTG functionality"
-#endif
-
-/* Allowing for a small tolerance.*/
-#if STM32_USBCLK < 47880000 || STM32_USBCLK > 48120000
-#error "the USB OTG driver requires a 48MHz clock"
-#endif
-
-#if (STM32_USB_HOST_WAKEUP_DURATION < 2) || (STM32_USB_HOST_WAKEUP_DURATION > 15)
-#error "invalid STM32_USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Peripheral-specific parameters block.
- */
-typedef struct {
- uint32_t rx_fifo_size;
- uint32_t otg_ram_size;
- uint32_t num_endpoints;
-} stm32_otg_params_t;
-
-/**
- * @brief Type of an IN endpoint state structure.
- */
-typedef struct {
- /**
- * @brief Requested transmit transfer size.
- */
- size_t txsize;
- /**
- * @brief Transmitted bytes so far.
- */
- size_t txcnt;
- /**
- * @brief Pointer to the transmission linear buffer.
- */
- const uint8_t *txbuf;
-#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Waiting thread.
- */
- thread_reference_t thread;
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Total transmit transfer size.
- */
- size_t totsize;
-} USBInEndpointState;
-
-/**
- * @brief Type of an OUT endpoint state structure.
- */
-typedef struct {
- /**
- * @brief Requested receive transfer size.
- */
- size_t rxsize;
- /**
- * @brief Received bytes so far.
- */
- size_t rxcnt;
- /**
- * @brief Pointer to the receive linear buffer.
- */
- uint8_t *rxbuf;
-#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Waiting thread.
- */
- thread_reference_t thread;
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Total receive transfer size.
- */
- size_t totsize;
-} USBOutEndpointState;
-
-/**
- * @brief Type of an USB endpoint configuration structure.
- * @note Platform specific restrictions may apply to endpoints.
- */
-typedef struct {
- /**
- * @brief Type and mode of the endpoint.
- */
- uint32_t ep_mode;
- /**
- * @brief Setup packet notification callback.
- * @details This callback is invoked when a setup packet has been
- * received.
- * @post The application must immediately call @p usbReadPacket() in
- * order to access the received packet.
- * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
- * endpoints, it should be set to @p NULL for other endpoint
- * types.
- */
- usbepcallback_t setup_cb;
- /**
- * @brief IN endpoint notification callback.
- * @details This field must be set to @p NULL if callback is not required.
- */
- usbepcallback_t in_cb;
- /**
- * @brief OUT endpoint notification callback.
- * @details This field must be set to @p NULL if callback is not required.
- */
- usbepcallback_t out_cb;
- /**
- * @brief IN endpoint maximum packet size.
- * @details This field must be set to zero if the IN endpoint is not used.
- */
- uint16_t in_maxsize;
- /**
- * @brief OUT endpoint maximum packet size.
- * @details This field must be set to zero if the OUT endpoint is not used.
- */
- uint16_t out_maxsize;
- /**
- * @brief @p USBEndpointState associated to the IN endpoint.
- * @details This field must be set to @p NULL if the IN endpoint is not
- * used.
- */
- USBInEndpointState *in_state;
- /**
- * @brief @p USBEndpointState associated to the OUT endpoint.
- * @details This field must be set to @p NULL if the OUT endpoint is not
- * used.
- */
- USBOutEndpointState *out_state;
- /* End of the mandatory fields.*/
- /**
- * @brief Determines the space allocated for the TXFIFO as multiples of
- * the packet size (@p in_maxsize). Note that zero is interpreted
- * as one for simplicity and robustness.
- */
- uint16_t in_multiplier;
- /**
- * @brief Pointer to a buffer for setup packets.
- * @details Setup packets require a dedicated 8-bytes buffer, set this
- * field to @p NULL for non-control endpoints.
- */
- uint8_t *setup_buf;
-} USBEndpointConfig;
-
-/**
- * @brief Type of an USB driver configuration structure.
- */
-typedef struct {
- /**
- * @brief USB events callback.
- * @details This callback is invoked when an USB driver event is registered.
- */
- usbeventcb_t event_cb;
- /**
- * @brief Device GET_DESCRIPTOR request callback.
- * @note This callback is mandatory and cannot be set to @p NULL.
- */
- usbgetdescriptor_t get_descriptor_cb;
- /**
- * @brief Requests hook callback.
- * @details This hook allows to be notified of standard requests or to
- * handle non standard requests.
- */
- usbreqhandler_t requests_hook_cb;
- /**
- * @brief Start Of Frame callback.
- */
- usbcallback_t sof_cb;
- /* End of the mandatory fields.*/
-} USBConfig;
-
-/**
- * @brief Structure representing an USB driver.
- */
-struct USBDriver {
- /**
- * @brief Driver state.
- */
- usbstate_t state;
- /**
- * @brief Current configuration data.
- */
- const USBConfig *config;
- /**
- * @brief Bit map of the transmitting IN endpoints.
- */
- uint16_t transmitting;
- /**
- * @brief Bit map of the receiving OUT endpoints.
- */
- uint16_t receiving;
- /**
- * @brief Active endpoints configurations.
- */
- const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
- /**
- * @brief Fields available to user, it can be used to associate an
- * application-defined handler to an IN endpoint.
- * @note The base index is one, the endpoint zero does not have a
- * reserved element in this array.
- */
- void *in_params[USB_MAX_ENDPOINTS];
- /**
- * @brief Fields available to user, it can be used to associate an
- * application-defined handler to an OUT endpoint.
- * @note The base index is one, the endpoint zero does not have a
- * reserved element in this array.
- */
- void *out_params[USB_MAX_ENDPOINTS];
- /**
- * @brief Endpoint 0 state.
- */
- usbep0state_t ep0state;
- /**
- * @brief Next position in the buffer to be transferred through endpoint 0.
- */
- uint8_t *ep0next;
- /**
- * @brief Number of bytes yet to be transferred through endpoint 0.
- */
- size_t ep0n;
- /**
- * @brief Endpoint 0 end transaction callback.
- */
- usbcallback_t ep0endcb;
- /**
- * @brief Setup packet buffer.
- */
- uint8_t setup[8];
- /**
- * @brief Current USB device status.
- */
- uint16_t status;
- /**
- * @brief Assigned USB address.
- */
- uint8_t address;
- /**
- * @brief Current USB device configuration.
- */
- uint8_t configuration;
- /**
- * @brief State of the driver when a suspend happened.
- */
- usbstate_t saved_state;
-#if defined(USB_DRIVER_EXT_FIELDS)
- USB_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the OTG peripheral associated to this driver.
- */
- stm32_otg_t *otg;
- /**
- * @brief Peripheral-specific parameters.
- */
- const stm32_otg_params_t *otgparams;
- /**
- * @brief Pointer to the next address in the packet memory.
- */
- uint32_t pmnext;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Returns the exact size of a receive transaction.
- * @details The received size can be different from the size specified in
- * @p usbStartReceiveI() because the last packet could have a size
- * different from the expected one.
- * @pre The OUT endpoint must have been configured in transaction mode
- * in order to use this function.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @return Received data size.
- *
- * @notapi
- */
-#define usb_lld_get_transaction_size(usbp, ep) \
- ((usbp)->epc[ep]->out_state->rxcnt)
-
-/**
- * @brief Connects the USB device.
- *
- * @notapi
- */
-#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__)
-#define usb_lld_connect_bus(usbp) ((usbp)->otg->GCCFG |= GCCFG_VBUSBSEN)
-#else
-#define usb_lld_connect_bus(usbp) ((usbp)->otg->DCTL &= ~DCTL_SDIS)
-#endif
-
-/**
- * @brief Disconnect the USB device.
- *
- * @notapi
- */
-#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__)
-#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN)
-#else
-#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->DCTL |= DCTL_SDIS)
-#endif
-
-/**
- * @brief Start of host wake-up procedure.
- *
- * @notapi
- */
-#define usb_lld_wakeup_host(usbp) \
- do { \
- (usbp)->otg->DCTL |= DCTL_RWUSIG; \
- osalThreadSleepMilliseconds(STM32_USB_HOST_WAKEUP_DURATION); \
- (usbp)->otg->DCTL &= ~DCTL_RWUSIG; \
- } while (false)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_USB_USE_OTG1 && !defined(__DOXYGEN__)
-extern USBDriver USBD1;
-#endif
-
-#if STM32_USB_USE_OTG2 && !defined(__DOXYGEN__)
-extern USBDriver USBD2;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void usb_lld_init(void);
- void usb_lld_start(USBDriver *usbp);
- void usb_lld_stop(USBDriver *usbp);
- void usb_lld_reset(USBDriver *usbp);
- void usb_lld_set_address(USBDriver *usbp);
- void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
- void usb_lld_disable_endpoints(USBDriver *usbp);
- usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
- usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
- void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
- void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
- void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_USB */
-
-#endif /* HAL_USB_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 OTGv1/hal_usb_lld.h
+ * @brief STM32 USB subsystem low level driver header.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef HAL_USB_LLD_H
+#define HAL_USB_LLD_H
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+#include "stm32_otg.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Status stage handling method.
+ */
+#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
+
+/**
+ * @brief The address can be changed immediately upon packet reception.
+ */
+#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS
+
+/**
+ * @brief Method for set address acknowledge.
+ */
+#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief OTG1 driver enable switch.
+ * @details If set to @p TRUE the support for OTG_FS is included.
+ * @note The default is @p FALSE
+ */
+#if !defined(STM32_USB_USE_OTG1) || defined(__DOXYGEN__)
+#define STM32_USB_USE_OTG1 FALSE
+#endif
+
+/**
+ * @brief OTG2 driver enable switch.
+ * @details If set to @p TRUE the support for OTG_HS is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_USB_USE_OTG2) || defined(__DOXYGEN__)
+#define STM32_USB_USE_OTG2 FALSE
+#endif
+
+/**
+ * @brief OTG1 interrupt priority level setting.
+ */
+#if !defined(STM32_USB_OTG1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_USB_OTG1_IRQ_PRIORITY 14
+#endif
+
+/**
+ * @brief OTG2 interrupt priority level setting.
+ */
+#if !defined(STM32_USB_OTG2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_USB_OTG2_IRQ_PRIORITY 14
+#endif
+
+/**
+ * @brief OTG1 RX shared FIFO size.
+ * @note Must be a multiple of 4.
+ */
+#if !defined(STM32_USB_OTG1_RX_FIFO_SIZE) || defined(__DOXYGEN__)
+#define STM32_USB_OTG1_RX_FIFO_SIZE 512
+#endif
+
+/**
+ * @brief OTG2 RX shared FIFO size.
+ * @note Must be a multiple of 4.
+ */
+#if !defined(STM32_USB_OTG2_RX_FIFO_SIZE) || defined(__DOXYGEN__)
+#define STM32_USB_OTG2_RX_FIFO_SIZE 1024
+#endif
+
+/**
+ * @brief Enables HS mode on OTG2 else FS mode.
+ * @note The default is @p TRUE.
+ * @note Has effect only if @p BOARD_OTG2_USES_ULPI is defined.
+ */
+#if !defined(STM32_USE_USB_OTG2_HS) || defined(__DOXYGEN__)
+#define STM32_USE_USB_OTG2_HS TRUE
+#endif
+
+/**
+ * @brief Exception priority level during TXFIFOs operations.
+ * @note Because an undocumented silicon behavior the operation of
+ * copying a packet into a TXFIFO must not be interrupted by
+ * any other operation on the OTG peripheral.
+ * This parameter represents the priority mask during copy
+ * operations. The default value only allows to call USB
+ * functions from callbacks invoked from USB ISR handlers.
+ * If you need to invoke USB functions from other handlers
+ * then raise this priority mast to the same level of the
+ * handler you need to use.
+ * @note The value zero means disabled, when disabled calling USB
+ * functions is only safe from thread level or from USB
+ * callbacks.
+ */
+#if !defined(STM32_USB_OTGFIFO_FILL_BASEPRI) || defined(__DOXYGEN__)
+#define STM32_USB_OTGFIFO_FILL_BASEPRI 0
+#endif
+
+/**
+ * @brief Host wake-up procedure duration.
+ */
+#if !defined(STM32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
+#define STM32_USB_HOST_WAKEUP_DURATION 2
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Registry checks.*/
+#if !defined(STM32_OTG_STEPPING)
+#error "STM32_OTG_STEPPING not defined in registry"
+#endif
+
+#if (STM32_OTG_STEPPING < 1) || (STM32_OTG_STEPPING > 2)
+#error "unsupported STM32_OTG_STEPPING"
+#endif
+
+#if !defined(STM32_HAS_OTG1) || !defined(STM32_HAS_OTG2)
+#error "STM32_HAS_OTGx not defined in registry"
+#endif
+
+#if STM32_HAS_OTG1 && !defined(STM32_OTG1_ENDPOINTS)
+#error "STM32_OTG1_ENDPOINTS not defined in registry"
+#endif
+
+#if STM32_HAS_OTG2 && !defined(STM32_OTG2_ENDPOINTS)
+#error "STM32_OTG2_ENDPOINTS not defined in registry"
+#endif
+
+#if STM32_HAS_OTG1 && !defined(STM32_OTG1_FIFO_MEM_SIZE)
+#error "STM32_OTG1_FIFO_MEM_SIZE not defined in registry"
+#endif
+
+#if STM32_HAS_OTG2 && !defined(STM32_OTG2_FIFO_MEM_SIZE)
+#error "STM32_OTG2_FIFO_MEM_SIZE not defined in registry"
+#endif
+
+#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_HANDLER)) || \
+ (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_HANDLER))
+#error "STM32_OTGx_HANDLER not defined in registry"
+#endif
+
+#if (STM32_USB_USE_OTG1 && !defined(STM32_OTG1_NUMBER)) || \
+ (STM32_USB_USE_OTG2 && !defined(STM32_OTG2_NUMBER))
+#error "STM32_OTGx_NUMBER not defined in registry"
+#endif
+
+/**
+ * @brief Maximum endpoint address.
+ */
+#if (STM32_HAS_OTG2 && STM32_USB_USE_OTG2) || defined(__DOXYGEN__)
+#if (STM32_OTG1_ENDPOINTS < STM32_OTG2_ENDPOINTS) || defined(__DOXYGEN__)
+#define USB_MAX_ENDPOINTS STM32_OTG2_ENDPOINTS
+#else
+#define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS
+#endif
+#else
+#define USB_MAX_ENDPOINTS STM32_OTG1_ENDPOINTS
+#endif
+
+#if STM32_USB_USE_OTG1 && !STM32_HAS_OTG1
+#error "OTG1 not present in the selected device"
+#endif
+
+#if STM32_USB_USE_OTG2 && !STM32_HAS_OTG2
+#error "OTG2 not present in the selected device"
+#endif
+
+#if !STM32_USB_USE_OTG1 && !STM32_USB_USE_OTG2
+#error "USB driver activated but no USB peripheral assigned"
+#endif
+
+#if STM32_USB_USE_OTG1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to OTG1"
+#endif
+
+#if STM32_USB_USE_OTG2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_OTG2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to OTG2"
+#endif
+
+#if (STM32_USB_OTG1_RX_FIFO_SIZE & 3) != 0
+#error "OTG1 RX FIFO size must be a multiple of 4"
+#endif
+
+#if (STM32_USB_OTG2_RX_FIFO_SIZE & 3) != 0
+#error "OTG2 RX FIFO size must be a multiple of 4"
+#endif
+
+#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F7XX)
+#define STM32_USBCLK STM32_PLL48CLK
+#elif defined(STM32F10X_CL)
+#define STM32_USBCLK STM32_OTGFSCLK
+#elif defined(STM32L4XX) || defined(STM32L4XXP)
+#define STM32_USBCLK STM32_48CLK
+#elif defined(STM32H7XX)
+/* Defines directly STM32_USBCLK.*/
+#define rccEnableOTG_FS rccEnableUSB2_OTG_FS
+#define rccDisableOTG_FS rccDisableUSB2_OTG_FS
+#define rccResetOTG_FS rccResetUSB2_OTG_FS
+#define rccEnableOTG_HS rccEnableUSB1_OTG_HS
+#define rccDisableOTG_HS rccDisableUSB1_OTG_HS
+#define rccResetOTG_HS rccResetUSB1_OTG_HS
+#define rccEnableOTG_HSULPI rccEnableUSB1_HSULPI
+#define rccDisableOTG_HSULPI rccDisableUSB1_HSULPI
+#else
+#error "unsupported STM32 platform for OTG functionality"
+#endif
+
+/* Allowing for a small tolerance.*/
+#if STM32_USBCLK < 47880000 || STM32_USBCLK > 48120000
+#error "the USB OTG driver requires a 48MHz clock"
+#endif
+
+#if (STM32_USB_HOST_WAKEUP_DURATION < 2) || (STM32_USB_HOST_WAKEUP_DURATION > 15)
+#error "invalid STM32_USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Peripheral-specific parameters block.
+ */
+typedef struct {
+ uint32_t rx_fifo_size;
+ uint32_t otg_ram_size;
+ uint32_t num_endpoints;
+} stm32_otg_params_t;
+
+/**
+ * @brief Type of an IN endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Requested transmit transfer size.
+ */
+ size_t txsize;
+ /**
+ * @brief Transmitted bytes so far.
+ */
+ size_t txcnt;
+ /**
+ * @brief Pointer to the transmission linear buffer.
+ */
+ const uint8_t *txbuf;
+#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ thread_reference_t thread;
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Total transmit transfer size.
+ */
+ size_t totsize;
+} USBInEndpointState;
+
+/**
+ * @brief Type of an OUT endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Requested receive transfer size.
+ */
+ size_t rxsize;
+ /**
+ * @brief Received bytes so far.
+ */
+ size_t rxcnt;
+ /**
+ * @brief Pointer to the receive linear buffer.
+ */
+ uint8_t *rxbuf;
+#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ thread_reference_t thread;
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Total receive transfer size.
+ */
+ size_t totsize;
+} USBOutEndpointState;
+
+/**
+ * @brief Type of an USB endpoint configuration structure.
+ * @note Platform specific restrictions may apply to endpoints.
+ */
+typedef struct {
+ /**
+ * @brief Type and mode of the endpoint.
+ */
+ uint32_t ep_mode;
+ /**
+ * @brief Setup packet notification callback.
+ * @details This callback is invoked when a setup packet has been
+ * received.
+ * @post The application must immediately call @p usbReadPacket() in
+ * order to access the received packet.
+ * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
+ * endpoints, it should be set to @p NULL for other endpoint
+ * types.
+ */
+ usbepcallback_t setup_cb;
+ /**
+ * @brief IN endpoint notification callback.
+ * @details This field must be set to @p NULL if callback is not required.
+ */
+ usbepcallback_t in_cb;
+ /**
+ * @brief OUT endpoint notification callback.
+ * @details This field must be set to @p NULL if callback is not required.
+ */
+ usbepcallback_t out_cb;
+ /**
+ * @brief IN endpoint maximum packet size.
+ * @details This field must be set to zero if the IN endpoint is not used.
+ */
+ uint16_t in_maxsize;
+ /**
+ * @brief OUT endpoint maximum packet size.
+ * @details This field must be set to zero if the OUT endpoint is not used.
+ */
+ uint16_t out_maxsize;
+ /**
+ * @brief @p USBEndpointState associated to the IN endpoint.
+ * @details This field must be set to @p NULL if the IN endpoint is not
+ * used.
+ */
+ USBInEndpointState *in_state;
+ /**
+ * @brief @p USBEndpointState associated to the OUT endpoint.
+ * @details This field must be set to @p NULL if the OUT endpoint is not
+ * used.
+ */
+ USBOutEndpointState *out_state;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Determines the space allocated for the TXFIFO as multiples of
+ * the packet size (@p in_maxsize). Note that zero is interpreted
+ * as one for simplicity and robustness.
+ */
+ uint16_t in_multiplier;
+ /**
+ * @brief Pointer to a buffer for setup packets.
+ * @details Setup packets require a dedicated 8-bytes buffer, set this
+ * field to @p NULL for non-control endpoints.
+ */
+ uint8_t *setup_buf;
+} USBEndpointConfig;
+
+/**
+ * @brief Type of an USB driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief USB events callback.
+ * @details This callback is invoked when an USB driver event is registered.
+ */
+ usbeventcb_t event_cb;
+ /**
+ * @brief Device GET_DESCRIPTOR request callback.
+ * @note This callback is mandatory and cannot be set to @p NULL.
+ */
+ usbgetdescriptor_t get_descriptor_cb;
+ /**
+ * @brief Requests hook callback.
+ * @details This hook allows to be notified of standard requests or to
+ * handle non standard requests.
+ */
+ usbreqhandler_t requests_hook_cb;
+ /**
+ * @brief Start Of Frame callback.
+ */
+ usbcallback_t sof_cb;
+ /* End of the mandatory fields.*/
+} USBConfig;
+
+/**
+ * @brief Structure representing an USB driver.
+ */
+struct USBDriver {
+ /**
+ * @brief Driver state.
+ */
+ usbstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const USBConfig *config;
+ /**
+ * @brief Bit map of the transmitting IN endpoints.
+ */
+ uint16_t transmitting;
+ /**
+ * @brief Bit map of the receiving OUT endpoints.
+ */
+ uint16_t receiving;
+ /**
+ * @brief Active endpoints configurations.
+ */
+ const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
+ /**
+ * @brief Fields available to user, it can be used to associate an
+ * application-defined handler to an IN endpoint.
+ * @note The base index is one, the endpoint zero does not have a
+ * reserved element in this array.
+ */
+ void *in_params[USB_MAX_ENDPOINTS];
+ /**
+ * @brief Fields available to user, it can be used to associate an
+ * application-defined handler to an OUT endpoint.
+ * @note The base index is one, the endpoint zero does not have a
+ * reserved element in this array.
+ */
+ void *out_params[USB_MAX_ENDPOINTS];
+ /**
+ * @brief Endpoint 0 state.
+ */
+ usbep0state_t ep0state;
+ /**
+ * @brief Next position in the buffer to be transferred through endpoint 0.
+ */
+ uint8_t *ep0next;
+ /**
+ * @brief Number of bytes yet to be transferred through endpoint 0.
+ */
+ size_t ep0n;
+ /**
+ * @brief Endpoint 0 end transaction callback.
+ */
+ usbcallback_t ep0endcb;
+ /**
+ * @brief Setup packet buffer.
+ */
+ uint8_t setup[8];
+ /**
+ * @brief Current USB device status.
+ */
+ uint16_t status;
+ /**
+ * @brief Assigned USB address.
+ */
+ uint8_t address;
+ /**
+ * @brief Current USB device configuration.
+ */
+ uint8_t configuration;
+ /**
+ * @brief State of the driver when a suspend happened.
+ */
+ usbstate_t saved_state;
+#if defined(USB_DRIVER_EXT_FIELDS)
+ USB_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the OTG peripheral associated to this driver.
+ */
+ stm32_otg_t *otg;
+ /**
+ * @brief Peripheral-specific parameters.
+ */
+ const stm32_otg_params_t *otgparams;
+ /**
+ * @brief Pointer to the next address in the packet memory.
+ */
+ uint32_t pmnext;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the exact size of a receive transaction.
+ * @details The received size can be different from the size specified in
+ * @p usbStartReceiveI() because the last packet could have a size
+ * different from the expected one.
+ * @pre The OUT endpoint must have been configured in transaction mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_transaction_size(usbp, ep) \
+ ((usbp)->epc[ep]->out_state->rxcnt)
+
+/**
+ * @brief Connects the USB device.
+ *
+ * @notapi
+ */
+#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__)
+#define usb_lld_connect_bus(usbp) ((usbp)->otg->GCCFG |= GCCFG_VBUSBSEN)
+#else
+#define usb_lld_connect_bus(usbp) ((usbp)->otg->DCTL &= ~DCTL_SDIS)
+#endif
+
+/**
+ * @brief Disconnect the USB device.
+ *
+ * @notapi
+ */
+#if (STM32_OTG_STEPPING == 1) || defined(__DOXYGEN__)
+#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->GCCFG &= ~GCCFG_VBUSBSEN)
+#else
+#define usb_lld_disconnect_bus(usbp) ((usbp)->otg->DCTL |= DCTL_SDIS)
+#endif
+
+/**
+ * @brief Start of host wake-up procedure.
+ *
+ * @notapi
+ */
+#define usb_lld_wakeup_host(usbp) \
+ do { \
+ (usbp)->otg->DCTL |= DCTL_RWUSIG; \
+ osalThreadSleepMilliseconds(STM32_USB_HOST_WAKEUP_DURATION); \
+ (usbp)->otg->DCTL &= ~DCTL_RWUSIG; \
+ } while (false)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_OTG1 && !defined(__DOXYGEN__)
+extern USBDriver USBD1;
+#endif
+
+#if STM32_USB_USE_OTG2 && !defined(__DOXYGEN__)
+extern USBDriver USBD2;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void usb_lld_init(void);
+ void usb_lld_start(USBDriver *usbp);
+ void usb_lld_stop(USBDriver *usbp);
+ void usb_lld_reset(USBDriver *usbp);
+ void usb_lld_set_address(USBDriver *usbp);
+ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
+ void usb_lld_disable_endpoints(USBDriver *usbp);
+ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
+ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_USB */
+
+#endif /* HAL_USB_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h b/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h
index 0ea7314053..c093470f10 100644
--- a/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h
+++ b/os/hal/ports/STM32/LLD/OTGv1/stm32_otg.h
@@ -1,927 +1,927 @@
-/*
- 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 OTGv1/stm32_otg.h
- * @brief STM32 OTG registers layout header.
- *
- * @addtogroup USB
- * @{
- */
-
-#ifndef STM32_OTG_H
-#define STM32_OTG_H
-
-/**
- * @brief OTG_FS FIFO memory size in words.
- */
-#define STM32_OTG1_FIFO_MEM_SIZE 320
-
-/**
- * @brief OTG_HS FIFO memory size in words.
- */
-#define STM32_OTG2_FIFO_MEM_SIZE 1024
-
-/**
- * @brief Host channel registers group.
- */
-typedef struct {
- volatile uint32_t HCCHAR; /**< @brief Host channel characteristics
- register. */
- volatile uint32_t resvd8;
- volatile uint32_t HCINT; /**< @brief Host channel interrupt register.*/
- volatile uint32_t HCINTMSK; /**< @brief Host channel interrupt mask
- register. */
- volatile uint32_t HCTSIZ; /**< @brief Host channel transfer size
- register. */
- volatile uint32_t resvd14;
- volatile uint32_t resvd18;
- volatile uint32_t resvd1c;
-} stm32_otg_host_chn_t;
-
-/**
- * @brief Device input endpoint registers group.
- */
-typedef struct {
- volatile uint32_t DIEPCTL; /**< @brief Device control IN endpoint
- control register. */
- volatile uint32_t resvd4;
- volatile uint32_t DIEPINT; /**< @brief Device IN endpoint interrupt
- register. */
- volatile uint32_t resvdC;
- volatile uint32_t DIEPTSIZ; /**< @brief Device IN endpoint transfer size
- register. */
- volatile uint32_t resvd14;
- volatile uint32_t DTXFSTS; /**< @brief Device IN endpoint transmit FIFO
- status register. */
- volatile uint32_t resvd1C;
-} stm32_otg_in_ep_t;
-
-/**
- * @brief Device output endpoint registers group.
- */
-typedef struct {
- volatile uint32_t DOEPCTL; /**< @brief Device control OUT endpoint
- control register. */
- volatile uint32_t resvd4;
- volatile uint32_t DOEPINT; /**< @brief Device OUT endpoint interrupt
- register. */
- volatile uint32_t resvdC;
- volatile uint32_t DOEPTSIZ; /**< @brief Device OUT endpoint transfer
- size register. */
- volatile uint32_t resvd14;
- volatile uint32_t resvd18;
- volatile uint32_t resvd1C;
-} stm32_otg_out_ep_t;
-
-/**
- * @brief USB registers memory map.
- */
-typedef struct {
- volatile uint32_t GOTGCTL; /**< @brief OTG control and status register.*/
- volatile uint32_t GOTGINT; /**< @brief OTG interrupt register. */
- volatile uint32_t GAHBCFG; /**< @brief AHB configuration register. */
- volatile uint32_t GUSBCFG; /**< @brief USB configuration register. */
- volatile uint32_t GRSTCTL; /**< @brief Reset register size. */
- volatile uint32_t GINTSTS; /**< @brief Interrupt register. */
- volatile uint32_t GINTMSK; /**< @brief Interrupt mask register. */
- volatile uint32_t GRXSTSR; /**< @brief Receive status debug read
- register. */
- volatile uint32_t GRXSTSP; /**< @brief Receive status read/pop
- register. */
- volatile uint32_t GRXFSIZ; /**< @brief Receive FIFO size register. */
- volatile uint32_t DIEPTXF0; /**< @brief Endpoint 0 transmit FIFO size
- register. */
- volatile uint32_t HNPTXSTS; /**< @brief Non-periodic transmit FIFO/queue
- status register. */
- volatile uint32_t resvd30;
- volatile uint32_t resvd34;
- volatile uint32_t GCCFG; /**< @brief General core configuration. */
- volatile uint32_t CID; /**< @brief Core ID register. */
- volatile uint32_t resvd58[48];
- volatile uint32_t HPTXFSIZ; /**< @brief Host periodic transmit FIFO size
- register. */
- volatile uint32_t DIEPTXF[15];/**< @brief Device IN endpoint transmit FIFO
- size registers. */
- volatile uint32_t resvd140[176];
- volatile uint32_t HCFG; /**< @brief Host configuration register. */
- volatile uint32_t HFIR; /**< @brief Host frame interval register. */
- volatile uint32_t HFNUM; /**< @brief Host frame number/frame time
- Remaining register. */
- volatile uint32_t resvd40C;
- volatile uint32_t HPTXSTS; /**< @brief Host periodic transmit FIFO/queue
- status register. */
- volatile uint32_t HAINT; /**< @brief Host all channels interrupt
- register. */
- volatile uint32_t HAINTMSK; /**< @brief Host all channels interrupt mask
- register. */
- volatile uint32_t resvd41C[9];
- volatile uint32_t HPRT; /**< @brief Host port control and status
- register. */
- volatile uint32_t resvd444[47];
- stm32_otg_host_chn_t hc[16]; /**< @brief Host channels array. */
- volatile uint32_t resvd700[64];
- volatile uint32_t DCFG; /**< @brief Device configuration register. */
- volatile uint32_t DCTL; /**< @brief Device control register. */
- volatile uint32_t DSTS; /**< @brief Device status register. */
- volatile uint32_t resvd80C;
- volatile uint32_t DIEPMSK; /**< @brief Device IN endpoint common
- interrupt mask register. */
- volatile uint32_t DOEPMSK; /**< @brief Device OUT endpoint common
- interrupt mask register. */
- volatile uint32_t DAINT; /**< @brief Device all endpoints interrupt
- register. */
- volatile uint32_t DAINTMSK; /**< @brief Device all endpoints interrupt
- mask register. */
- volatile uint32_t resvd820;
- volatile uint32_t resvd824;
- volatile uint32_t DVBUSDIS; /**< @brief Device VBUS discharge time
- register. */
- volatile uint32_t DVBUSPULSE; /**< @brief Device VBUS pulsing time
- register. */
- volatile uint32_t resvd830;
- volatile uint32_t DIEPEMPMSK; /**< @brief Device IN endpoint FIFO empty
- interrupt mask register. */
- volatile uint32_t resvd838;
- volatile uint32_t resvd83C;
- volatile uint32_t resvd840[16];
- volatile uint32_t resvd880[16];
- volatile uint32_t resvd8C0[16];
- stm32_otg_in_ep_t ie[16]; /**< @brief Input endpoints. */
- stm32_otg_out_ep_t oe[16]; /**< @brief Output endpoints. */
- volatile uint32_t resvdD00[64];
- volatile uint32_t PCGCCTL; /**< @brief Power and clock gating control
- register. */
- volatile uint32_t resvdE04[127];
- volatile uint32_t FIFO[16][1024];
-} stm32_otg_t;
-
-/**
- * @name GOTGCTL register bit definitions
- * @{
- */
-#define GOTGCTL_BSVLD (1U<<19) /**< B-Session Valid. */
-#define GOTGCTL_ASVLD (1U<<18) /**< A-Session Valid. */
-#define GOTGCTL_DBCT (1U<<17) /**< Long/Short debounce time. */
-#define GOTGCTL_CIDSTS (1U<<16) /**< Connector ID status. */
-#define GOTGCTL_EHEN (1U<<12)
-#define GOTGCTL_DHNPEN (1U<<11) /**< Device HNP enabled. */
-#define GOTGCTL_HSHNPEN (1U<<10) /**< Host Set HNP enable. */
-#define GOTGCTL_HNPRQ (1U<<9) /**< HNP request. */
-#define GOTGCTL_HNGSCS (1U<<8) /**< Host negotiation success. */
-#define GOTGCTL_BVALOVAL (1U<<7)
-#define GOTGCTL_BVALOEN (1U<<6)
-#define GOTGCTL_AVALOVAL (1U<<5)
-#define GOTGCTL_AVALOEN (1U<<4)
-#define GOTGCTL_VBVALOVAL (1U<<3)
-#define GOTGCTL_VBVALOEN (1U<<2)
-#define GOTGCTL_SRQ (1U<<1) /**< Session request. */
-#define GOTGCTL_SRQSCS (1U<<0) /**< Session request success. */
-/** @} */
-
-/**
- * @name GOTGINT register bit definitions
- * @{
- */
-#define GOTGINT_DBCDNE (1U<<19) /**< Debounce done. */
-#define GOTGINT_ADTOCHG (1U<<18) /**< A-Device timeout change. */
-#define GOTGINT_HNGDET (1U<<17) /**< Host negotiation detected. */
-#define GOTGINT_HNSSCHG (1U<<9) /**< Host negotiation success
- status change. */
-#define GOTGINT_SRSSCHG (1U<<8) /**< Session request success
- status change. */
-#define GOTGINT_SEDET (1U<<2) /**< Session end detected. */
-/** @} */
-
-/**
- * @name GAHBCFG register bit definitions
- * @{
- */
-#define GAHBCFG_PTXFELVL (1U<<8) /**< Periodic TxFIFO empty
- level. */
-#define GAHBCFG_TXFELVL (1U<<7) /**< Non-periodic TxFIFO empty
- level. */
-#define GAHBCFG_DMAEN (1U<<5) /**< DMA enable (HS only). */
-#define GAHBCFG_HBSTLEN_MASK (15U<<1) /**< Burst length/type mask (HS
- only). */
-#define GAHBCFG_HBSTLEN(n) ((n)<<1) /**< Burst length/type (HS
- only). */
-#define GAHBCFG_GINTMSK (1U<<0) /**< Global interrupt mask. */
-/** @} */
-
-/**
- * @name GUSBCFG register bit definitions
- * @{
- */
-#define GUSBCFG_CTXPKT (1U<<31) /**< Corrupt Tx packet. */
-#define GUSBCFG_FDMOD (1U<<30) /**< Force Device Mode. */
-#define GUSBCFG_FHMOD (1U<<29) /**< Force Host Mode. */
-#define GUSBCFG_TRDT_MASK (15U<<10) /**< USB Turnaround time field
- mask. */
-#define GUSBCFG_TRDT(n) ((n)<<10) /**< USB Turnaround time field
- value. */
-#define GUSBCFG_HNPCAP (1U<<9) /**< HNP-Capable. */
-#define GUSBCFG_SRPCAP (1U<<8) /**< SRP-Capable. */
-#define GUSBCFG_PHYSEL (1U<<6) /**< USB 2.0 High-Speed PHY or
- USB 1.1 Full-Speed serial
- transceiver Select. */
-#define GUSBCFG_TOCAL_MASK (7U<<0) /**< HS/FS timeout calibration
- field mask. */
-#define GUSBCFG_TOCAL(n) ((n)<<0) /**< HS/FS timeout calibration
- field value. */
-/** @} */
-
-/**
- * @name GRSTCTL register bit definitions
- * @{
- */
-#define GRSTCTL_AHBIDL (1U<<31) /**< AHB Master Idle. */
-#define GRSTCTL_TXFNUM_MASK (31U<<6) /**< TxFIFO number field mask. */
-#define GRSTCTL_TXFNUM(n) ((n)<<6) /**< TxFIFO number field value. */
-#define GRSTCTL_TXFFLSH (1U<<5) /**< TxFIFO flush. */
-#define GRSTCTL_RXFFLSH (1U<<4) /**< RxFIFO flush. */
-#define GRSTCTL_FCRST (1U<<2) /**< Host frame counter reset. */
-#define GRSTCTL_HSRST (1U<<1) /**< HClk soft reset. */
-#define GRSTCTL_CSRST (1U<<0) /**< Core soft reset. */
-/** @} */
-
-/**
- * @name GINTSTS register bit definitions
- * @{
- */
-#define GINTSTS_WKUPINT (1U<<31) /**< Resume/Remote wakeup
- detected interrupt. */
-#define GINTSTS_SRQINT (1U<<30) /**< Session request/New session
- detected interrupt. */
-#define GINTSTS_DISCINT (1U<<29) /**< Disconnect detected
- interrupt. */
-#define GINTSTS_CIDSCHG (1U<<28) /**< Connector ID status change.*/
-#define GINTSTS_PTXFE (1U<<26) /**< Periodic TxFIFO empty. */
-#define GINTSTS_HCINT (1U<<25) /**< Host channels interrupt. */
-#define GINTSTS_HPRTINT (1U<<24) /**< Host port interrupt. */
-#define GINTSTS_IPXFR (1U<<21) /**< Incomplete periodic
- transfer. */
-#define GINTSTS_IISOOXFR (1U<<21) /**< Incomplete isochronous OUT
- transfer. */
-#define GINTSTS_IISOIXFR (1U<<20) /**< Incomplete isochronous IN
- transfer. */
-#define GINTSTS_OEPINT (1U<<19) /**< OUT endpoints interrupt. */
-#define GINTSTS_IEPINT (1U<<18) /**< IN endpoints interrupt. */
-#define GINTSTS_EOPF (1U<<15) /**< End of periodic frame
- interrupt. */
-#define GINTSTS_ISOODRP (1U<<14) /**< Isochronous OUT packet
- dropped interrupt. */
-#define GINTSTS_ENUMDNE (1U<<13) /**< Enumeration done. */
-#define GINTSTS_USBRST (1U<<12) /**< USB reset. */
-#define GINTSTS_USBSUSP (1U<<11) /**< USB suspend. */
-#define GINTSTS_ESUSP (1U<<10) /**< Early suspend. */
-#define GINTSTS_GONAKEFF (1U<<7) /**< Global OUT NAK effective. */
-#define GINTSTS_GINAKEFF (1U<<6) /**< Global IN non-periodic NAK
- effective. */
-#define GINTSTS_NPTXFE (1U<<5) /**< Non-periodic TxFIFO empty. */
-#define GINTSTS_RXFLVL (1U<<4) /**< RxFIFO non-empty. */
-#define GINTSTS_SOF (1U<<3) /**< Start of frame. */
-#define GINTSTS_OTGINT (1U<<2) /**< OTG interrupt. */
-#define GINTSTS_MMIS (1U<<1) /**< Mode Mismatch interrupt. */
-#define GINTSTS_CMOD (1U<<0) /**< Current mode of operation. */
-/** @} */
-
-/**
- * @name GINTMSK register bit definitions
- * @{
- */
-#define GINTMSK_WKUM (1U<<31) /**< Resume/remote wakeup
- detected interrupt mask. */
-#define GINTMSK_SRQM (1U<<30) /**< Session request/New session
- detected interrupt mask. */
-#define GINTMSK_DISCM (1U<<29) /**< Disconnect detected
- interrupt mask. */
-#define GINTMSK_CIDSCHGM (1U<<28) /**< Connector ID status change
- mask. */
-#define GINTMSK_PTXFEM (1U<<26) /**< Periodic TxFIFO empty mask.*/
-#define GINTMSK_HCM (1U<<25) /**< Host channels interrupt
- mask. */
-#define GINTMSK_HPRTM (1U<<24) /**< Host port interrupt mask. */
-#define GINTMSK_IPXFRM (1U<<21) /**< Incomplete periodic
- transfer mask. */
-#define GINTMSK_IISOOXFRM (1U<<21) /**< Incomplete isochronous OUT
- transfer mask. */
-#define GINTMSK_IISOIXFRM (1U<<20) /**< Incomplete isochronous IN
- transfer mask. */
-#define GINTMSK_OEPM (1U<<19) /**< OUT endpoints interrupt
- mask. */
-#define GINTMSK_IEPM (1U<<18) /**< IN endpoints interrupt
- mask. */
-#define GINTMSK_EOPFM (1U<<15) /**< End of periodic frame
- interrupt mask. */
-#define GINTMSK_ISOODRPM (1U<<14) /**< Isochronous OUT packet
- dropped interrupt mask. */
-#define GINTMSK_ENUMDNEM (1U<<13) /**< Enumeration done mask. */
-#define GINTMSK_USBRSTM (1U<<12) /**< USB reset mask. */
-#define GINTMSK_USBSUSPM (1U<<11) /**< USB suspend mask. */
-#define GINTMSK_ESUSPM (1U<<10) /**< Early suspend mask. */
-#define GINTMSK_GONAKEFFM (1U<<7) /**< Global OUT NAK effective
- mask. */
-#define GINTMSK_GINAKEFFM (1U<<6) /**< Global non-periodic IN NAK
- effective mask. */
-#define GINTMSK_NPTXFEM (1U<<5) /**< Non-periodic TxFIFO empty
- mask. */
-#define GINTMSK_RXFLVLM (1U<<4) /**< Receive FIFO non-empty
- mask. */
-#define GINTMSK_SOFM (1U<<3) /**< Start of (micro)frame mask.*/
-#define GINTMSK_OTGM (1U<<2) /**< OTG interrupt mask. */
-#define GINTMSK_MMISM (1U<<1) /**< Mode Mismatch interrupt
- mask. */
-/** @} */
-
-/**
- * @name GRXSTSR register bit definitions
- * @{
- */
-#define GRXSTSR_PKTSTS_MASK (15U<<17) /**< Packet status mask. */
-#define GRXSTSR_PKTSTS(n) ((n)<<17) /**< Packet status value. */
-#define GRXSTSR_OUT_GLOBAL_NAK GRXSTSR_PKTSTS(1)
-#define GRXSTSR_OUT_DATA GRXSTSR_PKTSTS(2)
-#define GRXSTSR_OUT_COMP GRXSTSR_PKTSTS(3)
-#define GRXSTSR_SETUP_COMP GRXSTSR_PKTSTS(4)
-#define GRXSTSR_SETUP_DATA GRXSTSR_PKTSTS(6)
-#define GRXSTSR_DPID_MASK (3U<<15) /**< Data PID mask. */
-#define GRXSTSR_DPID(n) ((n)<<15) /**< Data PID value. */
-#define GRXSTSR_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
-#define GRXSTSR_BCNT(n) ((n)<<4) /**< Byte count value. */
-#define GRXSTSR_CHNUM_MASK (15U<<0) /**< Channel number mask. */
-#define GRXSTSR_CHNUM(n) ((n)<<0) /**< Channel number value. */
-#define GRXSTSR_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
-#define GRXSTSR_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
-/** @} */
-
-/**
- * @name GRXSTSP register bit definitions
- * @{
- */
-#define GRXSTSP_PKTSTS_MASK (15<<17) /**< Packet status mask. */
-#define GRXSTSP_PKTSTS(n) ((n)<<17) /**< Packet status value. */
-#define GRXSTSP_OUT_GLOBAL_NAK GRXSTSP_PKTSTS(1)
-#define GRXSTSP_OUT_DATA GRXSTSP_PKTSTS(2)
-#define GRXSTSP_OUT_COMP GRXSTSP_PKTSTS(3)
-#define GRXSTSP_SETUP_COMP GRXSTSP_PKTSTS(4)
-#define GRXSTSP_SETUP_DATA GRXSTSP_PKTSTS(6)
-#define GRXSTSP_DPID_MASK (3U<<15) /**< Data PID mask. */
-#define GRXSTSP_DPID(n) ((n)<<15) /**< Data PID value. */
-#define GRXSTSP_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
-#define GRXSTSP_BCNT_OFF 4 /**< Byte count offset. */
-#define GRXSTSP_BCNT(n) ((n)<<4) /**< Byte count value. */
-#define GRXSTSP_CHNUM_MASK (15U<<0) /**< Channel number mask. */
-#define GRXSTSP_CHNUM(n) ((n)<<0) /**< Channel number value. */
-#define GRXSTSP_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
-#define GRXSTSP_EPNUM_OFF 0 /**< Endpoint number offset. */
-#define GRXSTSP_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
-/** @} */
-
-/**
- * @name GRXFSIZ register bit definitions
- * @{
- */
-#define GRXFSIZ_RXFD_MASK (0xFFFF<<0) /**< RxFIFO depth mask. */
-#define GRXFSIZ_RXFD(n) ((n)<<0) /**< RxFIFO depth value. */
-/** @} */
-
-/**
- * @name DIEPTXFx register bit definitions
- * @{
- */
-#define DIEPTXF_INEPTXFD_MASK (0xFFFFU<<16)/**< IN endpoint TxFIFO depth
- mask. */
-#define DIEPTXF_INEPTXFD(n) ((n)<<16) /**< IN endpoint TxFIFO depth
- value. */
-#define DIEPTXF_INEPTXSA_MASK (0xFFFF<<0) /**< IN endpoint FIFOx transmit
- RAM start address mask. */
-#define DIEPTXF_INEPTXSA(n) ((n)<<0) /**< IN endpoint FIFOx transmit
- RAM start address value. */
-/** @} */
-
-/**
- * @name GCCFG register bit definitions
- * @{
- */
-/* Definitions for stepping 1.*/
-#define GCCFG_NOVBUSSENS (1U<<21) /**< VBUS sensing disable. */
-#define GCCFG_SOFOUTEN (1U<<20) /**< SOF output enable. */
-#define GCCFG_VBUSBSEN (1U<<19) /**< Enable the VBUS sensing "B"
- device. */
-#define GCCFG_VBUSASEN (1U<<18) /**< Enable the VBUS sensing "A"
- device. */
-
-/* Definitions for stepping 2.*/
-#define GCCFG_VBDEN (1U<<21) /**< VBUS sensing enable. */
-#define GCCFG_PWRDWN (1U<<16) /**< Power down. */
-/** @} */
-
-/**
- * @name HPTXFSIZ register bit definitions
- * @{
- */
-#define HPTXFSIZ_PTXFD_MASK (0xFFFFU<<16)/**< Host periodic TxFIFO
- depth mask. */
-#define HPTXFSIZ_PTXFD(n) ((n)<<16) /**< Host periodic TxFIFO
- depth value. */
-#define HPTXFSIZ_PTXSA_MASK (0xFFFFU<<0)/**< Host periodic TxFIFO
- Start address mask. */
-#define HPTXFSIZ_PTXSA(n) ((n)<<0) /**< Host periodic TxFIFO
- start address value. */
-/** @} */
-
-/**
- * @name HCFG register bit definitions
- * @{
- */
-#define HCFG_FSLSS (1U<<2) /**< FS- and LS-only support. */
-#define HCFG_FSLSPCS_MASK (3U<<0) /**< FS/LS PHY clock select
- mask. */
-#define HCFG_FSLSPCS_48 (1U<<0) /**< PHY clock is running at
- 48 MHz. */
-#define HCFG_FSLSPCS_6 (2U<<0) /**< PHY clock is running at
- 6 MHz. */
-/** @} */
-
-/**
- * @name HFIR register bit definitions
- * @{
- */
-#define HFIR_FRIVL_MASK (0xFFFFU<<0)/**< Frame interval mask. */
-#define HFIR_FRIVL(n) ((n)<<0) /**< Frame interval value. */
-/** @} */
-
-/**
- * @name HFNUM register bit definitions
- * @{
- */
-#define HFNUM_FTREM_MASK (0xFFFFU<<16)/**< Frame time Remaining mask.*/
-#define HFNUM_FTREM(n) ((n)<<16) /**< Frame time Remaining value.*/
-#define HFNUM_FRNUM_MASK (0xFFFFU<<0)/**< Frame number mask. */
-#define HFNUM_FRNUM(n) ((n)<<0) /**< Frame number value. */
-/** @} */
-
-/**
- * @name HPTXSTS register bit definitions
- * @{
- */
-#define HPTXSTS_PTXQTOP_MASK (0xFFU<<24) /**< Top of the periodic
- transmit request queue
- mask. */
-#define HPTXSTS_PTXQTOP(n) ((n)<<24) /**< Top of the periodic
- transmit request queue
- value. */
-#define HPTXSTS_PTXQSAV_MASK (0xFF<<16) /**< Periodic transmit request
- queue Space Available
- mask. */
-#define HPTXSTS_PTXQSAV(n) ((n)<<16) /**< Periodic transmit request
- queue Space Available
- value. */
-#define HPTXSTS_PTXFSAVL_MASK (0xFFFF<<0) /**< Periodic transmit Data
- FIFO Space Available
- mask. */
-#define HPTXSTS_PTXFSAVL(n) ((n)<<0) /**< Periodic transmit Data
- FIFO Space Available
- value. */
-/** @} */
-
-/**
- * @name HAINT register bit definitions
- * @{
- */
-#define HAINT_HAINT_MASK (0xFFFFU<<0)/**< Channel interrupts mask. */
-#define HAINT_HAINT(n) ((n)<<0) /**< Channel interrupts value. */
-/** @} */
-
-/**
- * @name HAINTMSK register bit definitions
- * @{
- */
-#define HAINTMSK_HAINTM_MASK (0xFFFFU<<0)/**< Channel interrupt mask
- mask. */
-#define HAINTMSK_HAINTM(n) ((n)<<0) /**< Channel interrupt mask
- value. */
-/** @} */
-
-/**
- * @name HPRT register bit definitions
- * @{
- */
-#define HPRT_PSPD_MASK (3U<<17) /**< Port speed mask. */
-#define HPRT_PSPD_FS (1U<<17) /**< Full speed value. */
-#define HPRT_PSPD_LS (2U<<17) /**< Low speed value. */
-#define HPRT_PTCTL_MASK (15<<13) /**< Port Test control mask. */
-#define HPRT_PTCTL(n) ((n)<<13) /**< Port Test control value. */
-#define HPRT_PPWR (1U<<12) /**< Port power. */
-#define HPRT_PLSTS_MASK (3U<<11) /**< Port Line status mask. */
-#define HPRT_PLSTS_DM (1U<<11) /**< Logic level of D-. */
-#define HPRT_PLSTS_DP (1U<<10) /**< Logic level of D+. */
-#define HPRT_PRST (1U<<8) /**< Port reset. */
-#define HPRT_PSUSP (1U<<7) /**< Port suspend. */
-#define HPRT_PRES (1U<<6) /**< Port Resume. */
-#define HPRT_POCCHNG (1U<<5) /**< Port overcurrent change. */
-#define HPRT_POCA (1U<<4) /**< Port overcurrent active. */
-#define HPRT_PENCHNG (1U<<3) /**< Port enable/disable change.*/
-#define HPRT_PENA (1U<<2) /**< Port enable. */
-#define HPRT_PCDET (1U<<1) /**< Port Connect detected. */
-#define HPRT_PCSTS (1U<<0) /**< Port connect status. */
-/** @} */
-
-/**
- * @name HCCHAR register bit definitions
- * @{
- */
-#define HCCHAR_CHENA (1U<<31) /**< Channel enable. */
-#define HCCHAR_CHDIS (1U<<30) /**< Channel Disable. */
-#define HCCHAR_ODDFRM (1U<<29) /**< Odd frame. */
-#define HCCHAR_DAD_MASK (0x7FU<<22) /**< Device Address mask. */
-#define HCCHAR_DAD(n) ((n)<<22) /**< Device Address value. */
-#define HCCHAR_MCNT_MASK (3U<<20) /**< Multicount mask. */
-#define HCCHAR_MCNT(n) ((n)<<20) /**< Multicount value. */
-#define HCCHAR_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
-#define HCCHAR_EPTYP(n) ((n)<<18) /**< Endpoint type value. */
-#define HCCHAR_EPTYP_CTL (0U<<18) /**< Control endpoint value. */
-#define HCCHAR_EPTYP_ISO (1U<<18) /**< Isochronous endpoint value.*/
-#define HCCHAR_EPTYP_BULK (2U<<18) /**< Bulk endpoint value. */
-#define HCCHAR_EPTYP_INTR (3U<<18) /**< Interrupt endpoint value. */
-#define HCCHAR_LSDEV (1U<<17) /**< Low-Speed device. */
-#define HCCHAR_EPDIR (1U<<15) /**< Endpoint direction. */
-#define HCCHAR_EPNUM_MASK (15U<<11) /**< Endpoint number mask. */
-#define HCCHAR_EPNUM(n) ((n)<<11) /**< Endpoint number value. */
-#define HCCHAR_MPS_MASK (0x7FFU<<0) /**< Maximum packet size mask. */
-#define HCCHAR_MPS(n) ((n)<<0) /**< Maximum packet size value. */
-/** @} */
-
-/**
- * @name HCINT register bit definitions
- * @{
- */
-#define HCINT_DTERR (1U<<10) /**< Data toggle error. */
-#define HCINT_FRMOR (1U<<9) /**< Frame overrun. */
-#define HCINT_BBERR (1U<<8) /**< Babble error. */
-#define HCINT_TRERR (1U<<7) /**< Transaction Error. */
-#define HCINT_ACK (1U<<5) /**< ACK response
- received/transmitted
- interrupt. */
-#define HCINT_NAK (1U<<4) /**< NAK response received
- interrupt. */
-#define HCINT_STALL (1U<<3) /**< STALL response received
- interrupt. */
-#define HCINT_AHBERR (1U<<2) /**< AHB error interrupt. */
-#define HCINT_CHH (1U<<1) /**< Channel halted. */
-#define HCINT_XFRC (1U<<0) /**< Transfer completed. */
-/** @} */
-
-/**
- * @name HCINTMSK register bit definitions
- * @{
- */
-#define HCINTMSK_DTERRM (1U<<10) /**< Data toggle error mask. */
-#define HCINTMSK_FRMORM (1U<<9) /**< Frame overrun mask. */
-#define HCINTMSK_BBERRM (1U<<8) /**< Babble error mask. */
-#define HCINTMSK_TRERRM (1U<<7) /**< Transaction error mask. */
-#define HCINTMSK_NYET (1U<<6) /**< NYET response received
- interrupt mask. */
-#define HCINTMSK_ACKM (1U<<5) /**< ACK Response
- received/transmitted
- interrupt mask. */
-#define HCINTMSK_NAKM (1U<<4) /**< NAK response received
- interrupt mask. */
-#define HCINTMSK_STALLM (1U<<3) /**< STALL response received
- interrupt mask. */
-#define HCINTMSK_AHBERRM (1U<<2) /**< AHB error interrupt mask. */
-#define HCINTMSK_CHHM (1U<<1) /**< Channel halted mask. */
-#define HCINTMSK_XFRCM (1U<<0) /**< Transfer completed mask. */
-/** @} */
-
-/**
- * @name HCTSIZ register bit definitions
- * @{
- */
-#define HCTSIZ_DPID_MASK (3U<<29) /**< PID mask. */
-#define HCTSIZ_DPID_DATA0 (0U<<29) /**< DATA0. */
-#define HCTSIZ_DPID_DATA2 (1U<<29) /**< DATA2. */
-#define HCTSIZ_DPID_DATA1 (2U<<29) /**< DATA1. */
-#define HCTSIZ_DPID_MDATA (3U<<29) /**< MDATA. */
-#define HCTSIZ_DPID_SETUP (3U<<29) /**< SETUP. */
-#define HCTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
-#define HCTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
-#define HCTSIZ_XFRSIZ_MASK (0x7FFFF<<0)/**< Transfer size mask. */
-#define HCTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
-/** @} */
-
-/**
- * @name DCFG register bit definitions
- * @{
- */
-#define DCFG_PFIVL_MASK (3U<<11) /**< Periodic frame interval
- mask. */
-#define DCFG_PFIVL(n) ((n)<<11) /**< Periodic frame interval
- value. */
-#define DCFG_DAD_MASK (0x7FU<<4) /**< Device address mask. */
-#define DCFG_DAD(n) ((n)<<4) /**< Device address value. */
-#define DCFG_NZLSOHSK (1U<<2) /**< Non-Zero-Length status
- OUT handshake. */
-#define DCFG_DSPD_MASK (3U<<0) /**< Device speed mask. */
-#define DCFG_DSPD_HS (0U<<0) /**< High speed (USB 2.0). */
-#define DCFG_DSPD_HS_FS (1U<<0) /**< High speed (USB 2.0) in FS
- mode. */
-#define DCFG_DSPD_FS11 (3U<<0) /**< Full speed (USB 1.1
- transceiver clock is 48
- MHz). */
-/** @} */
-
-/**
- * @name DCTL register bit definitions
- * @{
- */
-#define DCTL_POPRGDNE (1U<<11) /**< Power-on programming done. */
-#define DCTL_CGONAK (1U<<10) /**< Clear global OUT NAK. */
-#define DCTL_SGONAK (1U<<9) /**< Set global OUT NAK. */
-#define DCTL_CGINAK (1U<<8) /**< Clear global non-periodic
- IN NAK. */
-#define DCTL_SGINAK (1U<<7) /**< Set global non-periodic
- IN NAK. */
-#define DCTL_TCTL_MASK (7U<<4) /**< Test control mask. */
-#define DCTL_TCTL(n) ((n)<<4 /**< Test control value. */
-#define DCTL_GONSTS (1U<<3) /**< Global OUT NAK status. */
-#define DCTL_GINSTS (1U<<2) /**< Global non-periodic IN
- NAK status. */
-#define DCTL_SDIS (1U<<1) /**< Soft disconnect. */
-#define DCTL_RWUSIG (1U<<0) /**< Remote wakeup signaling. */
-/** @} */
-
-/**
- * @name DSTS register bit definitions
- * @{
- */
-#define DSTS_FNSOF_MASK (0x3FFU<<8) /**< Frame number of the received
- SOF mask. */
-#define DSTS_FNSOF(n) ((n)<<8) /**< Frame number of the received
- SOF value. */
-#define DSTS_FNSOF_ODD (1U<<8) /**< Frame parity of the received
- SOF value. */
-#define DSTS_EERR (1U<<3) /**< Erratic error. */
-#define DSTS_ENUMSPD_MASK (3U<<1) /**< Enumerated speed mask. */
-#define DSTS_ENUMSPD_FS_48 (3U<<1) /**< Full speed (PHY clock is
- running at 48 MHz). */
-#define DSTS_ENUMSPD_HS_480 (0U<<1) /**< High speed. */
-#define DSTS_SUSPSTS (1U<<0) /**< Suspend status. */
-/** @} */
-
-/**
- * @name DIEPMSK register bit definitions
- * @{
- */
-#define DIEPMSK_TXFEM (1U<<6) /**< Transmit FIFO empty mask. */
-#define DIEPMSK_INEPNEM (1U<<6) /**< IN endpoint NAK effective
- mask. */
-#define DIEPMSK_ITTXFEMSK (1U<<4) /**< IN token received when
- TxFIFO empty mask. */
-#define DIEPMSK_TOCM (1U<<3) /**< Timeout condition mask. */
-#define DIEPMSK_EPDM (1U<<1) /**< Endpoint disabled
- interrupt mask. */
-#define DIEPMSK_XFRCM (1U<<0) /**< Transfer completed
- interrupt mask. */
-/** @} */
-
-/**
- * @name DOEPMSK register bit definitions
- * @{
- */
-#define DOEPMSK_OTEPDM (1U<<4) /**< OUT token received when
- endpoint disabled mask. */
-#define DOEPMSK_STUPM (1U<<3) /**< SETUP phase done mask. */
-#define DOEPMSK_EPDM (1U<<1) /**< Endpoint disabled
- interrupt mask. */
-#define DOEPMSK_XFRCM (1U<<0) /**< Transfer completed
- interrupt mask. */
-/** @} */
-
-/**
- * @name DAINT register bit definitions
- * @{
- */
-#define DAINT_OEPINT_MASK (0xFFFFU<<16)/**< OUT endpoint interrupt
- bits mask. */
-#define DAINT_OEPINT(n) ((n)<<16) /**< OUT endpoint interrupt
- bits value. */
-#define DAINT_IEPINT_MASK (0xFFFFU<<0)/**< IN endpoint interrupt
- bits mask. */
-#define DAINT_IEPINT(n) ((n)<<0) /**< IN endpoint interrupt
- bits value. */
-/** @} */
-
-/**
- * @name DAINTMSK register bit definitions
- * @{
- */
-#define DAINTMSK_OEPM_MASK (0xFFFFU<<16)/**< OUT EP interrupt mask
- bits mask. */
-#define DAINTMSK_OEPM(n) (1U<<(16+(n)))/**< OUT EP interrupt mask
- bits value. */
-#define DAINTMSK_IEPM_MASK (0xFFFFU<<0)/**< IN EP interrupt mask
- bits mask. */
-#define DAINTMSK_IEPM(n) (1U<<(n)) /**< IN EP interrupt mask
- bits value. */
-/** @} */
-
-/**
- * @name DVBUSDIS register bit definitions
- * @{
- */
-#define DVBUSDIS_VBUSDT_MASK (0xFFFFU<<0)/**< Device VBUS discharge
- time mask. */
-#define DVBUSDIS_VBUSDT(n) ((n)<<0) /**< Device VBUS discharge
- time value. */
-/** @} */
-
-/**
- * @name DVBUSPULSE register bit definitions
- * @{
- */
-#define DVBUSPULSE_DVBUSP_MASK (0xFFFU<<0) /**< Device VBUSpulsing time
- mask. */
-#define DVBUSPULSE_DVBUSP(n) ((n)<<0) /**< Device VBUS pulsing time
- value. */
-/** @} */
-
-/**
- * @name DIEPEMPMSK register bit definitions
- * @{
- */
-#define DIEPEMPMSK_INEPTXFEM(n) (1U<<(n)) /**< IN EP Tx FIFO empty
- interrupt mask bit. */
-/** @} */
-
-/**
- * @name DIEPCTL register bit definitions
- * @{
- */
-#define DIEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
-#define DIEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
-#define DIEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
-#define DIEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
-#define DIEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
-#define DIEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
-#define DIEPCTL_SNAK (1U<<27) /**< Set NAK. */
-#define DIEPCTL_CNAK (1U<<26) /**< Clear NAK. */
-#define DIEPCTL_TXFNUM_MASK (15U<<22) /**< TxFIFO number mask. */
-#define DIEPCTL_TXFNUM(n) ((n)<<22) /**< TxFIFO number value. */
-#define DIEPCTL_STALL (1U<<21) /**< STALL handshake. */
-#define DIEPCTL_SNPM (1U<<20) /**< Snoop mode. */
-#define DIEPCTL_EPTYP_MASK (3<<18) /**< Endpoint type mask. */
-#define DIEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
-#define DIEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
-#define DIEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
-#define DIEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
-#define DIEPCTL_NAKSTS (1U<<17) /**< NAK status. */
-#define DIEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
-#define DIEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
-#define DIEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
-#define DIEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
-#define DIEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
-/** @} */
-
-/**
- * @name DIEPINT register bit definitions
- * @{
- */
-#define DIEPINT_TXFE (1U<<7) /**< Transmit FIFO empty. */
-#define DIEPINT_INEPNE (1U<<6) /**< IN endpoint NAK effective. */
-#define DIEPINT_ITTXFE (1U<<4) /**< IN Token received when
- TxFIFO is empty. */
-#define DIEPINT_TOC (1U<<3) /**< Timeout condition. */
-#define DIEPINT_EPDISD (1U<<1) /**< Endpoint disabled
- interrupt. */
-#define DIEPINT_XFRC (1U<<0) /**< Transfer completed. */
-/** @} */
-
-/**
- * @name DIEPTSIZ register bit definitions
- * @{
- */
-#define DIEPTSIZ_MCNT_MASK (3U<<29) /**< Multi count mask. */
-#define DIEPTSIZ_MCNT(n) ((n)<<29) /**< Multi count value. */
-#define DIEPTSIZ_PKTCNT_MASK (0x3FF<<19) /**< Packet count mask. */
-#define DIEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
-#define DIEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
-#define DIEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
-/** @} */
-
-/**
- * @name DTXFSTS register bit definitions.
- * @{
- */
-#define DTXFSTS_INEPTFSAV_MASK (0xFFFF<<0) /**< IN endpoint TxFIFO space
- available. */
-/** @} */
-
-/**
- * @name DOEPCTL register bit definitions.
- * @{
- */
-#define DOEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
-#define DOEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
-#define DOEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
-#define DOEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
-#define DOEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
-#define DOEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
-#define DOEPCTL_SNAK (1U<<27) /**< Set NAK. */
-#define DOEPCTL_CNAK (1U<<26) /**< Clear NAK. */
-#define DOEPCTL_STALL (1U<<21) /**< STALL handshake. */
-#define DOEPCTL_SNPM (1U<<20) /**< Snoop mode. */
-#define DOEPCTL_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
-#define DOEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
-#define DOEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
-#define DOEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
-#define DOEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
-#define DOEPCTL_NAKSTS (1U<<17) /**< NAK status. */
-#define DOEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
-#define DOEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
-#define DOEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
-#define DOEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
-#define DOEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
-/** @} */
-
-/**
- * @name DOEPINT register bit definitions
- * @{
- */
-#define DOEPINT_SETUP_RCVD (1U<<15) /**< SETUP packet received. */
-#define DOEPINT_B2BSTUP (1U<<6) /**< Back-to-back SETUP packets
- received. */
-#define DOEPINT_OTEPDIS (1U<<4) /**< OUT token received when
- endpoint disabled. */
-#define DOEPINT_STUP (1U<<3) /**< SETUP phase done. */
-#define DOEPINT_EPDISD (1U<<1) /**< Endpoint disabled
- interrupt. */
-#define DOEPINT_XFRC (1U<<0) /**< Transfer completed
- interrupt. */
-/** @} */
-
-/**
- * @name DOEPTSIZ register bit definitions
- * @{
- */
-#define DOEPTSIZ_RXDPID_MASK (3U<<29) /**< Received data PID mask. */
-#define DOEPTSIZ_RXDPID(n) ((n)<<29) /**< Received data PID value. */
-#define DOEPTSIZ_STUPCNT_MASK (3U<<29) /**< SETUP packet count mask. */
-#define DOEPTSIZ_STUPCNT(n) ((n)<<29) /**< SETUP packet count value. */
-#define DOEPTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
-#define DOEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
-#define DOEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
-#define DOEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
-/** @} */
-
-/**
- * @name PCGCCTL register bit definitions
- * @{
- */
-#define PCGCCTL_PHYSUSP (1U<<4) /**< PHY Suspended. */
-#define PCGCCTL_GATEHCLK (1U<<1) /**< Gate HCLK. */
-#define PCGCCTL_STPPCLK (1U<<0) /**< Stop PCLK. */
-/** @} */
-
-#if defined(STM32H7XX) || defined(__DOXYGEN__)
-/**
- * @brief OTG_FS registers block memory address.
- */
-#define OTG_FS_ADDR 0x40080000
-
-/**
- * @brief OTG_HS registers block memory address.
- */
-#define OTG_HS_ADDR 0x40040000
-#else
-#define OTG_FS_ADDR 0x50000000
-#define OTG_HS_ADDR 0x40040000
-#endif
-
-/**
- * @brief Accesses to the OTG_FS registers block.
- */
-#define OTG_FS ((stm32_otg_t *)OTG_FS_ADDR)
-
-/**
- * @brief Accesses to the OTG_HS registers block.
- */
-#define OTG_HS ((stm32_otg_t *)OTG_HS_ADDR)
-
-#endif /* STM32_OTG_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 OTGv1/stm32_otg.h
+ * @brief STM32 OTG registers layout header.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef STM32_OTG_H
+#define STM32_OTG_H
+
+/**
+ * @brief OTG_FS FIFO memory size in words.
+ */
+#define STM32_OTG1_FIFO_MEM_SIZE 320
+
+/**
+ * @brief OTG_HS FIFO memory size in words.
+ */
+#define STM32_OTG2_FIFO_MEM_SIZE 1024
+
+/**
+ * @brief Host channel registers group.
+ */
+typedef struct {
+ volatile uint32_t HCCHAR; /**< @brief Host channel characteristics
+ register. */
+ volatile uint32_t resvd8;
+ volatile uint32_t HCINT; /**< @brief Host channel interrupt register.*/
+ volatile uint32_t HCINTMSK; /**< @brief Host channel interrupt mask
+ register. */
+ volatile uint32_t HCTSIZ; /**< @brief Host channel transfer size
+ register. */
+ volatile uint32_t resvd14;
+ volatile uint32_t resvd18;
+ volatile uint32_t resvd1c;
+} stm32_otg_host_chn_t;
+
+/**
+ * @brief Device input endpoint registers group.
+ */
+typedef struct {
+ volatile uint32_t DIEPCTL; /**< @brief Device control IN endpoint
+ control register. */
+ volatile uint32_t resvd4;
+ volatile uint32_t DIEPINT; /**< @brief Device IN endpoint interrupt
+ register. */
+ volatile uint32_t resvdC;
+ volatile uint32_t DIEPTSIZ; /**< @brief Device IN endpoint transfer size
+ register. */
+ volatile uint32_t resvd14;
+ volatile uint32_t DTXFSTS; /**< @brief Device IN endpoint transmit FIFO
+ status register. */
+ volatile uint32_t resvd1C;
+} stm32_otg_in_ep_t;
+
+/**
+ * @brief Device output endpoint registers group.
+ */
+typedef struct {
+ volatile uint32_t DOEPCTL; /**< @brief Device control OUT endpoint
+ control register. */
+ volatile uint32_t resvd4;
+ volatile uint32_t DOEPINT; /**< @brief Device OUT endpoint interrupt
+ register. */
+ volatile uint32_t resvdC;
+ volatile uint32_t DOEPTSIZ; /**< @brief Device OUT endpoint transfer
+ size register. */
+ volatile uint32_t resvd14;
+ volatile uint32_t resvd18;
+ volatile uint32_t resvd1C;
+} stm32_otg_out_ep_t;
+
+/**
+ * @brief USB registers memory map.
+ */
+typedef struct {
+ volatile uint32_t GOTGCTL; /**< @brief OTG control and status register.*/
+ volatile uint32_t GOTGINT; /**< @brief OTG interrupt register. */
+ volatile uint32_t GAHBCFG; /**< @brief AHB configuration register. */
+ volatile uint32_t GUSBCFG; /**< @brief USB configuration register. */
+ volatile uint32_t GRSTCTL; /**< @brief Reset register size. */
+ volatile uint32_t GINTSTS; /**< @brief Interrupt register. */
+ volatile uint32_t GINTMSK; /**< @brief Interrupt mask register. */
+ volatile uint32_t GRXSTSR; /**< @brief Receive status debug read
+ register. */
+ volatile uint32_t GRXSTSP; /**< @brief Receive status read/pop
+ register. */
+ volatile uint32_t GRXFSIZ; /**< @brief Receive FIFO size register. */
+ volatile uint32_t DIEPTXF0; /**< @brief Endpoint 0 transmit FIFO size
+ register. */
+ volatile uint32_t HNPTXSTS; /**< @brief Non-periodic transmit FIFO/queue
+ status register. */
+ volatile uint32_t resvd30;
+ volatile uint32_t resvd34;
+ volatile uint32_t GCCFG; /**< @brief General core configuration. */
+ volatile uint32_t CID; /**< @brief Core ID register. */
+ volatile uint32_t resvd58[48];
+ volatile uint32_t HPTXFSIZ; /**< @brief Host periodic transmit FIFO size
+ register. */
+ volatile uint32_t DIEPTXF[15];/**< @brief Device IN endpoint transmit FIFO
+ size registers. */
+ volatile uint32_t resvd140[176];
+ volatile uint32_t HCFG; /**< @brief Host configuration register. */
+ volatile uint32_t HFIR; /**< @brief Host frame interval register. */
+ volatile uint32_t HFNUM; /**< @brief Host frame number/frame time
+ Remaining register. */
+ volatile uint32_t resvd40C;
+ volatile uint32_t HPTXSTS; /**< @brief Host periodic transmit FIFO/queue
+ status register. */
+ volatile uint32_t HAINT; /**< @brief Host all channels interrupt
+ register. */
+ volatile uint32_t HAINTMSK; /**< @brief Host all channels interrupt mask
+ register. */
+ volatile uint32_t resvd41C[9];
+ volatile uint32_t HPRT; /**< @brief Host port control and status
+ register. */
+ volatile uint32_t resvd444[47];
+ stm32_otg_host_chn_t hc[16]; /**< @brief Host channels array. */
+ volatile uint32_t resvd700[64];
+ volatile uint32_t DCFG; /**< @brief Device configuration register. */
+ volatile uint32_t DCTL; /**< @brief Device control register. */
+ volatile uint32_t DSTS; /**< @brief Device status register. */
+ volatile uint32_t resvd80C;
+ volatile uint32_t DIEPMSK; /**< @brief Device IN endpoint common
+ interrupt mask register. */
+ volatile uint32_t DOEPMSK; /**< @brief Device OUT endpoint common
+ interrupt mask register. */
+ volatile uint32_t DAINT; /**< @brief Device all endpoints interrupt
+ register. */
+ volatile uint32_t DAINTMSK; /**< @brief Device all endpoints interrupt
+ mask register. */
+ volatile uint32_t resvd820;
+ volatile uint32_t resvd824;
+ volatile uint32_t DVBUSDIS; /**< @brief Device VBUS discharge time
+ register. */
+ volatile uint32_t DVBUSPULSE; /**< @brief Device VBUS pulsing time
+ register. */
+ volatile uint32_t resvd830;
+ volatile uint32_t DIEPEMPMSK; /**< @brief Device IN endpoint FIFO empty
+ interrupt mask register. */
+ volatile uint32_t resvd838;
+ volatile uint32_t resvd83C;
+ volatile uint32_t resvd840[16];
+ volatile uint32_t resvd880[16];
+ volatile uint32_t resvd8C0[16];
+ stm32_otg_in_ep_t ie[16]; /**< @brief Input endpoints. */
+ stm32_otg_out_ep_t oe[16]; /**< @brief Output endpoints. */
+ volatile uint32_t resvdD00[64];
+ volatile uint32_t PCGCCTL; /**< @brief Power and clock gating control
+ register. */
+ volatile uint32_t resvdE04[127];
+ volatile uint32_t FIFO[16][1024];
+} stm32_otg_t;
+
+/**
+ * @name GOTGCTL register bit definitions
+ * @{
+ */
+#define GOTGCTL_BSVLD (1U<<19) /**< B-Session Valid. */
+#define GOTGCTL_ASVLD (1U<<18) /**< A-Session Valid. */
+#define GOTGCTL_DBCT (1U<<17) /**< Long/Short debounce time. */
+#define GOTGCTL_CIDSTS (1U<<16) /**< Connector ID status. */
+#define GOTGCTL_EHEN (1U<<12)
+#define GOTGCTL_DHNPEN (1U<<11) /**< Device HNP enabled. */
+#define GOTGCTL_HSHNPEN (1U<<10) /**< Host Set HNP enable. */
+#define GOTGCTL_HNPRQ (1U<<9) /**< HNP request. */
+#define GOTGCTL_HNGSCS (1U<<8) /**< Host negotiation success. */
+#define GOTGCTL_BVALOVAL (1U<<7)
+#define GOTGCTL_BVALOEN (1U<<6)
+#define GOTGCTL_AVALOVAL (1U<<5)
+#define GOTGCTL_AVALOEN (1U<<4)
+#define GOTGCTL_VBVALOVAL (1U<<3)
+#define GOTGCTL_VBVALOEN (1U<<2)
+#define GOTGCTL_SRQ (1U<<1) /**< Session request. */
+#define GOTGCTL_SRQSCS (1U<<0) /**< Session request success. */
+/** @} */
+
+/**
+ * @name GOTGINT register bit definitions
+ * @{
+ */
+#define GOTGINT_DBCDNE (1U<<19) /**< Debounce done. */
+#define GOTGINT_ADTOCHG (1U<<18) /**< A-Device timeout change. */
+#define GOTGINT_HNGDET (1U<<17) /**< Host negotiation detected. */
+#define GOTGINT_HNSSCHG (1U<<9) /**< Host negotiation success
+ status change. */
+#define GOTGINT_SRSSCHG (1U<<8) /**< Session request success
+ status change. */
+#define GOTGINT_SEDET (1U<<2) /**< Session end detected. */
+/** @} */
+
+/**
+ * @name GAHBCFG register bit definitions
+ * @{
+ */
+#define GAHBCFG_PTXFELVL (1U<<8) /**< Periodic TxFIFO empty
+ level. */
+#define GAHBCFG_TXFELVL (1U<<7) /**< Non-periodic TxFIFO empty
+ level. */
+#define GAHBCFG_DMAEN (1U<<5) /**< DMA enable (HS only). */
+#define GAHBCFG_HBSTLEN_MASK (15U<<1) /**< Burst length/type mask (HS
+ only). */
+#define GAHBCFG_HBSTLEN(n) ((n)<<1) /**< Burst length/type (HS
+ only). */
+#define GAHBCFG_GINTMSK (1U<<0) /**< Global interrupt mask. */
+/** @} */
+
+/**
+ * @name GUSBCFG register bit definitions
+ * @{
+ */
+#define GUSBCFG_CTXPKT (1U<<31) /**< Corrupt Tx packet. */
+#define GUSBCFG_FDMOD (1U<<30) /**< Force Device Mode. */
+#define GUSBCFG_FHMOD (1U<<29) /**< Force Host Mode. */
+#define GUSBCFG_TRDT_MASK (15U<<10) /**< USB Turnaround time field
+ mask. */
+#define GUSBCFG_TRDT(n) ((n)<<10) /**< USB Turnaround time field
+ value. */
+#define GUSBCFG_HNPCAP (1U<<9) /**< HNP-Capable. */
+#define GUSBCFG_SRPCAP (1U<<8) /**< SRP-Capable. */
+#define GUSBCFG_PHYSEL (1U<<6) /**< USB 2.0 High-Speed PHY or
+ USB 1.1 Full-Speed serial
+ transceiver Select. */
+#define GUSBCFG_TOCAL_MASK (7U<<0) /**< HS/FS timeout calibration
+ field mask. */
+#define GUSBCFG_TOCAL(n) ((n)<<0) /**< HS/FS timeout calibration
+ field value. */
+/** @} */
+
+/**
+ * @name GRSTCTL register bit definitions
+ * @{
+ */
+#define GRSTCTL_AHBIDL (1U<<31) /**< AHB Master Idle. */
+#define GRSTCTL_TXFNUM_MASK (31U<<6) /**< TxFIFO number field mask. */
+#define GRSTCTL_TXFNUM(n) ((n)<<6) /**< TxFIFO number field value. */
+#define GRSTCTL_TXFFLSH (1U<<5) /**< TxFIFO flush. */
+#define GRSTCTL_RXFFLSH (1U<<4) /**< RxFIFO flush. */
+#define GRSTCTL_FCRST (1U<<2) /**< Host frame counter reset. */
+#define GRSTCTL_HSRST (1U<<1) /**< HClk soft reset. */
+#define GRSTCTL_CSRST (1U<<0) /**< Core soft reset. */
+/** @} */
+
+/**
+ * @name GINTSTS register bit definitions
+ * @{
+ */
+#define GINTSTS_WKUPINT (1U<<31) /**< Resume/Remote wakeup
+ detected interrupt. */
+#define GINTSTS_SRQINT (1U<<30) /**< Session request/New session
+ detected interrupt. */
+#define GINTSTS_DISCINT (1U<<29) /**< Disconnect detected
+ interrupt. */
+#define GINTSTS_CIDSCHG (1U<<28) /**< Connector ID status change.*/
+#define GINTSTS_PTXFE (1U<<26) /**< Periodic TxFIFO empty. */
+#define GINTSTS_HCINT (1U<<25) /**< Host channels interrupt. */
+#define GINTSTS_HPRTINT (1U<<24) /**< Host port interrupt. */
+#define GINTSTS_IPXFR (1U<<21) /**< Incomplete periodic
+ transfer. */
+#define GINTSTS_IISOOXFR (1U<<21) /**< Incomplete isochronous OUT
+ transfer. */
+#define GINTSTS_IISOIXFR (1U<<20) /**< Incomplete isochronous IN
+ transfer. */
+#define GINTSTS_OEPINT (1U<<19) /**< OUT endpoints interrupt. */
+#define GINTSTS_IEPINT (1U<<18) /**< IN endpoints interrupt. */
+#define GINTSTS_EOPF (1U<<15) /**< End of periodic frame
+ interrupt. */
+#define GINTSTS_ISOODRP (1U<<14) /**< Isochronous OUT packet
+ dropped interrupt. */
+#define GINTSTS_ENUMDNE (1U<<13) /**< Enumeration done. */
+#define GINTSTS_USBRST (1U<<12) /**< USB reset. */
+#define GINTSTS_USBSUSP (1U<<11) /**< USB suspend. */
+#define GINTSTS_ESUSP (1U<<10) /**< Early suspend. */
+#define GINTSTS_GONAKEFF (1U<<7) /**< Global OUT NAK effective. */
+#define GINTSTS_GINAKEFF (1U<<6) /**< Global IN non-periodic NAK
+ effective. */
+#define GINTSTS_NPTXFE (1U<<5) /**< Non-periodic TxFIFO empty. */
+#define GINTSTS_RXFLVL (1U<<4) /**< RxFIFO non-empty. */
+#define GINTSTS_SOF (1U<<3) /**< Start of frame. */
+#define GINTSTS_OTGINT (1U<<2) /**< OTG interrupt. */
+#define GINTSTS_MMIS (1U<<1) /**< Mode Mismatch interrupt. */
+#define GINTSTS_CMOD (1U<<0) /**< Current mode of operation. */
+/** @} */
+
+/**
+ * @name GINTMSK register bit definitions
+ * @{
+ */
+#define GINTMSK_WKUM (1U<<31) /**< Resume/remote wakeup
+ detected interrupt mask. */
+#define GINTMSK_SRQM (1U<<30) /**< Session request/New session
+ detected interrupt mask. */
+#define GINTMSK_DISCM (1U<<29) /**< Disconnect detected
+ interrupt mask. */
+#define GINTMSK_CIDSCHGM (1U<<28) /**< Connector ID status change
+ mask. */
+#define GINTMSK_PTXFEM (1U<<26) /**< Periodic TxFIFO empty mask.*/
+#define GINTMSK_HCM (1U<<25) /**< Host channels interrupt
+ mask. */
+#define GINTMSK_HPRTM (1U<<24) /**< Host port interrupt mask. */
+#define GINTMSK_IPXFRM (1U<<21) /**< Incomplete periodic
+ transfer mask. */
+#define GINTMSK_IISOOXFRM (1U<<21) /**< Incomplete isochronous OUT
+ transfer mask. */
+#define GINTMSK_IISOIXFRM (1U<<20) /**< Incomplete isochronous IN
+ transfer mask. */
+#define GINTMSK_OEPM (1U<<19) /**< OUT endpoints interrupt
+ mask. */
+#define GINTMSK_IEPM (1U<<18) /**< IN endpoints interrupt
+ mask. */
+#define GINTMSK_EOPFM (1U<<15) /**< End of periodic frame
+ interrupt mask. */
+#define GINTMSK_ISOODRPM (1U<<14) /**< Isochronous OUT packet
+ dropped interrupt mask. */
+#define GINTMSK_ENUMDNEM (1U<<13) /**< Enumeration done mask. */
+#define GINTMSK_USBRSTM (1U<<12) /**< USB reset mask. */
+#define GINTMSK_USBSUSPM (1U<<11) /**< USB suspend mask. */
+#define GINTMSK_ESUSPM (1U<<10) /**< Early suspend mask. */
+#define GINTMSK_GONAKEFFM (1U<<7) /**< Global OUT NAK effective
+ mask. */
+#define GINTMSK_GINAKEFFM (1U<<6) /**< Global non-periodic IN NAK
+ effective mask. */
+#define GINTMSK_NPTXFEM (1U<<5) /**< Non-periodic TxFIFO empty
+ mask. */
+#define GINTMSK_RXFLVLM (1U<<4) /**< Receive FIFO non-empty
+ mask. */
+#define GINTMSK_SOFM (1U<<3) /**< Start of (micro)frame mask.*/
+#define GINTMSK_OTGM (1U<<2) /**< OTG interrupt mask. */
+#define GINTMSK_MMISM (1U<<1) /**< Mode Mismatch interrupt
+ mask. */
+/** @} */
+
+/**
+ * @name GRXSTSR register bit definitions
+ * @{
+ */
+#define GRXSTSR_PKTSTS_MASK (15U<<17) /**< Packet status mask. */
+#define GRXSTSR_PKTSTS(n) ((n)<<17) /**< Packet status value. */
+#define GRXSTSR_OUT_GLOBAL_NAK GRXSTSR_PKTSTS(1)
+#define GRXSTSR_OUT_DATA GRXSTSR_PKTSTS(2)
+#define GRXSTSR_OUT_COMP GRXSTSR_PKTSTS(3)
+#define GRXSTSR_SETUP_COMP GRXSTSR_PKTSTS(4)
+#define GRXSTSR_SETUP_DATA GRXSTSR_PKTSTS(6)
+#define GRXSTSR_DPID_MASK (3U<<15) /**< Data PID mask. */
+#define GRXSTSR_DPID(n) ((n)<<15) /**< Data PID value. */
+#define GRXSTSR_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
+#define GRXSTSR_BCNT(n) ((n)<<4) /**< Byte count value. */
+#define GRXSTSR_CHNUM_MASK (15U<<0) /**< Channel number mask. */
+#define GRXSTSR_CHNUM(n) ((n)<<0) /**< Channel number value. */
+#define GRXSTSR_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
+#define GRXSTSR_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
+/** @} */
+
+/**
+ * @name GRXSTSP register bit definitions
+ * @{
+ */
+#define GRXSTSP_PKTSTS_MASK (15<<17) /**< Packet status mask. */
+#define GRXSTSP_PKTSTS(n) ((n)<<17) /**< Packet status value. */
+#define GRXSTSP_OUT_GLOBAL_NAK GRXSTSP_PKTSTS(1)
+#define GRXSTSP_OUT_DATA GRXSTSP_PKTSTS(2)
+#define GRXSTSP_OUT_COMP GRXSTSP_PKTSTS(3)
+#define GRXSTSP_SETUP_COMP GRXSTSP_PKTSTS(4)
+#define GRXSTSP_SETUP_DATA GRXSTSP_PKTSTS(6)
+#define GRXSTSP_DPID_MASK (3U<<15) /**< Data PID mask. */
+#define GRXSTSP_DPID(n) ((n)<<15) /**< Data PID value. */
+#define GRXSTSP_BCNT_MASK (0x7FF<<4) /**< Byte count mask. */
+#define GRXSTSP_BCNT_OFF 4 /**< Byte count offset. */
+#define GRXSTSP_BCNT(n) ((n)<<4) /**< Byte count value. */
+#define GRXSTSP_CHNUM_MASK (15U<<0) /**< Channel number mask. */
+#define GRXSTSP_CHNUM(n) ((n)<<0) /**< Channel number value. */
+#define GRXSTSP_EPNUM_MASK (15U<<0) /**< Endpoint number mask. */
+#define GRXSTSP_EPNUM_OFF 0 /**< Endpoint number offset. */
+#define GRXSTSP_EPNUM(n) ((n)<<0) /**< Endpoint number value. */
+/** @} */
+
+/**
+ * @name GRXFSIZ register bit definitions
+ * @{
+ */
+#define GRXFSIZ_RXFD_MASK (0xFFFF<<0) /**< RxFIFO depth mask. */
+#define GRXFSIZ_RXFD(n) ((n)<<0) /**< RxFIFO depth value. */
+/** @} */
+
+/**
+ * @name DIEPTXFx register bit definitions
+ * @{
+ */
+#define DIEPTXF_INEPTXFD_MASK (0xFFFFU<<16)/**< IN endpoint TxFIFO depth
+ mask. */
+#define DIEPTXF_INEPTXFD(n) ((n)<<16) /**< IN endpoint TxFIFO depth
+ value. */
+#define DIEPTXF_INEPTXSA_MASK (0xFFFF<<0) /**< IN endpoint FIFOx transmit
+ RAM start address mask. */
+#define DIEPTXF_INEPTXSA(n) ((n)<<0) /**< IN endpoint FIFOx transmit
+ RAM start address value. */
+/** @} */
+
+/**
+ * @name GCCFG register bit definitions
+ * @{
+ */
+/* Definitions for stepping 1.*/
+#define GCCFG_NOVBUSSENS (1U<<21) /**< VBUS sensing disable. */
+#define GCCFG_SOFOUTEN (1U<<20) /**< SOF output enable. */
+#define GCCFG_VBUSBSEN (1U<<19) /**< Enable the VBUS sensing "B"
+ device. */
+#define GCCFG_VBUSASEN (1U<<18) /**< Enable the VBUS sensing "A"
+ device. */
+
+/* Definitions for stepping 2.*/
+#define GCCFG_VBDEN (1U<<21) /**< VBUS sensing enable. */
+#define GCCFG_PWRDWN (1U<<16) /**< Power down. */
+/** @} */
+
+/**
+ * @name HPTXFSIZ register bit definitions
+ * @{
+ */
+#define HPTXFSIZ_PTXFD_MASK (0xFFFFU<<16)/**< Host periodic TxFIFO
+ depth mask. */
+#define HPTXFSIZ_PTXFD(n) ((n)<<16) /**< Host periodic TxFIFO
+ depth value. */
+#define HPTXFSIZ_PTXSA_MASK (0xFFFFU<<0)/**< Host periodic TxFIFO
+ Start address mask. */
+#define HPTXFSIZ_PTXSA(n) ((n)<<0) /**< Host periodic TxFIFO
+ start address value. */
+/** @} */
+
+/**
+ * @name HCFG register bit definitions
+ * @{
+ */
+#define HCFG_FSLSS (1U<<2) /**< FS- and LS-only support. */
+#define HCFG_FSLSPCS_MASK (3U<<0) /**< FS/LS PHY clock select
+ mask. */
+#define HCFG_FSLSPCS_48 (1U<<0) /**< PHY clock is running at
+ 48 MHz. */
+#define HCFG_FSLSPCS_6 (2U<<0) /**< PHY clock is running at
+ 6 MHz. */
+/** @} */
+
+/**
+ * @name HFIR register bit definitions
+ * @{
+ */
+#define HFIR_FRIVL_MASK (0xFFFFU<<0)/**< Frame interval mask. */
+#define HFIR_FRIVL(n) ((n)<<0) /**< Frame interval value. */
+/** @} */
+
+/**
+ * @name HFNUM register bit definitions
+ * @{
+ */
+#define HFNUM_FTREM_MASK (0xFFFFU<<16)/**< Frame time Remaining mask.*/
+#define HFNUM_FTREM(n) ((n)<<16) /**< Frame time Remaining value.*/
+#define HFNUM_FRNUM_MASK (0xFFFFU<<0)/**< Frame number mask. */
+#define HFNUM_FRNUM(n) ((n)<<0) /**< Frame number value. */
+/** @} */
+
+/**
+ * @name HPTXSTS register bit definitions
+ * @{
+ */
+#define HPTXSTS_PTXQTOP_MASK (0xFFU<<24) /**< Top of the periodic
+ transmit request queue
+ mask. */
+#define HPTXSTS_PTXQTOP(n) ((n)<<24) /**< Top of the periodic
+ transmit request queue
+ value. */
+#define HPTXSTS_PTXQSAV_MASK (0xFF<<16) /**< Periodic transmit request
+ queue Space Available
+ mask. */
+#define HPTXSTS_PTXQSAV(n) ((n)<<16) /**< Periodic transmit request
+ queue Space Available
+ value. */
+#define HPTXSTS_PTXFSAVL_MASK (0xFFFF<<0) /**< Periodic transmit Data
+ FIFO Space Available
+ mask. */
+#define HPTXSTS_PTXFSAVL(n) ((n)<<0) /**< Periodic transmit Data
+ FIFO Space Available
+ value. */
+/** @} */
+
+/**
+ * @name HAINT register bit definitions
+ * @{
+ */
+#define HAINT_HAINT_MASK (0xFFFFU<<0)/**< Channel interrupts mask. */
+#define HAINT_HAINT(n) ((n)<<0) /**< Channel interrupts value. */
+/** @} */
+
+/**
+ * @name HAINTMSK register bit definitions
+ * @{
+ */
+#define HAINTMSK_HAINTM_MASK (0xFFFFU<<0)/**< Channel interrupt mask
+ mask. */
+#define HAINTMSK_HAINTM(n) ((n)<<0) /**< Channel interrupt mask
+ value. */
+/** @} */
+
+/**
+ * @name HPRT register bit definitions
+ * @{
+ */
+#define HPRT_PSPD_MASK (3U<<17) /**< Port speed mask. */
+#define HPRT_PSPD_FS (1U<<17) /**< Full speed value. */
+#define HPRT_PSPD_LS (2U<<17) /**< Low speed value. */
+#define HPRT_PTCTL_MASK (15<<13) /**< Port Test control mask. */
+#define HPRT_PTCTL(n) ((n)<<13) /**< Port Test control value. */
+#define HPRT_PPWR (1U<<12) /**< Port power. */
+#define HPRT_PLSTS_MASK (3U<<11) /**< Port Line status mask. */
+#define HPRT_PLSTS_DM (1U<<11) /**< Logic level of D-. */
+#define HPRT_PLSTS_DP (1U<<10) /**< Logic level of D+. */
+#define HPRT_PRST (1U<<8) /**< Port reset. */
+#define HPRT_PSUSP (1U<<7) /**< Port suspend. */
+#define HPRT_PRES (1U<<6) /**< Port Resume. */
+#define HPRT_POCCHNG (1U<<5) /**< Port overcurrent change. */
+#define HPRT_POCA (1U<<4) /**< Port overcurrent active. */
+#define HPRT_PENCHNG (1U<<3) /**< Port enable/disable change.*/
+#define HPRT_PENA (1U<<2) /**< Port enable. */
+#define HPRT_PCDET (1U<<1) /**< Port Connect detected. */
+#define HPRT_PCSTS (1U<<0) /**< Port connect status. */
+/** @} */
+
+/**
+ * @name HCCHAR register bit definitions
+ * @{
+ */
+#define HCCHAR_CHENA (1U<<31) /**< Channel enable. */
+#define HCCHAR_CHDIS (1U<<30) /**< Channel Disable. */
+#define HCCHAR_ODDFRM (1U<<29) /**< Odd frame. */
+#define HCCHAR_DAD_MASK (0x7FU<<22) /**< Device Address mask. */
+#define HCCHAR_DAD(n) ((n)<<22) /**< Device Address value. */
+#define HCCHAR_MCNT_MASK (3U<<20) /**< Multicount mask. */
+#define HCCHAR_MCNT(n) ((n)<<20) /**< Multicount value. */
+#define HCCHAR_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
+#define HCCHAR_EPTYP(n) ((n)<<18) /**< Endpoint type value. */
+#define HCCHAR_EPTYP_CTL (0U<<18) /**< Control endpoint value. */
+#define HCCHAR_EPTYP_ISO (1U<<18) /**< Isochronous endpoint value.*/
+#define HCCHAR_EPTYP_BULK (2U<<18) /**< Bulk endpoint value. */
+#define HCCHAR_EPTYP_INTR (3U<<18) /**< Interrupt endpoint value. */
+#define HCCHAR_LSDEV (1U<<17) /**< Low-Speed device. */
+#define HCCHAR_EPDIR (1U<<15) /**< Endpoint direction. */
+#define HCCHAR_EPNUM_MASK (15U<<11) /**< Endpoint number mask. */
+#define HCCHAR_EPNUM(n) ((n)<<11) /**< Endpoint number value. */
+#define HCCHAR_MPS_MASK (0x7FFU<<0) /**< Maximum packet size mask. */
+#define HCCHAR_MPS(n) ((n)<<0) /**< Maximum packet size value. */
+/** @} */
+
+/**
+ * @name HCINT register bit definitions
+ * @{
+ */
+#define HCINT_DTERR (1U<<10) /**< Data toggle error. */
+#define HCINT_FRMOR (1U<<9) /**< Frame overrun. */
+#define HCINT_BBERR (1U<<8) /**< Babble error. */
+#define HCINT_TRERR (1U<<7) /**< Transaction Error. */
+#define HCINT_ACK (1U<<5) /**< ACK response
+ received/transmitted
+ interrupt. */
+#define HCINT_NAK (1U<<4) /**< NAK response received
+ interrupt. */
+#define HCINT_STALL (1U<<3) /**< STALL response received
+ interrupt. */
+#define HCINT_AHBERR (1U<<2) /**< AHB error interrupt. */
+#define HCINT_CHH (1U<<1) /**< Channel halted. */
+#define HCINT_XFRC (1U<<0) /**< Transfer completed. */
+/** @} */
+
+/**
+ * @name HCINTMSK register bit definitions
+ * @{
+ */
+#define HCINTMSK_DTERRM (1U<<10) /**< Data toggle error mask. */
+#define HCINTMSK_FRMORM (1U<<9) /**< Frame overrun mask. */
+#define HCINTMSK_BBERRM (1U<<8) /**< Babble error mask. */
+#define HCINTMSK_TRERRM (1U<<7) /**< Transaction error mask. */
+#define HCINTMSK_NYET (1U<<6) /**< NYET response received
+ interrupt mask. */
+#define HCINTMSK_ACKM (1U<<5) /**< ACK Response
+ received/transmitted
+ interrupt mask. */
+#define HCINTMSK_NAKM (1U<<4) /**< NAK response received
+ interrupt mask. */
+#define HCINTMSK_STALLM (1U<<3) /**< STALL response received
+ interrupt mask. */
+#define HCINTMSK_AHBERRM (1U<<2) /**< AHB error interrupt mask. */
+#define HCINTMSK_CHHM (1U<<1) /**< Channel halted mask. */
+#define HCINTMSK_XFRCM (1U<<0) /**< Transfer completed mask. */
+/** @} */
+
+/**
+ * @name HCTSIZ register bit definitions
+ * @{
+ */
+#define HCTSIZ_DPID_MASK (3U<<29) /**< PID mask. */
+#define HCTSIZ_DPID_DATA0 (0U<<29) /**< DATA0. */
+#define HCTSIZ_DPID_DATA2 (1U<<29) /**< DATA2. */
+#define HCTSIZ_DPID_DATA1 (2U<<29) /**< DATA1. */
+#define HCTSIZ_DPID_MDATA (3U<<29) /**< MDATA. */
+#define HCTSIZ_DPID_SETUP (3U<<29) /**< SETUP. */
+#define HCTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
+#define HCTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
+#define HCTSIZ_XFRSIZ_MASK (0x7FFFF<<0)/**< Transfer size mask. */
+#define HCTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
+/** @} */
+
+/**
+ * @name DCFG register bit definitions
+ * @{
+ */
+#define DCFG_PFIVL_MASK (3U<<11) /**< Periodic frame interval
+ mask. */
+#define DCFG_PFIVL(n) ((n)<<11) /**< Periodic frame interval
+ value. */
+#define DCFG_DAD_MASK (0x7FU<<4) /**< Device address mask. */
+#define DCFG_DAD(n) ((n)<<4) /**< Device address value. */
+#define DCFG_NZLSOHSK (1U<<2) /**< Non-Zero-Length status
+ OUT handshake. */
+#define DCFG_DSPD_MASK (3U<<0) /**< Device speed mask. */
+#define DCFG_DSPD_HS (0U<<0) /**< High speed (USB 2.0). */
+#define DCFG_DSPD_HS_FS (1U<<0) /**< High speed (USB 2.0) in FS
+ mode. */
+#define DCFG_DSPD_FS11 (3U<<0) /**< Full speed (USB 1.1
+ transceiver clock is 48
+ MHz). */
+/** @} */
+
+/**
+ * @name DCTL register bit definitions
+ * @{
+ */
+#define DCTL_POPRGDNE (1U<<11) /**< Power-on programming done. */
+#define DCTL_CGONAK (1U<<10) /**< Clear global OUT NAK. */
+#define DCTL_SGONAK (1U<<9) /**< Set global OUT NAK. */
+#define DCTL_CGINAK (1U<<8) /**< Clear global non-periodic
+ IN NAK. */
+#define DCTL_SGINAK (1U<<7) /**< Set global non-periodic
+ IN NAK. */
+#define DCTL_TCTL_MASK (7U<<4) /**< Test control mask. */
+#define DCTL_TCTL(n) ((n)<<4 /**< Test control value. */
+#define DCTL_GONSTS (1U<<3) /**< Global OUT NAK status. */
+#define DCTL_GINSTS (1U<<2) /**< Global non-periodic IN
+ NAK status. */
+#define DCTL_SDIS (1U<<1) /**< Soft disconnect. */
+#define DCTL_RWUSIG (1U<<0) /**< Remote wakeup signaling. */
+/** @} */
+
+/**
+ * @name DSTS register bit definitions
+ * @{
+ */
+#define DSTS_FNSOF_MASK (0x3FFU<<8) /**< Frame number of the received
+ SOF mask. */
+#define DSTS_FNSOF(n) ((n)<<8) /**< Frame number of the received
+ SOF value. */
+#define DSTS_FNSOF_ODD (1U<<8) /**< Frame parity of the received
+ SOF value. */
+#define DSTS_EERR (1U<<3) /**< Erratic error. */
+#define DSTS_ENUMSPD_MASK (3U<<1) /**< Enumerated speed mask. */
+#define DSTS_ENUMSPD_FS_48 (3U<<1) /**< Full speed (PHY clock is
+ running at 48 MHz). */
+#define DSTS_ENUMSPD_HS_480 (0U<<1) /**< High speed. */
+#define DSTS_SUSPSTS (1U<<0) /**< Suspend status. */
+/** @} */
+
+/**
+ * @name DIEPMSK register bit definitions
+ * @{
+ */
+#define DIEPMSK_TXFEM (1U<<6) /**< Transmit FIFO empty mask. */
+#define DIEPMSK_INEPNEM (1U<<6) /**< IN endpoint NAK effective
+ mask. */
+#define DIEPMSK_ITTXFEMSK (1U<<4) /**< IN token received when
+ TxFIFO empty mask. */
+#define DIEPMSK_TOCM (1U<<3) /**< Timeout condition mask. */
+#define DIEPMSK_EPDM (1U<<1) /**< Endpoint disabled
+ interrupt mask. */
+#define DIEPMSK_XFRCM (1U<<0) /**< Transfer completed
+ interrupt mask. */
+/** @} */
+
+/**
+ * @name DOEPMSK register bit definitions
+ * @{
+ */
+#define DOEPMSK_OTEPDM (1U<<4) /**< OUT token received when
+ endpoint disabled mask. */
+#define DOEPMSK_STUPM (1U<<3) /**< SETUP phase done mask. */
+#define DOEPMSK_EPDM (1U<<1) /**< Endpoint disabled
+ interrupt mask. */
+#define DOEPMSK_XFRCM (1U<<0) /**< Transfer completed
+ interrupt mask. */
+/** @} */
+
+/**
+ * @name DAINT register bit definitions
+ * @{
+ */
+#define DAINT_OEPINT_MASK (0xFFFFU<<16)/**< OUT endpoint interrupt
+ bits mask. */
+#define DAINT_OEPINT(n) ((n)<<16) /**< OUT endpoint interrupt
+ bits value. */
+#define DAINT_IEPINT_MASK (0xFFFFU<<0)/**< IN endpoint interrupt
+ bits mask. */
+#define DAINT_IEPINT(n) ((n)<<0) /**< IN endpoint interrupt
+ bits value. */
+/** @} */
+
+/**
+ * @name DAINTMSK register bit definitions
+ * @{
+ */
+#define DAINTMSK_OEPM_MASK (0xFFFFU<<16)/**< OUT EP interrupt mask
+ bits mask. */
+#define DAINTMSK_OEPM(n) (1U<<(16+(n)))/**< OUT EP interrupt mask
+ bits value. */
+#define DAINTMSK_IEPM_MASK (0xFFFFU<<0)/**< IN EP interrupt mask
+ bits mask. */
+#define DAINTMSK_IEPM(n) (1U<<(n)) /**< IN EP interrupt mask
+ bits value. */
+/** @} */
+
+/**
+ * @name DVBUSDIS register bit definitions
+ * @{
+ */
+#define DVBUSDIS_VBUSDT_MASK (0xFFFFU<<0)/**< Device VBUS discharge
+ time mask. */
+#define DVBUSDIS_VBUSDT(n) ((n)<<0) /**< Device VBUS discharge
+ time value. */
+/** @} */
+
+/**
+ * @name DVBUSPULSE register bit definitions
+ * @{
+ */
+#define DVBUSPULSE_DVBUSP_MASK (0xFFFU<<0) /**< Device VBUSpulsing time
+ mask. */
+#define DVBUSPULSE_DVBUSP(n) ((n)<<0) /**< Device VBUS pulsing time
+ value. */
+/** @} */
+
+/**
+ * @name DIEPEMPMSK register bit definitions
+ * @{
+ */
+#define DIEPEMPMSK_INEPTXFEM(n) (1U<<(n)) /**< IN EP Tx FIFO empty
+ interrupt mask bit. */
+/** @} */
+
+/**
+ * @name DIEPCTL register bit definitions
+ * @{
+ */
+#define DIEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
+#define DIEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
+#define DIEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
+#define DIEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
+#define DIEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
+#define DIEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
+#define DIEPCTL_SNAK (1U<<27) /**< Set NAK. */
+#define DIEPCTL_CNAK (1U<<26) /**< Clear NAK. */
+#define DIEPCTL_TXFNUM_MASK (15U<<22) /**< TxFIFO number mask. */
+#define DIEPCTL_TXFNUM(n) ((n)<<22) /**< TxFIFO number value. */
+#define DIEPCTL_STALL (1U<<21) /**< STALL handshake. */
+#define DIEPCTL_SNPM (1U<<20) /**< Snoop mode. */
+#define DIEPCTL_EPTYP_MASK (3<<18) /**< Endpoint type mask. */
+#define DIEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
+#define DIEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
+#define DIEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
+#define DIEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
+#define DIEPCTL_NAKSTS (1U<<17) /**< NAK status. */
+#define DIEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
+#define DIEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
+#define DIEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
+#define DIEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
+#define DIEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
+/** @} */
+
+/**
+ * @name DIEPINT register bit definitions
+ * @{
+ */
+#define DIEPINT_TXFE (1U<<7) /**< Transmit FIFO empty. */
+#define DIEPINT_INEPNE (1U<<6) /**< IN endpoint NAK effective. */
+#define DIEPINT_ITTXFE (1U<<4) /**< IN Token received when
+ TxFIFO is empty. */
+#define DIEPINT_TOC (1U<<3) /**< Timeout condition. */
+#define DIEPINT_EPDISD (1U<<1) /**< Endpoint disabled
+ interrupt. */
+#define DIEPINT_XFRC (1U<<0) /**< Transfer completed. */
+/** @} */
+
+/**
+ * @name DIEPTSIZ register bit definitions
+ * @{
+ */
+#define DIEPTSIZ_MCNT_MASK (3U<<29) /**< Multi count mask. */
+#define DIEPTSIZ_MCNT(n) ((n)<<29) /**< Multi count value. */
+#define DIEPTSIZ_PKTCNT_MASK (0x3FF<<19) /**< Packet count mask. */
+#define DIEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
+#define DIEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
+#define DIEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
+/** @} */
+
+/**
+ * @name DTXFSTS register bit definitions.
+ * @{
+ */
+#define DTXFSTS_INEPTFSAV_MASK (0xFFFF<<0) /**< IN endpoint TxFIFO space
+ available. */
+/** @} */
+
+/**
+ * @name DOEPCTL register bit definitions.
+ * @{
+ */
+#define DOEPCTL_EPENA (1U<<31) /**< Endpoint enable. */
+#define DOEPCTL_EPDIS (1U<<30) /**< Endpoint disable. */
+#define DOEPCTL_SD1PID (1U<<29) /**< Set DATA1 PID. */
+#define DOEPCTL_SODDFRM (1U<<29) /**< Set odd frame. */
+#define DOEPCTL_SD0PID (1U<<28) /**< Set DATA0 PID. */
+#define DOEPCTL_SEVNFRM (1U<<28) /**< Set even frame. */
+#define DOEPCTL_SNAK (1U<<27) /**< Set NAK. */
+#define DOEPCTL_CNAK (1U<<26) /**< Clear NAK. */
+#define DOEPCTL_STALL (1U<<21) /**< STALL handshake. */
+#define DOEPCTL_SNPM (1U<<20) /**< Snoop mode. */
+#define DOEPCTL_EPTYP_MASK (3U<<18) /**< Endpoint type mask. */
+#define DOEPCTL_EPTYP_CTRL (0U<<18) /**< Control. */
+#define DOEPCTL_EPTYP_ISO (1U<<18) /**< Isochronous. */
+#define DOEPCTL_EPTYP_BULK (2U<<18) /**< Bulk. */
+#define DOEPCTL_EPTYP_INTR (3U<<18) /**< Interrupt. */
+#define DOEPCTL_NAKSTS (1U<<17) /**< NAK status. */
+#define DOEPCTL_EONUM (1U<<16) /**< Even/odd frame. */
+#define DOEPCTL_DPID (1U<<16) /**< Endpoint data PID. */
+#define DOEPCTL_USBAEP (1U<<15) /**< USB active endpoint. */
+#define DOEPCTL_MPSIZ_MASK (0x3FFU<<0) /**< Maximum Packet size mask. */
+#define DOEPCTL_MPSIZ(n) ((n)<<0) /**< Maximum Packet size value. */
+/** @} */
+
+/**
+ * @name DOEPINT register bit definitions
+ * @{
+ */
+#define DOEPINT_SETUP_RCVD (1U<<15) /**< SETUP packet received. */
+#define DOEPINT_B2BSTUP (1U<<6) /**< Back-to-back SETUP packets
+ received. */
+#define DOEPINT_OTEPDIS (1U<<4) /**< OUT token received when
+ endpoint disabled. */
+#define DOEPINT_STUP (1U<<3) /**< SETUP phase done. */
+#define DOEPINT_EPDISD (1U<<1) /**< Endpoint disabled
+ interrupt. */
+#define DOEPINT_XFRC (1U<<0) /**< Transfer completed
+ interrupt. */
+/** @} */
+
+/**
+ * @name DOEPTSIZ register bit definitions
+ * @{
+ */
+#define DOEPTSIZ_RXDPID_MASK (3U<<29) /**< Received data PID mask. */
+#define DOEPTSIZ_RXDPID(n) ((n)<<29) /**< Received data PID value. */
+#define DOEPTSIZ_STUPCNT_MASK (3U<<29) /**< SETUP packet count mask. */
+#define DOEPTSIZ_STUPCNT(n) ((n)<<29) /**< SETUP packet count value. */
+#define DOEPTSIZ_PKTCNT_MASK (0x3FFU<<19)/**< Packet count mask. */
+#define DOEPTSIZ_PKTCNT(n) ((n)<<19) /**< Packet count value. */
+#define DOEPTSIZ_XFRSIZ_MASK (0x7FFFFU<<0)/**< Transfer size mask. */
+#define DOEPTSIZ_XFRSIZ(n) ((n)<<0) /**< Transfer size value. */
+/** @} */
+
+/**
+ * @name PCGCCTL register bit definitions
+ * @{
+ */
+#define PCGCCTL_PHYSUSP (1U<<4) /**< PHY Suspended. */
+#define PCGCCTL_GATEHCLK (1U<<1) /**< Gate HCLK. */
+#define PCGCCTL_STPPCLK (1U<<0) /**< Stop PCLK. */
+/** @} */
+
+#if defined(STM32H7XX) || defined(__DOXYGEN__)
+/**
+ * @brief OTG_FS registers block memory address.
+ */
+#define OTG_FS_ADDR 0x40080000
+
+/**
+ * @brief OTG_HS registers block memory address.
+ */
+#define OTG_HS_ADDR 0x40040000
+#else
+#define OTG_FS_ADDR 0x50000000
+#define OTG_HS_ADDR 0x40040000
+#endif
+
+/**
+ * @brief Accesses to the OTG_FS registers block.
+ */
+#define OTG_FS ((stm32_otg_t *)OTG_FS_ADDR)
+
+/**
+ * @brief Accesses to the OTG_HS registers block.
+ */
+#define OTG_HS ((stm32_otg_t *)OTG_HS_ADDR)
+
+#endif /* STM32_OTG_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk b/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
index e59aec084b..eaec8176f0 100644
--- a/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1
diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
index 915135ccf9..7301d80335 100644
--- a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
+++ b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.c
@@ -1,383 +1,383 @@
-/*
- 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 QUADSPIv1//hal_wspi_lld.c
- * @brief STM32 WSPI subsystem low level driver source.
- *
- * @addtogroup WSPI
- * @{
- */
-
-#include "hal.h"
-
-#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define QUADSPI1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_WSPI_QUADSPI1_DMA_STREAM, \
- STM32_QUADSPI1_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief QUADSPI1 driver identifier.*/
-#if STM32_WSPI_USE_QUADSPI1 || defined(__DOXYGEN__)
-WSPIDriver WSPID1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Waits for completion of previous operation.
- */
-static inline void wspi_lld_sync(WSPIDriver *wspip) {
-
- while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
- }
-}
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void wspi_lld_serve_dma_interrupt(WSPIDriver *wspip, uint32_t flags) {
-
- (void)wspip;
- (void)flags;
-
- /* DMA errors handling.*/
-#if defined(STM32_WSPI_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_WSPI_DMA_ERROR_HOOK(wspip);
- }
-#endif
-}
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- */
-static void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
-
- /* Portable WSPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _wspi_isr_code(wspip);
-
- /* Stop everything, we need to give DMA enough time to complete the ongoing
- operation. Race condition hidden here.*/
- while (dmaStreamGetTransactionSize(wspip->dma) > 0U)
- ;
-
- /* Clearing DMA interrupts here because the DMA ISR is not called on
- transfer complete.*/
- dmaStreamClearInterrupt(wspip->dma);
- dmaStreamDisable(wspip->dma);
-
-#if defined(STM32L471xx) || defined(STM32L475xx) || \
- defined(STM32L476xx) || defined(STM32L486xx)
- /* Handling of errata: Extra data written in the FIFO at the end of a
- read transfer.*/
- if (wspip->state == WSPI_RECEIVE) {
- while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
- (void) wspip->qspi->DR;
- }
- }
-#endif
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_WSPI_USE_QUADSPI1 || defined(__DOXYGEN__)
-#if !defined(STM32_QUADSPI1_SUPPRESS_ISR)
-#if !defined(STM32_QUADSPI1_HANDLER)
-#error "STM32_QUADSPI1_HANDLER not defined"
-#endif
-/**
- * @brief STM32_QUADSPI1_HANDLER interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_QUADSPI1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- QUADSPI->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF |
- QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF;
-
- wspi_lld_serve_interrupt(&WSPID1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_QUADSPI1_SUPPRESS_ISR) */
-#endif /* STM32_WSPI_USE_QUADSPI1 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level WSPI driver initialization.
- *
- * @notapi
- */
-void wspi_lld_init(void) {
-
-#if STM32_WSPI_USE_QUADSPI1
- wspiObjectInit(&WSPID1);
- WSPID1.qspi = QUADSPI;
- WSPID1.dma = NULL;
- WSPID1.dmamode = STM32_DMA_CR_CHSEL(QUADSPI1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_WSPI_QUADSPI1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_BYTE |
- STM32_DMA_CR_MSIZE_BYTE |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- nvicEnableVector(STM32_QUADSPI1_NUMBER, STM32_WSPI_QUADSPI1_IRQ_PRIORITY);
-#endif
-}
-
-/**
- * @brief Configures and activates the WSPI peripheral.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_start(WSPIDriver *wspip) {
-
- /* If in stopped state then full initialization.*/
- if (wspip->state == WSPI_STOP) {
-#if STM32_WSPI_USE_QUADSPI1
- if (&WSPID1 == wspip) {
- wspip->dma = dmaStreamAllocI(STM32_WSPI_QUADSPI1_DMA_STREAM,
- STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)wspi_lld_serve_dma_interrupt,
- (void *)wspip);
- osalDbgAssert(wspip->dma != NULL, "unable to allocate stream");
- rccEnableQUADSPI1(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(wspip->dma, STM32_DMAMUX1_QUADSPI);
-#endif
- }
-#endif
-
- /* Common initializations.*/
- dmaStreamSetPeripheral(wspip->dma, &wspip->qspi->DR);
- }
-
- /* WSPI setup and enable.*/
- wspip->qspi->DCR = wspip->config->dcr;
- wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) |
- QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_EN;
- wspip->qspi->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF |
- QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF;
-}
-
-/**
- * @brief Deactivates the WSPI peripheral.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_stop(WSPIDriver *wspip) {
-
- /* If in ready state then disables the QUADSPI clock.*/
- if (wspip->state == WSPI_READY) {
-
- /* WSPI disable.*/
- wspip->qspi->CR = 0U;
-
- /* Releasing the DMA.*/
- dmaStreamFreeI(wspip->dma);
- wspip->dma = NULL;
-
- /* Stopping involved clocks.*/
-#if STM32_WSPI_USE_QUADSPI1
- if (&WSPID1 == wspip) {
- rccDisableQUADSPI1();
- }
-#endif
- }
-}
-
-/**
- * @brief Sends a command without data phase.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- *
- * @notapi
- */
-void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) {
-
-#if STM32_USE_STM32_D1_WORKAROUND == TRUE
- /* If it is a command without address and alternate phases then the command
- is sent as an alternate byte, the command phase is suppressed.*/
- if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) {
- /* The command mode field is copied in the alternate mode field. All
- other fields are not used in this scenario.*/
- wspip->qspi->DLR = 0U;
- wspip->qspi->ABR = cmdp->cmd;
- wspip->qspi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U;
- return;
- }
-#endif
- wspip->qspi->DLR = 0U;
- wspip->qspi->ABR = cmdp->alt;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->qspi->AR = cmdp->addr;
- }
-
- /* Waiting for the previous operation to complete.*/
- wspi_lld_sync(wspip);
-}
-
-/**
- * @brief Sends a command with data over the WSPI bus.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[in] n number of bytes to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, const uint8_t *txbuf) {
-
- dmaStreamSetMemory0(wspip->dma, txbuf);
- dmaStreamSetTransactionSize(wspip->dma, n);
- dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_M2P);
-
- wspip->qspi->DLR = n - 1;
- wspip->qspi->ABR = cmdp->alt;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->qspi->AR = cmdp->addr;
- }
-
- dmaStreamEnable(wspip->dma);
-}
-
-/**
- * @brief Sends a command then receives data over the WSPI bus.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[in] n number of bytes to send
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, uint8_t *rxbuf) {
-
- dmaStreamSetMemory0(wspip->dma, rxbuf);
- dmaStreamSetTransactionSize(wspip->dma, n);
- dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_P2M);
-
- wspip->qspi->DLR = n - 1;
- wspip->qspi->ABR = cmdp->alt;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
- QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
- QUADSPI_CCR_FMODE_0;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->qspi->AR = cmdp->addr;
- }
-
- dmaStreamEnable(wspip->dma);
-}
-
-#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Maps in memory space a WSPI flash device.
- * @pre The memory flash device must be initialized appropriately
- * before mapping it in memory space.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[out] addrp pointer to the memory start address of the mapped
- * flash or @p NULL
- *
- * @notapi
- */
-void wspi_lld_map_flash(WSPIDriver *wspip,
- const wspi_command_t *cmdp,
- uint8_t **addrp) {
-
- /* Disabling the DMA request while in memory mapped mode.*/
- wspip->qspi->CR &= ~QUADSPI_CR_DMAEN;
-
- /* Starting memory mapped mode using the passed parameters.*/
- wspip->qspi->DLR = 0;
- wspip->qspi->ABR = 0;
- wspip->qspi->AR = 0;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
- QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
- QUADSPI_CCR_FMODE_1 | QUADSPI_CCR_FMODE_0;
-
- /* Mapped flash absolute base address.*/
- if (addrp != NULL) {
- *addrp = (uint8_t *)0x90000000;
- }
-}
-
-/**
- * @brief Unmaps from memory space a WSPI flash device.
- * @post The memory flash device must be re-initialized for normal
- * commands exchange.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_unmap_flash(WSPIDriver *wspip) {
-
- /* Aborting memory mapped mode.*/
- wspip->qspi->CR |= QUADSPI_CR_ABORT;
- while ((wspip->qspi->CR & QUADSPI_CR_ABORT) != 0U) {
- }
-
- /* Re-enabling DMA request, we are going back to indirect mode.*/
- wspip->qspi->CR |= QUADSPI_CR_DMAEN;
-}
-#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
-
-#endif /* HAL_USE_WSPI */
-
-/** @} */
+/*
+ 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 QUADSPIv1//hal_wspi_lld.c
+ * @brief STM32 WSPI subsystem low level driver source.
+ *
+ * @addtogroup WSPI
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define QUADSPI1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_WSPI_QUADSPI1_DMA_STREAM, \
+ STM32_QUADSPI1_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief QUADSPI1 driver identifier.*/
+#if STM32_WSPI_USE_QUADSPI1 || defined(__DOXYGEN__)
+WSPIDriver WSPID1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Waits for completion of previous operation.
+ */
+static inline void wspi_lld_sync(WSPIDriver *wspip) {
+
+ while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
+ }
+}
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void wspi_lld_serve_dma_interrupt(WSPIDriver *wspip, uint32_t flags) {
+
+ (void)wspip;
+ (void)flags;
+
+ /* DMA errors handling.*/
+#if defined(STM32_WSPI_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_WSPI_DMA_ERROR_HOOK(wspip);
+ }
+#endif
+}
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ */
+static void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
+
+ /* Portable WSPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _wspi_isr_code(wspip);
+
+ /* Stop everything, we need to give DMA enough time to complete the ongoing
+ operation. Race condition hidden here.*/
+ while (dmaStreamGetTransactionSize(wspip->dma) > 0U)
+ ;
+
+ /* Clearing DMA interrupts here because the DMA ISR is not called on
+ transfer complete.*/
+ dmaStreamClearInterrupt(wspip->dma);
+ dmaStreamDisable(wspip->dma);
+
+#if defined(STM32L471xx) || defined(STM32L475xx) || \
+ defined(STM32L476xx) || defined(STM32L486xx)
+ /* Handling of errata: Extra data written in the FIFO at the end of a
+ read transfer.*/
+ if (wspip->state == WSPI_RECEIVE) {
+ while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
+ (void) wspip->qspi->DR;
+ }
+ }
+#endif
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_WSPI_USE_QUADSPI1 || defined(__DOXYGEN__)
+#if !defined(STM32_QUADSPI1_SUPPRESS_ISR)
+#if !defined(STM32_QUADSPI1_HANDLER)
+#error "STM32_QUADSPI1_HANDLER not defined"
+#endif
+/**
+ * @brief STM32_QUADSPI1_HANDLER interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_QUADSPI1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ QUADSPI->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF |
+ QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF;
+
+ wspi_lld_serve_interrupt(&WSPID1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_QUADSPI1_SUPPRESS_ISR) */
+#endif /* STM32_WSPI_USE_QUADSPI1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level WSPI driver initialization.
+ *
+ * @notapi
+ */
+void wspi_lld_init(void) {
+
+#if STM32_WSPI_USE_QUADSPI1
+ wspiObjectInit(&WSPID1);
+ WSPID1.qspi = QUADSPI;
+ WSPID1.dma = NULL;
+ WSPID1.dmamode = STM32_DMA_CR_CHSEL(QUADSPI1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_WSPI_QUADSPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_BYTE |
+ STM32_DMA_CR_MSIZE_BYTE |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ nvicEnableVector(STM32_QUADSPI1_NUMBER, STM32_WSPI_QUADSPI1_IRQ_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Configures and activates the WSPI peripheral.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_start(WSPIDriver *wspip) {
+
+ /* If in stopped state then full initialization.*/
+ if (wspip->state == WSPI_STOP) {
+#if STM32_WSPI_USE_QUADSPI1
+ if (&WSPID1 == wspip) {
+ wspip->dma = dmaStreamAllocI(STM32_WSPI_QUADSPI1_DMA_STREAM,
+ STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)wspi_lld_serve_dma_interrupt,
+ (void *)wspip);
+ osalDbgAssert(wspip->dma != NULL, "unable to allocate stream");
+ rccEnableQUADSPI1(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(wspip->dma, STM32_DMAMUX1_QUADSPI);
+#endif
+ }
+#endif
+
+ /* Common initializations.*/
+ dmaStreamSetPeripheral(wspip->dma, &wspip->qspi->DR);
+ }
+
+ /* WSPI setup and enable.*/
+ wspip->qspi->DCR = wspip->config->dcr;
+ wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) |
+ QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_EN;
+ wspip->qspi->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF |
+ QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF;
+}
+
+/**
+ * @brief Deactivates the WSPI peripheral.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_stop(WSPIDriver *wspip) {
+
+ /* If in ready state then disables the QUADSPI clock.*/
+ if (wspip->state == WSPI_READY) {
+
+ /* WSPI disable.*/
+ wspip->qspi->CR = 0U;
+
+ /* Releasing the DMA.*/
+ dmaStreamFreeI(wspip->dma);
+ wspip->dma = NULL;
+
+ /* Stopping involved clocks.*/
+#if STM32_WSPI_USE_QUADSPI1
+ if (&WSPID1 == wspip) {
+ rccDisableQUADSPI1();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Sends a command without data phase.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ *
+ * @notapi
+ */
+void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) {
+
+#if STM32_USE_STM32_D1_WORKAROUND == TRUE
+ /* If it is a command without address and alternate phases then the command
+ is sent as an alternate byte, the command phase is suppressed.*/
+ if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) {
+ /* The command mode field is copied in the alternate mode field. All
+ other fields are not used in this scenario.*/
+ wspip->qspi->DLR = 0U;
+ wspip->qspi->ABR = cmdp->cmd;
+ wspip->qspi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U;
+ return;
+ }
+#endif
+ wspip->qspi->DLR = 0U;
+ wspip->qspi->ABR = cmdp->alt;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->qspi->AR = cmdp->addr;
+ }
+
+ /* Waiting for the previous operation to complete.*/
+ wspi_lld_sync(wspip);
+}
+
+/**
+ * @brief Sends a command with data over the WSPI bus.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[in] n number of bytes to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, const uint8_t *txbuf) {
+
+ dmaStreamSetMemory0(wspip->dma, txbuf);
+ dmaStreamSetTransactionSize(wspip->dma, n);
+ dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_M2P);
+
+ wspip->qspi->DLR = n - 1;
+ wspip->qspi->ABR = cmdp->alt;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->qspi->AR = cmdp->addr;
+ }
+
+ dmaStreamEnable(wspip->dma);
+}
+
+/**
+ * @brief Sends a command then receives data over the WSPI bus.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[in] n number of bytes to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, uint8_t *rxbuf) {
+
+ dmaStreamSetMemory0(wspip->dma, rxbuf);
+ dmaStreamSetTransactionSize(wspip->dma, n);
+ dmaStreamSetMode(wspip->dma, wspip->dmamode | STM32_DMA_CR_DIR_P2M);
+
+ wspip->qspi->DLR = n - 1;
+ wspip->qspi->ABR = cmdp->alt;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
+ QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
+ QUADSPI_CCR_FMODE_0;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->qspi->AR = cmdp->addr;
+ }
+
+ dmaStreamEnable(wspip->dma);
+}
+
+#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Maps in memory space a WSPI flash device.
+ * @pre The memory flash device must be initialized appropriately
+ * before mapping it in memory space.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[out] addrp pointer to the memory start address of the mapped
+ * flash or @p NULL
+ *
+ * @notapi
+ */
+void wspi_lld_map_flash(WSPIDriver *wspip,
+ const wspi_command_t *cmdp,
+ uint8_t **addrp) {
+
+ /* Disabling the DMA request while in memory mapped mode.*/
+ wspip->qspi->CR &= ~QUADSPI_CR_DMAEN;
+
+ /* Starting memory mapped mode using the passed parameters.*/
+ wspip->qspi->DLR = 0;
+ wspip->qspi->ABR = 0;
+ wspip->qspi->AR = 0;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
+ QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
+ QUADSPI_CCR_FMODE_1 | QUADSPI_CCR_FMODE_0;
+
+ /* Mapped flash absolute base address.*/
+ if (addrp != NULL) {
+ *addrp = (uint8_t *)0x90000000;
+ }
+}
+
+/**
+ * @brief Unmaps from memory space a WSPI flash device.
+ * @post The memory flash device must be re-initialized for normal
+ * commands exchange.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_unmap_flash(WSPIDriver *wspip) {
+
+ /* Aborting memory mapped mode.*/
+ wspip->qspi->CR |= QUADSPI_CR_ABORT;
+ while ((wspip->qspi->CR & QUADSPI_CR_ABORT) != 0U) {
+ }
+
+ /* Re-enabling DMA request, we are going back to indirect mode.*/
+ wspip->qspi->CR |= QUADSPI_CR_DMAEN;
+}
+#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
+
+#endif /* HAL_USE_WSPI */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h
index f415dae49e..b7db86c474 100644
--- a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h
+++ b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_wspi_lld.h
@@ -1,313 +1,313 @@
-/*
- 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 QUADSPIv1/hal_wspi_lld.h
- * @brief STM32 WSPI subsystem low level driver header.
- *
- * @addtogroup WSPI
- * @{
- */
-
-#ifndef HAL_WSPI_LLD_H
-#define HAL_WSPI_LLD_H
-
-#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name WSPI implementation capabilities
- * @{
- */
-#define WSPI_SUPPORTS_MEMMAP TRUE
-#define WSPI_DEFAULT_CFG_MASKS FALSE
-/** @} */
-
-/**
- * @name Transfer options
- * @note The low level driver has the option to override the following
- * definitions and use its own ones. In must take care to use
- * the same name for the same function or compatibility is not
- * ensured.
- * @note There are the following limitations in this implementation:
- * - Eight lines are not supported.
- * - DDR mode is only supported for the whole command, separate
- * masks are defined but all define the same bit.
- * - Only 8 bits instructions are supported.
- * .
- * @{
- */
-#define WSPI_CFG_CMD_MODE_MASK (3LU << 8LU)
-#define WSPI_CFG_CMD_MODE_NONE (0LU << 8LU)
-#define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 8LU)
-#define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 8LU)
-#define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 8LU)
-
-#define WSPI_CFG_CMD_DDR (1LU << 31LU)
-
-#define WSPI_CFG_CMD_SIZE_MASK 0LU
-#define WSPI_CFG_CMD_SIZE_8 0LU
-
-#define WSPI_CFG_ADDR_MODE_MASK (3LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_NONE (0LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU)
-
-#define WSPI_CFG_ADDR_DDR (1LU << 31LU)
-
-#define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU)
-
-#define WSPI_CFG_ALT_MODE_MASK (3LU << 14LU)
-#define WSPI_CFG_ALT_MODE_NONE (0LU << 14LU)
-#define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU)
-#define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU)
-#define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU)
-
-#define WSPI_CFG_ALT_DDR (1LU << 31LU)
-
-#define WSPI_CFG_ALT_SIZE_MASK (3LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_8 (0LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_16 (1LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_24 (2LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_32 (3LU << 16LU)
-
-#define WSPI_CFG_DATA_MODE_MASK (3LU << 24LU)
-#define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU)
-#define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU)
-#define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU)
-#define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU)
-
-#define WSPI_CFG_DATA_DDR (1LU << 31LU)
-
-#define WSPI_CFG_SIOO (1LU << 28LU)
-/** @} */
-
-/**
- * @name Helpers for CCR register.
- * @{
- */
-#define QUADSPI_CCR_DUMMY_CYCLES_MASK (0x1FLU << 18LU)
-#define QUADSPI_CCR_DUMMY_CYCLES(n) ((n) << 18LU)
-/** @} */
-
-/**
- * @name DCR register options
- * @{
- */
-#define STM32_DCR_CK_MODE (1U << 0U)
-#define STM32_DCR_CSHT_MASK (7U << 8U)
-#define STM32_DCR_CSHT(n) ((n) << 8U)
-#define STM32_DCR_FSIZE_MASK (31U << 16U)
-#define STM32_DCR_FSIZE(n) ((n) << 16U)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief WSPID1 driver enable switch.
- * @details If set to @p TRUE the support for QUADSPI1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_WSPI_USE_QUADSPI1) || defined(__DOXYGEN__)
-#define STM32_WSPI_USE_QUADSPI1 FALSE
-#endif
-
-/**
- * @brief QUADSPI1 prescaler setting.
- * @note This is the prescaler divider value 1..256. The maximum frequency
- * varies depending on the STM32 model and operating conditions,
- * find the details in the data sheet.
- */
-#if !defined(STM32_WSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
-#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1
-#endif
-
-/**
- * @brief QUADSPI1 interrupt priority level setting.
- */
-#if !defined(STM32_WSPI_QUADSPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_QUADSPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief QUADSPI1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_WSPI_QUADSPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_QUADSPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief QUADSPI1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief QUADSPI DMA error hook.
- */
-#if !defined(STM32_WSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_WSPI_DMA_ERROR_HOOK(wspip) osalSysHalt("DMA failure")
-#endif
-
-/**
- * @brief Enables a workaround for a STM32L476 QUADSPI errata.
- * @details The document DM00111498 states: "QUADSPI_BK1_IO1 is always an
- * input when the command is sent in dual or quad SPI mode".
- * This workaround makes commands without address or data phases
- * to be sent as alternate bytes.
- */
-#if !defined(STM32_USE_STM32_D1_WORKAROUND) || defined(__DOXYGEN__)
-#define STM32_USE_STM32_D1_WORKAROUND TRUE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_QUADSPI1)
-#define STM32_HAS_QUADSPI1 FALSE
-#endif
-
-#if STM32_WSPI_USE_QUADSPI1 && !STM32_HAS_QUADSPI1
-#error "QUADSPI1 not present in the selected device"
-#endif
-
-#if !STM32_WSPI_USE_QUADSPI1
-#error "WSPI driver activated but no QUADSPI peripheral assigned"
-#endif
-
-#if STM32_WSPI_USE_QUADSPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to QUADSPI1"
-#endif
-
-#if STM32_WSPI_USE_QUADSPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to QUADSPI1 DMA"
-#endif
-
-#if STM32_WSPI_USE_QUADSPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to QUADSPI1"
-#endif
-
-#if (STM32_WSPI_QUADSPI1_PRESCALER_VALUE < 1) || \
- (STM32_WSPI_QUADSPI1_PRESCALER_VALUE > 256)
-#error "STM32_WSPI_QUADSPI1_PRESCALER_VALUE not within 1..256"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_WSPI_USE_QUADSPI1 && !defined(STM32_WSPI_QUADSPI1_DMA_STREAM)
-#error "QUADSPI1 DMA stream not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_WSPI_USE_QUADSPI1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_WSPI_QUADSPI1_DMA_STREAM)
-#error "invalid DMA stream associated to QUADSPI1"
-#endif
-
-/* Devices without DMAMUX require an additional check.*/
-#if !STM32_DMA_SUPPORTS_DMAMUX
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_WSPI_USE_QUADSPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_WSPI_QUADSPI1_DMA_STREAM, STM32_QUADSPI1_DMA_MSK)
-#error "invalid DMA stream associated to QUADSPI1"
-#endif
-
-#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the WSPI configuration structure.
- */
-#define wspi_lld_config_fields \
- /* DCR register initialization data.*/ \
- uint32_t dcr
-
-/**
- * @brief Low level fields of the WSPI driver structure.
- */
-#define wspi_lld_driver_fields \
- /* Pointer to the QUADSPIx registers block.*/ \
- QUADSPI_TypeDef *qspi; \
- /* QUADSPI DMA stream.*/ \
- const stm32_dma_stream_t *dma; \
- /* QUADSPI DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if (STM32_WSPI_USE_QUADSPI1 == TRUE) && !defined(__DOXYGEN__)
-extern WSPIDriver WSPID1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void wspi_lld_init(void);
- void wspi_lld_start(WSPIDriver *wspip);
- void wspi_lld_stop(WSPIDriver *wspip);
- void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp);
- void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, const uint8_t *txbuf);
- void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, uint8_t *rxbuf);
-#if WSPI_SUPPORTS_MEMMAP == TRUE
- void wspi_lld_map_flash(WSPIDriver *wspip,
- const wspi_command_t *cmdp,
- uint8_t **addrp);
- void wspi_lld_unmap_flash(WSPIDriver *wspip);
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_WSPI */
-
-#endif /* HAL_WSPI_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 QUADSPIv1/hal_wspi_lld.h
+ * @brief STM32 WSPI subsystem low level driver header.
+ *
+ * @addtogroup WSPI
+ * @{
+ */
+
+#ifndef HAL_WSPI_LLD_H
+#define HAL_WSPI_LLD_H
+
+#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name WSPI implementation capabilities
+ * @{
+ */
+#define WSPI_SUPPORTS_MEMMAP TRUE
+#define WSPI_DEFAULT_CFG_MASKS FALSE
+/** @} */
+
+/**
+ * @name Transfer options
+ * @note The low level driver has the option to override the following
+ * definitions and use its own ones. In must take care to use
+ * the same name for the same function or compatibility is not
+ * ensured.
+ * @note There are the following limitations in this implementation:
+ * - Eight lines are not supported.
+ * - DDR mode is only supported for the whole command, separate
+ * masks are defined but all define the same bit.
+ * - Only 8 bits instructions are supported.
+ * .
+ * @{
+ */
+#define WSPI_CFG_CMD_MODE_MASK (3LU << 8LU)
+#define WSPI_CFG_CMD_MODE_NONE (0LU << 8LU)
+#define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 8LU)
+#define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 8LU)
+#define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 8LU)
+
+#define WSPI_CFG_CMD_DDR (1LU << 31LU)
+
+#define WSPI_CFG_CMD_SIZE_MASK 0LU
+#define WSPI_CFG_CMD_SIZE_8 0LU
+
+#define WSPI_CFG_ADDR_MODE_MASK (3LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_NONE (0LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU)
+
+#define WSPI_CFG_ADDR_DDR (1LU << 31LU)
+
+#define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU)
+
+#define WSPI_CFG_ALT_MODE_MASK (3LU << 14LU)
+#define WSPI_CFG_ALT_MODE_NONE (0LU << 14LU)
+#define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU)
+#define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU)
+#define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU)
+
+#define WSPI_CFG_ALT_DDR (1LU << 31LU)
+
+#define WSPI_CFG_ALT_SIZE_MASK (3LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_8 (0LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_16 (1LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_24 (2LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_32 (3LU << 16LU)
+
+#define WSPI_CFG_DATA_MODE_MASK (3LU << 24LU)
+#define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU)
+#define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU)
+#define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU)
+#define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU)
+
+#define WSPI_CFG_DATA_DDR (1LU << 31LU)
+
+#define WSPI_CFG_SIOO (1LU << 28LU)
+/** @} */
+
+/**
+ * @name Helpers for CCR register.
+ * @{
+ */
+#define QUADSPI_CCR_DUMMY_CYCLES_MASK (0x1FLU << 18LU)
+#define QUADSPI_CCR_DUMMY_CYCLES(n) ((n) << 18LU)
+/** @} */
+
+/**
+ * @name DCR register options
+ * @{
+ */
+#define STM32_DCR_CK_MODE (1U << 0U)
+#define STM32_DCR_CSHT_MASK (7U << 8U)
+#define STM32_DCR_CSHT(n) ((n) << 8U)
+#define STM32_DCR_FSIZE_MASK (31U << 16U)
+#define STM32_DCR_FSIZE(n) ((n) << 16U)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief WSPID1 driver enable switch.
+ * @details If set to @p TRUE the support for QUADSPI1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_WSPI_USE_QUADSPI1) || defined(__DOXYGEN__)
+#define STM32_WSPI_USE_QUADSPI1 FALSE
+#endif
+
+/**
+ * @brief QUADSPI1 prescaler setting.
+ * @note This is the prescaler divider value 1..256. The maximum frequency
+ * varies depending on the STM32 model and operating conditions,
+ * find the details in the data sheet.
+ */
+#if !defined(STM32_WSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
+#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1
+#endif
+
+/**
+ * @brief QUADSPI1 interrupt priority level setting.
+ */
+#if !defined(STM32_WSPI_QUADSPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_QUADSPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief QUADSPI1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_WSPI_QUADSPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_QUADSPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief QUADSPI1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief QUADSPI DMA error hook.
+ */
+#if !defined(STM32_WSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_WSPI_DMA_ERROR_HOOK(wspip) osalSysHalt("DMA failure")
+#endif
+
+/**
+ * @brief Enables a workaround for a STM32L476 QUADSPI errata.
+ * @details The document DM00111498 states: "QUADSPI_BK1_IO1 is always an
+ * input when the command is sent in dual or quad SPI mode".
+ * This workaround makes commands without address or data phases
+ * to be sent as alternate bytes.
+ */
+#if !defined(STM32_USE_STM32_D1_WORKAROUND) || defined(__DOXYGEN__)
+#define STM32_USE_STM32_D1_WORKAROUND TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_QUADSPI1)
+#define STM32_HAS_QUADSPI1 FALSE
+#endif
+
+#if STM32_WSPI_USE_QUADSPI1 && !STM32_HAS_QUADSPI1
+#error "QUADSPI1 not present in the selected device"
+#endif
+
+#if !STM32_WSPI_USE_QUADSPI1
+#error "WSPI driver activated but no QUADSPI peripheral assigned"
+#endif
+
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to QUADSPI1"
+#endif
+
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to QUADSPI1 DMA"
+#endif
+
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to QUADSPI1"
+#endif
+
+#if (STM32_WSPI_QUADSPI1_PRESCALER_VALUE < 1) || \
+ (STM32_WSPI_QUADSPI1_PRESCALER_VALUE > 256)
+#error "STM32_WSPI_QUADSPI1_PRESCALER_VALUE not within 1..256"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_WSPI_USE_QUADSPI1 && !defined(STM32_WSPI_QUADSPI1_DMA_STREAM)
+#error "QUADSPI1 DMA stream not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_WSPI_QUADSPI1_DMA_STREAM)
+#error "invalid DMA stream associated to QUADSPI1"
+#endif
+
+/* Devices without DMAMUX require an additional check.*/
+#if !STM32_DMA_SUPPORTS_DMAMUX
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_WSPI_QUADSPI1_DMA_STREAM, STM32_QUADSPI1_DMA_MSK)
+#error "invalid DMA stream associated to QUADSPI1"
+#endif
+
+#endif /* !STM32_DMA_SUPPORTS_DMAMUX */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the WSPI configuration structure.
+ */
+#define wspi_lld_config_fields \
+ /* DCR register initialization data.*/ \
+ uint32_t dcr
+
+/**
+ * @brief Low level fields of the WSPI driver structure.
+ */
+#define wspi_lld_driver_fields \
+ /* Pointer to the QUADSPIx registers block.*/ \
+ QUADSPI_TypeDef *qspi; \
+ /* QUADSPI DMA stream.*/ \
+ const stm32_dma_stream_t *dma; \
+ /* QUADSPI DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if (STM32_WSPI_USE_QUADSPI1 == TRUE) && !defined(__DOXYGEN__)
+extern WSPIDriver WSPID1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void wspi_lld_init(void);
+ void wspi_lld_start(WSPIDriver *wspip);
+ void wspi_lld_stop(WSPIDriver *wspip);
+ void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp);
+ void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, const uint8_t *txbuf);
+ void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, uint8_t *rxbuf);
+#if WSPI_SUPPORTS_MEMMAP == TRUE
+ void wspi_lld_map_flash(WSPIDriver *wspip,
+ const wspi_command_t *cmdp,
+ uint8_t **addrp);
+ void wspi_lld_unmap_flash(WSPIDriver *wspip);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_WSPI */
+
+#endif /* HAL_WSPI_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/QUADSPIv2/driver.mk b/os/hal/ports/STM32/LLD/QUADSPIv2/driver.mk
index 0a9e0992c5..91ea2d3eb2 100644
--- a/os/hal/ports/STM32/LLD/QUADSPIv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/QUADSPIv2/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_WSPI TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2
diff --git a/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c b/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
index 7f9cb1aea0..a7e9a330bd 100644
--- a/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
+++ b/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.c
@@ -1,382 +1,382 @@
-/*
- 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 QUADSPIv2/hal_wspi_lld.c
- * @brief STM32 WSPI subsystem low level driver source.
- *
- * @addtogroup WSPI
- * @{
- */
-
-#include "hal.h"
-
-#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* @brief MDMA HW request is QSPI FIFO threshold Flag */
-#define MDMA_REQUEST_QUADSPI_FIFO_TH ((uint32_t)0x00000016U)
-
-/* @brief MDMA HW request is QSPI Transfer complete Flag */
-#define MDMA_REQUEST_QUADSPI_TC ((uint32_t)0x00000017U)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief QUADSPI1 driver identifier.*/
-#if STM32_WSPI_USE_QUADSPI1 || defined(__DOXYGEN__)
-WSPIDriver WSPID1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Waits for completion of previous operation.
- */
-static inline void wspi_lld_sync(WSPIDriver *wspip) {
-
- while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
- }
-}
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] flags content of the CISR register
- */
-static void wspi_lld_serve_mdma_interrupt(WSPIDriver *wspip, uint32_t flags) {
-
- (void)wspip;
- (void)flags;
-
- if (((flags & STM32_MDMA_CISR_CTCIF) != 0U) &&
- (wspip->state == WSPI_RECEIVE)) {
- /* Portable WSPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _wspi_isr_code(wspip);
-
- mdmaChannelDisableX(wspip->mdma);
- }
- /* DMA errors handling.*/
-#if defined(STM32_WSPI_MDMA_ERROR_HOOK)
- else if ((flags & STM32_MDMA_CISR_TEIF) != 0) {
- STM32_WSPI_MDMA_ERROR_HOOK(wspip);
- }
-#endif
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level WSPI driver initialization.
- *
- * @notapi
- */
-void wspi_lld_init(void) {
-
-#if STM32_WSPI_USE_QUADSPI1
- wspiObjectInit(&WSPID1);
- WSPID1.qspi = QUADSPI;
- WSPID1.mdma = NULL;
-#endif
-}
-
-/**
- * @brief Configures and activates the WSPI peripheral.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_start(WSPIDriver *wspip) {
-
- /* If in stopped state then full initialization.*/
- if (wspip->state == WSPI_STOP) {
-#if STM32_WSPI_USE_QUADSPI1
- if (&WSPID1 == wspip) {
- wspip->mdma = mdmaChannelAllocI(STM32_WSPI_QUADSPI1_MDMA_CHANNEL,
- (stm32_mdmaisr_t)wspi_lld_serve_mdma_interrupt,
- (void *)wspip);
- osalDbgAssert(wspip->mdma != NULL, "unable to allocate MDMA channel");
- rccEnableQUADSPI1(true);
- }
-#endif
- }
-
- /* WSPI setup and enable.*/
- wspip->qspi->DCR = wspip->config->dcr;
-#if STM32_WSPI_SET_CR_SSHIFT
- wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) |
- QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_SSHIFT |
- QUADSPI_CR_EN;
-#else
- wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) |
- QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_EN;
-#endif
- wspip->qspi->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF |
- QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF;
-}
-
-/**
- * @brief Deactivates the WSPI peripheral.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_stop(WSPIDriver *wspip) {
-
- /* If in ready state then disables the QUADSPI clock.*/
- if (wspip->state == WSPI_READY) {
-
- /* WSPI disable.*/
- wspip->qspi->CR = 0U;
-
- /* Releasing the DMA.*/
- mdmaChannelFreeI(wspip->mdma);
- wspip->mdma = NULL;
-
- /* Stopping involved clocks.*/
-#if STM32_WSPI_USE_QUADSPI1
- if (&WSPID1 == wspip) {
- rccDisableQUADSPI1();
- }
-#endif
- }
-}
-
-/**
- * @brief Sends a command without data phase.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- *
- * @notapi
- */
-void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) {
-
-#if STM32_USE_STM32_D1_WORKAROUND == TRUE
- /* If it is a command without address and alternate phases then the command
- is sent as an alternate byte, the command phase is suppressed.*/
- if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) {
- /* The command mode field is copied in the alternate mode field. All
- other fields are not used in this scenario.*/
- wspip->qspi->DLR = 0U;
- wspip->qspi->ABR = cmdp->cmd;
- wspip->qspi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U;
- return;
- }
-#endif
- wspip->qspi->DLR = 0U;
- wspip->qspi->ABR = cmdp->alt;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->qspi->AR = cmdp->addr;
- }
-
- /* Waiting for the previous operation to complete.*/
- wspi_lld_sync(wspip);
-}
-
-/**
- * @brief Sends a command with data over the WSPI bus.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[in] n number of bytes to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, const uint8_t *txbuf) {
- uint32_t ctcr = STM32_MDMA_CTCR_BWM_NON_BUFF | /* Dest. non-cacheable. */
- STM32_MDMA_CTCR_TRGM_BUFFER | /* Trigger on buffer. */
- STM32_MDMA_CTCR_TLEN(0U) | /* One byte buffer. */
- STM32_MDMA_CTCR_DBURST_1 | /* Assuming AXI bus. */
- STM32_MDMA_CTCR_SBURST_1 | /* Assuming AXI bus. */
- STM32_MDMA_CTCR_DINCOS_BYTE | /* Byte increment. */
- STM32_MDMA_CTCR_SINCOS_BYTE | /* Byte increment. */
- STM32_MDMA_CTCR_DSIZE_BYTE | /* Destination size. */
- STM32_MDMA_CTCR_SSIZE_BYTE | /* Source size. */
- STM32_MDMA_CTCR_DINC_FIXED | /* Destination fixed. */
- STM32_MDMA_CTCR_SINC_INC; /* Source incremented. */
- uint32_t ccr = STM32_MDMA_CCR_PL(STM32_WSPI_QUADSPI1_MDMA_PRIORITY) |
- STM32_MDMA_CCR_TEIE; /* On transfer error. */
-
- /* MDMA initializations.*/
- mdmaChannelSetSourceX(wspip->mdma, txbuf);
- mdmaChannelSetDestinationX(wspip->mdma, &wspip->qspi->DR);
- mdmaChannelSetTransactionSizeX(wspip->mdma, n, 0, 0);
- mdmaChannelSetModeX(wspip->mdma, ctcr, ccr);
- mdmaChannelSetTrigModeX(wspip->mdma, MDMA_REQUEST_QUADSPI_FIFO_TH);
-
- wspip->qspi->DLR = n - 1;
- wspip->qspi->ABR = cmdp->alt;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->qspi->AR = cmdp->addr;
- }
-
- mdmaChannelEnableX(wspip->mdma);
-}
-
-/**
- * @brief Sends a command then receives data over the WSPI bus.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[in] n number of bytes to send
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, uint8_t *rxbuf) {
- uint32_t ctcr = STM32_MDMA_CTCR_BWM_NON_BUFF | /* Dest. non-cacheable. */
- STM32_MDMA_CTCR_TRGM_BUFFER | /* Trigger on buffer. */
- STM32_MDMA_CTCR_TLEN(0) | /* One byte buffer. */
- STM32_MDMA_CTCR_DBURST_1 | /* Assuming AXI bus. */
- STM32_MDMA_CTCR_SBURST_1 | /* Assuming AXI bus. */
- STM32_MDMA_CTCR_DINCOS_BYTE | /* Byte increment. */
- STM32_MDMA_CTCR_SINCOS_BYTE | /* Byte increment. */
- STM32_MDMA_CTCR_DSIZE_BYTE | /* Destination size. */
- STM32_MDMA_CTCR_SSIZE_BYTE | /* Source size. */
- STM32_MDMA_CTCR_DINC_INC | /* Destination incr. */
- STM32_MDMA_CTCR_SINC_FIXED; /* Source fixed. */
- uint32_t ccr = STM32_MDMA_CCR_PL(STM32_WSPI_QUADSPI1_MDMA_PRIORITY) |
- STM32_MDMA_CCR_CTCIE | /* On transfer complete.*/
- STM32_MDMA_CCR_TEIE; /* On transfer error. */
-
- /* MDMA initializations.*/
- mdmaChannelSetSourceX(wspip->mdma, &wspip->qspi->DR);
- mdmaChannelSetDestinationX(wspip->mdma, rxbuf);
- mdmaChannelSetTransactionSizeX(wspip->mdma, n, 0, 0);
- mdmaChannelSetModeX(wspip->mdma, ctcr, ccr);
- mdmaChannelSetTrigModeX(wspip->mdma, MDMA_REQUEST_QUADSPI_FIFO_TH);
-
- wspip->qspi->DLR = n - 1;
- wspip->qspi->ABR = cmdp->alt;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
- QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
- QUADSPI_CCR_FMODE_0;
- if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
- wspip->qspi->AR = cmdp->addr;
- }
-
- mdmaChannelEnableX(wspip->mdma);
-}
-
-#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Maps in memory space a WSPI flash device.
- * @pre The memory flash device must be initialized appropriately
- * before mapping it in memory space.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- * @param[in] cmdp pointer to the command descriptor
- * @param[out] addrp pointer to the memory start address of the mapped
- * flash or @p NULL
- *
- * @notapi
- */
-void wspi_lld_map_flash(WSPIDriver *wspip,
- const wspi_command_t *cmdp,
- uint8_t **addrp) {
-
- /* Disabling the DMA request while in memory mapped mode.*/
- wspip->qspi->CR &= ~QUADSPI_CR_DMAEN;
-
- /* Starting memory mapped mode using the passed parameters.*/
- wspip->qspi->DLR = 0;
- wspip->qspi->ABR = 0;
- wspip->qspi->AR = 0;
- wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
- QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
- QUADSPI_CCR_FMODE_1 | QUADSPI_CCR_FMODE_0;
-
- /* Mapped flash absolute base address.*/
- if (addrp != NULL) {
- *addrp = (uint8_t *)0x90000000;
- }
-}
-
-/**
- * @brief Unmaps from memory space a WSPI flash device.
- * @post The memory flash device must be re-initialized for normal
- * commands exchange.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- *
- * @notapi
- */
-void wspi_lld_unmap_flash(WSPIDriver *wspip) {
-
- /* Aborting memory mapped mode.*/
- wspip->qspi->CR |= QUADSPI_CR_ABORT;
- while ((wspip->qspi->CR & QUADSPI_CR_ABORT) != 0U) {
- }
-
- /* Re-enabling DMA request, we are going back to indirect mode.*/
- wspip->qspi->CR |= QUADSPI_CR_DMAEN;
-}
-#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] wspip pointer to the @p WSPIDriver object
- */
-void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
- uint32_t sr;
-
- sr = wspip->qspi->SR;
- wspip->qspi->FCR = sr;
-
- if (((sr & QUADSPI_FCR_CTCF) != 0U) && (wspip->state == WSPI_SEND)) {
- /* Portable WSPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _wspi_isr_code(wspip);
-
- mdmaChannelDisableX(wspip->mdma);
- }
-
- /* TODO errors handling.*/
-}
-
-#endif /* HAL_USE_WSPI */
-
-/** @} */
+/*
+ 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 QUADSPIv2/hal_wspi_lld.c
+ * @brief STM32 WSPI subsystem low level driver source.
+ *
+ * @addtogroup WSPI
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* @brief MDMA HW request is QSPI FIFO threshold Flag */
+#define MDMA_REQUEST_QUADSPI_FIFO_TH ((uint32_t)0x00000016U)
+
+/* @brief MDMA HW request is QSPI Transfer complete Flag */
+#define MDMA_REQUEST_QUADSPI_TC ((uint32_t)0x00000017U)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief QUADSPI1 driver identifier.*/
+#if STM32_WSPI_USE_QUADSPI1 || defined(__DOXYGEN__)
+WSPIDriver WSPID1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Waits for completion of previous operation.
+ */
+static inline void wspi_lld_sync(WSPIDriver *wspip) {
+
+ while ((wspip->qspi->SR & QUADSPI_SR_BUSY) != 0U) {
+ }
+}
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] flags content of the CISR register
+ */
+static void wspi_lld_serve_mdma_interrupt(WSPIDriver *wspip, uint32_t flags) {
+
+ (void)wspip;
+ (void)flags;
+
+ if (((flags & STM32_MDMA_CISR_CTCIF) != 0U) &&
+ (wspip->state == WSPI_RECEIVE)) {
+ /* Portable WSPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _wspi_isr_code(wspip);
+
+ mdmaChannelDisableX(wspip->mdma);
+ }
+ /* DMA errors handling.*/
+#if defined(STM32_WSPI_MDMA_ERROR_HOOK)
+ else if ((flags & STM32_MDMA_CISR_TEIF) != 0) {
+ STM32_WSPI_MDMA_ERROR_HOOK(wspip);
+ }
+#endif
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level WSPI driver initialization.
+ *
+ * @notapi
+ */
+void wspi_lld_init(void) {
+
+#if STM32_WSPI_USE_QUADSPI1
+ wspiObjectInit(&WSPID1);
+ WSPID1.qspi = QUADSPI;
+ WSPID1.mdma = NULL;
+#endif
+}
+
+/**
+ * @brief Configures and activates the WSPI peripheral.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_start(WSPIDriver *wspip) {
+
+ /* If in stopped state then full initialization.*/
+ if (wspip->state == WSPI_STOP) {
+#if STM32_WSPI_USE_QUADSPI1
+ if (&WSPID1 == wspip) {
+ wspip->mdma = mdmaChannelAllocI(STM32_WSPI_QUADSPI1_MDMA_CHANNEL,
+ (stm32_mdmaisr_t)wspi_lld_serve_mdma_interrupt,
+ (void *)wspip);
+ osalDbgAssert(wspip->mdma != NULL, "unable to allocate MDMA channel");
+ rccEnableQUADSPI1(true);
+ }
+#endif
+ }
+
+ /* WSPI setup and enable.*/
+ wspip->qspi->DCR = wspip->config->dcr;
+#if STM32_WSPI_SET_CR_SSHIFT
+ wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) |
+ QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_SSHIFT |
+ QUADSPI_CR_EN;
+#else
+ wspip->qspi->CR = ((STM32_WSPI_QUADSPI1_PRESCALER_VALUE - 1U) << 24U) |
+ QUADSPI_CR_TCIE | QUADSPI_CR_DMAEN | QUADSPI_CR_EN;
+#endif
+ wspip->qspi->FCR = QUADSPI_FCR_CTEF | QUADSPI_FCR_CTCF |
+ QUADSPI_FCR_CSMF | QUADSPI_FCR_CTOF;
+}
+
+/**
+ * @brief Deactivates the WSPI peripheral.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_stop(WSPIDriver *wspip) {
+
+ /* If in ready state then disables the QUADSPI clock.*/
+ if (wspip->state == WSPI_READY) {
+
+ /* WSPI disable.*/
+ wspip->qspi->CR = 0U;
+
+ /* Releasing the DMA.*/
+ mdmaChannelFreeI(wspip->mdma);
+ wspip->mdma = NULL;
+
+ /* Stopping involved clocks.*/
+#if STM32_WSPI_USE_QUADSPI1
+ if (&WSPID1 == wspip) {
+ rccDisableQUADSPI1();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Sends a command without data phase.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ *
+ * @notapi
+ */
+void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp) {
+
+#if STM32_USE_STM32_D1_WORKAROUND == TRUE
+ /* If it is a command without address and alternate phases then the command
+ is sent as an alternate byte, the command phase is suppressed.*/
+ if ((cmdp->cfg & (WSPI_CFG_ADDR_MODE_MASK | WSPI_CFG_ALT_MODE_MASK)) == 0U) {
+ /* The command mode field is copied in the alternate mode field. All
+ other fields are not used in this scenario.*/
+ wspip->qspi->DLR = 0U;
+ wspip->qspi->ABR = cmdp->cmd;
+ wspip->qspi->CCR = (cmdp->cfg & WSPI_CFG_CMD_MODE_MASK) << 6U;
+ return;
+ }
+#endif
+ wspip->qspi->DLR = 0U;
+ wspip->qspi->ABR = cmdp->alt;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->qspi->AR = cmdp->addr;
+ }
+
+ /* Waiting for the previous operation to complete.*/
+ wspi_lld_sync(wspip);
+}
+
+/**
+ * @brief Sends a command with data over the WSPI bus.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[in] n number of bytes to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, const uint8_t *txbuf) {
+ uint32_t ctcr = STM32_MDMA_CTCR_BWM_NON_BUFF | /* Dest. non-cacheable. */
+ STM32_MDMA_CTCR_TRGM_BUFFER | /* Trigger on buffer. */
+ STM32_MDMA_CTCR_TLEN(0U) | /* One byte buffer. */
+ STM32_MDMA_CTCR_DBURST_1 | /* Assuming AXI bus. */
+ STM32_MDMA_CTCR_SBURST_1 | /* Assuming AXI bus. */
+ STM32_MDMA_CTCR_DINCOS_BYTE | /* Byte increment. */
+ STM32_MDMA_CTCR_SINCOS_BYTE | /* Byte increment. */
+ STM32_MDMA_CTCR_DSIZE_BYTE | /* Destination size. */
+ STM32_MDMA_CTCR_SSIZE_BYTE | /* Source size. */
+ STM32_MDMA_CTCR_DINC_FIXED | /* Destination fixed. */
+ STM32_MDMA_CTCR_SINC_INC; /* Source incremented. */
+ uint32_t ccr = STM32_MDMA_CCR_PL(STM32_WSPI_QUADSPI1_MDMA_PRIORITY) |
+ STM32_MDMA_CCR_TEIE; /* On transfer error. */
+
+ /* MDMA initializations.*/
+ mdmaChannelSetSourceX(wspip->mdma, txbuf);
+ mdmaChannelSetDestinationX(wspip->mdma, &wspip->qspi->DR);
+ mdmaChannelSetTransactionSizeX(wspip->mdma, n, 0, 0);
+ mdmaChannelSetModeX(wspip->mdma, ctcr, ccr);
+ mdmaChannelSetTrigModeX(wspip->mdma, MDMA_REQUEST_QUADSPI_FIFO_TH);
+
+ wspip->qspi->DLR = n - 1;
+ wspip->qspi->ABR = cmdp->alt;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->qspi->AR = cmdp->addr;
+ }
+
+ mdmaChannelEnableX(wspip->mdma);
+}
+
+/**
+ * @brief Sends a command then receives data over the WSPI bus.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[in] n number of bytes to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, uint8_t *rxbuf) {
+ uint32_t ctcr = STM32_MDMA_CTCR_BWM_NON_BUFF | /* Dest. non-cacheable. */
+ STM32_MDMA_CTCR_TRGM_BUFFER | /* Trigger on buffer. */
+ STM32_MDMA_CTCR_TLEN(0) | /* One byte buffer. */
+ STM32_MDMA_CTCR_DBURST_1 | /* Assuming AXI bus. */
+ STM32_MDMA_CTCR_SBURST_1 | /* Assuming AXI bus. */
+ STM32_MDMA_CTCR_DINCOS_BYTE | /* Byte increment. */
+ STM32_MDMA_CTCR_SINCOS_BYTE | /* Byte increment. */
+ STM32_MDMA_CTCR_DSIZE_BYTE | /* Destination size. */
+ STM32_MDMA_CTCR_SSIZE_BYTE | /* Source size. */
+ STM32_MDMA_CTCR_DINC_INC | /* Destination incr. */
+ STM32_MDMA_CTCR_SINC_FIXED; /* Source fixed. */
+ uint32_t ccr = STM32_MDMA_CCR_PL(STM32_WSPI_QUADSPI1_MDMA_PRIORITY) |
+ STM32_MDMA_CCR_CTCIE | /* On transfer complete.*/
+ STM32_MDMA_CCR_TEIE; /* On transfer error. */
+
+ /* MDMA initializations.*/
+ mdmaChannelSetSourceX(wspip->mdma, &wspip->qspi->DR);
+ mdmaChannelSetDestinationX(wspip->mdma, rxbuf);
+ mdmaChannelSetTransactionSizeX(wspip->mdma, n, 0, 0);
+ mdmaChannelSetModeX(wspip->mdma, ctcr, ccr);
+ mdmaChannelSetTrigModeX(wspip->mdma, MDMA_REQUEST_QUADSPI_FIFO_TH);
+
+ wspip->qspi->DLR = n - 1;
+ wspip->qspi->ABR = cmdp->alt;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
+ QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
+ QUADSPI_CCR_FMODE_0;
+ if ((cmdp->cfg & WSPI_CFG_ADDR_MODE_MASK) != WSPI_CFG_ADDR_MODE_NONE) {
+ wspip->qspi->AR = cmdp->addr;
+ }
+
+ mdmaChannelEnableX(wspip->mdma);
+}
+
+#if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Maps in memory space a WSPI flash device.
+ * @pre The memory flash device must be initialized appropriately
+ * before mapping it in memory space.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ * @param[in] cmdp pointer to the command descriptor
+ * @param[out] addrp pointer to the memory start address of the mapped
+ * flash or @p NULL
+ *
+ * @notapi
+ */
+void wspi_lld_map_flash(WSPIDriver *wspip,
+ const wspi_command_t *cmdp,
+ uint8_t **addrp) {
+
+ /* Disabling the DMA request while in memory mapped mode.*/
+ wspip->qspi->CR &= ~QUADSPI_CR_DMAEN;
+
+ /* Starting memory mapped mode using the passed parameters.*/
+ wspip->qspi->DLR = 0;
+ wspip->qspi->ABR = 0;
+ wspip->qspi->AR = 0;
+ wspip->qspi->CCR = cmdp->cmd | cmdp->cfg |
+ QUADSPI_CCR_DUMMY_CYCLES(cmdp->dummy) |
+ QUADSPI_CCR_FMODE_1 | QUADSPI_CCR_FMODE_0;
+
+ /* Mapped flash absolute base address.*/
+ if (addrp != NULL) {
+ *addrp = (uint8_t *)0x90000000;
+ }
+}
+
+/**
+ * @brief Unmaps from memory space a WSPI flash device.
+ * @post The memory flash device must be re-initialized for normal
+ * commands exchange.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ *
+ * @notapi
+ */
+void wspi_lld_unmap_flash(WSPIDriver *wspip) {
+
+ /* Aborting memory mapped mode.*/
+ wspip->qspi->CR |= QUADSPI_CR_ABORT;
+ while ((wspip->qspi->CR & QUADSPI_CR_ABORT) != 0U) {
+ }
+
+ /* Re-enabling DMA request, we are going back to indirect mode.*/
+ wspip->qspi->CR |= QUADSPI_CR_DMAEN;
+}
+#endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] wspip pointer to the @p WSPIDriver object
+ */
+void wspi_lld_serve_interrupt(WSPIDriver *wspip) {
+ uint32_t sr;
+
+ sr = wspip->qspi->SR;
+ wspip->qspi->FCR = sr;
+
+ if (((sr & QUADSPI_FCR_CTCF) != 0U) && (wspip->state == WSPI_SEND)) {
+ /* Portable WSPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _wspi_isr_code(wspip);
+
+ mdmaChannelDisableX(wspip->mdma);
+ }
+
+ /* TODO errors handling.*/
+}
+
+#endif /* HAL_USE_WSPI */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.h b/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.h
index 2452bb255f..229c3220f0 100644
--- a/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.h
+++ b/os/hal/ports/STM32/LLD/QUADSPIv2/hal_wspi_lld.h
@@ -1,286 +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 QUADSPIv2/hal_wspi_lld.h
- * @brief STM32 WSPI subsystem low level driver header.
- *
- * @addtogroup WSPI
- * @{
- */
-
-#ifndef HAL_WSPI_LLD_H
-#define HAL_WSPI_LLD_H
-
-#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name WSPI implementation capabilities
- * @{
- */
-#define WSPI_SUPPORTS_MEMMAP TRUE
-#define WSPI_DEFAULT_CFG_MASKS FALSE
-/** @} */
-
-/**
- * @name Transfer options
- * @note The low level driver has the option to override the following
- * definitions and use its own ones. In must take care to use
- * the same name for the same function or compatibility is not
- * ensured.
- * @note There are the following limitations in this implementation:
- * - Eight lines are not supported.
- * - DDR mode is only supported for the whole command, separate
- * masks are defined but all define the same bit.
- * - Only 8 bits instructions are supported.
- * .
- * @{
- */
-#define WSPI_CFG_CMD_MODE_MASK (3LU << 8LU)
-#define WSPI_CFG_CMD_MODE_NONE (0LU << 8LU)
-#define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 8LU)
-#define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 8LU)
-#define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 8LU)
-
-#define WSPI_CFG_CMD_DDR (1LU << 31LU)
-
-#define WSPI_CFG_CMD_SIZE_MASK 0LU
-#define WSPI_CFG_CMD_SIZE_8 0LU
-
-#define WSPI_CFG_ADDR_MODE_MASK (3LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_NONE (0LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU)
-#define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU)
-
-#define WSPI_CFG_ADDR_DDR (1LU << 31LU)
-
-#define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU)
-#define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU)
-
-#define WSPI_CFG_ALT_MODE_MASK (3LU << 14LU)
-#define WSPI_CFG_ALT_MODE_NONE (0LU << 14LU)
-#define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU)
-#define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU)
-#define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU)
-
-#define WSPI_CFG_ALT_DDR (1LU << 31LU)
-
-#define WSPI_CFG_ALT_SIZE_MASK (3LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_8 (0LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_16 (1LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_24 (2LU << 16LU)
-#define WSPI_CFG_ALT_SIZE_32 (3LU << 16LU)
-
-#define WSPI_CFG_DATA_MODE_MASK (3LU << 24LU)
-#define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU)
-#define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU)
-#define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU)
-#define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU)
-
-#define WSPI_CFG_DATA_DDR (1LU << 31LU)
-
-#define WSPI_CFG_SIOO (1LU << 28LU)
-/** @} */
-
-/**
- * @name Helpers for CCR register.
- * @{
- */
-#define QUADSPI_CCR_DUMMY_CYCLES_MASK (0x1FLU << 18LU)
-#define QUADSPI_CCR_DUMMY_CYCLES(n) ((n) << 18LU)
-/** @} */
-
-/**
- * @name DCR register options
- * @{
- */
-#define STM32_DCR_CK_MODE (1U << 0U)
-#define STM32_DCR_CSHT_MASK (7U << 8U)
-#define STM32_DCR_CSHT(n) ((n) << 8U)
-#define STM32_DCR_FSIZE_MASK (31U << 16U)
-#define STM32_DCR_FSIZE(n) ((n) << 16U)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief WSPID1 driver enable switch.
- * @details If set to @p TRUE the support for QUADSPI1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_WSPI_USE_QUADSPI1) || defined(__DOXYGEN__)
-#define STM32_WSPI_USE_QUADSPI1 FALSE
-#endif
-
-/**
- * @brief QUADSPI1 prescaler setting.
- * @note This is the prescaler divider value 1..256. The maximum frequency
- * varies depending on the STM32 model and operating conditions,
- * find the details in the data sheet.
- */
-#if !defined(STM32_WSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
-#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1
-#endif
-
-/**
- * @brief QUADSPI1 CR_SSHIFT enforcing.
- */
-#if !defined(STM32_WSPI_SET_CR_SSHIFT) || defined(__DOXYGEN__)
-#define STM32_WSPI_SET_CR_SSHIFT TRUE
-#endif
-
-/**
- * @brief QUADSPI1 MDMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_WSPI_QUADSPI1_MDMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_WSPI_QUADSPI1_MDMA_PRIORITY 1
-#endif
-
-/**
- * @brief QUADSPI MDMA error hook.
- */
-#if !defined(STM32_WSPI_MDMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_WSPI_MDMA_ERROR_HOOK(wspip) osalSysHalt("MDMA failure")
-#endif
-
-/**
- * @brief Enables a workaround for a STM32L476 QUADSPI errata.
- * @details The document DM00111498 states: "QUADSPI_BK1_IO1 is always an
- * input when the command is sent in dual or quad SPI mode".
- * This workaround makes commands without address or data phases
- * to be sent as alternate bytes.
- */
-#if !defined(STM32_USE_STM32_D1_WORKAROUND) || defined(__DOXYGEN__)
-#define STM32_USE_STM32_D1_WORKAROUND TRUE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_QUADSPI1)
-#define STM32_HAS_QUADSPI1 FALSE
-#endif
-
-#if STM32_WSPI_USE_QUADSPI1 && !STM32_HAS_QUADSPI1
-#error "QUADSPI1 not present in the selected device"
-#endif
-
-#if !STM32_WSPI_USE_QUADSPI1
-#error "WSPI driver activated but no QUADSPI peripheral assigned"
-#endif
-
-/* MDMA-related checks.*/
-#if STM32_WSPI_USE_QUADSPI1 && \
- !STM32_MDMA_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_MDMA_PRIORITY)
-#error "Invalid MDMA priority assigned to QUADSPI1"
-#endif
-
-/* Checks on prescaler setting.*/
-#if (STM32_WSPI_QUADSPI1_PRESCALER_VALUE < 1) || \
- (STM32_WSPI_QUADSPI1_PRESCALER_VALUE > 256)
-#error "STM32_WSPI_QUADSPI1_PRESCALER_VALUE not within 1..256"
-#endif
-
-/* Check on the presence of the DMA channels settings in mcuconf.h.*/
-#if STM32_WSPI_USE_QUADSPI1 && !defined(STM32_WSPI_QUADSPI1_MDMA_CHANNEL)
-#error "QUADSPI1 MDMA channel not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_WSPI_USE_QUADSPI1 && \
- !STM32_MDMA_IS_VALID_CHANNEL(STM32_WSPI_QUADSPI1_MDMA_CHANNEL)
-#error "invalid MDMA channel associated to QUADSPI1"
-#endif
-
-#if !defined(STM32_MDMA_REQUIRED)
-#define STM32_MDMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the WSPI configuration structure.
- */
-#define wspi_lld_config_fields \
- /* DCR register initialization data.*/ \
- uint32_t dcr
-
-/**
- * @brief Low level fields of the WSPI driver structure.
- */
-#define wspi_lld_driver_fields \
- /* Pointer to the QUADSPIx registers block.*/ \
- QUADSPI_TypeDef *qspi; \
- /* QUADSPI MDMA channel.*/ \
- const stm32_mdma_channel_t *mdma
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if (STM32_WSPI_USE_QUADSPI1 == TRUE) && !defined(__DOXYGEN__)
-extern WSPIDriver WSPID1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void wspi_lld_init(void);
- void wspi_lld_start(WSPIDriver *wspip);
- void wspi_lld_stop(WSPIDriver *wspip);
- void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp);
- void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, const uint8_t *txbuf);
- void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
- size_t n, uint8_t *rxbuf);
-#if WSPI_SUPPORTS_MEMMAP == TRUE
- void wspi_lld_map_flash(WSPIDriver *wspip,
- const wspi_command_t *cmdp,
- uint8_t **addrp);
- void wspi_lld_unmap_flash(WSPIDriver *wspip);
-#endif
- void wspi_lld_serve_interrupt(WSPIDriver *wspip);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_WSPI */
-
-#endif /* HAL_WSPI_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 QUADSPIv2/hal_wspi_lld.h
+ * @brief STM32 WSPI subsystem low level driver header.
+ *
+ * @addtogroup WSPI
+ * @{
+ */
+
+#ifndef HAL_WSPI_LLD_H
+#define HAL_WSPI_LLD_H
+
+#if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name WSPI implementation capabilities
+ * @{
+ */
+#define WSPI_SUPPORTS_MEMMAP TRUE
+#define WSPI_DEFAULT_CFG_MASKS FALSE
+/** @} */
+
+/**
+ * @name Transfer options
+ * @note The low level driver has the option to override the following
+ * definitions and use its own ones. In must take care to use
+ * the same name for the same function or compatibility is not
+ * ensured.
+ * @note There are the following limitations in this implementation:
+ * - Eight lines are not supported.
+ * - DDR mode is only supported for the whole command, separate
+ * masks are defined but all define the same bit.
+ * - Only 8 bits instructions are supported.
+ * .
+ * @{
+ */
+#define WSPI_CFG_CMD_MODE_MASK (3LU << 8LU)
+#define WSPI_CFG_CMD_MODE_NONE (0LU << 8LU)
+#define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 8LU)
+#define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 8LU)
+#define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 8LU)
+
+#define WSPI_CFG_CMD_DDR (1LU << 31LU)
+
+#define WSPI_CFG_CMD_SIZE_MASK 0LU
+#define WSPI_CFG_CMD_SIZE_8 0LU
+
+#define WSPI_CFG_ADDR_MODE_MASK (3LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_NONE (0LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU)
+#define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU)
+
+#define WSPI_CFG_ADDR_DDR (1LU << 31LU)
+
+#define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU)
+#define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU)
+
+#define WSPI_CFG_ALT_MODE_MASK (3LU << 14LU)
+#define WSPI_CFG_ALT_MODE_NONE (0LU << 14LU)
+#define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU)
+#define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU)
+#define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU)
+
+#define WSPI_CFG_ALT_DDR (1LU << 31LU)
+
+#define WSPI_CFG_ALT_SIZE_MASK (3LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_8 (0LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_16 (1LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_24 (2LU << 16LU)
+#define WSPI_CFG_ALT_SIZE_32 (3LU << 16LU)
+
+#define WSPI_CFG_DATA_MODE_MASK (3LU << 24LU)
+#define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU)
+#define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU)
+#define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU)
+#define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU)
+
+#define WSPI_CFG_DATA_DDR (1LU << 31LU)
+
+#define WSPI_CFG_SIOO (1LU << 28LU)
+/** @} */
+
+/**
+ * @name Helpers for CCR register.
+ * @{
+ */
+#define QUADSPI_CCR_DUMMY_CYCLES_MASK (0x1FLU << 18LU)
+#define QUADSPI_CCR_DUMMY_CYCLES(n) ((n) << 18LU)
+/** @} */
+
+/**
+ * @name DCR register options
+ * @{
+ */
+#define STM32_DCR_CK_MODE (1U << 0U)
+#define STM32_DCR_CSHT_MASK (7U << 8U)
+#define STM32_DCR_CSHT(n) ((n) << 8U)
+#define STM32_DCR_FSIZE_MASK (31U << 16U)
+#define STM32_DCR_FSIZE(n) ((n) << 16U)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief WSPID1 driver enable switch.
+ * @details If set to @p TRUE the support for QUADSPI1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_WSPI_USE_QUADSPI1) || defined(__DOXYGEN__)
+#define STM32_WSPI_USE_QUADSPI1 FALSE
+#endif
+
+/**
+ * @brief QUADSPI1 prescaler setting.
+ * @note This is the prescaler divider value 1..256. The maximum frequency
+ * varies depending on the STM32 model and operating conditions,
+ * find the details in the data sheet.
+ */
+#if !defined(STM32_WSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
+#define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 1
+#endif
+
+/**
+ * @brief QUADSPI1 CR_SSHIFT enforcing.
+ */
+#if !defined(STM32_WSPI_SET_CR_SSHIFT) || defined(__DOXYGEN__)
+#define STM32_WSPI_SET_CR_SSHIFT TRUE
+#endif
+
+/**
+ * @brief QUADSPI1 MDMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_WSPI_QUADSPI1_MDMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_WSPI_QUADSPI1_MDMA_PRIORITY 1
+#endif
+
+/**
+ * @brief QUADSPI MDMA error hook.
+ */
+#if !defined(STM32_WSPI_MDMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_WSPI_MDMA_ERROR_HOOK(wspip) osalSysHalt("MDMA failure")
+#endif
+
+/**
+ * @brief Enables a workaround for a STM32L476 QUADSPI errata.
+ * @details The document DM00111498 states: "QUADSPI_BK1_IO1 is always an
+ * input when the command is sent in dual or quad SPI mode".
+ * This workaround makes commands without address or data phases
+ * to be sent as alternate bytes.
+ */
+#if !defined(STM32_USE_STM32_D1_WORKAROUND) || defined(__DOXYGEN__)
+#define STM32_USE_STM32_D1_WORKAROUND TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_QUADSPI1)
+#define STM32_HAS_QUADSPI1 FALSE
+#endif
+
+#if STM32_WSPI_USE_QUADSPI1 && !STM32_HAS_QUADSPI1
+#error "QUADSPI1 not present in the selected device"
+#endif
+
+#if !STM32_WSPI_USE_QUADSPI1
+#error "WSPI driver activated but no QUADSPI peripheral assigned"
+#endif
+
+/* MDMA-related checks.*/
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !STM32_MDMA_IS_VALID_PRIORITY(STM32_WSPI_QUADSPI1_MDMA_PRIORITY)
+#error "Invalid MDMA priority assigned to QUADSPI1"
+#endif
+
+/* Checks on prescaler setting.*/
+#if (STM32_WSPI_QUADSPI1_PRESCALER_VALUE < 1) || \
+ (STM32_WSPI_QUADSPI1_PRESCALER_VALUE > 256)
+#error "STM32_WSPI_QUADSPI1_PRESCALER_VALUE not within 1..256"
+#endif
+
+/* Check on the presence of the DMA channels settings in mcuconf.h.*/
+#if STM32_WSPI_USE_QUADSPI1 && !defined(STM32_WSPI_QUADSPI1_MDMA_CHANNEL)
+#error "QUADSPI1 MDMA channel not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_WSPI_USE_QUADSPI1 && \
+ !STM32_MDMA_IS_VALID_CHANNEL(STM32_WSPI_QUADSPI1_MDMA_CHANNEL)
+#error "invalid MDMA channel associated to QUADSPI1"
+#endif
+
+#if !defined(STM32_MDMA_REQUIRED)
+#define STM32_MDMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the WSPI configuration structure.
+ */
+#define wspi_lld_config_fields \
+ /* DCR register initialization data.*/ \
+ uint32_t dcr
+
+/**
+ * @brief Low level fields of the WSPI driver structure.
+ */
+#define wspi_lld_driver_fields \
+ /* Pointer to the QUADSPIx registers block.*/ \
+ QUADSPI_TypeDef *qspi; \
+ /* QUADSPI MDMA channel.*/ \
+ const stm32_mdma_channel_t *mdma
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if (STM32_WSPI_USE_QUADSPI1 == TRUE) && !defined(__DOXYGEN__)
+extern WSPIDriver WSPID1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void wspi_lld_init(void);
+ void wspi_lld_start(WSPIDriver *wspip);
+ void wspi_lld_stop(WSPIDriver *wspip);
+ void wspi_lld_command(WSPIDriver *wspip, const wspi_command_t *cmdp);
+ void wspi_lld_send(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, const uint8_t *txbuf);
+ void wspi_lld_receive(WSPIDriver *wspip, const wspi_command_t *cmdp,
+ size_t n, uint8_t *rxbuf);
+#if WSPI_SUPPORTS_MEMMAP == TRUE
+ void wspi_lld_map_flash(WSPIDriver *wspip,
+ const wspi_command_t *cmdp,
+ uint8_t **addrp);
+ void wspi_lld_unmap_flash(WSPIDriver *wspip);
+#endif
+ void wspi_lld_serve_interrupt(WSPIDriver *wspip);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_WSPI */
+
+#endif /* HAL_WSPI_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/RNGv1/driver.mk b/os/hal/ports/STM32/LLD/RNGv1/driver.mk
index 3c905004a4..35ba327814 100644
--- a/os/hal/ports/STM32/LLD/RNGv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/RNGv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_TRNG TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_TRNG TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1
diff --git a/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c b/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
index c81e433f6c..3708c1cac8 100644
--- a/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
+++ b/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.c
@@ -1,179 +1,179 @@
-/*
- 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 hal_trng_lld.c
- * @brief STM32 TRNG subsystem low level driver source.
- *
- * @addtogroup TRNG
- * @{
- */
-
-#include "hal.h"
-
-#if (HAL_USE_TRNG == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief TRNGD1 driver identifier.
- */
-#if (STM32_TRNG_USE_RNG1 == TRUE) || defined(__DOXYGEN__)
-TRNGDriver TRNGD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const TRNGConfig default_cfg = {.cr = 0};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level TRNG driver initialization.
- *
- * @notapi
- */
-void trng_lld_init(void) {
-
-#if STM32_TRNG_USE_RNG1 == TRUE
- /* Driver initialization.*/
- trngObjectInit(&TRNGD1);
- TRNGD1.rng = RNG;
-#endif
-}
-
-/**
- * @brief Configures and activates the TRNG peripheral.
- *
- * @param[in] trngp pointer to the @p TRNGDriver object
- *
- * @notapi
- */
-void trng_lld_start(TRNGDriver *trngp) {
-
- /* There is no real configuration but setting up a valid pointer anyway.*/
- if (trngp->config == NULL) {
- trngp->config = &default_cfg;
- }
-
- if (trngp->state == TRNG_STOP) {
- /* Enables the peripheral.*/
-#if STM32_TRNG_USE_RNG1 == TRUE
- if (&TRNGD1 == trngp) {
- rccEnableRNG(false);
- }
-#endif
- }
- /* Configures the peripheral.*/
- trngp->rng->CR |= RNG_CR_RNGEN;
-}
-
-/**
- * @brief Deactivates the TRNG peripheral.
- *
- * @param[in] trngp pointer to the @p TRNGDriver object
- *
- * @notapi
- */
-void trng_lld_stop(TRNGDriver *trngp) {
-
- if (trngp->state == TRNG_READY) {
- /* Resets the peripheral.*/
- trngp->rng->CR &= ~RNG_CR_RNGEN;
-
- /* Disables the peripheral.*/
-#if STM32_TRNG_USE_RNG1 == TRUE
- if (&TRNGD1 == trngp) {
- rccDisableRNG();
- }
-#endif
- }
-}
-
-/**
- * @brief True random numbers generator.
- * @note The function is blocking and likely performs polled waiting
- * inside the low level implementation.
- *
- * @param[in] trngp pointer to the @p TRNGDriver object
- * @param[in] size size of output buffer
- * @param[out] out output buffer
- * @return The operation status.
- * @retval false if a random number has been generated.
- * @retval true if an HW error occurred.
- *
- * @api
- */
-bool trng_lld_generate(TRNGDriver *trngp, size_t size, uint8_t *out) {
-
- while (true) {
- uint32_t r, tmo;
- size_t i;
-
- /* Waiting for error conditions to be cleared.*/
- tmo = STM32_TRNG_ERROR_CLEAR_ATTEMPTS;
- while ((tmo > 0) && ((trngp->rng->SR & (RNG_SR_CECS | RNG_SR_SECS)) != 0)) {
- tmo--;
- if (tmo == 0) {
- return true;
- }
- }
-
- /* Waiting for a random number in data register.*/
- tmo = STM32_DATA_FETCH_ATTEMPTS;
- while ((tmo > 0) && ((trngp->rng->SR & RNG_SR_DRDY) == 0)) {
- tmo--;
- if (tmo == 0) {
- return true;
- }
- }
-
- /* Getting the generated random number.*/
- r = trngp->rng->DR;
-
- /* Writing in the output buffer.*/
- for (i = 0; i < sizeof (uint32_t) / sizeof (uint8_t); i++) {
- *out++ = (uint8_t)r;
- r = r >> 8;
- size--;
- if (size == 0) {
- return false;
- }
- }
- }
-}
-
-#endif /* HAL_USE_TRNG == 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 hal_trng_lld.c
+ * @brief STM32 TRNG subsystem low level driver source.
+ *
+ * @addtogroup TRNG
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_TRNG == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief TRNGD1 driver identifier.
+ */
+#if (STM32_TRNG_USE_RNG1 == TRUE) || defined(__DOXYGEN__)
+TRNGDriver TRNGD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const TRNGConfig default_cfg = {.cr = 0};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level TRNG driver initialization.
+ *
+ * @notapi
+ */
+void trng_lld_init(void) {
+
+#if STM32_TRNG_USE_RNG1 == TRUE
+ /* Driver initialization.*/
+ trngObjectInit(&TRNGD1);
+ TRNGD1.rng = RNG;
+#endif
+}
+
+/**
+ * @brief Configures and activates the TRNG peripheral.
+ *
+ * @param[in] trngp pointer to the @p TRNGDriver object
+ *
+ * @notapi
+ */
+void trng_lld_start(TRNGDriver *trngp) {
+
+ /* There is no real configuration but setting up a valid pointer anyway.*/
+ if (trngp->config == NULL) {
+ trngp->config = &default_cfg;
+ }
+
+ if (trngp->state == TRNG_STOP) {
+ /* Enables the peripheral.*/
+#if STM32_TRNG_USE_RNG1 == TRUE
+ if (&TRNGD1 == trngp) {
+ rccEnableRNG(false);
+ }
+#endif
+ }
+ /* Configures the peripheral.*/
+ trngp->rng->CR |= RNG_CR_RNGEN;
+}
+
+/**
+ * @brief Deactivates the TRNG peripheral.
+ *
+ * @param[in] trngp pointer to the @p TRNGDriver object
+ *
+ * @notapi
+ */
+void trng_lld_stop(TRNGDriver *trngp) {
+
+ if (trngp->state == TRNG_READY) {
+ /* Resets the peripheral.*/
+ trngp->rng->CR &= ~RNG_CR_RNGEN;
+
+ /* Disables the peripheral.*/
+#if STM32_TRNG_USE_RNG1 == TRUE
+ if (&TRNGD1 == trngp) {
+ rccDisableRNG();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief True random numbers generator.
+ * @note The function is blocking and likely performs polled waiting
+ * inside the low level implementation.
+ *
+ * @param[in] trngp pointer to the @p TRNGDriver object
+ * @param[in] size size of output buffer
+ * @param[out] out output buffer
+ * @return The operation status.
+ * @retval false if a random number has been generated.
+ * @retval true if an HW error occurred.
+ *
+ * @api
+ */
+bool trng_lld_generate(TRNGDriver *trngp, size_t size, uint8_t *out) {
+
+ while (true) {
+ uint32_t r, tmo;
+ size_t i;
+
+ /* Waiting for error conditions to be cleared.*/
+ tmo = STM32_TRNG_ERROR_CLEAR_ATTEMPTS;
+ while ((tmo > 0) && ((trngp->rng->SR & (RNG_SR_CECS | RNG_SR_SECS)) != 0)) {
+ tmo--;
+ if (tmo == 0) {
+ return true;
+ }
+ }
+
+ /* Waiting for a random number in data register.*/
+ tmo = STM32_DATA_FETCH_ATTEMPTS;
+ while ((tmo > 0) && ((trngp->rng->SR & RNG_SR_DRDY) == 0)) {
+ tmo--;
+ if (tmo == 0) {
+ return true;
+ }
+ }
+
+ /* Getting the generated random number.*/
+ r = trngp->rng->DR;
+
+ /* Writing in the output buffer.*/
+ for (i = 0; i < sizeof (uint32_t) / sizeof (uint8_t); i++) {
+ *out++ = (uint8_t)r;
+ r = r >> 8;
+ size--;
+ if (size == 0) {
+ return false;
+ }
+ }
+ }
+}
+
+#endif /* HAL_USE_TRNG == TRUE */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.h b/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.h
index 2a1e9ba469..b39392b596 100644
--- a/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.h
+++ b/os/hal/ports/STM32/LLD/RNGv1/hal_trng_lld.h
@@ -1,141 +1,141 @@
-/*
- 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 hal_trng_lld.h
- * @brief STM32 TRNG subsystem low level driver header.
- *
- * @addtogroup TRNG
- * @{
- */
-
-#ifndef HAL_TRNG_LLD_H
-#define HAL_TRNG_LLD_H
-
-#if (HAL_USE_TRNG == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name STM32 configuration options
- * @{
- */
-/**
- * @brief TRNGD1 driver enable switch.
- * @details If set to @p TRUE the support for TRNGD1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_TRNG_USE_RNG1) || defined(__DOXYGEN__)
-#define STM32_TRNG_USE_RNG1 FALSE
-#endif
-
-/**
- * @brief TRNGD1 error clear timeout counter.
- * @details Number of status register fetches before failing.
- */
-#if !defined(STM32_TRNG_ERROR_CLEAR_ATTEMPTS) || defined(__DOXYGEN__)
-#define STM32_TRNG_ERROR_CLEAR_ATTEMPTS 1000
-#endif
-
-/**
- * @brief TRNGD1 data available timeout counter.
- * @details Number of status register fetches before failing.
- */
-#if !defined(STM32_DATA_FETCH_ATTEMPTS) || defined(__DOXYGEN__)
-#define STM32_DATA_FETCH_ATTEMPTS 1000
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_RNG1)
-#define STM32_HAS_RNG1 FALSE
-#endif
-
-#if STM32_TRNG_USE_RNG1 && !STM32_HAS_RNG1
-#error "RNG1 not present in the selected device"
-#endif
-
-#if !STM32_TRNG_USE_RNG1
-#error "TRNG driver activated but no RNG peripheral assigned"
-#endif
-
-#if !defined(STM32_RNGCLK)
-#error "STM32_RNGCLK not defined in this HAL"
-#endif
-
-#if ((STM32_RNGCLK < 47000000) || (STM32_RNGCLK > 49000000)) && \
- ((STM32_RNGCLK < 3500000) || (STM32_RNGCLK > 4500000))
-#if !defined(STM32_DISABLE_RNG_CLOCK_CHECK)
-#error "STM32_RNGCLK is not within a tested clock range"
-#error "define STM32_DISABLE_RNG_CLOCK_CHECK to override this check"
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the TRNG configuration structure.
- */
-#define trng_lld_config_fields \
- /* CR register initialization value.*/ \
- uint32_t cr
-
-/**
- * @brief Low level fields of the TRNG driver structure.
- */
-#define trng_lld_driver_fields \
- /* Pointer to the RNG registers block.*/ \
- RNG_TypeDef *rng
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if (STM32_TRNG_USE_RNG1 == TRUE) && !defined(__DOXYGEN__)
-extern TRNGDriver TRNGD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void trng_lld_init(void);
- void trng_lld_start(TRNGDriver *trngp);
- void trng_lld_stop(TRNGDriver *trngp);
- bool trng_lld_generate(TRNGDriver *trngp, size_t size, uint8_t *out);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_TRNG == TRUE */
-
-#endif /* HAL_TRNG_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 hal_trng_lld.h
+ * @brief STM32 TRNG subsystem low level driver header.
+ *
+ * @addtogroup TRNG
+ * @{
+ */
+
+#ifndef HAL_TRNG_LLD_H
+#define HAL_TRNG_LLD_H
+
+#if (HAL_USE_TRNG == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name STM32 configuration options
+ * @{
+ */
+/**
+ * @brief TRNGD1 driver enable switch.
+ * @details If set to @p TRUE the support for TRNGD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_TRNG_USE_RNG1) || defined(__DOXYGEN__)
+#define STM32_TRNG_USE_RNG1 FALSE
+#endif
+
+/**
+ * @brief TRNGD1 error clear timeout counter.
+ * @details Number of status register fetches before failing.
+ */
+#if !defined(STM32_TRNG_ERROR_CLEAR_ATTEMPTS) || defined(__DOXYGEN__)
+#define STM32_TRNG_ERROR_CLEAR_ATTEMPTS 1000
+#endif
+
+/**
+ * @brief TRNGD1 data available timeout counter.
+ * @details Number of status register fetches before failing.
+ */
+#if !defined(STM32_DATA_FETCH_ATTEMPTS) || defined(__DOXYGEN__)
+#define STM32_DATA_FETCH_ATTEMPTS 1000
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_RNG1)
+#define STM32_HAS_RNG1 FALSE
+#endif
+
+#if STM32_TRNG_USE_RNG1 && !STM32_HAS_RNG1
+#error "RNG1 not present in the selected device"
+#endif
+
+#if !STM32_TRNG_USE_RNG1
+#error "TRNG driver activated but no RNG peripheral assigned"
+#endif
+
+#if !defined(STM32_RNGCLK)
+#error "STM32_RNGCLK not defined in this HAL"
+#endif
+
+#if ((STM32_RNGCLK < 47000000) || (STM32_RNGCLK > 49000000)) && \
+ ((STM32_RNGCLK < 3500000) || (STM32_RNGCLK > 4500000))
+#if !defined(STM32_DISABLE_RNG_CLOCK_CHECK)
+#error "STM32_RNGCLK is not within a tested clock range"
+#error "define STM32_DISABLE_RNG_CLOCK_CHECK to override this check"
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the TRNG configuration structure.
+ */
+#define trng_lld_config_fields \
+ /* CR register initialization value.*/ \
+ uint32_t cr
+
+/**
+ * @brief Low level fields of the TRNG driver structure.
+ */
+#define trng_lld_driver_fields \
+ /* Pointer to the RNG registers block.*/ \
+ RNG_TypeDef *rng
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if (STM32_TRNG_USE_RNG1 == TRUE) && !defined(__DOXYGEN__)
+extern TRNGDriver TRNGD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void trng_lld_init(void);
+ void trng_lld_start(TRNGDriver *trngp);
+ void trng_lld_stop(TRNGDriver *trngp);
+ bool trng_lld_generate(TRNGDriver *trngp, size_t size, uint8_t *out);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_TRNG == TRUE */
+
+#endif /* HAL_TRNG_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/RNGv1/notes.txt b/os/hal/ports/STM32/LLD/RNGv1/notes.txt
index 8e0c8e530d..5216b28c9f 100644
--- a/os/hal/ports/STM32/LLD/RNGv1/notes.txt
+++ b/os/hal/ports/STM32/LLD/RNGv1/notes.txt
@@ -1,10 +1,10 @@
-STM32 RNGv1 driver.
-
-Driver capability:
-
-- Supports the STM32 TRNGv1 found on STM32L4 and STM32L4+ families.
-
-The file registry must export:
-
-STM32_HAS_RNG1 - RNG presence flag.
-
+STM32 RNGv1 driver.
+
+Driver capability:
+
+- Supports the STM32 TRNGv1 found on STM32L4 and STM32L4+ families.
+
+The file registry must export:
+
+STM32_HAS_RNG1 - RNG presence flag.
+
diff --git a/os/hal/ports/STM32/LLD/RTCv1/driver.mk b/os/hal/ports/STM32/LLD/RTCv1/driver.mk
index 972b475b50..1dbb3b7733 100644
--- a/os/hal/ports/STM32/LLD/RTCv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/RTCv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1/hal_rtc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1
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/driver.mk b/os/hal/ports/STM32/LLD/RTCv2/driver.mk
index 25ef11d41e..720f4d331e 100644
--- a/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/RTCv2/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/hal_rtc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2
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/driver.mk b/os/hal/ports/STM32/LLD/RTCv3/driver.mk
index be3a5ad06e..d8b1181017 100644
--- a/os/hal/ports/STM32/LLD/RTCv3/driver.mk
+++ b/os/hal/ports/STM32/LLD/RTCv3/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3
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/LLD/SDIOv1/driver.mk b/os/hal/ports/STM32/LLD/SDIOv1/driver.mk
index a1ce6d48ce..1a1a4bde73 100644
--- a/os/hal/ports/STM32/LLD/SDIOv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/SDIOv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1
diff --git a/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c b/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
index 37d4989626..be97134b9a 100644
--- a/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
+++ b/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.c
@@ -1,876 +1,876 @@
-/*
- 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 SDIOv1/hal_sdc_lld.c
- * @brief STM32 SDC subsystem low level driver source.
- *
- * @addtogroup SDC
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \
- STM32_SDC_SDIO_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SDCD1 driver identifier.*/
-SDCDriver SDCD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
-/**
- * @brief Buffer for temporary storage during unaligned transfers.
- */
-static union {
- uint32_t alignment;
- uint8_t buf[MMCSD_BLOCK_SIZE];
-} u;
-#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */
-
-/**
- * @brief SDIO default configuration.
- */
-static const SDCConfig sdc_default_cfg = {
- SDC_MODE_4BIT
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Prepares to handle read transaction.
- * @details Designed for read special registers from card.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[out] buf pointer to the read buffer
- * @param[in] bytes number of bytes to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp,
- uint8_t *buf, uint32_t bytes) {
- osalDbgCheck(bytes < 0x1000000);
-
- sdcp->sdio->DTIMER = STM32_SDC_READ_TIMEOUT;
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Prepares the DMA channel for writing.*/
- dmaStreamSetMemory0(sdcp->dma, buf);
- dmaStreamSetTransactionSize(sdcp->dma, bytes / sizeof (uint32_t));
- dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
- dmaStreamEnable(sdcp->dma);
-
- /* Setting up data transfer.*/
- sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
- sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE |
- SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_STBITERRIE |
- SDIO_MASK_RXOVERRIE |
- SDIO_MASK_DATAENDIE;
- sdcp->sdio->DLEN = bytes;
-
- /* Transaction starts just after DTEN bit setting.*/
- sdcp->sdio->DCTRL = SDIO_DCTRL_DTDIR |
- SDIO_DCTRL_DTMODE | /* Multibyte data transfer.*/
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Prepares card to handle read transaction.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[in] n number of blocks to read
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
- uint32_t n, uint32_t *resp) {
-
- /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
- have not HC card than we must convert address from blocks to bytes.*/
- if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
- startblk *= MMCSD_BLOCK_SIZE;
-
- if (n > 1) {
- /* Send read multiple blocks command to card.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
- else {
- /* Send read single block command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Prepares card to handle write transaction.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[in] n number of blocks to write
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
- uint32_t n, uint32_t *resp) {
-
- /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
- have not HC card than we must convert address from blocks to bytes.*/
- if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
- startblk *= MMCSD_BLOCK_SIZE;
-
- if (n > 1) {
- /* Write multiple blocks command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
- else {
- /* Write single block command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Wait end of data transaction and performs finalizations.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] n number of blocks in transaction
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- */
-static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
- uint32_t *resp) {
-
- /* Note the mask is checked before going to sleep because the interrupt
- may have occurred before reaching the critical zone.*/
- osalSysLock();
- if (sdcp->sdio->MASK != 0)
- osalThreadSuspendS(&sdcp->thread);
- if ((sdcp->sdio->STA & SDIO_STA_DATAEND) == 0) {
- osalSysUnlock();
- return HAL_FAILED;
- }
-
-#if (defined(STM32F4XX) || defined(STM32F2XX))
- /* Wait until DMA channel enabled to be sure that all data transferred.*/
- while (sdcp->dma->stream->CR & STM32_DMA_CR_EN)
- ;
-
- /* DMA event flags must be manually cleared.*/
- dmaStreamClearInterrupt(sdcp->dma);
-
- sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
- sdcp->sdio->DCTRL = 0;
- osalSysUnlock();
-#else
- /* Waits for transfer completion at DMA level, then the stream is
- disabled and cleared.*/
- dmaWaitCompletion(sdcp->dma);
-
- sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
- sdcp->sdio->DCTRL = 0;
- osalSysUnlock();
-#endif
-
- /* Finalize transaction.*/
- if (n > 1)
- return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Gets SDC errors.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] sta value of the STA register
- *
- * @notapi
- */
-static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
- uint32_t errors = SDC_NO_ERROR;
-
- if (sta & SDIO_STA_CCRCFAIL)
- errors |= SDC_CMD_CRC_ERROR;
- if (sta & SDIO_STA_DCRCFAIL)
- errors |= SDC_DATA_CRC_ERROR;
- if (sta & SDIO_STA_CTIMEOUT)
- errors |= SDC_COMMAND_TIMEOUT;
- if (sta & SDIO_STA_DTIMEOUT)
- errors |= SDC_DATA_TIMEOUT;
- if (sta & SDIO_STA_TXUNDERR)
- errors |= SDC_TX_UNDERRUN;
- if (sta & SDIO_STA_RXOVERR)
- errors |= SDC_RX_OVERRUN;
- if (sta & SDIO_STA_STBITERR)
- errors |= SDC_STARTBIT_ERROR;
-
- sdcp->errors |= errors;
-}
-
-/**
- * @brief Performs clean transaction stopping in case of errors.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] n number of blocks in transaction
- * @param[in] resp pointer to the response buffer
- *
- * @notapi
- */
-static void sdc_lld_error_cleanup(SDCDriver *sdcp,
- uint32_t n,
- uint32_t *resp) {
- uint32_t sta = sdcp->sdio->STA;
-
- dmaStreamClearInterrupt(sdcp->dma);
- dmaStreamDisable(sdcp->dma);
- sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
- sdcp->sdio->MASK = 0;
- sdcp->sdio->DCTRL = 0;
- sdc_lld_collect_errors(sdcp, sta);
- if (n > 1)
- sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if !defined(STM32_SDIO_HANDLER)
-#error "STM32_SDIO_HANDLER not defined"
-#endif
-/**
- * @brief SDIO IRQ handler.
- * @details It just wakes transaction thread. All error handling performs in
- * that thread.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SDIO_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- osalSysLockFromISR();
-
- /* Disables the source but the status flags are not reset because the
- read/write functions needs to check them.*/
- SDIO->MASK = 0;
-
- osalThreadResumeI(&SDCD1.thread, MSG_OK);
-
- osalSysUnlockFromISR();
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SDC driver initialization.
- *
- * @notapi
- */
-void sdc_lld_init(void) {
-
- sdcObjectInit(&SDCD1);
- SDCD1.thread = NULL;
- SDCD1.dma = NULL;
- SDCD1.sdio = SDIO;
- nvicEnableVector(STM32_SDIO_NUMBER, STM32_SDC_SDIO_IRQ_PRIORITY);
-}
-
-/**
- * @brief Configures and activates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start(SDCDriver *sdcp) {
-
- /* Checking configuration, using a default if NULL has been passed.*/
- if (sdcp->config == NULL) {
- sdcp->config = &sdc_default_cfg;
- }
-
- sdcp->dmamode = STM32_DMA_CR_CHSEL(DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_WORD |
- STM32_DMA_CR_MSIZE_WORD |
- STM32_DMA_CR_MINC;
-
-#if (defined(STM32F4XX) || defined(STM32F2XX))
- sdcp->dmamode |= STM32_DMA_CR_PFCTRL |
- STM32_DMA_CR_PBURST_INCR4 |
- STM32_DMA_CR_MBURST_INCR4;
-#endif
-
- if (sdcp->state == BLK_STOP) {
- sdcp->dma = dmaStreamAllocI(STM32_SDC_SDIO_DMA_STREAM,
- STM32_SDC_SDIO_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(sdcp->dma != NULL, "unable to allocate stream");
-
- dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdio->FIFO);
-#if (defined(STM32F4XX) || defined(STM32F2XX))
- dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_FULL);
-#endif
- rccEnableSDIO(true);
- }
-
- /* Configuration, card clock is initially stopped.*/
- sdcp->sdio->POWER = 0;
- sdcp->sdio->CLKCR = 0;
- sdcp->sdio->DCTRL = 0;
- sdcp->sdio->DTIMER = 0;
-}
-
-/**
- * @brief Deactivates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop(SDCDriver *sdcp) {
-
- if (sdcp->state != BLK_STOP) {
-
- /* SDIO deactivation.*/
- sdcp->sdio->POWER = 0;
- sdcp->sdio->CLKCR = 0;
- sdcp->sdio->DCTRL = 0;
- sdcp->sdio->DTIMER = 0;
-
- /* DMA stream released.*/
- dmaStreamFreeI(sdcp->dma);
- sdcp->dma = NULL;
-
- /* Clock deactivation.*/
- rccDisableSDIO();
- }
-}
-
-/**
- * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start_clk(SDCDriver *sdcp) {
-
- /* Initial clock setting: 400kHz, 1bit mode.*/
- sdcp->sdio->CLKCR = STM32_SDIO_DIV_LS;
- sdcp->sdio->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1;
- sdcp->sdio->CLKCR |= SDIO_CLKCR_CLKEN;
-
- /* Clock activation delay.*/
- osalThreadSleep(OSAL_MS2I(STM32_SDC_CLOCK_ACTIVATION_DELAY));
-}
-
-/**
- * @brief Sets the SDIO clock to data mode (25MHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] clk the clock mode
- *
- * @notapi
- */
-void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) {
-
-#if STM32_SDC_SDIO_50MHZ
- if (SDC_CLK_50MHz == clk) {
- sdcp->sdio->CLKCR = (sdcp->sdio->CLKCR & 0xFFFFFF00U) | STM32_SDIO_DIV_HS
- | SDIO_CLKCR_BYPASS;
- }
- else
- sdcp->sdio->CLKCR = (sdcp->sdio->CLKCR & 0xFFFFFF00U) | STM32_SDIO_DIV_HS;
-#else
- (void)clk;
-
- sdcp->sdio->CLKCR = (sdcp->sdio->CLKCR & 0xFFFFFF00U) | STM32_SDIO_DIV_HS;
-#endif
-}
-
-/**
- * @brief Stops the SDIO clock.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop_clk(SDCDriver *sdcp) {
-
- sdcp->sdio->CLKCR = 0;
- sdcp->sdio->POWER = 0;
-}
-
-/**
- * @brief Switches the bus to 4 bits mode.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] mode bus mode
- *
- * @notapi
- */
-void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
- uint32_t clk = sdcp->sdio->CLKCR & ~SDIO_CLKCR_WIDBUS;
-
- switch (mode) {
- case SDC_MODE_1BIT:
- sdcp->sdio->CLKCR = clk;
- break;
- case SDC_MODE_4BIT:
- sdcp->sdio->CLKCR = clk | SDIO_CLKCR_WIDBUS_0;
- break;
- case SDC_MODE_8BIT:
- sdcp->sdio->CLKCR = clk | SDIO_CLKCR_WIDBUS_1;
- break;
- }
-}
-
-/**
- * @brief Sends an SDIO command with no response expected.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- *
- * @notapi
- */
-void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
-
- sdcp->sdio->ARG = arg;
- sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
- while ((sdcp->sdio->STA & SDIO_STA_CMDSENT) == 0)
- ;
- sdcp->sdio->ICR = SDIO_ICR_CMDSENTC;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected.
- * @note The CRC is not verified.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- sdcp->sdio->ARG = arg;
- sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
- while (((sta = sdcp->sdio->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdio->ICR = sta & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL);
- if ((sta & (SDIO_STA_CTIMEOUT)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- *resp = sdcp->sdio->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- sdcp->sdio->ARG = arg;
- sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
- while (((sta = sdcp->sdio->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdio->ICR = sta & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL);
- if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- *resp = sdcp->sdio->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Sends an SDIO command with a long response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (four words)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- (void)sdcp;
-
- sdcp->sdio->ARG = arg;
- sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 |
- SDIO_CMD_CPSMEN;
- while (((sta = sdcp->sdio->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdio->ICR = sta & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL);
- if ((sta & (STM32_SDIO_STA_ERROR_MASK)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- /* Save bytes in reverse order because MSB in response comes first.*/
- *resp++ = sdcp->sdio->RESP4;
- *resp++ = sdcp->sdio->RESP3;
- *resp++ = sdcp->sdio->RESP2;
- *resp = sdcp->sdio->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Reads special registers using data bus.
- * @details Needs only during card detection procedure.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[out] buf pointer to the read buffer
- * @param[in] bytes number of bytes to read
- * @param[in] cmd card command
- * @param[in] arg argument for command
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
- uint8_t cmd, uint32_t arg) {
- uint32_t resp[1];
-
- if (sdc_lld_prepare_read_bytes(sdcp, buf, bytes))
- goto error;
-
- if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp)
- || MMCSD_R1_ERROR(resp[0]))
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, 1, resp))
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, 1, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Reads one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer
- * @param[in] blocks number of blocks to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks) {
- uint32_t resp[1];
-
- osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
-
- sdcp->sdio->DTIMER = STM32_SDC_READ_TIMEOUT;
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Prepares the DMA channel for writing.*/
- dmaStreamSetMemory0(sdcp->dma, buf);
- dmaStreamSetTransactionSize(sdcp->dma,
- (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
- dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
- dmaStreamEnable(sdcp->dma);
-
- /* Setting up data transfer.*/
- sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
- sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE |
- SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_STBITERRIE |
- SDIO_MASK_RXOVERRIE |
- SDIO_MASK_DATAENDIE;
- sdcp->sdio->DLEN = blocks * MMCSD_BLOCK_SIZE;
-
- /* Transaction starts just after DTEN bit setting.*/
- sdcp->sdio->DCTRL = SDIO_DCTRL_DTDIR |
- SDIO_DCTRL_DBLOCKSIZE_3 |
- SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == true)
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, blocks, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] n number of blocks to write
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks) {
- uint32_t resp[1];
-
- osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
-
- sdcp->sdio->DTIMER = STM32_SDC_WRITE_TIMEOUT;
-
- /* Checks for errors and waits for the card to be ready for writing.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Prepares the DMA channel for writing.*/
- dmaStreamSetMemory0(sdcp->dma, buf);
- dmaStreamSetTransactionSize(sdcp->dma,
- (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
- dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P);
- dmaStreamEnable(sdcp->dma);
-
- /* Setting up data transfer.*/
- sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
- sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE |
- SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_STBITERRIE |
- SDIO_MASK_TXUNDERRIE |
- SDIO_MASK_DATAENDIE;
- sdcp->sdio->DLEN = blocks * MMCSD_BLOCK_SIZE;
-
- /* Talk to card what we want from it.*/
- if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == true)
- goto error;
-
- /* Transaction starts just after DTEN bit setting.*/
- sdcp->sdio->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 |
- SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, blocks, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Reads one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer
- * @param[in] blocks number of blocks to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks) {
-
-#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < blocks; i++) {
- if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1))
- return HAL_FAILED;
- memcpy(buf, u.buf, MMCSD_BLOCK_SIZE);
- buf += MMCSD_BLOCK_SIZE;
- startblk++;
- }
- return HAL_SUCCESS;
- }
-#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
-#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- return sdc_lld_read_aligned(sdcp, startblk, buf, blocks);
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] blocks number of blocks to write
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks) {
-
-#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < blocks; i++) {
- memcpy(u.buf, buf, MMCSD_BLOCK_SIZE);
- buf += MMCSD_BLOCK_SIZE;
- if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1))
- return HAL_FAILED;
- startblk++;
- }
- return HAL_SUCCESS;
- }
-#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
-#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
-}
-
-/**
- * @brief Waits for card idle condition.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @return The operation status.
- * @retval HAL_SUCCESS the operation succeeded.
- * @retval HAL_FAILED the operation failed.
- *
- * @api
- */
-bool sdc_lld_sync(SDCDriver *sdcp) {
-
- /* CHTODO: Implement.*/
- (void)sdcp;
- return HAL_SUCCESS;
-}
-
-#endif /* HAL_USE_SDC */
-
-/** @} */
+/*
+ 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 SDIOv1/hal_sdc_lld.c
+ * @brief STM32 SDC subsystem low level driver source.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \
+ STM32_SDC_SDIO_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SDCD1 driver identifier.*/
+SDCDriver SDCD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
+/**
+ * @brief Buffer for temporary storage during unaligned transfers.
+ */
+static union {
+ uint32_t alignment;
+ uint8_t buf[MMCSD_BLOCK_SIZE];
+} u;
+#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+
+/**
+ * @brief SDIO default configuration.
+ */
+static const SDCConfig sdc_default_cfg = {
+ SDC_MODE_4BIT
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Prepares to handle read transaction.
+ * @details Designed for read special registers from card.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] buf pointer to the read buffer
+ * @param[in] bytes number of bytes to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp,
+ uint8_t *buf, uint32_t bytes) {
+ osalDbgCheck(bytes < 0x1000000);
+
+ sdcp->sdio->DTIMER = STM32_SDC_READ_TIMEOUT;
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaStreamSetMemory0(sdcp->dma, buf);
+ dmaStreamSetTransactionSize(sdcp->dma, bytes / sizeof (uint32_t));
+ dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
+ dmaStreamEnable(sdcp->dma);
+
+ /* Setting up data transfer.*/
+ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
+ sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE |
+ SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_STBITERRIE |
+ SDIO_MASK_RXOVERRIE |
+ SDIO_MASK_DATAENDIE;
+ sdcp->sdio->DLEN = bytes;
+
+ /* Transaction starts just after DTEN bit setting.*/
+ sdcp->sdio->DCTRL = SDIO_DCTRL_DTDIR |
+ SDIO_DCTRL_DTMODE | /* Multibyte data transfer.*/
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Prepares card to handle read transaction.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[in] n number of blocks to read
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
+ uint32_t n, uint32_t *resp) {
+
+ /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
+ have not HC card than we must convert address from blocks to bytes.*/
+ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
+ startblk *= MMCSD_BLOCK_SIZE;
+
+ if (n > 1) {
+ /* Send read multiple blocks command to card.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+ else {
+ /* Send read single block command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Prepares card to handle write transaction.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[in] n number of blocks to write
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
+ uint32_t n, uint32_t *resp) {
+
+ /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
+ have not HC card than we must convert address from blocks to bytes.*/
+ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
+ startblk *= MMCSD_BLOCK_SIZE;
+
+ if (n > 1) {
+ /* Write multiple blocks command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+ else {
+ /* Write single block command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Wait end of data transaction and performs finalizations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] n number of blocks in transaction
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ */
+static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
+ uint32_t *resp) {
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ osalSysLock();
+ if (sdcp->sdio->MASK != 0)
+ osalThreadSuspendS(&sdcp->thread);
+ if ((sdcp->sdio->STA & SDIO_STA_DATAEND) == 0) {
+ osalSysUnlock();
+ return HAL_FAILED;
+ }
+
+#if (defined(STM32F4XX) || defined(STM32F2XX))
+ /* Wait until DMA channel enabled to be sure that all data transferred.*/
+ while (sdcp->dma->stream->CR & STM32_DMA_CR_EN)
+ ;
+
+ /* DMA event flags must be manually cleared.*/
+ dmaStreamClearInterrupt(sdcp->dma);
+
+ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
+ sdcp->sdio->DCTRL = 0;
+ osalSysUnlock();
+#else
+ /* Waits for transfer completion at DMA level, then the stream is
+ disabled and cleared.*/
+ dmaWaitCompletion(sdcp->dma);
+
+ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
+ sdcp->sdio->DCTRL = 0;
+ osalSysUnlock();
+#endif
+
+ /* Finalize transaction.*/
+ if (n > 1)
+ return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Gets SDC errors.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] sta value of the STA register
+ *
+ * @notapi
+ */
+static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
+ uint32_t errors = SDC_NO_ERROR;
+
+ if (sta & SDIO_STA_CCRCFAIL)
+ errors |= SDC_CMD_CRC_ERROR;
+ if (sta & SDIO_STA_DCRCFAIL)
+ errors |= SDC_DATA_CRC_ERROR;
+ if (sta & SDIO_STA_CTIMEOUT)
+ errors |= SDC_COMMAND_TIMEOUT;
+ if (sta & SDIO_STA_DTIMEOUT)
+ errors |= SDC_DATA_TIMEOUT;
+ if (sta & SDIO_STA_TXUNDERR)
+ errors |= SDC_TX_UNDERRUN;
+ if (sta & SDIO_STA_RXOVERR)
+ errors |= SDC_RX_OVERRUN;
+ if (sta & SDIO_STA_STBITERR)
+ errors |= SDC_STARTBIT_ERROR;
+
+ sdcp->errors |= errors;
+}
+
+/**
+ * @brief Performs clean transaction stopping in case of errors.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] n number of blocks in transaction
+ * @param[in] resp pointer to the response buffer
+ *
+ * @notapi
+ */
+static void sdc_lld_error_cleanup(SDCDriver *sdcp,
+ uint32_t n,
+ uint32_t *resp) {
+ uint32_t sta = sdcp->sdio->STA;
+
+ dmaStreamClearInterrupt(sdcp->dma);
+ dmaStreamDisable(sdcp->dma);
+ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
+ sdcp->sdio->MASK = 0;
+ sdcp->sdio->DCTRL = 0;
+ sdc_lld_collect_errors(sdcp, sta);
+ if (n > 1)
+ sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if !defined(STM32_SDIO_HANDLER)
+#error "STM32_SDIO_HANDLER not defined"
+#endif
+/**
+ * @brief SDIO IRQ handler.
+ * @details It just wakes transaction thread. All error handling performs in
+ * that thread.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SDIO_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ osalSysLockFromISR();
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions needs to check them.*/
+ SDIO->MASK = 0;
+
+ osalThreadResumeI(&SDCD1.thread, MSG_OK);
+
+ osalSysUnlockFromISR();
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SDC driver initialization.
+ *
+ * @notapi
+ */
+void sdc_lld_init(void) {
+
+ sdcObjectInit(&SDCD1);
+ SDCD1.thread = NULL;
+ SDCD1.dma = NULL;
+ SDCD1.sdio = SDIO;
+ nvicEnableVector(STM32_SDIO_NUMBER, STM32_SDC_SDIO_IRQ_PRIORITY);
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start(SDCDriver *sdcp) {
+
+ /* Checking configuration, using a default if NULL has been passed.*/
+ if (sdcp->config == NULL) {
+ sdcp->config = &sdc_default_cfg;
+ }
+
+ sdcp->dmamode = STM32_DMA_CR_CHSEL(DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_WORD |
+ STM32_DMA_CR_MSIZE_WORD |
+ STM32_DMA_CR_MINC;
+
+#if (defined(STM32F4XX) || defined(STM32F2XX))
+ sdcp->dmamode |= STM32_DMA_CR_PFCTRL |
+ STM32_DMA_CR_PBURST_INCR4 |
+ STM32_DMA_CR_MBURST_INCR4;
+#endif
+
+ if (sdcp->state == BLK_STOP) {
+ sdcp->dma = dmaStreamAllocI(STM32_SDC_SDIO_DMA_STREAM,
+ STM32_SDC_SDIO_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(sdcp->dma != NULL, "unable to allocate stream");
+
+ dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdio->FIFO);
+#if (defined(STM32F4XX) || defined(STM32F2XX))
+ dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_FULL);
+#endif
+ rccEnableSDIO(true);
+ }
+
+ /* Configuration, card clock is initially stopped.*/
+ sdcp->sdio->POWER = 0;
+ sdcp->sdio->CLKCR = 0;
+ sdcp->sdio->DCTRL = 0;
+ sdcp->sdio->DTIMER = 0;
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop(SDCDriver *sdcp) {
+
+ if (sdcp->state != BLK_STOP) {
+
+ /* SDIO deactivation.*/
+ sdcp->sdio->POWER = 0;
+ sdcp->sdio->CLKCR = 0;
+ sdcp->sdio->DCTRL = 0;
+ sdcp->sdio->DTIMER = 0;
+
+ /* DMA stream released.*/
+ dmaStreamFreeI(sdcp->dma);
+ sdcp->dma = NULL;
+
+ /* Clock deactivation.*/
+ rccDisableSDIO();
+ }
+}
+
+/**
+ * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start_clk(SDCDriver *sdcp) {
+
+ /* Initial clock setting: 400kHz, 1bit mode.*/
+ sdcp->sdio->CLKCR = STM32_SDIO_DIV_LS;
+ sdcp->sdio->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1;
+ sdcp->sdio->CLKCR |= SDIO_CLKCR_CLKEN;
+
+ /* Clock activation delay.*/
+ osalThreadSleep(OSAL_MS2I(STM32_SDC_CLOCK_ACTIVATION_DELAY));
+}
+
+/**
+ * @brief Sets the SDIO clock to data mode (25MHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] clk the clock mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) {
+
+#if STM32_SDC_SDIO_50MHZ
+ if (SDC_CLK_50MHz == clk) {
+ sdcp->sdio->CLKCR = (sdcp->sdio->CLKCR & 0xFFFFFF00U) | STM32_SDIO_DIV_HS
+ | SDIO_CLKCR_BYPASS;
+ }
+ else
+ sdcp->sdio->CLKCR = (sdcp->sdio->CLKCR & 0xFFFFFF00U) | STM32_SDIO_DIV_HS;
+#else
+ (void)clk;
+
+ sdcp->sdio->CLKCR = (sdcp->sdio->CLKCR & 0xFFFFFF00U) | STM32_SDIO_DIV_HS;
+#endif
+}
+
+/**
+ * @brief Stops the SDIO clock.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop_clk(SDCDriver *sdcp) {
+
+ sdcp->sdio->CLKCR = 0;
+ sdcp->sdio->POWER = 0;
+}
+
+/**
+ * @brief Switches the bus to 4 bits mode.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] mode bus mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
+ uint32_t clk = sdcp->sdio->CLKCR & ~SDIO_CLKCR_WIDBUS;
+
+ switch (mode) {
+ case SDC_MODE_1BIT:
+ sdcp->sdio->CLKCR = clk;
+ break;
+ case SDC_MODE_4BIT:
+ sdcp->sdio->CLKCR = clk | SDIO_CLKCR_WIDBUS_0;
+ break;
+ case SDC_MODE_8BIT:
+ sdcp->sdio->CLKCR = clk | SDIO_CLKCR_WIDBUS_1;
+ break;
+ }
+}
+
+/**
+ * @brief Sends an SDIO command with no response expected.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ *
+ * @notapi
+ */
+void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
+
+ sdcp->sdio->ARG = arg;
+ sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
+ while ((sdcp->sdio->STA & SDIO_STA_CMDSENT) == 0)
+ ;
+ sdcp->sdio->ICR = SDIO_ICR_CMDSENTC;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected.
+ * @note The CRC is not verified.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ sdcp->sdio->ARG = arg;
+ sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
+ while (((sta = sdcp->sdio->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdio->ICR = sta & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL);
+ if ((sta & (SDIO_STA_CTIMEOUT)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ *resp = sdcp->sdio->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ sdcp->sdio->ARG = arg;
+ sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
+ while (((sta = sdcp->sdio->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdio->ICR = sta & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL);
+ if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ *resp = sdcp->sdio->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Sends an SDIO command with a long response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (four words)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+
+ sdcp->sdio->ARG = arg;
+ sdcp->sdio->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 |
+ SDIO_CMD_CPSMEN;
+ while (((sta = sdcp->sdio->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdio->ICR = sta & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
+ SDIO_STA_CCRCFAIL);
+ if ((sta & (STM32_SDIO_STA_ERROR_MASK)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ /* Save bytes in reverse order because MSB in response comes first.*/
+ *resp++ = sdcp->sdio->RESP4;
+ *resp++ = sdcp->sdio->RESP3;
+ *resp++ = sdcp->sdio->RESP2;
+ *resp = sdcp->sdio->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Reads special registers using data bus.
+ * @details Needs only during card detection procedure.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] buf pointer to the read buffer
+ * @param[in] bytes number of bytes to read
+ * @param[in] cmd card command
+ * @param[in] arg argument for command
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
+ uint8_t cmd, uint32_t arg) {
+ uint32_t resp[1];
+
+ if (sdc_lld_prepare_read_bytes(sdcp, buf, bytes))
+ goto error;
+
+ if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp)
+ || MMCSD_R1_ERROR(resp[0]))
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, 1, resp))
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, 1, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] blocks number of blocks to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks) {
+ uint32_t resp[1];
+
+ osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
+
+ sdcp->sdio->DTIMER = STM32_SDC_READ_TIMEOUT;
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaStreamSetMemory0(sdcp->dma, buf);
+ dmaStreamSetTransactionSize(sdcp->dma,
+ (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
+ dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
+ dmaStreamEnable(sdcp->dma);
+
+ /* Setting up data transfer.*/
+ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
+ sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE |
+ SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_STBITERRIE |
+ SDIO_MASK_RXOVERRIE |
+ SDIO_MASK_DATAENDIE;
+ sdcp->sdio->DLEN = blocks * MMCSD_BLOCK_SIZE;
+
+ /* Transaction starts just after DTEN bit setting.*/
+ sdcp->sdio->DCTRL = SDIO_DCTRL_DTDIR |
+ SDIO_DCTRL_DBLOCKSIZE_3 |
+ SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == true)
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, blocks, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks) {
+ uint32_t resp[1];
+
+ osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
+
+ sdcp->sdio->DTIMER = STM32_SDC_WRITE_TIMEOUT;
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaStreamSetMemory0(sdcp->dma, buf);
+ dmaStreamSetTransactionSize(sdcp->dma,
+ (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
+ dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P);
+ dmaStreamEnable(sdcp->dma);
+
+ /* Setting up data transfer.*/
+ sdcp->sdio->ICR = STM32_SDIO_ICR_ALL_FLAGS;
+ sdcp->sdio->MASK = SDIO_MASK_DCRCFAILIE |
+ SDIO_MASK_DTIMEOUTIE |
+ SDIO_MASK_STBITERRIE |
+ SDIO_MASK_TXUNDERRIE |
+ SDIO_MASK_DATAENDIE;
+ sdcp->sdio->DLEN = blocks * MMCSD_BLOCK_SIZE;
+
+ /* Talk to card what we want from it.*/
+ if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == true)
+ goto error;
+
+ /* Transaction starts just after DTEN bit setting.*/
+ sdcp->sdio->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 |
+ SDIO_DCTRL_DBLOCKSIZE_0 |
+ SDIO_DCTRL_DMAEN |
+ SDIO_DCTRL_DTEN;
+
+ if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, blocks, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] blocks number of blocks to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks) {
+
+#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < blocks; i++) {
+ if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1))
+ return HAL_FAILED;
+ memcpy(buf, u.buf, MMCSD_BLOCK_SIZE);
+ buf += MMCSD_BLOCK_SIZE;
+ startblk++;
+ }
+ return HAL_SUCCESS;
+ }
+#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
+#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ return sdc_lld_read_aligned(sdcp, startblk, buf, blocks);
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] blocks number of blocks to write
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks) {
+
+#if STM32_SDC_SDIO_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < blocks; i++) {
+ memcpy(u.buf, buf, MMCSD_BLOCK_SIZE);
+ buf += MMCSD_BLOCK_SIZE;
+ if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1))
+ return HAL_FAILED;
+ startblk++;
+ }
+ return HAL_SUCCESS;
+ }
+#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
+#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
+}
+
+/**
+ * @brief Waits for card idle condition.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS the operation succeeded.
+ * @retval HAL_FAILED the operation failed.
+ *
+ * @api
+ */
+bool sdc_lld_sync(SDCDriver *sdcp) {
+
+ /* CHTODO: Implement.*/
+ (void)sdcp;
+ return HAL_SUCCESS;
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.h b/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.h
index 4f0a430739..f20beb4e44 100644
--- a/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.h
+++ b/os/hal/ports/STM32/LLD/SDIOv1/hal_sdc_lld.h
@@ -1,353 +1,353 @@
-/*
- 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 SDIOv1/hal_sdc_lld.h
- * @brief STM32 SDC subsystem low level driver header.
- *
- * @addtogroup SDC
- * @{
- */
-
-#ifndef HAL_SDC_LLD_H
-#define HAL_SDC_LLD_H
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*
- * The following definitions are missing from some implementations, fixing
- * as zeroed masks.
- */
-#if !defined(SDIO_STA_STBITERR)
-#define SDIO_STA_STBITERR 0
-#endif
-
-#if !defined(SDIO_ICR_STBITERRC)
-#define SDIO_ICR_STBITERRC 0
-#endif
-
-#if !defined(SDIO_ICR_CEATAENDC)
-#define SDIO_ICR_CEATAENDC 0
-#endif
-
-#if !defined(SDIO_MASK_STBITERRIE)
-#define SDIO_MASK_STBITERRIE 0
-#endif
-
-/**
- * @brief Value to clear all interrupts flag at once.
- */
-#define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \
- SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \
- SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \
- SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \
- SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \
- SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \
- SDIO_ICR_CEATAENDC)
-
-/**
- * @brief Mask of error flags in STA register.
- */
-#define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \
- SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \
- SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SDIO DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_SDC_SDIO_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDIO_DMA_PRIORITY 3
-#endif
-
-/**
- * @brief SDIO interrupt priority level setting.
- */
-#if !defined(STM32_SDC_SDIO_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDIO_IRQ_PRIORITY 9
-#endif
-
-/**
- * @brief Enable clock bypass.
- * @note Allow clock speed up to 50 Mhz.
- */
-#if !defined(STM32_SDC_SDIO_50MHZ) || defined(__DOXYGEN__)
-#define STM32_SDC_SDIO_50MHZ FALSE
-#endif
-
-/**
- * @brief Write timeout in milliseconds.
- */
-#if !defined(STM32_SDC_WRITE_TIMEOUT_MS) || defined(__DOXYGEN__)
-#define STM32_SDC_WRITE_TIMEOUT_MS 1000
-#endif
-
-/**
- * @brief Read timeout in milliseconds.
- */
-#if !defined(STM32_SDC_READ_TIMEOUT_MS) || defined(__DOXYGEN__)
-#define STM32_SDC_READ_TIMEOUT_MS 1000
-#endif
-
-/**
- * @brief Card clock activation delay in milliseconds.
- */
-#if !defined(STM32_SDC_CLOCK_ACTIVATION_DELAY) || defined(__DOXYGEN__)
-#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10
-#endif
-
-/**
- * @brief Support for unaligned transfers.
- * @note Unaligned transfers are much slower.
- */
-#if !defined(STM32_SDC_SDIO_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !STM32_HAS_SDIO
-#error "SDIO not present in the selected device"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDIO_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDIO"
-#endif
-
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDIO_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDIO"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if !defined(STM32_SDC_SDIO_DMA_STREAM)
-#error "SDIO DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if !STM32_DMA_IS_VALID_ID(STM32_SDC_SDIO_DMA_STREAM, STM32_SDC_SDIO_DMA_MSK)
-#error "invalid DMA stream associated to SDIO"
-#endif
-#endif /* STM32_ADVANCED_DMA */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*
- * SDIO clock divider.
- */
-#if (defined(STM32F4XX) || defined(STM32F2XX))
-#define STM32_SDIO_DIV_HS 0
-#define STM32_SDIO_DIV_LS 120
-
-#elif STM32_HCLK > 48000000
-#define STM32_SDIO_DIV_HS 1
-#define STM32_SDIO_DIV_LS 178
-#else
-
-#define STM32_SDIO_DIV_HS 0
-#define STM32_SDIO_DIV_LS 118
-#endif
-
-/**
- * @brief SDIO data timeouts in SDIO clock cycles.
- */
-#if (defined(STM32F4XX) || defined(STM32F2XX))
-#if !STM32_CLOCK48_REQUIRED
-#error "SDIO requires STM32_CLOCK48_REQUIRED to be enabled"
-#endif
-
-#if STM32_PLL48CLK != 48000000
-#error "invalid STM32_PLL48CLK clock value"
-#endif
-
-#define STM32_SDC_WRITE_TIMEOUT \
- (((STM32_PLL48CLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
- STM32_SDC_WRITE_TIMEOUT_MS)
-#define STM32_SDC_READ_TIMEOUT \
- (((STM32_PLL48CLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
- STM32_SDC_READ_TIMEOUT_MS)
-
-#else /* !(defined(STM32F4XX) || defined(STM32F2XX)) */
-
-#define STM32_SDC_WRITE_TIMEOUT \
- (((STM32_HCLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
- STM32_SDC_WRITE_TIMEOUT_MS)
-#define STM32_SDC_READ_TIMEOUT \
- (((STM32_HCLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
- STM32_SDC_READ_TIMEOUT_MS)
-
-#endif /* !(defined(STM32F4XX) || defined(STM32F2XX)) */
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of card flags.
- */
-typedef uint32_t sdcmode_t;
-
-/**
- * @brief SDC Driver condition flags type.
- */
-typedef uint32_t sdcflags_t;
-
-/**
- * @brief Type of a structure representing an SDC driver.
- */
-typedef struct SDCDriver SDCDriver;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Bus width.
- */
- sdcbusmode_t bus_width;
- /* End of the mandatory fields.*/
-} SDCConfig;
-
-/**
- * @brief @p SDCDriver specific methods.
- */
-#define _sdc_driver_methods \
- _mmcsd_block_device_methods
-
-/**
- * @extends MMCSDBlockDeviceVMT
- *
- * @brief @p SDCDriver virtual methods table.
- */
-struct SDCDriverVMT {
- _sdc_driver_methods
-};
-
-/**
- * @brief Structure representing an SDC driver.
- */
-struct SDCDriver {
- /**
- * @brief Virtual Methods Table.
- */
- const struct SDCDriverVMT *vmt;
- _mmcsd_block_device_data
- /**
- * @brief Current configuration data.
- */
- const SDCConfig *config;
- /**
- * @brief Various flags regarding the mounted card.
- */
- sdcmode_t cardmode;
- /**
- * @brief Errors flags.
- */
- sdcflags_t errors;
- /**
- * @brief Card RCA.
- */
- uint32_t rca;
- /* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion IRQ.
- */
- thread_reference_t thread;
- /**
- * @brief DMA mode bit mask.
- */
- uint32_t dmamode;
- /**
- * @brief Transmit DMA channel.
- */
- const stm32_dma_stream_t *dma;
- /**
- * @brief Pointer to the SDIO registers block.
- * @note Needed for debugging aid.
- */
- SDIO_TypeDef *sdio;
- /**
- * @brief Buffer for internal operations.
- */
- uint8_t buf[MMCSD_BLOCK_SIZE];
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if !defined(__DOXYGEN__)
-extern SDCDriver SDCD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void sdc_lld_init(void);
- void sdc_lld_start(SDCDriver *sdcp);
- void sdc_lld_stop(SDCDriver *sdcp);
- void sdc_lld_start_clk(SDCDriver *sdcp);
- void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk);
- void sdc_lld_stop_clk(SDCDriver *sdcp);
- void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
- void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
- bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
- uint8_t cmd, uint32_t argument);
- bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks);
- bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks);
- bool sdc_lld_sync(SDCDriver *sdcp);
- bool sdc_lld_is_card_inserted(SDCDriver *sdcp);
- bool sdc_lld_is_write_protected(SDCDriver *sdcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SDC */
-
-#endif /* HAL_SDC_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 SDIOv1/hal_sdc_lld.h
+ * @brief STM32 SDC subsystem low level driver header.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef HAL_SDC_LLD_H
+#define HAL_SDC_LLD_H
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*
+ * The following definitions are missing from some implementations, fixing
+ * as zeroed masks.
+ */
+#if !defined(SDIO_STA_STBITERR)
+#define SDIO_STA_STBITERR 0
+#endif
+
+#if !defined(SDIO_ICR_STBITERRC)
+#define SDIO_ICR_STBITERRC 0
+#endif
+
+#if !defined(SDIO_ICR_CEATAENDC)
+#define SDIO_ICR_CEATAENDC 0
+#endif
+
+#if !defined(SDIO_MASK_STBITERRIE)
+#define SDIO_MASK_STBITERRIE 0
+#endif
+
+/**
+ * @brief Value to clear all interrupts flag at once.
+ */
+#define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \
+ SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \
+ SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \
+ SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \
+ SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \
+ SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \
+ SDIO_ICR_CEATAENDC)
+
+/**
+ * @brief Mask of error flags in STA register.
+ */
+#define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \
+ SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \
+ SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SDIO DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_SDC_SDIO_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_DMA_PRIORITY 3
+#endif
+
+/**
+ * @brief SDIO interrupt priority level setting.
+ */
+#if !defined(STM32_SDC_SDIO_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_IRQ_PRIORITY 9
+#endif
+
+/**
+ * @brief Enable clock bypass.
+ * @note Allow clock speed up to 50 Mhz.
+ */
+#if !defined(STM32_SDC_SDIO_50MHZ) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_50MHZ FALSE
+#endif
+
+/**
+ * @brief Write timeout in milliseconds.
+ */
+#if !defined(STM32_SDC_WRITE_TIMEOUT_MS) || defined(__DOXYGEN__)
+#define STM32_SDC_WRITE_TIMEOUT_MS 1000
+#endif
+
+/**
+ * @brief Read timeout in milliseconds.
+ */
+#if !defined(STM32_SDC_READ_TIMEOUT_MS) || defined(__DOXYGEN__)
+#define STM32_SDC_READ_TIMEOUT_MS 1000
+#endif
+
+/**
+ * @brief Card clock activation delay in milliseconds.
+ */
+#if !defined(STM32_SDC_CLOCK_ACTIVATION_DELAY) || defined(__DOXYGEN__)
+#define STM32_SDC_CLOCK_ACTIVATION_DELAY 10
+#endif
+
+/**
+ * @brief Support for unaligned transfers.
+ * @note Unaligned transfers are much slower.
+ */
+#if !defined(STM32_SDC_SDIO_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !STM32_HAS_SDIO
+#error "SDIO not present in the selected device"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDIO_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDIO"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDIO_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDIO"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if !defined(STM32_SDC_SDIO_DMA_STREAM)
+#error "SDIO DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if !STM32_DMA_IS_VALID_ID(STM32_SDC_SDIO_DMA_STREAM, STM32_SDC_SDIO_DMA_MSK)
+#error "invalid DMA stream associated to SDIO"
+#endif
+#endif /* STM32_ADVANCED_DMA */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*
+ * SDIO clock divider.
+ */
+#if (defined(STM32F4XX) || defined(STM32F2XX))
+#define STM32_SDIO_DIV_HS 0
+#define STM32_SDIO_DIV_LS 120
+
+#elif STM32_HCLK > 48000000
+#define STM32_SDIO_DIV_HS 1
+#define STM32_SDIO_DIV_LS 178
+#else
+
+#define STM32_SDIO_DIV_HS 0
+#define STM32_SDIO_DIV_LS 118
+#endif
+
+/**
+ * @brief SDIO data timeouts in SDIO clock cycles.
+ */
+#if (defined(STM32F4XX) || defined(STM32F2XX))
+#if !STM32_CLOCK48_REQUIRED
+#error "SDIO requires STM32_CLOCK48_REQUIRED to be enabled"
+#endif
+
+#if STM32_PLL48CLK != 48000000
+#error "invalid STM32_PLL48CLK clock value"
+#endif
+
+#define STM32_SDC_WRITE_TIMEOUT \
+ (((STM32_PLL48CLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
+ STM32_SDC_WRITE_TIMEOUT_MS)
+#define STM32_SDC_READ_TIMEOUT \
+ (((STM32_PLL48CLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
+ STM32_SDC_READ_TIMEOUT_MS)
+
+#else /* !(defined(STM32F4XX) || defined(STM32F2XX)) */
+
+#define STM32_SDC_WRITE_TIMEOUT \
+ (((STM32_HCLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
+ STM32_SDC_WRITE_TIMEOUT_MS)
+#define STM32_SDC_READ_TIMEOUT \
+ (((STM32_HCLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \
+ STM32_SDC_READ_TIMEOUT_MS)
+
+#endif /* !(defined(STM32F4XX) || defined(STM32F2XX)) */
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of card flags.
+ */
+typedef uint32_t sdcmode_t;
+
+/**
+ * @brief SDC Driver condition flags type.
+ */
+typedef uint32_t sdcflags_t;
+
+/**
+ * @brief Type of a structure representing an SDC driver.
+ */
+typedef struct SDCDriver SDCDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Bus width.
+ */
+ sdcbusmode_t bus_width;
+ /* End of the mandatory fields.*/
+} SDCConfig;
+
+/**
+ * @brief @p SDCDriver specific methods.
+ */
+#define _sdc_driver_methods \
+ _mmcsd_block_device_methods
+
+/**
+ * @extends MMCSDBlockDeviceVMT
+ *
+ * @brief @p SDCDriver virtual methods table.
+ */
+struct SDCDriverVMT {
+ _sdc_driver_methods
+};
+
+/**
+ * @brief Structure representing an SDC driver.
+ */
+struct SDCDriver {
+ /**
+ * @brief Virtual Methods Table.
+ */
+ const struct SDCDriverVMT *vmt;
+ _mmcsd_block_device_data
+ /**
+ * @brief Current configuration data.
+ */
+ const SDCConfig *config;
+ /**
+ * @brief Various flags regarding the mounted card.
+ */
+ sdcmode_t cardmode;
+ /**
+ * @brief Errors flags.
+ */
+ sdcflags_t errors;
+ /**
+ * @brief Card RCA.
+ */
+ uint32_t rca;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion IRQ.
+ */
+ thread_reference_t thread;
+ /**
+ * @brief DMA mode bit mask.
+ */
+ uint32_t dmamode;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const stm32_dma_stream_t *dma;
+ /**
+ * @brief Pointer to the SDIO registers block.
+ * @note Needed for debugging aid.
+ */
+ SDIO_TypeDef *sdio;
+ /**
+ * @brief Buffer for internal operations.
+ */
+ uint8_t buf[MMCSD_BLOCK_SIZE];
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern SDCDriver SDCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdc_lld_init(void);
+ void sdc_lld_start(SDCDriver *sdcp);
+ void sdc_lld_stop(SDCDriver *sdcp);
+ void sdc_lld_start_clk(SDCDriver *sdcp);
+ void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk);
+ void sdc_lld_stop_clk(SDCDriver *sdcp);
+ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
+ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
+ bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
+ uint8_t cmd, uint32_t argument);
+ bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks);
+ bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks);
+ bool sdc_lld_sync(SDCDriver *sdcp);
+ bool sdc_lld_is_card_inserted(SDCDriver *sdcp);
+ bool sdc_lld_is_write_protected(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* HAL_SDC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk b/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
index 7edbc24389..7f0658c698 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1
diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
index 1544981f7a..12c20d9db2 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
+++ b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.c
@@ -1,981 +1,981 @@
-/*
- 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 SDMMCv1/hal_sdc_lld.c
- * @brief STM32 SDC subsystem low level driver source.
- *
- * @addtogroup SDC
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define SDMMC_ICR_ALL_FLAGS \
- (SDMMC_ICR_CCRCFAILC | SDMMC_ICR_DCRCFAILC | \
- SDMMC_ICR_CTIMEOUTC | SDMMC_ICR_DTIMEOUTC | \
- SDMMC_ICR_TXUNDERRC | SDMMC_ICR_RXOVERRC | \
- SDMMC_ICR_CMDRENDC | SDMMC_ICR_CMDSENTC | \
- SDMMC_ICR_DATAENDC | SDMMC_ICR_DBCKENDC | \
- SDMMC_ICR_SDIOITC)
-
-#define SDMMC_STA_ERROR_MASK \
- (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | \
- SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | \
- SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR)
-
-#define SDMMC_CLKDIV_HS (2 - 2)
-#define SDMMC_CLKDIV_LS (120 - 2)
-
-#define SDMMC1_WRITE_TIMEOUT \
- (((STM32_SDMMC1CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
- STM32_SDC_SDMMC_WRITE_TIMEOUT)
-#define SDMMC1_READ_TIMEOUT \
- (((STM32_SDMMC1CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
- STM32_SDC_SDMMC_READ_TIMEOUT)
-
-#define SDMMC2_WRITE_TIMEOUT \
- (((STM32_SDMMC2CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
- STM32_SDC_SDMMC_WRITE_TIMEOUT)
-#define SDMMC2_READ_TIMEOUT \
- (((STM32_SDMMC2CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
- STM32_SDC_SDMMC_READ_TIMEOUT)
-
-#define SDMMC1_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC1_DMA_STREAM, \
- STM32_SDC_SDMMC1_DMA_CHN)
-
-#define SDMMC2_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC2_DMA_STREAM, \
- STM32_SDC_SDMMC2_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SDCD1 driver identifier.*/
-#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
-SDCDriver SDCD1;
-#endif
-
-/** @brief SDCD2 driver identifier.*/
-#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
-SDCDriver SDCD2;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief SDIO default configuration.
- */
-static const SDCConfig sdc_default_cfg = {
- SDC_MODE_4BIT
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Prepares to handle read transaction.
- * @details Designed for read special registers from card.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[out] buf pointer to the read buffer
- * @param[in] bytes number of bytes to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp,
- uint8_t *buf, uint32_t bytes) {
- osalDbgCheck(bytes < 0x1000000);
-
- sdcp->sdmmc->DTIMER = sdcp->rtmo;
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Prepares the DMA channel for writing.*/
- dmaStreamSetMemory0(sdcp->dma, buf);
- dmaStreamSetTransactionSize(sdcp->dma, bytes / sizeof (uint32_t));
- dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
- dmaStreamEnable(sdcp->dma);
-
- /* Setting up data transfer.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
- SDMMC_MASK_DTIMEOUTIE |
- SDMMC_MASK_RXOVERRIE |
- SDMMC_MASK_DATAENDIE;
- sdcp->sdmmc->DLEN = bytes;
-
- /* Transaction starts just after DTEN bit setting.*/
- sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
- SDMMC_DCTRL_DTMODE | /* Multibyte data transfer.*/
- SDMMC_DCTRL_DMAEN |
- SDMMC_DCTRL_DTEN;
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Prepares card to handle read transaction.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[in] n number of blocks to read
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
- uint32_t n, uint32_t *resp) {
-
- /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
- have not HC card than we must convert address from blocks to bytes.*/
- if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
- startblk *= MMCSD_BLOCK_SIZE;
-
- if (n > 1) {
- /* Send read multiple blocks command to card.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
- else {
- /* Send read single block command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Prepares card to handle write transaction.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[in] n number of blocks to write
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
- uint32_t n, uint32_t *resp) {
-
- /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
- have not HC card than we must convert address from blocks to bytes.*/
- if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
- startblk *= MMCSD_BLOCK_SIZE;
-
- if (n > 1) {
- /* Write multiple blocks command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
- else {
- /* Write single block command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Wait end of data transaction and performs finalizations.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] n number of blocks in transaction
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- */
-static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
- uint32_t *resp) {
-
- /* Note the mask is checked before going to sleep because the interrupt
- may have occurred before reaching the critical zone.*/
- osalSysLock();
- if (sdcp->sdmmc->MASK != 0)
- osalThreadSuspendS(&sdcp->thread);
- if ((sdcp->sdmmc->STA & SDMMC_STA_DATAEND) == 0) {
- osalSysUnlock();
- return HAL_FAILED;
- }
-
- /* Waits for transfer completion at DMA level, then the stream is
- disabled and cleared.*/
- dmaWaitCompletion(sdcp->dma);
-
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->DCTRL = 0;
- osalSysUnlock();
-
- /* Finalize transaction.*/
- if (n > 1)
- return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Gets SDC errors.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] sta value of the STA register
- *
- * @notapi
- */
-static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
- uint32_t errors = SDC_NO_ERROR;
-
- if (sta & SDMMC_STA_CCRCFAIL)
- errors |= SDC_CMD_CRC_ERROR;
- if (sta & SDMMC_STA_DCRCFAIL)
- errors |= SDC_DATA_CRC_ERROR;
- if (sta & SDMMC_STA_CTIMEOUT)
- errors |= SDC_COMMAND_TIMEOUT;
- if (sta & SDMMC_STA_DTIMEOUT)
- errors |= SDC_DATA_TIMEOUT;
- if (sta & SDMMC_STA_TXUNDERR)
- errors |= SDC_TX_UNDERRUN;
- if (sta & SDMMC_STA_RXOVERR)
- errors |= SDC_RX_OVERRUN;
-/* if (sta & SDMMC_STA_STBITERR)
- errors |= SDC_STARTBIT_ERROR;*/
-
- sdcp->errors |= errors;
-}
-
-/**
- * @brief Performs clean transaction stopping in case of errors.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] n number of blocks in transaction
- * @param[in] resp pointer to the response buffer
- *
- * @notapi
- */
-static void sdc_lld_error_cleanup(SDCDriver *sdcp,
- uint32_t n,
- uint32_t *resp) {
- uint32_t sta = sdcp->sdmmc->STA;
-
- dmaStreamDisable(sdcp->dma);
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = 0;
- sdcp->sdmmc->DCTRL = 0;
- sdc_lld_collect_errors(sdcp, sta);
-
- if (n > 1)
- sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/**
- * @brief SDMMC1 IRQ handler.
- * @details It just wakes transaction thread, errors handling is performed in
- * there.
- *
- * @isr
- */
-#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
-OSAL_IRQ_HANDLER(STM32_SDMMC1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- osalSysLockFromISR();
-
- /* Disables the source but the status flags are not reset because the
- read/write functions needs to check them.*/
- SDMMC1->MASK = 0;
-
- osalThreadResumeI(&SDCD1.thread, MSG_OK);
-
- osalSysUnlockFromISR();
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/**
- * @brief SDMMC2 IRQ handler.
- * @details It just wakes transaction thread, errors handling is performed in
- * there.
- *
- * @isr
- */
-#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
-OSAL_IRQ_HANDLER(STM32_SDMMC2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- osalSysLockFromISR();
-
- /* Disables the source but the status flags are not reset because the
- read/write functions needs to check them.*/
- SDMMC2->MASK = 0;
-
- osalThreadResumeI(&SDCD2.thread, MSG_OK);
-
- osalSysUnlockFromISR();
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SDC driver initialization.
- *
- * @notapi
- */
-void sdc_lld_init(void) {
-
-#if STM32_SDC_USE_SDMMC1
- sdcObjectInit(&SDCD1);
- SDCD1.thread = NULL;
- SDCD1.rtmo = SDMMC1_READ_TIMEOUT;
- SDCD1.wtmo = SDMMC1_WRITE_TIMEOUT;
- SDCD1.dma = NULL;
- SDCD1.sdmmc = SDMMC1;
- nvicEnableVector(STM32_SDMMC1_NUMBER, STM32_SDC_SDMMC1_IRQ_PRIORITY);
-#endif
-
-#if STM32_SDC_USE_SDMMC2
- sdcObjectInit(&SDCD2);
- SDCD2.thread = NULL;
- SDCD2.rtmo = SDMMC2_READ_TIMEOUT;
- SDCD2.wtmo = SDMMC2_WRITE_TIMEOUT;
- SDCD2.dma = NULL;
- SDCD2.sdmmc = SDMMC2;
- nvicEnableVector(STM32_SDMMC2_NUMBER, STM32_SDC_SDMMC2_IRQ_PRIORITY);
-#endif
-}
-
-/**
- * @brief Configures and activates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start(SDCDriver *sdcp) {
-
- /* Checking configuration, using a default if NULL has been passed.*/
- if (sdcp->config == NULL) {
- sdcp->config = &sdc_default_cfg;
- }
-
- sdcp->dmamode = STM32_DMA_CR_PSIZE_WORD |
- STM32_DMA_CR_MSIZE_WORD |
- STM32_DMA_CR_MINC;
-
-#if STM32_DMA_ADVANCED
- sdcp->dmamode |= STM32_DMA_CR_PFCTRL |
- STM32_DMA_CR_PBURST_INCR4 |
- STM32_DMA_CR_MBURST_INCR4;
-#endif
-
- /* If in stopped state then clocks are enabled and DMA initialized.*/
- if (sdcp->state == BLK_STOP) {
-#if STM32_SDC_USE_SDMMC1
- if (&SDCD1 == sdcp) {
- sdcp->dma = dmaStreamAllocI(STM32_SDC_SDMMC1_DMA_STREAM,
- STM32_SDC_SDMMC1_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(sdcp->dma != NULL, "unable to allocate stream");
-
- sdcp->dmamode |= STM32_DMA_CR_CHSEL(SDMMC1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SDC_SDMMC1_DMA_PRIORITY);
- dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
-#if STM32_DMA_ADVANCED
- dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS |
- STM32_DMA_FCR_FTH_FULL);
-#endif
- rccEnableSDMMC1(true);
- }
-#endif /* STM32_SDC_USE_SDMMC1 */
-
-#if STM32_SDC_USE_SDMMC2
- if (&SDCD2 == sdcp) {
- sdcp->dma = dmaStreamAllocI(STM32_SDC_SDMMC2_DMA_STREAM,
- STM32_SDC_SDMMC2_IRQ_PRIORITY,
- NULL,
- NULL);
- osalDbgAssert(sdcp->dma != NULL, "unable to allocate stream");
-
- sdcp->dmamode |= STM32_DMA_CR_CHSEL(SDMMC2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SDC_SDMMC2_DMA_PRIORITY);
- dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
-#if STM32_DMA_ADVANCED
- dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS |
- STM32_DMA_FCR_FTH_FULL);
-#endif
- rccEnableSDMMC2(true);
- }
-#endif /* STM32_SDC_USE_SDMMC2 */
- }
-
- /* Configuration, card clock is initially stopped.*/
- sdcp->sdmmc->POWER = 0;
- sdcp->sdmmc->CLKCR = 0;
- sdcp->sdmmc->DCTRL = 0;
- sdcp->sdmmc->DTIMER = 0;
-}
-
-/**
- * @brief Deactivates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop(SDCDriver *sdcp) {
-
- if (sdcp->state != BLK_STOP) {
-
- /* SDIO deactivation.*/
- sdcp->sdmmc->POWER = 0;
- sdcp->sdmmc->CLKCR = 0;
- sdcp->sdmmc->DCTRL = 0;
- sdcp->sdmmc->DTIMER = 0;
-
- /* DMA stream released.*/
- dmaStreamFreeI(sdcp->dma);
- sdcp->dma = NULL;
-
- /* Clock deactivation.*/
-#if STM32_SDC_USE_SDMMC1
- if (&SDCD1 == sdcp) {
- rccDisableSDMMC1();
- }
-#endif
-
-#if STM32_SDC_USE_SDMMC2
- if (&SDCD2 == sdcp) {
- rccDisableSDMMC2();
- }
-#endif
- }
-}
-
-/**
- * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start_clk(SDCDriver *sdcp) {
-
- /* Initial clock setting: 400kHz, 1bit mode.*/
- sdcp->sdmmc->CLKCR = SDMMC_CLKDIV_LS;
- sdcp->sdmmc->POWER |= SDMMC_POWER_PWRCTRL_0 | SDMMC_POWER_PWRCTRL_1;
- sdcp->sdmmc->CLKCR |= SDMMC_CLKCR_CLKEN;
-
- /* Clock activation delay.*/
- osalThreadSleep(OSAL_MS2I(STM32_SDC_SDMMC_CLOCK_DELAY));
-}
-
-/**
- * @brief Sets the SDIO clock to data mode (25/50 MHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] clk the clock mode
- *
- * @notapi
- */
-void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) {
-
-#if STM32_SDC_SDMMC_50MHZ
- if (SDC_CLK_50MHz == clk) {
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
-#if STM32_SDC_SDMMC_PWRSAV
- SDMMC_CLKDIV_HS | SDMMC_CLKCR_BYPASS |
- SDMMC_CLKCR_PWRSAV;
-#else
- SDMMC_CLKDIV_HS | SDMMC_CLKCR_BYPASS;
-#endif
- }
- else {
-#if STM32_SDC_SDMMC_PWRSAV
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS |
- SDMMC_CLKCR_PWRSAV;
-#else
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS;
-#endif
- }
-#else
- (void)clk;
-
-#if STM32_SDC_SDMMC_PWRSAV
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS |
- SDMMC_CLKCR_PWRSAV;
-#else
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS;
-#endif
-#endif
-}
-
-/**
- * @brief Stops the SDIO clock.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop_clk(SDCDriver *sdcp) {
-
- sdcp->sdmmc->CLKCR = 0;
- sdcp->sdmmc->POWER = 0;
-}
-
-/**
- * @brief Switches the bus to 1, 4 or 8 bits mode.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] mode bus mode
- *
- * @notapi
- */
-void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
- uint32_t clk = sdcp->sdmmc->CLKCR & ~SDMMC_CLKCR_WIDBUS;
-
- switch (mode) {
- case SDC_MODE_1BIT:
- sdcp->sdmmc->CLKCR = clk;
- break;
- case SDC_MODE_4BIT:
- sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_0;
- break;
- case SDC_MODE_8BIT:
- sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_1;
- break;
- }
-}
-
-/**
- * @brief Sends an SDIO command with no response expected.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- *
- * @notapi
- */
-void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_CPSMEN;
- while ((sdcp->sdmmc->STA & SDMMC_STA_CMDSENT) == 0)
- ;
- sdcp->sdmmc->ICR = SDMMC_ICR_CMDSENTC;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected.
- * @note The CRC is not verified.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
- while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL);
- if ((sta & (SDMMC_STA_CTIMEOUT)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- *resp = sdcp->sdmmc->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
- while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL);
- if ((sta & (SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- *resp = sdcp->sdmmc->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Sends an SDIO command with a long response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (four words)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- (void)sdcp;
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_WAITRESP_1 |
- SDMMC_CMD_CPSMEN;
- while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL);
- if ((sta & (SDMMC_STA_ERROR_MASK)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- /* Save bytes in reverse order because MSB in response comes first.*/
- *resp++ = sdcp->sdmmc->RESP4;
- *resp++ = sdcp->sdmmc->RESP3;
- *resp++ = sdcp->sdmmc->RESP2;
- *resp = sdcp->sdmmc->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Reads special registers using data bus.
- * @details Needs only during card detection procedure.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[out] buf pointer to the read buffer
- * @param[in] bytes number of bytes to read
- * @param[in] cmd card command
- * @param[in] arg argument for command
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
- uint8_t cmd, uint32_t arg) {
- uint32_t resp[1];
-
- if (sdc_lld_prepare_read_bytes(sdcp, buf, bytes))
- goto error;
-
- if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp)
- || MMCSD_R1_ERROR(resp[0]))
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, 1, resp))
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, 1, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Reads one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer
- * @param[in] blocks number of blocks to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks) {
- uint32_t resp[1];
-
- osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
-
- sdcp->sdmmc->DTIMER = sdcp->rtmo;
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Prepares the DMA channel for writing.*/
- dmaStreamSetMemory0(sdcp->dma, buf);
- dmaStreamSetTransactionSize(sdcp->dma,
- (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
- dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
- dmaStreamEnable(sdcp->dma);
-
- /* Setting up data transfer.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
- SDMMC_MASK_DTIMEOUTIE |
- SDMMC_MASK_RXOVERRIE |
- SDMMC_MASK_DATAENDIE;
- sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
-
- /* Transaction starts just after DTEN bit setting.*/
- sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
- SDMMC_DCTRL_DBLOCKSIZE_3 |
- SDMMC_DCTRL_DBLOCKSIZE_0 |
- SDMMC_DCTRL_DMAEN |
- SDMMC_DCTRL_DTEN;
-
- if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == true)
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, blocks, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] n number of blocks to write
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks) {
- uint32_t resp[1];
-
- osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
-
- sdcp->sdmmc->DTIMER = sdcp->wtmo;
-
- /* Checks for errors and waits for the card to be ready for writing.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Prepares the DMA channel for writing.*/
- dmaStreamSetMemory0(sdcp->dma, buf);
- dmaStreamSetTransactionSize(sdcp->dma,
- (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
- dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P);
- dmaStreamEnable(sdcp->dma);
-
- /* Setting up data transfer.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
- SDMMC_MASK_DTIMEOUTIE |
- SDMMC_MASK_TXUNDERRIE |
- SDMMC_MASK_DATAENDIE;
- sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
-
- /* Talk to card what we want from it.*/
- if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == true)
- goto error;
-
- /* Transaction starts just after DTEN bit setting.*/
- sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DBLOCKSIZE_3 |
- SDMMC_DCTRL_DBLOCKSIZE_0 |
- SDMMC_DCTRL_DMAEN |
- SDMMC_DCTRL_DTEN;
-
- if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, blocks, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Reads one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer
- * @param[in] blocks number of blocks to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks) {
-
-#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < blocks; i++) {
- if (sdc_lld_read_aligned(sdcp, startblk, sdcp->buf, 1))
- return HAL_FAILED;
- memcpy(buf, sdcp->buf, MMCSD_BLOCK_SIZE);
- buf += MMCSD_BLOCK_SIZE;
- startblk++;
- }
- return HAL_SUCCESS;
- }
-#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
-#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- return sdc_lld_read_aligned(sdcp, startblk, buf, blocks);
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] blocks number of blocks to write
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks) {
-
-#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < blocks; i++) {
- memcpy(sdcp->buf, buf, MMCSD_BLOCK_SIZE);
- buf += MMCSD_BLOCK_SIZE;
- if (sdc_lld_write_aligned(sdcp, startblk, sdcp->buf, 1))
- return HAL_FAILED;
- startblk++;
- }
- return HAL_SUCCESS;
- }
-#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
-#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
-}
-
-/**
- * @brief Waits for card idle condition.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @return The operation status.
- * @retval HAL_SUCCESS the operation succeeded.
- * @retval HAL_FAILED the operation failed.
- *
- * @api
- */
-bool sdc_lld_sync(SDCDriver *sdcp) {
-
- /* CHTODO: Implement.*/
- (void)sdcp;
- return HAL_SUCCESS;
-}
-
-#endif /* HAL_USE_SDC */
-
-/** @} */
+/*
+ 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 SDMMCv1/hal_sdc_lld.c
+ * @brief STM32 SDC subsystem low level driver source.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define SDMMC_ICR_ALL_FLAGS \
+ (SDMMC_ICR_CCRCFAILC | SDMMC_ICR_DCRCFAILC | \
+ SDMMC_ICR_CTIMEOUTC | SDMMC_ICR_DTIMEOUTC | \
+ SDMMC_ICR_TXUNDERRC | SDMMC_ICR_RXOVERRC | \
+ SDMMC_ICR_CMDRENDC | SDMMC_ICR_CMDSENTC | \
+ SDMMC_ICR_DATAENDC | SDMMC_ICR_DBCKENDC | \
+ SDMMC_ICR_SDIOITC)
+
+#define SDMMC_STA_ERROR_MASK \
+ (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | \
+ SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | \
+ SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR)
+
+#define SDMMC_CLKDIV_HS (2 - 2)
+#define SDMMC_CLKDIV_LS (120 - 2)
+
+#define SDMMC1_WRITE_TIMEOUT \
+ (((STM32_SDMMC1CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
+ STM32_SDC_SDMMC_WRITE_TIMEOUT)
+#define SDMMC1_READ_TIMEOUT \
+ (((STM32_SDMMC1CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
+ STM32_SDC_SDMMC_READ_TIMEOUT)
+
+#define SDMMC2_WRITE_TIMEOUT \
+ (((STM32_SDMMC2CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
+ STM32_SDC_SDMMC_WRITE_TIMEOUT)
+#define SDMMC2_READ_TIMEOUT \
+ (((STM32_SDMMC2CLK / (SDMMC_CLKDIV_HS + 2)) / 1000) * \
+ STM32_SDC_SDMMC_READ_TIMEOUT)
+
+#define SDMMC1_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC1_DMA_STREAM, \
+ STM32_SDC_SDMMC1_DMA_CHN)
+
+#define SDMMC2_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SDC_SDMMC2_DMA_STREAM, \
+ STM32_SDC_SDMMC2_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SDCD1 driver identifier.*/
+#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
+SDCDriver SDCD1;
+#endif
+
+/** @brief SDCD2 driver identifier.*/
+#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
+SDCDriver SDCD2;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief SDIO default configuration.
+ */
+static const SDCConfig sdc_default_cfg = {
+ SDC_MODE_4BIT
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Prepares to handle read transaction.
+ * @details Designed for read special registers from card.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] buf pointer to the read buffer
+ * @param[in] bytes number of bytes to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp,
+ uint8_t *buf, uint32_t bytes) {
+ osalDbgCheck(bytes < 0x1000000);
+
+ sdcp->sdmmc->DTIMER = sdcp->rtmo;
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaStreamSetMemory0(sdcp->dma, buf);
+ dmaStreamSetTransactionSize(sdcp->dma, bytes / sizeof (uint32_t));
+ dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
+ dmaStreamEnable(sdcp->dma);
+
+ /* Setting up data transfer.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
+ SDMMC_MASK_DTIMEOUTIE |
+ SDMMC_MASK_RXOVERRIE |
+ SDMMC_MASK_DATAENDIE;
+ sdcp->sdmmc->DLEN = bytes;
+
+ /* Transaction starts just after DTEN bit setting.*/
+ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
+ SDMMC_DCTRL_DTMODE | /* Multibyte data transfer.*/
+ SDMMC_DCTRL_DMAEN |
+ SDMMC_DCTRL_DTEN;
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Prepares card to handle read transaction.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[in] n number of blocks to read
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
+ uint32_t n, uint32_t *resp) {
+
+ /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
+ have not HC card than we must convert address from blocks to bytes.*/
+ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
+ startblk *= MMCSD_BLOCK_SIZE;
+
+ if (n > 1) {
+ /* Send read multiple blocks command to card.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+ else {
+ /* Send read single block command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Prepares card to handle write transaction.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[in] n number of blocks to write
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
+ uint32_t n, uint32_t *resp) {
+
+ /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
+ have not HC card than we must convert address from blocks to bytes.*/
+ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
+ startblk *= MMCSD_BLOCK_SIZE;
+
+ if (n > 1) {
+ /* Write multiple blocks command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+ else {
+ /* Write single block command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Wait end of data transaction and performs finalizations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] n number of blocks in transaction
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ */
+static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
+ uint32_t *resp) {
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ osalSysLock();
+ if (sdcp->sdmmc->MASK != 0)
+ osalThreadSuspendS(&sdcp->thread);
+ if ((sdcp->sdmmc->STA & SDMMC_STA_DATAEND) == 0) {
+ osalSysUnlock();
+ return HAL_FAILED;
+ }
+
+ /* Waits for transfer completion at DMA level, then the stream is
+ disabled and cleared.*/
+ dmaWaitCompletion(sdcp->dma);
+
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->DCTRL = 0;
+ osalSysUnlock();
+
+ /* Finalize transaction.*/
+ if (n > 1)
+ return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Gets SDC errors.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] sta value of the STA register
+ *
+ * @notapi
+ */
+static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
+ uint32_t errors = SDC_NO_ERROR;
+
+ if (sta & SDMMC_STA_CCRCFAIL)
+ errors |= SDC_CMD_CRC_ERROR;
+ if (sta & SDMMC_STA_DCRCFAIL)
+ errors |= SDC_DATA_CRC_ERROR;
+ if (sta & SDMMC_STA_CTIMEOUT)
+ errors |= SDC_COMMAND_TIMEOUT;
+ if (sta & SDMMC_STA_DTIMEOUT)
+ errors |= SDC_DATA_TIMEOUT;
+ if (sta & SDMMC_STA_TXUNDERR)
+ errors |= SDC_TX_UNDERRUN;
+ if (sta & SDMMC_STA_RXOVERR)
+ errors |= SDC_RX_OVERRUN;
+/* if (sta & SDMMC_STA_STBITERR)
+ errors |= SDC_STARTBIT_ERROR;*/
+
+ sdcp->errors |= errors;
+}
+
+/**
+ * @brief Performs clean transaction stopping in case of errors.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] n number of blocks in transaction
+ * @param[in] resp pointer to the response buffer
+ *
+ * @notapi
+ */
+static void sdc_lld_error_cleanup(SDCDriver *sdcp,
+ uint32_t n,
+ uint32_t *resp) {
+ uint32_t sta = sdcp->sdmmc->STA;
+
+ dmaStreamDisable(sdcp->dma);
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = 0;
+ sdcp->sdmmc->DCTRL = 0;
+ sdc_lld_collect_errors(sdcp, sta);
+
+ if (n > 1)
+ sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief SDMMC1 IRQ handler.
+ * @details It just wakes transaction thread, errors handling is performed in
+ * there.
+ *
+ * @isr
+ */
+#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
+OSAL_IRQ_HANDLER(STM32_SDMMC1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ osalSysLockFromISR();
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions needs to check them.*/
+ SDMMC1->MASK = 0;
+
+ osalThreadResumeI(&SDCD1.thread, MSG_OK);
+
+ osalSysUnlockFromISR();
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/**
+ * @brief SDMMC2 IRQ handler.
+ * @details It just wakes transaction thread, errors handling is performed in
+ * there.
+ *
+ * @isr
+ */
+#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
+OSAL_IRQ_HANDLER(STM32_SDMMC2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ osalSysLockFromISR();
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions needs to check them.*/
+ SDMMC2->MASK = 0;
+
+ osalThreadResumeI(&SDCD2.thread, MSG_OK);
+
+ osalSysUnlockFromISR();
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SDC driver initialization.
+ *
+ * @notapi
+ */
+void sdc_lld_init(void) {
+
+#if STM32_SDC_USE_SDMMC1
+ sdcObjectInit(&SDCD1);
+ SDCD1.thread = NULL;
+ SDCD1.rtmo = SDMMC1_READ_TIMEOUT;
+ SDCD1.wtmo = SDMMC1_WRITE_TIMEOUT;
+ SDCD1.dma = NULL;
+ SDCD1.sdmmc = SDMMC1;
+ nvicEnableVector(STM32_SDMMC1_NUMBER, STM32_SDC_SDMMC1_IRQ_PRIORITY);
+#endif
+
+#if STM32_SDC_USE_SDMMC2
+ sdcObjectInit(&SDCD2);
+ SDCD2.thread = NULL;
+ SDCD2.rtmo = SDMMC2_READ_TIMEOUT;
+ SDCD2.wtmo = SDMMC2_WRITE_TIMEOUT;
+ SDCD2.dma = NULL;
+ SDCD2.sdmmc = SDMMC2;
+ nvicEnableVector(STM32_SDMMC2_NUMBER, STM32_SDC_SDMMC2_IRQ_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start(SDCDriver *sdcp) {
+
+ /* Checking configuration, using a default if NULL has been passed.*/
+ if (sdcp->config == NULL) {
+ sdcp->config = &sdc_default_cfg;
+ }
+
+ sdcp->dmamode = STM32_DMA_CR_PSIZE_WORD |
+ STM32_DMA_CR_MSIZE_WORD |
+ STM32_DMA_CR_MINC;
+
+#if STM32_DMA_ADVANCED
+ sdcp->dmamode |= STM32_DMA_CR_PFCTRL |
+ STM32_DMA_CR_PBURST_INCR4 |
+ STM32_DMA_CR_MBURST_INCR4;
+#endif
+
+ /* If in stopped state then clocks are enabled and DMA initialized.*/
+ if (sdcp->state == BLK_STOP) {
+#if STM32_SDC_USE_SDMMC1
+ if (&SDCD1 == sdcp) {
+ sdcp->dma = dmaStreamAllocI(STM32_SDC_SDMMC1_DMA_STREAM,
+ STM32_SDC_SDMMC1_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(sdcp->dma != NULL, "unable to allocate stream");
+
+ sdcp->dmamode |= STM32_DMA_CR_CHSEL(SDMMC1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SDC_SDMMC1_DMA_PRIORITY);
+ dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
+#if STM32_DMA_ADVANCED
+ dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS |
+ STM32_DMA_FCR_FTH_FULL);
+#endif
+ rccEnableSDMMC1(true);
+ }
+#endif /* STM32_SDC_USE_SDMMC1 */
+
+#if STM32_SDC_USE_SDMMC2
+ if (&SDCD2 == sdcp) {
+ sdcp->dma = dmaStreamAllocI(STM32_SDC_SDMMC2_DMA_STREAM,
+ STM32_SDC_SDMMC2_IRQ_PRIORITY,
+ NULL,
+ NULL);
+ osalDbgAssert(sdcp->dma != NULL, "unable to allocate stream");
+
+ sdcp->dmamode |= STM32_DMA_CR_CHSEL(SDMMC2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SDC_SDMMC2_DMA_PRIORITY);
+ dmaStreamSetPeripheral(sdcp->dma, &sdcp->sdmmc->FIFO);
+#if STM32_DMA_ADVANCED
+ dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS |
+ STM32_DMA_FCR_FTH_FULL);
+#endif
+ rccEnableSDMMC2(true);
+ }
+#endif /* STM32_SDC_USE_SDMMC2 */
+ }
+
+ /* Configuration, card clock is initially stopped.*/
+ sdcp->sdmmc->POWER = 0;
+ sdcp->sdmmc->CLKCR = 0;
+ sdcp->sdmmc->DCTRL = 0;
+ sdcp->sdmmc->DTIMER = 0;
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop(SDCDriver *sdcp) {
+
+ if (sdcp->state != BLK_STOP) {
+
+ /* SDIO deactivation.*/
+ sdcp->sdmmc->POWER = 0;
+ sdcp->sdmmc->CLKCR = 0;
+ sdcp->sdmmc->DCTRL = 0;
+ sdcp->sdmmc->DTIMER = 0;
+
+ /* DMA stream released.*/
+ dmaStreamFreeI(sdcp->dma);
+ sdcp->dma = NULL;
+
+ /* Clock deactivation.*/
+#if STM32_SDC_USE_SDMMC1
+ if (&SDCD1 == sdcp) {
+ rccDisableSDMMC1();
+ }
+#endif
+
+#if STM32_SDC_USE_SDMMC2
+ if (&SDCD2 == sdcp) {
+ rccDisableSDMMC2();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start_clk(SDCDriver *sdcp) {
+
+ /* Initial clock setting: 400kHz, 1bit mode.*/
+ sdcp->sdmmc->CLKCR = SDMMC_CLKDIV_LS;
+ sdcp->sdmmc->POWER |= SDMMC_POWER_PWRCTRL_0 | SDMMC_POWER_PWRCTRL_1;
+ sdcp->sdmmc->CLKCR |= SDMMC_CLKCR_CLKEN;
+
+ /* Clock activation delay.*/
+ osalThreadSleep(OSAL_MS2I(STM32_SDC_SDMMC_CLOCK_DELAY));
+}
+
+/**
+ * @brief Sets the SDIO clock to data mode (25/50 MHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] clk the clock mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) {
+
+#if STM32_SDC_SDMMC_50MHZ
+ if (SDC_CLK_50MHz == clk) {
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
+#if STM32_SDC_SDMMC_PWRSAV
+ SDMMC_CLKDIV_HS | SDMMC_CLKCR_BYPASS |
+ SDMMC_CLKCR_PWRSAV;
+#else
+ SDMMC_CLKDIV_HS | SDMMC_CLKCR_BYPASS;
+#endif
+ }
+ else {
+#if STM32_SDC_SDMMC_PWRSAV
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS |
+ SDMMC_CLKCR_PWRSAV;
+#else
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS;
+#endif
+ }
+#else
+ (void)clk;
+
+#if STM32_SDC_SDMMC_PWRSAV
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS |
+ SDMMC_CLKCR_PWRSAV;
+#else
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) | SDMMC_CLKDIV_HS;
+#endif
+#endif
+}
+
+/**
+ * @brief Stops the SDIO clock.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop_clk(SDCDriver *sdcp) {
+
+ sdcp->sdmmc->CLKCR = 0;
+ sdcp->sdmmc->POWER = 0;
+}
+
+/**
+ * @brief Switches the bus to 1, 4 or 8 bits mode.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] mode bus mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
+ uint32_t clk = sdcp->sdmmc->CLKCR & ~SDMMC_CLKCR_WIDBUS;
+
+ switch (mode) {
+ case SDC_MODE_1BIT:
+ sdcp->sdmmc->CLKCR = clk;
+ break;
+ case SDC_MODE_4BIT:
+ sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_0;
+ break;
+ case SDC_MODE_8BIT:
+ sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_1;
+ break;
+ }
+}
+
+/**
+ * @brief Sends an SDIO command with no response expected.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ *
+ * @notapi
+ */
+void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_CPSMEN;
+ while ((sdcp->sdmmc->STA & SDMMC_STA_CMDSENT) == 0)
+ ;
+ sdcp->sdmmc->ICR = SDMMC_ICR_CMDSENTC;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected.
+ * @note The CRC is not verified.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
+ while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL);
+ if ((sta & (SDMMC_STA_CTIMEOUT)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ *resp = sdcp->sdmmc->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
+ while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL);
+ if ((sta & (SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ *resp = sdcp->sdmmc->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Sends an SDIO command with a long response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (four words)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_WAITRESP_1 |
+ SDMMC_CMD_CPSMEN;
+ while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL);
+ if ((sta & (SDMMC_STA_ERROR_MASK)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ /* Save bytes in reverse order because MSB in response comes first.*/
+ *resp++ = sdcp->sdmmc->RESP4;
+ *resp++ = sdcp->sdmmc->RESP3;
+ *resp++ = sdcp->sdmmc->RESP2;
+ *resp = sdcp->sdmmc->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Reads special registers using data bus.
+ * @details Needs only during card detection procedure.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] buf pointer to the read buffer
+ * @param[in] bytes number of bytes to read
+ * @param[in] cmd card command
+ * @param[in] arg argument for command
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
+ uint8_t cmd, uint32_t arg) {
+ uint32_t resp[1];
+
+ if (sdc_lld_prepare_read_bytes(sdcp, buf, bytes))
+ goto error;
+
+ if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp)
+ || MMCSD_R1_ERROR(resp[0]))
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, 1, resp))
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, 1, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] blocks number of blocks to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks) {
+ uint32_t resp[1];
+
+ osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
+
+ sdcp->sdmmc->DTIMER = sdcp->rtmo;
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaStreamSetMemory0(sdcp->dma, buf);
+ dmaStreamSetTransactionSize(sdcp->dma,
+ (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
+ dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
+ dmaStreamEnable(sdcp->dma);
+
+ /* Setting up data transfer.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
+ SDMMC_MASK_DTIMEOUTIE |
+ SDMMC_MASK_RXOVERRIE |
+ SDMMC_MASK_DATAENDIE;
+ sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
+
+ /* Transaction starts just after DTEN bit setting.*/
+ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
+ SDMMC_DCTRL_DBLOCKSIZE_3 |
+ SDMMC_DCTRL_DBLOCKSIZE_0 |
+ SDMMC_DCTRL_DMAEN |
+ SDMMC_DCTRL_DTEN;
+
+ if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == true)
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, blocks, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks) {
+ uint32_t resp[1];
+
+ osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
+
+ sdcp->sdmmc->DTIMER = sdcp->wtmo;
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Prepares the DMA channel for writing.*/
+ dmaStreamSetMemory0(sdcp->dma, buf);
+ dmaStreamSetTransactionSize(sdcp->dma,
+ (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t));
+ dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P);
+ dmaStreamEnable(sdcp->dma);
+
+ /* Setting up data transfer.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
+ SDMMC_MASK_DTIMEOUTIE |
+ SDMMC_MASK_TXUNDERRIE |
+ SDMMC_MASK_DATAENDIE;
+ sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
+
+ /* Talk to card what we want from it.*/
+ if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == true)
+ goto error;
+
+ /* Transaction starts just after DTEN bit setting.*/
+ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DBLOCKSIZE_3 |
+ SDMMC_DCTRL_DBLOCKSIZE_0 |
+ SDMMC_DCTRL_DMAEN |
+ SDMMC_DCTRL_DTEN;
+
+ if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, blocks, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] blocks number of blocks to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks) {
+
+#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < blocks; i++) {
+ if (sdc_lld_read_aligned(sdcp, startblk, sdcp->buf, 1))
+ return HAL_FAILED;
+ memcpy(buf, sdcp->buf, MMCSD_BLOCK_SIZE);
+ buf += MMCSD_BLOCK_SIZE;
+ startblk++;
+ }
+ return HAL_SUCCESS;
+ }
+#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
+#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ return sdc_lld_read_aligned(sdcp, startblk, buf, blocks);
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] blocks number of blocks to write
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks) {
+
+#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < blocks; i++) {
+ memcpy(sdcp->buf, buf, MMCSD_BLOCK_SIZE);
+ buf += MMCSD_BLOCK_SIZE;
+ if (sdc_lld_write_aligned(sdcp, startblk, sdcp->buf, 1))
+ return HAL_FAILED;
+ startblk++;
+ }
+ return HAL_SUCCESS;
+ }
+#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
+#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
+}
+
+/**
+ * @brief Waits for card idle condition.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS the operation succeeded.
+ * @retval HAL_FAILED the operation failed.
+ *
+ * @api
+ */
+bool sdc_lld_sync(SDCDriver *sdcp) {
+
+ /* CHTODO: Implement.*/
+ (void)sdcp;
+ return HAL_SUCCESS;
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h
index b9ad69c715..77353f519e 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h
+++ b/os/hal/ports/STM32/LLD/SDMMCv1/hal_sdc_lld.h
@@ -1,400 +1,400 @@
-/*
- 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 SDMMCv1/hal_sdc_lld.h
- * @brief STM32 SDC subsystem low level driver header.
- *
- * @addtogroup SDC
- * @{
- */
-
-#ifndef HAL_SDC_LLD_H
-#define HAL_SDC_LLD_H
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SDMMC1 driver enable switch.
- * @details If set to @p TRUE the support for SDMMC1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SDC_USE_SDMMC1) || defined(__DOXYGEN__)
-#define STM32_SDC_USE_SDMMC1 FALSE
-#endif
-
-/**
- * @brief SDMMC2 driver enable switch.
- * @details If set to @p TRUE the support for SDMMC2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SDC_USE_SDMMC2) || defined(__DOXYGEN__)
-#define STM32_SDC_USE_SDMMC2 FALSE
-#endif
-
-/**
- * @brief Support for unaligned transfers.
- * @note Unaligned transfers are much slower.
- */
-#if !defined(STM32_SDC_SDMMC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE
-#endif
-
-/**
- * @brief Enable clock bypass.
- * @note Allow clock speed up to 50 Mhz.
- */
-#if !defined(STM32_SDC_SDMMC_50MHZ) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_50MHZ FALSE
-#endif
-
-/**
- * @brief Write timeout in milliseconds.
- */
-#if !defined(STM32_SDC_SDMMC_WRITE_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_WRITE_TIMEOUT 1000
-#endif
-
-/**
- * @brief Read timeout in milliseconds.
- */
-#if !defined(STM32_SDC_SDMMC_READ_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_READ_TIMEOUT 1000
-#endif
-
-/**
- * @brief Card clock activation delay in milliseconds.
- */
-#if !defined(STM32_SDC_SDMMC_CLOCK_DELAY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_CLOCK_DELAY 10
-#endif
-
-/**
- * @brief Card clock power saving enable.
- */
-#if !defined(STM32_SDC_SDMMC_PWRSAV) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_PWRSAV TRUE
-#endif
-
-/**
- * @brief SDMMC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_SDC_SDMMC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC1_DMA_PRIORITY 3
-#endif
-
-/**
- * @brief SDMMC2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_SDC_SDMMC2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC2_DMA_PRIORITY 3
-#endif
-
-/**
- * @brief SDMMC1 interrupt priority level setting.
- */
-#if !defined(STM32_SDC_SDMMC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9
-#endif
-
-/**
- * @brief SDMMC2 interrupt priority level setting.
- */
-#if !defined(STM32_SDC_SDMMC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC2_IRQ_PRIORITY 9
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Registry checks.*/
-#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_HANDLER)) || \
- (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_HANDLER))
-#error "STM32_SDMMCx_HANDLER not defined in registry"
-#endif
-
-#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_NUMBER)) || \
- (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_NUMBER))
-#error "STM32_SDMMCx_NUMBER not defined in registry"
-#endif
-
-#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_MSK)) || \
- (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_MSK))
-#error "STM32_SDC_SDMMCx_DMA_MSK not defined in registry"
-#endif
-
-#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_CHN)) || \
- (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_CHN))
-#error "STM32_SDC_SDMMCx_DMA_CHN not defined in registry"
-#endif
-
-/* Units checks.*/
-#if STM32_SDC_USE_SDMMC1 && !STM32_HAS_SDMMC1
-#error "SDMMC1 not present in the selected device"
-#endif
-
-#if STM32_SDC_USE_SDMMC2 && !STM32_HAS_SDMMC2
-#error "SDMMC2 not present in the selected device"
-#endif
-
-#if !STM32_SDC_USE_SDMMC1 && !STM32_SDC_USE_SDMMC2
-#error "SDC driver activated but no SDMMC peripheral assigned"
-#endif
-
-/* Clock related tests.*/
-#if STM32_HAS_SDMMC1 && !defined(STM32_SDMMC1CLK)
-#error "STM32_SDMMC1CLK not defined"
-#endif
-
-/* Clock related tests.*/
-#if STM32_HAS_SDMMC2 && !defined(STM32_SDMMC2CLK)
-#error "STM32_SDMMC2CLK not defined"
-#endif
-
-#if !defined(STM32_HCLK)
-#error "STM32_HCLK not defined"
-#endif
-
-#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK * 10 > STM32_HCLK * 7)
-#error "STM32_SDMMC1CLK must not exceed STM32_HCLK * 0.7"
-#endif
-
-#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK * 10 > STM32_HCLK * 7)
-#error "STM32_SDMMC2CLK must not exceed STM32_HCLK * 0.7"
-#endif
-
-#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK > 48000000)
-#error "STM32_SDMMC1CLK must not exceed 48MHz"
-#endif
-
-#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK > 48000000)
-#error "STM32_SDMMC2CLK must not exceed 48MHz"
-#endif
-
-#if defined(STM32_SDC_SDMMC_50MHZ) && STM32_SDC_SDMMC_50MHZ && !defined(STM32F7XX)
-#error "50 Mhz clock only works for STM32F7XX"
-#endif
-
-/* SDMMC IRQ priority tests.*/
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDMMC1"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDMMC2"
-#endif
-
-/* DMA priority tests.*/
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDMMC1"
-#endif
-
-#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDMMC2"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_STREAM)
-#error "SDMMC1 DMA streams not defined"
-#endif
-
-#if STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_STREAM)
-#error "SDMMC2 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_SDC_USE_SDMMC1 && \
- !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC1_DMA_STREAM, STM32_SDC_SDMMC1_DMA_MSK)
-#error "invalid DMA stream associated to SDMMC1"
-#endif
-
-#if STM32_SDC_USE_SDMMC2 && \
- !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC2_DMA_STREAM, STM32_SDC_SDMMC2_DMA_MSK)
-#error "invalid DMA stream associated to SDMMC2"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of card flags.
- */
-typedef uint32_t sdcmode_t;
-
-/**
- * @brief SDC Driver condition flags type.
- */
-typedef uint32_t sdcflags_t;
-
-/**
- * @brief Type of a structure representing an SDC driver.
- */
-typedef struct SDCDriver SDCDriver;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Bus width.
- */
- sdcbusmode_t bus_width;
- /* End of the mandatory fields.*/
-} SDCConfig;
-
-/**
- * @brief @p SDCDriver specific methods.
- */
-#define _sdc_driver_methods \
- _mmcsd_block_device_methods
-
-/**
- * @extends MMCSDBlockDeviceVMT
- *
- * @brief @p SDCDriver virtual methods table.
- */
-struct SDCDriverVMT {
- _sdc_driver_methods
-};
-
-/**
- * @brief Structure representing an SDC driver.
- */
-struct SDCDriver {
- /**
- * @brief Virtual Methods Table.
- */
- const struct SDCDriverVMT *vmt;
- _mmcsd_block_device_data
- /**
- * @brief Current configuration data.
- */
- const SDCConfig *config;
- /**
- * @brief Various flags regarding the mounted card.
- */
- sdcmode_t cardmode;
- /**
- * @brief Errors flags.
- */
- sdcflags_t errors;
- /**
- * @brief Card RCA.
- */
- uint32_t rca;
- /* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion IRQ.
- */
- thread_reference_t thread;
- /**
- * @brief DTIMER register value for read operations.
- */
- uint32_t rtmo;
- /**
- * @brief DTIMER register value for write operations.
- */
- uint32_t wtmo;
- /**
- * @brief DMA mode bit mask.
- */
- uint32_t dmamode;
- /**
- * @brief Transmit DMA channel.
- */
- const stm32_dma_stream_t *dma;
- /**
- * @brief Pointer to the SDMMC registers block.
- * @note Needed for debugging aid.
- */
- SDMMC_TypeDef *sdmmc;
- /**
- * @brief Buffer for internal operations.
- */
- uint8_t buf[MMCSD_BLOCK_SIZE];
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SDC_USE_SDMMC1 && !defined(__DOXYGEN__)
-extern SDCDriver SDCD1;
-#endif
-
-#if STM32_SDC_USE_SDMMC2 && !defined(__DOXYGEN__)
-extern SDCDriver SDCD2;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void sdc_lld_init(void);
- void sdc_lld_start(SDCDriver *sdcp);
- void sdc_lld_stop(SDCDriver *sdcp);
- void sdc_lld_start_clk(SDCDriver *sdcp);
- void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk);
- void sdc_lld_stop_clk(SDCDriver *sdcp);
- void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
- void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
- bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
- uint8_t cmd, uint32_t argument);
- bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks);
- bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks);
- bool sdc_lld_sync(SDCDriver *sdcp);
- bool sdc_lld_is_card_inserted(SDCDriver *sdcp);
- bool sdc_lld_is_write_protected(SDCDriver *sdcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SDC */
-
-#endif /* HAL_SDC_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 SDMMCv1/hal_sdc_lld.h
+ * @brief STM32 SDC subsystem low level driver header.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef HAL_SDC_LLD_H
+#define HAL_SDC_LLD_H
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SDMMC1 driver enable switch.
+ * @details If set to @p TRUE the support for SDMMC1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SDC_USE_SDMMC1) || defined(__DOXYGEN__)
+#define STM32_SDC_USE_SDMMC1 FALSE
+#endif
+
+/**
+ * @brief SDMMC2 driver enable switch.
+ * @details If set to @p TRUE the support for SDMMC2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SDC_USE_SDMMC2) || defined(__DOXYGEN__)
+#define STM32_SDC_USE_SDMMC2 FALSE
+#endif
+
+/**
+ * @brief Support for unaligned transfers.
+ * @note Unaligned transfers are much slower.
+ */
+#if !defined(STM32_SDC_SDMMC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE
+#endif
+
+/**
+ * @brief Enable clock bypass.
+ * @note Allow clock speed up to 50 Mhz.
+ */
+#if !defined(STM32_SDC_SDMMC_50MHZ) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_50MHZ FALSE
+#endif
+
+/**
+ * @brief Write timeout in milliseconds.
+ */
+#if !defined(STM32_SDC_SDMMC_WRITE_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_WRITE_TIMEOUT 1000
+#endif
+
+/**
+ * @brief Read timeout in milliseconds.
+ */
+#if !defined(STM32_SDC_SDMMC_READ_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_READ_TIMEOUT 1000
+#endif
+
+/**
+ * @brief Card clock activation delay in milliseconds.
+ */
+#if !defined(STM32_SDC_SDMMC_CLOCK_DELAY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_CLOCK_DELAY 10
+#endif
+
+/**
+ * @brief Card clock power saving enable.
+ */
+#if !defined(STM32_SDC_SDMMC_PWRSAV) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_PWRSAV TRUE
+#endif
+
+/**
+ * @brief SDMMC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_SDC_SDMMC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC1_DMA_PRIORITY 3
+#endif
+
+/**
+ * @brief SDMMC2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_SDC_SDMMC2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC2_DMA_PRIORITY 3
+#endif
+
+/**
+ * @brief SDMMC1 interrupt priority level setting.
+ */
+#if !defined(STM32_SDC_SDMMC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC1_IRQ_PRIORITY 9
+#endif
+
+/**
+ * @brief SDMMC2 interrupt priority level setting.
+ */
+#if !defined(STM32_SDC_SDMMC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC2_IRQ_PRIORITY 9
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Registry checks.*/
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_HANDLER)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_HANDLER))
+#error "STM32_SDMMCx_HANDLER not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_NUMBER)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_NUMBER))
+#error "STM32_SDMMCx_NUMBER not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_MSK)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_MSK))
+#error "STM32_SDC_SDMMCx_DMA_MSK not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_CHN)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_CHN))
+#error "STM32_SDC_SDMMCx_DMA_CHN not defined in registry"
+#endif
+
+/* Units checks.*/
+#if STM32_SDC_USE_SDMMC1 && !STM32_HAS_SDMMC1
+#error "SDMMC1 not present in the selected device"
+#endif
+
+#if STM32_SDC_USE_SDMMC2 && !STM32_HAS_SDMMC2
+#error "SDMMC2 not present in the selected device"
+#endif
+
+#if !STM32_SDC_USE_SDMMC1 && !STM32_SDC_USE_SDMMC2
+#error "SDC driver activated but no SDMMC peripheral assigned"
+#endif
+
+/* Clock related tests.*/
+#if STM32_HAS_SDMMC1 && !defined(STM32_SDMMC1CLK)
+#error "STM32_SDMMC1CLK not defined"
+#endif
+
+/* Clock related tests.*/
+#if STM32_HAS_SDMMC2 && !defined(STM32_SDMMC2CLK)
+#error "STM32_SDMMC2CLK not defined"
+#endif
+
+#if !defined(STM32_HCLK)
+#error "STM32_HCLK not defined"
+#endif
+
+#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK * 10 > STM32_HCLK * 7)
+#error "STM32_SDMMC1CLK must not exceed STM32_HCLK * 0.7"
+#endif
+
+#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK * 10 > STM32_HCLK * 7)
+#error "STM32_SDMMC2CLK must not exceed STM32_HCLK * 0.7"
+#endif
+
+#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK > 48000000)
+#error "STM32_SDMMC1CLK must not exceed 48MHz"
+#endif
+
+#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK > 48000000)
+#error "STM32_SDMMC2CLK must not exceed 48MHz"
+#endif
+
+#if defined(STM32_SDC_SDMMC_50MHZ) && STM32_SDC_SDMMC_50MHZ && !defined(STM32F7XX)
+#error "50 Mhz clock only works for STM32F7XX"
+#endif
+
+/* SDMMC IRQ priority tests.*/
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDMMC1"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SDC_SDMMC2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDMMC2"
+#endif
+
+/* DMA priority tests.*/
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDMMC1"
+#endif
+
+#if !STM32_DMA_IS_VALID_PRIORITY(STM32_SDC_SDMMC2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDMMC2"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_SDC_USE_SDMMC1 && !defined(STM32_SDC_SDMMC1_DMA_STREAM)
+#error "SDMMC1 DMA streams not defined"
+#endif
+
+#if STM32_SDC_USE_SDMMC2 && !defined(STM32_SDC_SDMMC2_DMA_STREAM)
+#error "SDMMC2 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_SDC_USE_SDMMC1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC1_DMA_STREAM, STM32_SDC_SDMMC1_DMA_MSK)
+#error "invalid DMA stream associated to SDMMC1"
+#endif
+
+#if STM32_SDC_USE_SDMMC2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SDC_SDMMC2_DMA_STREAM, STM32_SDC_SDMMC2_DMA_MSK)
+#error "invalid DMA stream associated to SDMMC2"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of card flags.
+ */
+typedef uint32_t sdcmode_t;
+
+/**
+ * @brief SDC Driver condition flags type.
+ */
+typedef uint32_t sdcflags_t;
+
+/**
+ * @brief Type of a structure representing an SDC driver.
+ */
+typedef struct SDCDriver SDCDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Bus width.
+ */
+ sdcbusmode_t bus_width;
+ /* End of the mandatory fields.*/
+} SDCConfig;
+
+/**
+ * @brief @p SDCDriver specific methods.
+ */
+#define _sdc_driver_methods \
+ _mmcsd_block_device_methods
+
+/**
+ * @extends MMCSDBlockDeviceVMT
+ *
+ * @brief @p SDCDriver virtual methods table.
+ */
+struct SDCDriverVMT {
+ _sdc_driver_methods
+};
+
+/**
+ * @brief Structure representing an SDC driver.
+ */
+struct SDCDriver {
+ /**
+ * @brief Virtual Methods Table.
+ */
+ const struct SDCDriverVMT *vmt;
+ _mmcsd_block_device_data
+ /**
+ * @brief Current configuration data.
+ */
+ const SDCConfig *config;
+ /**
+ * @brief Various flags regarding the mounted card.
+ */
+ sdcmode_t cardmode;
+ /**
+ * @brief Errors flags.
+ */
+ sdcflags_t errors;
+ /**
+ * @brief Card RCA.
+ */
+ uint32_t rca;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion IRQ.
+ */
+ thread_reference_t thread;
+ /**
+ * @brief DTIMER register value for read operations.
+ */
+ uint32_t rtmo;
+ /**
+ * @brief DTIMER register value for write operations.
+ */
+ uint32_t wtmo;
+ /**
+ * @brief DMA mode bit mask.
+ */
+ uint32_t dmamode;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const stm32_dma_stream_t *dma;
+ /**
+ * @brief Pointer to the SDMMC registers block.
+ * @note Needed for debugging aid.
+ */
+ SDMMC_TypeDef *sdmmc;
+ /**
+ * @brief Buffer for internal operations.
+ */
+ uint8_t buf[MMCSD_BLOCK_SIZE];
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SDC_USE_SDMMC1 && !defined(__DOXYGEN__)
+extern SDCDriver SDCD1;
+#endif
+
+#if STM32_SDC_USE_SDMMC2 && !defined(__DOXYGEN__)
+extern SDCDriver SDCD2;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdc_lld_init(void);
+ void sdc_lld_start(SDCDriver *sdcp);
+ void sdc_lld_stop(SDCDriver *sdcp);
+ void sdc_lld_start_clk(SDCDriver *sdcp);
+ void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk);
+ void sdc_lld_stop_clk(SDCDriver *sdcp);
+ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
+ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
+ bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
+ uint8_t cmd, uint32_t argument);
+ bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks);
+ bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks);
+ bool sdc_lld_sync(SDCDriver *sdcp);
+ bool sdc_lld_is_card_inserted(SDCDriver *sdcp);
+ bool sdc_lld_is_write_protected(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* HAL_SDC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk b/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
index cf8b9d20e8..774cca9246 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_SDC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2
diff --git a/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c b/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
index 79701e04ca..bbdd07f135 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
+++ b/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.c
@@ -1,865 +1,865 @@
-/*
- 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 SDMMCv2/hal_sdc_lld.c
- * @brief STM32 SDC subsystem low level driver source.
- *
- * @addtogroup SDC
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define SDMMC_ICR_ALL_FLAGS 0xFFFFFFFFU
-
-#define SDMMC_STA_ERROR_MASK \
- (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | \
- SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | \
- SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SDCD1 driver identifier.*/
-#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
-SDCDriver SDCD1;
-#endif
-
-/** @brief SDCD2 driver identifier.*/
-#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
-SDCDriver SDCD2;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief SDIO default configuration.
- */
-static const SDCConfig sdc_default_cfg = {
- SDC_MODE_4BIT
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Calculates a clock divider for the specified frequency.
- * @note The divider is calculated to not exceed the required frequency
- * in case of non-integer division.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] f required frequency
- */
-static uint32_t sdc_lld_clkdiv(SDCDriver *sdcp, uint32_t f) {
-
- if (f >= sdcp->clkfreq) {
- return 0;
- }
-
- return (sdcp->clkfreq + (f * 2) - 1) / (f * 2);
-}
-
-/**
- * @brief Prepares to handle read transaction.
- * @details Designed for read special registers from card.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[out] buf pointer to the read buffer
- * @param[in] bytes number of bytes to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp,
- uint8_t *buf, uint32_t bytes) {
- osalDbgCheck(bytes < 0x1000000);
-
- sdcp->sdmmc->DTIMER = STM32_SDC_SDMMC_READ_TIMEOUT;
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Setting up data transfer.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
- SDMMC_MASK_DTIMEOUTIE |
- SDMMC_MASK_RXOVERRIE |
- SDMMC_MASK_DATAENDIE;
- sdcp->sdmmc->DLEN = bytes;
-
- /* Transfer modes.*/
- sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
- SDMMC_DCTRL_DTMODE_0; /* Multibyte data transfer.*/
-
- /* Prepares IDMA.*/
- sdcp->sdmmc->IDMABASE0 = (uint32_t)buf;
- sdcp->sdmmc->IDMACTRL = SDMMC_IDMA_IDMAEN;
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Prepares card to handle read transaction.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[in] n number of blocks to read
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
- uint32_t n, uint32_t *resp) {
-
- /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
- have not HC card than we must convert address from blocks to bytes.*/
- if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
- startblk *= MMCSD_BLOCK_SIZE;
-
- if (n > 1) {
- /* Send read multiple blocks command to card.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_READ_MULTIPLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
- else {
- /* Send read single block command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_READ_SINGLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Prepares card to handle write transaction.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[in] n number of blocks to write
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
- uint32_t n, uint32_t *resp) {
-
- /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
- have not HC card than we must convert address from blocks to bytes.*/
- if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
- startblk *= MMCSD_BLOCK_SIZE;
-
- if (n > 1) {
- /* Write multiple blocks command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
- else {
- /* Write single block command.*/
- if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_WRITE_BLOCK,
- startblk, resp) || MMCSD_R1_ERROR(resp[0]))
- return HAL_FAILED;
- }
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Wait end of data transaction and performs finalizations.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] n number of blocks in transaction
- * @param[in] resp pointer to the response buffer
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- */
-static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
- uint32_t *resp) {
-
- /* Note the mask is checked before going to sleep because the interrupt
- may have occurred before reaching the critical zone.*/
- osalSysLock();
- if (sdcp->sdmmc->MASK != 0)
- osalThreadSuspendS(&sdcp->thread);
-
- /* Stopping operations.*/
- sdcp->sdmmc->IDMACTRL = 0;
- sdcp->sdmmc->MASK = 0;
- sdcp->sdmmc->DCTRL = 0;
-
- if ((sdcp->sdmmc->STA & SDMMC_STA_DATAEND) == 0) {
- osalSysUnlock();
- return HAL_FAILED;
- }
-
- /* Clearing status.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- osalSysUnlock();
-
- /* Finalize transaction.*/
- if (n > 1)
- return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
-
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Gets SDC errors.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] sta value of the STA register
- *
- * @notapi
- */
-static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
- uint32_t errors = SDC_NO_ERROR;
-
- if (sta & SDMMC_STA_CCRCFAIL)
- errors |= SDC_CMD_CRC_ERROR;
- if (sta & SDMMC_STA_DCRCFAIL)
- errors |= SDC_DATA_CRC_ERROR;
- if (sta & SDMMC_STA_CTIMEOUT)
- errors |= SDC_COMMAND_TIMEOUT;
- if (sta & SDMMC_STA_DTIMEOUT)
- errors |= SDC_DATA_TIMEOUT;
- if (sta & SDMMC_STA_TXUNDERR)
- errors |= SDC_TX_UNDERRUN;
- if (sta & SDMMC_STA_RXOVERR)
- errors |= SDC_RX_OVERRUN;
-/* if (sta & SDMMC_STA_STBITERR)
- errors |= SDC_STARTBIT_ERROR;*/
-
- sdcp->errors |= errors;
-}
-
-/**
- * @brief Performs clean transaction stopping in case of errors.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] n number of blocks in transaction
- * @param[in] resp pointer to the response buffer
- *
- * @notapi
- */
-static void sdc_lld_error_cleanup(SDCDriver *sdcp,
- uint32_t n,
- uint32_t *resp) {
- uint32_t sta = sdcp->sdmmc->STA;
-
- /* Clearing status.*/
- sta = sdcp->sdmmc->STA;
- sdcp->sdmmc->ICR = sta;
- sdc_lld_collect_errors(sdcp, sta);
-
- if (n > 1)
- sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SDC driver initialization.
- *
- * @notapi
- */
-void sdc_lld_init(void) {
-
-#if STM32_SDC_USE_SDMMC1
- sdcObjectInit(&SDCD1);
- SDCD1.thread = NULL;
- SDCD1.sdmmc = SDMMC1;
- SDCD1.clkfreq = STM32_SDMMC1CLK;
-#endif
-
-#if STM32_SDC_USE_SDMMC2
- sdcObjectInit(&SDCD2);
- SDCD2.thread = NULL;
- SDCD2.sdmmc = SDMMC2;
- SDCD2.clkfreq = STM32_SDMMC2CLK;
-#endif
-}
-
-/**
- * @brief Configures and activates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start(SDCDriver *sdcp) {
-
- /* Checking configuration, using a default if NULL has been passed.*/
- if (sdcp->config == NULL) {
- sdcp->config = &sdc_default_cfg;
- }
-
- /* If in stopped state then clocks are enabled and DMA initialized.*/
- if (sdcp->state == BLK_STOP) {
-#if STM32_SDC_USE_SDMMC1
- if (&SDCD1 == sdcp) {
- rccEnableSDMMC1(true);
- }
-#endif /* STM32_SDC_USE_SDMMC1 */
-
-#if STM32_SDC_USE_SDMMC2
- if (&SDCD2 == sdcp) {
- rccEnableSDMMC2(true);
- }
-#endif /* STM32_SDC_USE_SDMMC2 */
- }
-
- /* Configuration, card clock is initially stopped.*/
- sdcp->sdmmc->IDMACTRL = 0;
- sdcp->sdmmc->DCTRL = 0;
- sdcp->sdmmc->POWER = 0;
- sdcp->sdmmc->CLKCR = 0;
- sdcp->sdmmc->DTIMER = 0;
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
-}
-
-/**
- * @brief Deactivates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop(SDCDriver *sdcp) {
-
- if (sdcp->state != BLK_STOP) {
-
- /* SDIO deactivation.*/
- sdcp->sdmmc->IDMACTRL = 0;
- sdcp->sdmmc->DCTRL = 0;
- sdcp->sdmmc->POWER = 0;
- sdcp->sdmmc->CLKCR = 0;
- sdcp->sdmmc->DTIMER = 0;
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
-
- /* Clock deactivation.*/
-#if STM32_SDC_USE_SDMMC1
- if (&SDCD1 == sdcp) {
- rccDisableSDMMC1();
- }
-#endif
-
-#if STM32_SDC_USE_SDMMC2
- if (&SDCD2 == sdcp) {
- rccDisableSDMMC2();
- }
-#endif
- }
-}
-
-/**
- * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start_clk(SDCDriver *sdcp) {
-
- /* Initial clock setting: 400kHz, 1bit mode.*/
- sdcp->sdmmc->CLKCR = sdc_lld_clkdiv(sdcp, 400000);
- sdcp->sdmmc->POWER |= SDMMC_POWER_PWRCTRL_0 | SDMMC_POWER_PWRCTRL_1;
-/* TODO sdcp->sdmmc->CLKCR |= SDMMC_CLKCR_CLKEN;*/
-
- /* Clock activation delay.*/
- osalThreadSleep(OSAL_MS2I(STM32_SDC_SDMMC_CLOCK_DELAY));
-}
-
-/**
- * @brief Sets the SDIO clock to data mode (25/50 MHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] clk the clock mode
- *
- * @notapi
- */
-void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) {
-
- if (SDC_CLK_50MHz == clk) {
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
-#if STM32_SDC_SDMMC_PWRSAV
- sdc_lld_clkdiv(sdcp, 50000000) | SDMMC_CLKCR_PWRSAV;
-#else
- sdc_lld_clkdiv(sdcp, 50000000);
-#endif
- }
- else {
-#if STM32_SDC_SDMMC_PWRSAV
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
- sdc_lld_clkdiv(sdcp, 25000000) | SDMMC_CLKCR_PWRSAV;
-#else
- sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
- sdc_lld_clkdiv(sdcp, 25000000);
-#endif
- }
-}
-
-/**
- * @brief Stops the SDIO clock.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop_clk(SDCDriver *sdcp) {
-
- sdcp->sdmmc->CLKCR = 0;
- sdcp->sdmmc->POWER = 0;
-}
-
-/**
- * @brief Switches the bus to 1, 4 or 8 bits mode.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] mode bus mode
- *
- * @notapi
- */
-void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
- uint32_t clk = sdcp->sdmmc->CLKCR & ~SDMMC_CLKCR_WIDBUS;
-
- switch (mode) {
- case SDC_MODE_1BIT:
- sdcp->sdmmc->CLKCR = clk;
- break;
- case SDC_MODE_4BIT:
- sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_0;
- break;
- case SDC_MODE_8BIT:
- sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_1;
- break;
- }
-}
-
-/**
- * @brief Sends an SDIO command with no response expected.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- *
- * @notapi
- */
-void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_CPSMEN;
- while ((sdcp->sdmmc->STA & SDMMC_STA_CMDSENT) == 0)
- ;
- sdcp->sdmmc->ICR = SDMMC_ICR_CMDSENTC;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected.
- * @note The CRC is not verified.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
- while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL);
- if ((sta & (SDMMC_STA_CTIMEOUT)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- *resp = sdcp->sdmmc->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
- while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL);
- if ((sta & (SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- *resp = sdcp->sdmmc->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Sends an SDIO command with a long response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (four words)
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- (void)sdcp;
-
- sdcp->sdmmc->ARG = arg;
- sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_WAITRESP_1 |
- SDMMC_CMD_CPSMEN;
- while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL)) == 0)
- ;
- sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
- SDMMC_STA_CCRCFAIL);
- if ((sta & (SDMMC_STA_ERROR_MASK)) != 0) {
- sdc_lld_collect_errors(sdcp, sta);
- return HAL_FAILED;
- }
- /* Save bytes in reverse order because MSB in response comes first.*/
- *resp++ = sdcp->sdmmc->RESP4;
- *resp++ = sdcp->sdmmc->RESP3;
- *resp++ = sdcp->sdmmc->RESP2;
- *resp = sdcp->sdmmc->RESP1;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Reads special registers using data bus.
- * @details Needs only during card detection procedure.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[out] buf pointer to the read buffer
- * @param[in] bytes number of bytes to read
- * @param[in] cmd card command
- * @param[in] arg argument for command
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
- uint8_t cmd, uint32_t arg) {
- uint32_t resp[1];
-
- if (sdc_lld_prepare_read_bytes(sdcp, buf, bytes))
- goto error;
-
- if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | cmd, arg, resp) ||
- MMCSD_R1_ERROR(resp[0]))
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, 1, resp))
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, 1, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Reads one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer
- * @param[in] blocks number of blocks to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks) {
- uint32_t resp[1];
-
- osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
-
- sdcp->sdmmc->DTIMER = STM32_SDC_SDMMC_READ_TIMEOUT;
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Setting up data transfer.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
- SDMMC_MASK_DTIMEOUTIE |
- SDMMC_MASK_RXOVERRIE |
- SDMMC_MASK_DATAENDIE;
- sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
-
- /* Transfer modes.*/
- sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
- SDMMC_DCTRL_DBLOCKSIZE_3 |
- SDMMC_DCTRL_DBLOCKSIZE_0;
-
- /* Prepares IDMA.*/
- sdcp->sdmmc->IDMABASE0 = (uint32_t)buf;
- sdcp->sdmmc->IDMACTRL = SDMMC_IDMA_IDMAEN;
-
- if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == true)
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, blocks, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] n number of blocks to write
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks) {
- uint32_t resp[1];
-
- osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
-
- sdcp->sdmmc->DTIMER = STM32_SDC_SDMMC_WRITE_TIMEOUT;
-
- /* Checks for errors and waits for the card to be ready for writing.*/
- if (_sdc_wait_for_transfer_state(sdcp))
- return HAL_FAILED;
-
- /* Setting up data transfer.*/
- sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
- sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
- SDMMC_MASK_DTIMEOUTIE |
- SDMMC_MASK_TXUNDERRIE |
- SDMMC_MASK_DATAENDIE;
- sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
-
- /* Transfer modes.*/
- sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DBLOCKSIZE_3 |
- SDMMC_DCTRL_DBLOCKSIZE_0;
-
- /* Prepares IDMA.*/
- sdcp->sdmmc->IDMABASE0 = (uint32_t)buf;
- sdcp->sdmmc->IDMACTRL = SDMMC_IDMA_IDMAEN;
-
- if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == true)
- goto error;
-
- if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
- goto error;
-
- return HAL_SUCCESS;
-
-error:
- sdc_lld_error_cleanup(sdcp, blocks, resp);
- return HAL_FAILED;
-}
-
-/**
- * @brief Reads one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer
- * @param[in] blocks number of blocks to read
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks) {
-
-#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < blocks; i++) {
- if (sdc_lld_read_aligned(sdcp, startblk, sdcp->buf, 1))
- return HAL_FAILED;
- memcpy(buf, sdcp->buf, MMCSD_BLOCK_SIZE);
- buf += MMCSD_BLOCK_SIZE;
- startblk++;
- }
- return HAL_SUCCESS;
- }
-#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
-#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- return sdc_lld_read_aligned(sdcp, startblk, buf, blocks);
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] blocks number of blocks to write
- *
- * @return The operation status.
- * @retval HAL_SUCCESS operation succeeded.
- * @retval HAL_FAILED operation failed.
- *
- * @notapi
- */
-bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks) {
-
-#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < blocks; i++) {
- memcpy(sdcp->buf, buf, MMCSD_BLOCK_SIZE);
- buf += MMCSD_BLOCK_SIZE;
- if (sdc_lld_write_aligned(sdcp, startblk, sdcp->buf, 1))
- return HAL_FAILED;
- startblk++;
- }
- return HAL_SUCCESS;
- }
-#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
-#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
- return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
-}
-
-/**
- * @brief Waits for card idle condition.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @return The operation status.
- * @retval HAL_SUCCESS the operation succeeded.
- * @retval HAL_FAILED the operation failed.
- *
- * @api
- */
-bool sdc_lld_sync(SDCDriver *sdcp) {
-
- /* CHTODO: Implement.*/
- (void)sdcp;
- return HAL_SUCCESS;
-}
-
-/**
- * @brief Shared service routine.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- */
-void sdc_lld_serve_interrupt(SDCDriver *sdcp) {
-
- /* Disables the source but the status flags are not reset because the
- read/write functions needs to check them.*/
- sdcp->sdmmc->MASK = 0;
-
- osalSysLockFromISR();
- osalThreadResumeI(&sdcp->thread, MSG_OK);
- osalSysUnlockFromISR();
-}
-
-#endif /* HAL_USE_SDC */
-
-/** @} */
+/*
+ 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 SDMMCv2/hal_sdc_lld.c
+ * @brief STM32 SDC subsystem low level driver source.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define SDMMC_ICR_ALL_FLAGS 0xFFFFFFFFU
+
+#define SDMMC_STA_ERROR_MASK \
+ (SDMMC_STA_CCRCFAIL | SDMMC_STA_DCRCFAIL | \
+ SDMMC_STA_CTIMEOUT | SDMMC_STA_DTIMEOUT | \
+ SDMMC_STA_TXUNDERR | SDMMC_STA_RXOVERR)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SDCD1 driver identifier.*/
+#if STM32_SDC_USE_SDMMC1 || defined(__DOXYGEN__)
+SDCDriver SDCD1;
+#endif
+
+/** @brief SDCD2 driver identifier.*/
+#if STM32_SDC_USE_SDMMC2 || defined(__DOXYGEN__)
+SDCDriver SDCD2;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief SDIO default configuration.
+ */
+static const SDCConfig sdc_default_cfg = {
+ SDC_MODE_4BIT
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Calculates a clock divider for the specified frequency.
+ * @note The divider is calculated to not exceed the required frequency
+ * in case of non-integer division.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] f required frequency
+ */
+static uint32_t sdc_lld_clkdiv(SDCDriver *sdcp, uint32_t f) {
+
+ if (f >= sdcp->clkfreq) {
+ return 0;
+ }
+
+ return (sdcp->clkfreq + (f * 2) - 1) / (f * 2);
+}
+
+/**
+ * @brief Prepares to handle read transaction.
+ * @details Designed for read special registers from card.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] buf pointer to the read buffer
+ * @param[in] bytes number of bytes to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp,
+ uint8_t *buf, uint32_t bytes) {
+ osalDbgCheck(bytes < 0x1000000);
+
+ sdcp->sdmmc->DTIMER = STM32_SDC_SDMMC_READ_TIMEOUT;
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Setting up data transfer.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
+ SDMMC_MASK_DTIMEOUTIE |
+ SDMMC_MASK_RXOVERRIE |
+ SDMMC_MASK_DATAENDIE;
+ sdcp->sdmmc->DLEN = bytes;
+
+ /* Transfer modes.*/
+ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
+ SDMMC_DCTRL_DTMODE_0; /* Multibyte data transfer.*/
+
+ /* Prepares IDMA.*/
+ sdcp->sdmmc->IDMABASE0 = (uint32_t)buf;
+ sdcp->sdmmc->IDMACTRL = SDMMC_IDMA_IDMAEN;
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Prepares card to handle read transaction.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[in] n number of blocks to read
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
+ uint32_t n, uint32_t *resp) {
+
+ /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
+ have not HC card than we must convert address from blocks to bytes.*/
+ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
+ startblk *= MMCSD_BLOCK_SIZE;
+
+ if (n > 1) {
+ /* Send read multiple blocks command to card.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_READ_MULTIPLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+ else {
+ /* Send read single block command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_READ_SINGLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Prepares card to handle write transaction.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[in] n number of blocks to write
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+static bool sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
+ uint32_t n, uint32_t *resp) {
+
+ /* Driver handles data in 512 bytes blocks (just like HC cards). But if we
+ have not HC card than we must convert address from blocks to bytes.*/
+ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
+ startblk *= MMCSD_BLOCK_SIZE;
+
+ if (n > 1) {
+ /* Write multiple blocks command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+ else {
+ /* Write single block command.*/
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | MMCSD_CMD_WRITE_BLOCK,
+ startblk, resp) || MMCSD_R1_ERROR(resp[0]))
+ return HAL_FAILED;
+ }
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Wait end of data transaction and performs finalizations.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] n number of blocks in transaction
+ * @param[in] resp pointer to the response buffer
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ */
+static bool sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
+ uint32_t *resp) {
+
+ /* Note the mask is checked before going to sleep because the interrupt
+ may have occurred before reaching the critical zone.*/
+ osalSysLock();
+ if (sdcp->sdmmc->MASK != 0)
+ osalThreadSuspendS(&sdcp->thread);
+
+ /* Stopping operations.*/
+ sdcp->sdmmc->IDMACTRL = 0;
+ sdcp->sdmmc->MASK = 0;
+ sdcp->sdmmc->DCTRL = 0;
+
+ if ((sdcp->sdmmc->STA & SDMMC_STA_DATAEND) == 0) {
+ osalSysUnlock();
+ return HAL_FAILED;
+ }
+
+ /* Clearing status.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ osalSysUnlock();
+
+ /* Finalize transaction.*/
+ if (n > 1)
+ return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
+
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Gets SDC errors.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] sta value of the STA register
+ *
+ * @notapi
+ */
+static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
+ uint32_t errors = SDC_NO_ERROR;
+
+ if (sta & SDMMC_STA_CCRCFAIL)
+ errors |= SDC_CMD_CRC_ERROR;
+ if (sta & SDMMC_STA_DCRCFAIL)
+ errors |= SDC_DATA_CRC_ERROR;
+ if (sta & SDMMC_STA_CTIMEOUT)
+ errors |= SDC_COMMAND_TIMEOUT;
+ if (sta & SDMMC_STA_DTIMEOUT)
+ errors |= SDC_DATA_TIMEOUT;
+ if (sta & SDMMC_STA_TXUNDERR)
+ errors |= SDC_TX_UNDERRUN;
+ if (sta & SDMMC_STA_RXOVERR)
+ errors |= SDC_RX_OVERRUN;
+/* if (sta & SDMMC_STA_STBITERR)
+ errors |= SDC_STARTBIT_ERROR;*/
+
+ sdcp->errors |= errors;
+}
+
+/**
+ * @brief Performs clean transaction stopping in case of errors.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] n number of blocks in transaction
+ * @param[in] resp pointer to the response buffer
+ *
+ * @notapi
+ */
+static void sdc_lld_error_cleanup(SDCDriver *sdcp,
+ uint32_t n,
+ uint32_t *resp) {
+ uint32_t sta = sdcp->sdmmc->STA;
+
+ /* Clearing status.*/
+ sta = sdcp->sdmmc->STA;
+ sdcp->sdmmc->ICR = sta;
+ sdc_lld_collect_errors(sdcp, sta);
+
+ if (n > 1)
+ sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SDC driver initialization.
+ *
+ * @notapi
+ */
+void sdc_lld_init(void) {
+
+#if STM32_SDC_USE_SDMMC1
+ sdcObjectInit(&SDCD1);
+ SDCD1.thread = NULL;
+ SDCD1.sdmmc = SDMMC1;
+ SDCD1.clkfreq = STM32_SDMMC1CLK;
+#endif
+
+#if STM32_SDC_USE_SDMMC2
+ sdcObjectInit(&SDCD2);
+ SDCD2.thread = NULL;
+ SDCD2.sdmmc = SDMMC2;
+ SDCD2.clkfreq = STM32_SDMMC2CLK;
+#endif
+}
+
+/**
+ * @brief Configures and activates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start(SDCDriver *sdcp) {
+
+ /* Checking configuration, using a default if NULL has been passed.*/
+ if (sdcp->config == NULL) {
+ sdcp->config = &sdc_default_cfg;
+ }
+
+ /* If in stopped state then clocks are enabled and DMA initialized.*/
+ if (sdcp->state == BLK_STOP) {
+#if STM32_SDC_USE_SDMMC1
+ if (&SDCD1 == sdcp) {
+ rccEnableSDMMC1(true);
+ }
+#endif /* STM32_SDC_USE_SDMMC1 */
+
+#if STM32_SDC_USE_SDMMC2
+ if (&SDCD2 == sdcp) {
+ rccEnableSDMMC2(true);
+ }
+#endif /* STM32_SDC_USE_SDMMC2 */
+ }
+
+ /* Configuration, card clock is initially stopped.*/
+ sdcp->sdmmc->IDMACTRL = 0;
+ sdcp->sdmmc->DCTRL = 0;
+ sdcp->sdmmc->POWER = 0;
+ sdcp->sdmmc->CLKCR = 0;
+ sdcp->sdmmc->DTIMER = 0;
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+}
+
+/**
+ * @brief Deactivates the SDC peripheral.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop(SDCDriver *sdcp) {
+
+ if (sdcp->state != BLK_STOP) {
+
+ /* SDIO deactivation.*/
+ sdcp->sdmmc->IDMACTRL = 0;
+ sdcp->sdmmc->DCTRL = 0;
+ sdcp->sdmmc->POWER = 0;
+ sdcp->sdmmc->CLKCR = 0;
+ sdcp->sdmmc->DTIMER = 0;
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+
+ /* Clock deactivation.*/
+#if STM32_SDC_USE_SDMMC1
+ if (&SDCD1 == sdcp) {
+ rccDisableSDMMC1();
+ }
+#endif
+
+#if STM32_SDC_USE_SDMMC2
+ if (&SDCD2 == sdcp) {
+ rccDisableSDMMC2();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the SDIO clock and sets it to init mode (400kHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_start_clk(SDCDriver *sdcp) {
+
+ /* Initial clock setting: 400kHz, 1bit mode.*/
+ sdcp->sdmmc->CLKCR = sdc_lld_clkdiv(sdcp, 400000);
+ sdcp->sdmmc->POWER |= SDMMC_POWER_PWRCTRL_0 | SDMMC_POWER_PWRCTRL_1;
+/* TODO sdcp->sdmmc->CLKCR |= SDMMC_CLKCR_CLKEN;*/
+
+ /* Clock activation delay.*/
+ osalThreadSleep(OSAL_MS2I(STM32_SDC_SDMMC_CLOCK_DELAY));
+}
+
+/**
+ * @brief Sets the SDIO clock to data mode (25/50 MHz or less).
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] clk the clock mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk) {
+
+ if (SDC_CLK_50MHz == clk) {
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
+#if STM32_SDC_SDMMC_PWRSAV
+ sdc_lld_clkdiv(sdcp, 50000000) | SDMMC_CLKCR_PWRSAV;
+#else
+ sdc_lld_clkdiv(sdcp, 50000000);
+#endif
+ }
+ else {
+#if STM32_SDC_SDMMC_PWRSAV
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
+ sdc_lld_clkdiv(sdcp, 25000000) | SDMMC_CLKCR_PWRSAV;
+#else
+ sdcp->sdmmc->CLKCR = (sdcp->sdmmc->CLKCR & 0xFFFFFF00U) |
+ sdc_lld_clkdiv(sdcp, 25000000);
+#endif
+ }
+}
+
+/**
+ * @brief Stops the SDIO clock.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @notapi
+ */
+void sdc_lld_stop_clk(SDCDriver *sdcp) {
+
+ sdcp->sdmmc->CLKCR = 0;
+ sdcp->sdmmc->POWER = 0;
+}
+
+/**
+ * @brief Switches the bus to 1, 4 or 8 bits mode.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] mode bus mode
+ *
+ * @notapi
+ */
+void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
+ uint32_t clk = sdcp->sdmmc->CLKCR & ~SDMMC_CLKCR_WIDBUS;
+
+ switch (mode) {
+ case SDC_MODE_1BIT:
+ sdcp->sdmmc->CLKCR = clk;
+ break;
+ case SDC_MODE_4BIT:
+ sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_0;
+ break;
+ case SDC_MODE_8BIT:
+ sdcp->sdmmc->CLKCR = clk | SDMMC_CLKCR_WIDBUS_1;
+ break;
+ }
+}
+
+/**
+ * @brief Sends an SDIO command with no response expected.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ *
+ * @notapi
+ */
+void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_CPSMEN;
+ while ((sdcp->sdmmc->STA & SDMMC_STA_CMDSENT) == 0)
+ ;
+ sdcp->sdmmc->ICR = SDMMC_ICR_CMDSENTC;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected.
+ * @note The CRC is not verified.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
+ while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL);
+ if ((sta & (SDMMC_STA_CTIMEOUT)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ *resp = sdcp->sdmmc->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Sends an SDIO command with a short response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (one word)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_CPSMEN;
+ while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL);
+ if ((sta & (SDMMC_STA_CTIMEOUT | SDMMC_STA_CCRCFAIL)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ *resp = sdcp->sdmmc->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Sends an SDIO command with a long response expected and CRC.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] cmd card command
+ * @param[in] arg command argument
+ * @param[out] resp pointer to the response buffer (four words)
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp) {
+ uint32_t sta;
+
+ (void)sdcp;
+
+ sdcp->sdmmc->ARG = arg;
+ sdcp->sdmmc->CMD = (uint32_t)cmd | SDMMC_CMD_WAITRESP_0 | SDMMC_CMD_WAITRESP_1 |
+ SDMMC_CMD_CPSMEN;
+ while (((sta = sdcp->sdmmc->STA) & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL)) == 0)
+ ;
+ sdcp->sdmmc->ICR = sta & (SDMMC_STA_CMDREND | SDMMC_STA_CTIMEOUT |
+ SDMMC_STA_CCRCFAIL);
+ if ((sta & (SDMMC_STA_ERROR_MASK)) != 0) {
+ sdc_lld_collect_errors(sdcp, sta);
+ return HAL_FAILED;
+ }
+ /* Save bytes in reverse order because MSB in response comes first.*/
+ *resp++ = sdcp->sdmmc->RESP4;
+ *resp++ = sdcp->sdmmc->RESP3;
+ *resp++ = sdcp->sdmmc->RESP2;
+ *resp = sdcp->sdmmc->RESP1;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Reads special registers using data bus.
+ * @details Needs only during card detection procedure.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] buf pointer to the read buffer
+ * @param[in] bytes number of bytes to read
+ * @param[in] cmd card command
+ * @param[in] arg argument for command
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
+ uint8_t cmd, uint32_t arg) {
+ uint32_t resp[1];
+
+ if (sdc_lld_prepare_read_bytes(sdcp, buf, bytes))
+ goto error;
+
+ if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_CMDTRANS | cmd, arg, resp) ||
+ MMCSD_R1_ERROR(resp[0]))
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, 1, resp))
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, 1, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] blocks number of blocks to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks) {
+ uint32_t resp[1];
+
+ osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
+
+ sdcp->sdmmc->DTIMER = STM32_SDC_SDMMC_READ_TIMEOUT;
+
+ /* Checks for errors and waits for the card to be ready for reading.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Setting up data transfer.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
+ SDMMC_MASK_DTIMEOUTIE |
+ SDMMC_MASK_RXOVERRIE |
+ SDMMC_MASK_DATAENDIE;
+ sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
+
+ /* Transfer modes.*/
+ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DTDIR |
+ SDMMC_DCTRL_DBLOCKSIZE_3 |
+ SDMMC_DCTRL_DBLOCKSIZE_0;
+
+ /* Prepares IDMA.*/
+ sdcp->sdmmc->IDMABASE0 = (uint32_t)buf;
+ sdcp->sdmmc->IDMACTRL = SDMMC_IDMA_IDMAEN;
+
+ if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == true)
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, blocks, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] n number of blocks to write
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks) {
+ uint32_t resp[1];
+
+ osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE);
+
+ sdcp->sdmmc->DTIMER = STM32_SDC_SDMMC_WRITE_TIMEOUT;
+
+ /* Checks for errors and waits for the card to be ready for writing.*/
+ if (_sdc_wait_for_transfer_state(sdcp))
+ return HAL_FAILED;
+
+ /* Setting up data transfer.*/
+ sdcp->sdmmc->ICR = SDMMC_ICR_ALL_FLAGS;
+ sdcp->sdmmc->MASK = SDMMC_MASK_DCRCFAILIE |
+ SDMMC_MASK_DTIMEOUTIE |
+ SDMMC_MASK_TXUNDERRIE |
+ SDMMC_MASK_DATAENDIE;
+ sdcp->sdmmc->DLEN = blocks * MMCSD_BLOCK_SIZE;
+
+ /* Transfer modes.*/
+ sdcp->sdmmc->DCTRL = SDMMC_DCTRL_DBLOCKSIZE_3 |
+ SDMMC_DCTRL_DBLOCKSIZE_0;
+
+ /* Prepares IDMA.*/
+ sdcp->sdmmc->IDMABASE0 = (uint32_t)buf;
+ sdcp->sdmmc->IDMACTRL = SDMMC_IDMA_IDMAEN;
+
+ if (sdc_lld_prepare_write(sdcp, startblk, blocks, resp) == true)
+ goto error;
+
+ if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == true)
+ goto error;
+
+ return HAL_SUCCESS;
+
+error:
+ sdc_lld_error_cleanup(sdcp, blocks, resp);
+ return HAL_FAILED;
+}
+
+/**
+ * @brief Reads one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to read
+ * @param[out] buf pointer to the read buffer
+ * @param[in] blocks number of blocks to read
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks) {
+
+#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < blocks; i++) {
+ if (sdc_lld_read_aligned(sdcp, startblk, sdcp->buf, 1))
+ return HAL_FAILED;
+ memcpy(buf, sdcp->buf, MMCSD_BLOCK_SIZE);
+ buf += MMCSD_BLOCK_SIZE;
+ startblk++;
+ }
+ return HAL_SUCCESS;
+ }
+#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
+#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ return sdc_lld_read_aligned(sdcp, startblk, buf, blocks);
+}
+
+/**
+ * @brief Writes one or more blocks.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[in] startblk first block to write
+ * @param[out] buf pointer to the write buffer
+ * @param[in] blocks number of blocks to write
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS operation succeeded.
+ * @retval HAL_FAILED operation failed.
+ *
+ * @notapi
+ */
+bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks) {
+
+#if STM32_SDC_SDMMC_UNALIGNED_SUPPORT
+ if (((unsigned)buf & 3) != 0) {
+ uint32_t i;
+ for (i = 0; i < blocks; i++) {
+ memcpy(sdcp->buf, buf, MMCSD_BLOCK_SIZE);
+ buf += MMCSD_BLOCK_SIZE;
+ if (sdc_lld_write_aligned(sdcp, startblk, sdcp->buf, 1))
+ return HAL_FAILED;
+ startblk++;
+ }
+ return HAL_SUCCESS;
+ }
+#else /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ osalDbgAssert((((unsigned)buf & 3) == 0), "unaligned buffer");
+#endif /* !STM32_SDC_SDIO_UNALIGNED_SUPPORT */
+ return sdc_lld_write_aligned(sdcp, startblk, buf, blocks);
+}
+
+/**
+ * @brief Waits for card idle condition.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @return The operation status.
+ * @retval HAL_SUCCESS the operation succeeded.
+ * @retval HAL_FAILED the operation failed.
+ *
+ * @api
+ */
+bool sdc_lld_sync(SDCDriver *sdcp) {
+
+ /* CHTODO: Implement.*/
+ (void)sdcp;
+ return HAL_SUCCESS;
+}
+
+/**
+ * @brief Shared service routine.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ */
+void sdc_lld_serve_interrupt(SDCDriver *sdcp) {
+
+ /* Disables the source but the status flags are not reset because the
+ read/write functions needs to check them.*/
+ sdcp->sdmmc->MASK = 0;
+
+ osalSysLockFromISR();
+ osalThreadResumeI(&sdcp->thread, MSG_OK);
+ osalSysUnlockFromISR();
+}
+
+#endif /* HAL_USE_SDC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.h b/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.h
index 334bf7a701..d67bb60624 100644
--- a/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.h
+++ b/os/hal/ports/STM32/LLD/SDMMCv2/hal_sdc_lld.h
@@ -1,301 +1,301 @@
-/*
- 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 SDMMCv2/hal_sdc_lld.h
- * @brief STM32 SDC subsystem low level driver header.
- *
- * @addtogroup SDC
- * @{
- */
-
-#ifndef HAL_SDC_LLD_H
-#define HAL_SDC_LLD_H
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SDMMC1 driver enable switch.
- * @details If set to @p TRUE the support for SDMMC1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SDC_USE_SDMMC1) || defined(__DOXYGEN__)
-#define STM32_SDC_USE_SDMMC1 FALSE
-#endif
-
-/**
- * @brief SDMMC2 driver enable switch.
- * @details If set to @p TRUE the support for SDMMC2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SDC_USE_SDMMC2) || defined(__DOXYGEN__)
-#define STM32_SDC_USE_SDMMC2 FALSE
-#endif
-
-/**
- * @brief Support for unaligned transfers.
- * @note Unaligned transfers are much slower.
- */
-#if !defined(STM32_SDC_SDMMC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE
-#endif
-
-/**
- * @brief Write timeout in card clock cycles.
- */
-#if !defined(STM32_SDC_SDMMC_WRITE_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_WRITE_TIMEOUT 1000000
-#endif
-
-/**
- * @brief Read timeout in card clock cycles.
- */
-#if !defined(STM32_SDC_SDMMC_READ_TIMEOUT) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_READ_TIMEOUT 1000000
-#endif
-
-/**
- * @brief Card clock activation delay in milliseconds.
- */
-#if !defined(STM32_SDC_SDMMC_CLOCK_DELAY) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_CLOCK_DELAY 10
-#endif
-
-/**
- * @brief Card clock power saving enable.
- */
-#if !defined(STM32_SDC_SDMMC_PWRSAV) || defined(__DOXYGEN__)
-#define STM32_SDC_SDMMC_PWRSAV TRUE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* Registry checks.*/
-#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_HANDLER)) || \
- (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_HANDLER))
-#error "STM32_SDMMCx_HANDLER not defined in registry"
-#endif
-
-#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_NUMBER)) || \
- (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_NUMBER))
-#error "STM32_SDMMCx_NUMBER not defined in registry"
-#endif
-
-/* Units checks.*/
-#if STM32_SDC_USE_SDMMC1 && !STM32_HAS_SDMMC1
-#error "SDMMC1 not present in the selected device"
-#endif
-
-#if STM32_SDC_USE_SDMMC2 && !STM32_HAS_SDMMC2
-#error "SDMMC2 not present in the selected device"
-#endif
-
-#if !STM32_SDC_USE_SDMMC1 && !STM32_SDC_USE_SDMMC2
-#error "SDC driver activated but no SDMMC peripheral assigned"
-#endif
-
-/* Clock related tests.*/
-#if STM32_HAS_SDMMC1 && !defined(STM32_SDMMC1CLK)
-#error "STM32_SDMMC1CLK not defined"
-#endif
-
-/* Clock related tests.*/
-#if STM32_HAS_SDMMC2 && !defined(STM32_SDMMC2CLK)
-#error "STM32_SDMMC2CLK not defined"
-#endif
-
-#if !defined(STM32_HCLK)
-#error "STM32_HCLK not defined"
-#endif
-
-#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK * 10 > STM32_HCLK * 7)
-#error "STM32_SDMMC1CLK must not exceed STM32_HCLK * 0.7"
-#endif
-
-#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK * 10 > STM32_HCLK * 7)
-#error "STM32_SDMMC2CLK must not exceed STM32_HCLK * 0.7"
-#endif
-
-#if !defined(STM32_SDMMC_MAXCLK)
-#define STM32_SDMMC_MAXCLK 50000000
-#endif
-
-#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK > STM32_SDMMC_MAXCLK)
-#error "STM32_SDMMC1CLK must not exceed STM32_SDMMC_MAXCLK"
-#endif
-
-#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK > STM32_SDMMC_MAXCLK)
-#error "STM32_SDMMC2CLK must not exceed STM32_SDMMC_MAXCLK"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of card flags.
- */
-typedef uint32_t sdcmode_t;
-
-/**
- * @brief SDC Driver condition flags type.
- */
-typedef uint32_t sdcflags_t;
-
-/**
- * @brief Type of a structure representing an SDC driver.
- */
-typedef struct SDCDriver SDCDriver;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Bus width.
- */
- sdcbusmode_t bus_width;
- /* End of the mandatory fields.*/
-} SDCConfig;
-
-/**
- * @brief @p SDCDriver specific methods.
- */
-#define _sdc_driver_methods \
- _mmcsd_block_device_methods
-
-/**
- * @extends MMCSDBlockDeviceVMT
- *
- * @brief @p SDCDriver virtual methods table.
- */
-struct SDCDriverVMT {
- _sdc_driver_methods
-};
-
-/**
- * @brief Structure representing an SDC driver.
- */
-struct SDCDriver {
- /**
- * @brief Virtual Methods Table.
- */
- const struct SDCDriverVMT *vmt;
- _mmcsd_block_device_data
- /**
- * @brief Current configuration data.
- */
- const SDCConfig *config;
- /**
- * @brief Various flags regarding the mounted card.
- */
- sdcmode_t cardmode;
- /**
- * @brief Errors flags.
- */
- sdcflags_t errors;
- /**
- * @brief Card RCA.
- */
- uint32_t rca;
- /* End of the mandatory fields.*/
- /**
- * @brief Thread waiting for I/O completion IRQ.
- */
- thread_reference_t thread;
- /**
- * @brief Pointer to the SDMMC registers block.
- * @note Needed for debugging aid.
- */
- SDMMC_TypeDef *sdmmc;
- /**
- * @brief Input clock frequency.
- */
- uint32_t clkfreq;
- /**
- * @brief Buffer for internal operations.
- */
- uint8_t buf[MMCSD_BLOCK_SIZE];
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SDC_USE_SDMMC1 && !defined(__DOXYGEN__)
-extern SDCDriver SDCD1;
-#endif
-
-#if STM32_SDC_USE_SDMMC2 && !defined(__DOXYGEN__)
-extern SDCDriver SDCD2;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void sdc_lld_init(void);
- void sdc_lld_start(SDCDriver *sdcp);
- void sdc_lld_stop(SDCDriver *sdcp);
- void sdc_lld_start_clk(SDCDriver *sdcp);
- void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk);
- void sdc_lld_stop_clk(SDCDriver *sdcp);
- void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
- void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
- bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp);
- bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
- uint8_t cmd, uint32_t argument);
- bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t blocks);
- bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t blocks);
- bool sdc_lld_sync(SDCDriver *sdcp);
- bool sdc_lld_is_card_inserted(SDCDriver *sdcp);
- bool sdc_lld_is_write_protected(SDCDriver *sdcp);
- void sdc_lld_serve_interrupt(SDCDriver *sdcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SDC */
-
-#endif /* HAL_SDC_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 SDMMCv2/hal_sdc_lld.h
+ * @brief STM32 SDC subsystem low level driver header.
+ *
+ * @addtogroup SDC
+ * @{
+ */
+
+#ifndef HAL_SDC_LLD_H
+#define HAL_SDC_LLD_H
+
+#if HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SDMMC1 driver enable switch.
+ * @details If set to @p TRUE the support for SDMMC1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SDC_USE_SDMMC1) || defined(__DOXYGEN__)
+#define STM32_SDC_USE_SDMMC1 FALSE
+#endif
+
+/**
+ * @brief SDMMC2 driver enable switch.
+ * @details If set to @p TRUE the support for SDMMC2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SDC_USE_SDMMC2) || defined(__DOXYGEN__)
+#define STM32_SDC_USE_SDMMC2 FALSE
+#endif
+
+/**
+ * @brief Support for unaligned transfers.
+ * @note Unaligned transfers are much slower.
+ */
+#if !defined(STM32_SDC_SDMMC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE
+#endif
+
+/**
+ * @brief Write timeout in card clock cycles.
+ */
+#if !defined(STM32_SDC_SDMMC_WRITE_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_WRITE_TIMEOUT 1000000
+#endif
+
+/**
+ * @brief Read timeout in card clock cycles.
+ */
+#if !defined(STM32_SDC_SDMMC_READ_TIMEOUT) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_READ_TIMEOUT 1000000
+#endif
+
+/**
+ * @brief Card clock activation delay in milliseconds.
+ */
+#if !defined(STM32_SDC_SDMMC_CLOCK_DELAY) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_CLOCK_DELAY 10
+#endif
+
+/**
+ * @brief Card clock power saving enable.
+ */
+#if !defined(STM32_SDC_SDMMC_PWRSAV) || defined(__DOXYGEN__)
+#define STM32_SDC_SDMMC_PWRSAV TRUE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* Registry checks.*/
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_HANDLER)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_HANDLER))
+#error "STM32_SDMMCx_HANDLER not defined in registry"
+#endif
+
+#if (STM32_SDC_USE_SDMMC1 && !defined(STM32_SDMMC1_NUMBER)) || \
+ (STM32_SDC_USE_SDMMC2 && !defined(STM32_SDMMC2_NUMBER))
+#error "STM32_SDMMCx_NUMBER not defined in registry"
+#endif
+
+/* Units checks.*/
+#if STM32_SDC_USE_SDMMC1 && !STM32_HAS_SDMMC1
+#error "SDMMC1 not present in the selected device"
+#endif
+
+#if STM32_SDC_USE_SDMMC2 && !STM32_HAS_SDMMC2
+#error "SDMMC2 not present in the selected device"
+#endif
+
+#if !STM32_SDC_USE_SDMMC1 && !STM32_SDC_USE_SDMMC2
+#error "SDC driver activated but no SDMMC peripheral assigned"
+#endif
+
+/* Clock related tests.*/
+#if STM32_HAS_SDMMC1 && !defined(STM32_SDMMC1CLK)
+#error "STM32_SDMMC1CLK not defined"
+#endif
+
+/* Clock related tests.*/
+#if STM32_HAS_SDMMC2 && !defined(STM32_SDMMC2CLK)
+#error "STM32_SDMMC2CLK not defined"
+#endif
+
+#if !defined(STM32_HCLK)
+#error "STM32_HCLK not defined"
+#endif
+
+#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK * 10 > STM32_HCLK * 7)
+#error "STM32_SDMMC1CLK must not exceed STM32_HCLK * 0.7"
+#endif
+
+#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK * 10 > STM32_HCLK * 7)
+#error "STM32_SDMMC2CLK must not exceed STM32_HCLK * 0.7"
+#endif
+
+#if !defined(STM32_SDMMC_MAXCLK)
+#define STM32_SDMMC_MAXCLK 50000000
+#endif
+
+#if STM32_HAS_SDMMC1 && (STM32_SDMMC1CLK > STM32_SDMMC_MAXCLK)
+#error "STM32_SDMMC1CLK must not exceed STM32_SDMMC_MAXCLK"
+#endif
+
+#if STM32_HAS_SDMMC2 && (STM32_SDMMC2CLK > STM32_SDMMC_MAXCLK)
+#error "STM32_SDMMC2CLK must not exceed STM32_SDMMC_MAXCLK"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of card flags.
+ */
+typedef uint32_t sdcmode_t;
+
+/**
+ * @brief SDC Driver condition flags type.
+ */
+typedef uint32_t sdcflags_t;
+
+/**
+ * @brief Type of a structure representing an SDC driver.
+ */
+typedef struct SDCDriver SDCDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Bus width.
+ */
+ sdcbusmode_t bus_width;
+ /* End of the mandatory fields.*/
+} SDCConfig;
+
+/**
+ * @brief @p SDCDriver specific methods.
+ */
+#define _sdc_driver_methods \
+ _mmcsd_block_device_methods
+
+/**
+ * @extends MMCSDBlockDeviceVMT
+ *
+ * @brief @p SDCDriver virtual methods table.
+ */
+struct SDCDriverVMT {
+ _sdc_driver_methods
+};
+
+/**
+ * @brief Structure representing an SDC driver.
+ */
+struct SDCDriver {
+ /**
+ * @brief Virtual Methods Table.
+ */
+ const struct SDCDriverVMT *vmt;
+ _mmcsd_block_device_data
+ /**
+ * @brief Current configuration data.
+ */
+ const SDCConfig *config;
+ /**
+ * @brief Various flags regarding the mounted card.
+ */
+ sdcmode_t cardmode;
+ /**
+ * @brief Errors flags.
+ */
+ sdcflags_t errors;
+ /**
+ * @brief Card RCA.
+ */
+ uint32_t rca;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Thread waiting for I/O completion IRQ.
+ */
+ thread_reference_t thread;
+ /**
+ * @brief Pointer to the SDMMC registers block.
+ * @note Needed for debugging aid.
+ */
+ SDMMC_TypeDef *sdmmc;
+ /**
+ * @brief Input clock frequency.
+ */
+ uint32_t clkfreq;
+ /**
+ * @brief Buffer for internal operations.
+ */
+ uint8_t buf[MMCSD_BLOCK_SIZE];
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SDC_USE_SDMMC1 && !defined(__DOXYGEN__)
+extern SDCDriver SDCD1;
+#endif
+
+#if STM32_SDC_USE_SDMMC2 && !defined(__DOXYGEN__)
+extern SDCDriver SDCD2;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sdc_lld_init(void);
+ void sdc_lld_start(SDCDriver *sdcp);
+ void sdc_lld_stop(SDCDriver *sdcp);
+ void sdc_lld_start_clk(SDCDriver *sdcp);
+ void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk);
+ void sdc_lld_stop_clk(SDCDriver *sdcp);
+ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode);
+ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg);
+ bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
+ uint32_t *resp);
+ bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes,
+ uint8_t cmd, uint32_t argument);
+ bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
+ uint8_t *buf, uint32_t blocks);
+ bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
+ const uint8_t *buf, uint32_t blocks);
+ bool sdc_lld_sync(SDCDriver *sdcp);
+ bool sdc_lld_is_card_inserted(SDCDriver *sdcp);
+ bool sdc_lld_is_write_protected(SDCDriver *sdcp);
+ void sdc_lld_serve_interrupt(SDCDriver *sdcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SDC */
+
+#endif /* HAL_SDC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv1/driver.mk b/os/hal/ports/STM32/LLD/SPIv1/driver.mk
index 1af9692f9d..619ff93196 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/SPIv1/driver.mk
@@ -1,13 +1,13 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_I2S TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
-endif
-ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_I2S TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
+endif
+ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1
diff --git a/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c b/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
index 235d2b8132..4025bee3ed 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.c
@@ -1,584 +1,584 @@
-/*
- 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 SPIv1/hal_i2s_lld.c
- * @brief STM32 I2S subsystem low level driver source.
- *
- * @addtogroup I2S
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_I2S || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define I2S1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_RX_DMA_STREAM, \
- STM32_SPI1_RX_DMA_CHN)
-
-#define I2S1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_TX_DMA_STREAM, \
- STM32_SPI1_TX_DMA_CHN)
-
-#define I2S2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_RX_DMA_STREAM, \
- STM32_SPI2_RX_DMA_CHN)
-
-#define I2S2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_TX_DMA_STREAM, \
- STM32_SPI2_TX_DMA_CHN)
-
-#define I2S3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_RX_DMA_STREAM, \
- STM32_SPI3_RX_DMA_CHN)
-
-#define I2S3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_TX_DMA_STREAM, \
- STM32_SPI3_TX_DMA_CHN)
-
-/*
- * Static I2S settings for I2S1.
- */
-#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE)
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG 0
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
-#endif
-#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
- SPI_I2SCFGR_I2SCFG_0)
-#endif
-#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
-
-/*
- * Static I2S settings for I2S2.
- */
-#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE)
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG 0
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
-#endif
-#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
- SPI_I2SCFGR_I2SCFG_0)
-#endif
-#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
-
-/*
- * Static I2S settings for I2S3.
- */
-#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE)
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG 0
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
-#endif
-#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
- SPI_I2SCFGR_I2SCFG_0)
-#endif
-#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief I2S1 driver identifier.*/
-#if STM32_I2S_USE_SPI1 || defined(__DOXYGEN__)
-I2SDriver I2SD1;
-#endif
-
-/** @brief I2S2 driver identifier.*/
-#if STM32_I2S_USE_SPI2 || defined(__DOXYGEN__)
-I2SDriver I2SD2;
-#endif
-
-/** @brief I2S3 driver identifier.*/
-#if STM32_I2S_USE_SPI3 || defined(__DOXYGEN__)
-I2SDriver I2SD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) || \
- STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) || \
- STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
-/**
- * @brief Shared end-of-rx service routine.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) {
-
- (void)i2sp;
-
- /* DMA errors handling.*/
-#if defined(STM32_I2S_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_I2S_DMA_ERROR_HOOK(i2sp);
- }
-#endif
-
- /* Callbacks handling, note it is portable code defined in the high
- level driver.*/
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _i2s_isr_full_code(i2sp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _i2s_isr_half_code(i2sp);
- }
-}
-#endif
-
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE) || \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE) || \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
-/**
- * @brief Shared end-of-tx service routine.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) {
-
- (void)i2sp;
-
- /* DMA errors handling.*/
-#if defined(STM32_I2S_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_I2S_DMA_ERROR_HOOK(i2sp);
- }
-#endif
-
- /* Callbacks handling, note it is portable code defined in the high
- level driver.*/
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _i2s_isr_full_code(i2sp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _i2s_isr_half_code(i2sp);
- }
-}
-#endif
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level I2S driver initialization.
- *
- * @notapi
- */
-void i2s_lld_init(void) {
-
-#if STM32_I2S_USE_SPI1
- i2sObjectInit(&I2SD1);
- I2SD1.spi = SPI1;
- I2SD1.cfg = STM32_I2S1_CFGR_CFG;
- I2SD1.dmarx = NULL;
- I2SD1.dmatx = NULL;
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
- I2SD1.rxdmamode = STM32_DMA_CR_CHSEL(I2S1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD1.rxdmamode = 0;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
- I2SD1.txdmamode = STM32_DMA_CR_CHSEL(I2S1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD1.txdmamode = 0;
-#endif
-#endif
-
-#if STM32_I2S_USE_SPI2
- i2sObjectInit(&I2SD2);
- I2SD2.spi = SPI2;
- I2SD2.cfg = STM32_I2S2_CFGR_CFG;
- I2SD2.dmarx = NULL;
- I2SD2.dmatx = NULL;
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
- I2SD2.rxdmamode = STM32_DMA_CR_CHSEL(I2S2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD2.rxdmamode = 0;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
- I2SD2.txdmamode = STM32_DMA_CR_CHSEL(I2S2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD2.txdmamode = 0;
-#endif
-#endif
-
-#if STM32_I2S_USE_SPI3
- i2sObjectInit(&I2SD3);
- I2SD3.spi = SPI3;
- I2SD3.cfg = STM32_I2S3_CFGR_CFG;
- I2SD3.dmarx = NULL;
- I2SD3.dmatx = NULL;
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
- I2SD3.rxdmamode = STM32_DMA_CR_CHSEL(I2S3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD3.rxdmamode = 0;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
- I2SD3.txdmamode = STM32_DMA_CR_CHSEL(I2S3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD3.txdmamode = 0;
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the I2S peripheral.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_start(I2SDriver *i2sp) {
-
- /* If in stopped state then enables the SPI and DMA clocks.*/
- if (i2sp->state == I2S_STOP) {
-
-#if STM32_I2S_USE_SPI1
- if (&I2SD1 == i2sp) {
-
- /* Enabling I2S unit clock.*/
- rccEnableSPI1(true);
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
- i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI1_RX_DMA_STREAM,
- STM32_I2S_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
- i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI1_TX_DMA_STREAM,
- STM32_I2S_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
-#endif
- }
-#endif
-
-#if STM32_I2S_USE_SPI2
- if (&I2SD2 == i2sp) {
-
- /* Enabling I2S unit clock.*/
- rccEnableSPI2(true);
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
- i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI2_RX_DMA_STREAM,
- STM32_I2S_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
- i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI2_TX_DMA_STREAM,
- STM32_I2S_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
-#endif
- }
-#endif
-
-#if STM32_I2S_USE_SPI3
- if (&I2SD3 == i2sp) {
-
- /* Enabling I2S unit clock.*/
- rccEnableSPI3(true);
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
- i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI3_RX_DMA_STREAM,
- STM32_I2S_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
- i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI3_TX_DMA_STREAM,
- STM32_I2S_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
-#endif
- }
-#endif
- }
-
- /* I2S (re)configuration.*/
- i2sp->spi->I2SPR = i2sp->config->i2spr;
- i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD;
-}
-
-/**
- * @brief Deactivates the I2S peripheral.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_stop(I2SDriver *i2sp) {
-
- /* If in ready state then disables the SPI clock.*/
- if (i2sp->state == I2S_READY) {
-
- /* SPI disable.*/
- i2sp->spi->CR2 = 0;
- if (NULL != i2sp->dmarx) {
- dmaStreamFreeI(i2sp->dmarx);
- i2sp->dmarx = NULL;
- }
- if (NULL != i2sp->dmatx) {
- dmaStreamFreeI(i2sp->dmatx);
- i2sp->dmatx = NULL;
- }
-
-#if STM32_I2S_USE_SPI1
- if (&I2SD1 == i2sp)
- rccDisableSPI1();
-#endif
-
-#if STM32_I2S_USE_SPI2
- if (&I2SD2 == i2sp)
- rccDisableSPI2();
-#endif
-
-#if STM32_I2S_USE_SPI3
- if (&I2SD3 == i2sp)
- rccDisableSPI3();
-#endif
- }
-}
-
-/**
- * @brief Starts a I2S data exchange.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_start_exchange(I2SDriver *i2sp) {
- size_t size = i2sp->config->size;
-
- /* In 32 bit modes the DMA has to perform double operations because fetches
- are always performed using 16 bit accesses.
- DATLEN CHLEN SIZE
- 00 (16) 0 (16) 16
- 00 (16) 1 (32) 16
- 01 (24) X 32
- 10 (32) X 32
- 11 (NA) X NA
- */
- if ((i2sp->config->i2scfgr & SPI_I2SCFGR_DATLEN) != 0)
- size *= 2;
-
- /* RX DMA setup.*/
- if (NULL != i2sp->dmarx) {
- dmaStreamSetMode(i2sp->dmarx, i2sp->rxdmamode);
- dmaStreamSetPeripheral(i2sp->dmarx, &i2sp->spi->DR);
- dmaStreamSetMemory0(i2sp->dmarx, i2sp->config->rx_buffer);
- dmaStreamSetTransactionSize(i2sp->dmarx, size);
- dmaStreamEnable(i2sp->dmarx);
- }
-
- /* TX DMA setup.*/
- if (NULL != i2sp->dmatx) {
- dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode);
- dmaStreamSetPeripheral(i2sp->dmatx, &i2sp->spi->DR);
- dmaStreamSetMemory0(i2sp->dmatx, i2sp->config->tx_buffer);
- dmaStreamSetTransactionSize(i2sp->dmatx, size);
- dmaStreamEnable(i2sp->dmatx);
- }
-
- /* Starting transfer.*/
- i2sp->spi->I2SCFGR |= SPI_I2SCFGR_I2SE;
-}
-
-/**
- * @brief Stops the ongoing data exchange.
- * @details The ongoing data exchange, if any, is stopped, if the driver
- * was not active the function does nothing.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_stop_exchange(I2SDriver *i2sp) {
-
- /* Stop TX DMA, if enabled.*/
- if (NULL != i2sp->dmatx) {
- dmaStreamDisable(i2sp->dmatx);
-
- /* From the RM: To switch off the I2S, by clearing I2SE, it is mandatory
- to wait for TXE = 1 and BSY = 0.*/
- while ((i2sp->spi->SR & (SPI_SR_TXE | SPI_SR_BSY)) != SPI_SR_TXE)
- ;
-
- /* Stop SPI/I2S peripheral.*/
- i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
- }
-
- /* Stop RX DMA, if enabled then draining the RX DR.*/
- if (NULL != i2sp->dmarx) {
- dmaStreamDisable(i2sp->dmarx);
-
- /* Waiting for some data to be present in RX DR.*/
- while ((i2sp->spi->SR & SPI_SR_RXNE) != SPI_SR_RXNE)
- ;
-
- /* Stop SPI/I2S peripheral.*/
- i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
-
- /* Purging data in DR.*/
- while ((i2sp->spi->SR & SPI_SR_RXNE) != 0)
- (void) i2sp->spi->DR;
- }
-}
-
-#endif /* HAL_USE_I2S */
-
-/** @} */
+/*
+ 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 SPIv1/hal_i2s_lld.c
+ * @brief STM32 I2S subsystem low level driver source.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define I2S1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_RX_DMA_STREAM, \
+ STM32_SPI1_RX_DMA_CHN)
+
+#define I2S1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_TX_DMA_STREAM, \
+ STM32_SPI1_TX_DMA_CHN)
+
+#define I2S2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_RX_DMA_STREAM, \
+ STM32_SPI2_RX_DMA_CHN)
+
+#define I2S2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_TX_DMA_STREAM, \
+ STM32_SPI2_TX_DMA_CHN)
+
+#define I2S3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_RX_DMA_STREAM, \
+ STM32_SPI3_RX_DMA_CHN)
+
+#define I2S3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_TX_DMA_STREAM, \
+ STM32_SPI3_TX_DMA_CHN)
+
+/*
+ * Static I2S settings for I2S1.
+ */
+#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE)
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG 0
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
+#endif
+#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
+ SPI_I2SCFGR_I2SCFG_0)
+#endif
+#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
+
+/*
+ * Static I2S settings for I2S2.
+ */
+#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE)
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG 0
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
+#endif
+#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
+ SPI_I2SCFGR_I2SCFG_0)
+#endif
+#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
+
+/*
+ * Static I2S settings for I2S3.
+ */
+#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE)
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG 0
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
+#endif
+#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
+ SPI_I2SCFGR_I2SCFG_0)
+#endif
+#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief I2S1 driver identifier.*/
+#if STM32_I2S_USE_SPI1 || defined(__DOXYGEN__)
+I2SDriver I2SD1;
+#endif
+
+/** @brief I2S2 driver identifier.*/
+#if STM32_I2S_USE_SPI2 || defined(__DOXYGEN__)
+I2SDriver I2SD2;
+#endif
+
+/** @brief I2S3 driver identifier.*/
+#if STM32_I2S_USE_SPI3 || defined(__DOXYGEN__)
+I2SDriver I2SD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) || \
+ STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) || \
+ STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
+/**
+ * @brief Shared end-of-rx service routine.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) {
+
+ (void)i2sp;
+
+ /* DMA errors handling.*/
+#if defined(STM32_I2S_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_I2S_DMA_ERROR_HOOK(i2sp);
+ }
+#endif
+
+ /* Callbacks handling, note it is portable code defined in the high
+ level driver.*/
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _i2s_isr_full_code(i2sp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _i2s_isr_half_code(i2sp);
+ }
+}
+#endif
+
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE) || \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE) || \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
+/**
+ * @brief Shared end-of-tx service routine.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) {
+
+ (void)i2sp;
+
+ /* DMA errors handling.*/
+#if defined(STM32_I2S_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_I2S_DMA_ERROR_HOOK(i2sp);
+ }
+#endif
+
+ /* Callbacks handling, note it is portable code defined in the high
+ level driver.*/
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _i2s_isr_full_code(i2sp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _i2s_isr_half_code(i2sp);
+ }
+}
+#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2S driver initialization.
+ *
+ * @notapi
+ */
+void i2s_lld_init(void) {
+
+#if STM32_I2S_USE_SPI1
+ i2sObjectInit(&I2SD1);
+ I2SD1.spi = SPI1;
+ I2SD1.cfg = STM32_I2S1_CFGR_CFG;
+ I2SD1.dmarx = NULL;
+ I2SD1.dmatx = NULL;
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+ I2SD1.rxdmamode = STM32_DMA_CR_CHSEL(I2S1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD1.rxdmamode = 0;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+ I2SD1.txdmamode = STM32_DMA_CR_CHSEL(I2S1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD1.txdmamode = 0;
+#endif
+#endif
+
+#if STM32_I2S_USE_SPI2
+ i2sObjectInit(&I2SD2);
+ I2SD2.spi = SPI2;
+ I2SD2.cfg = STM32_I2S2_CFGR_CFG;
+ I2SD2.dmarx = NULL;
+ I2SD2.dmatx = NULL;
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+ I2SD2.rxdmamode = STM32_DMA_CR_CHSEL(I2S2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD2.rxdmamode = 0;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+ I2SD2.txdmamode = STM32_DMA_CR_CHSEL(I2S2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD2.txdmamode = 0;
+#endif
+#endif
+
+#if STM32_I2S_USE_SPI3
+ i2sObjectInit(&I2SD3);
+ I2SD3.spi = SPI3;
+ I2SD3.cfg = STM32_I2S3_CFGR_CFG;
+ I2SD3.dmarx = NULL;
+ I2SD3.dmatx = NULL;
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+ I2SD3.rxdmamode = STM32_DMA_CR_CHSEL(I2S3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD3.rxdmamode = 0;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+ I2SD3.txdmamode = STM32_DMA_CR_CHSEL(I2S3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD3.txdmamode = 0;
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start(I2SDriver *i2sp) {
+
+ /* If in stopped state then enables the SPI and DMA clocks.*/
+ if (i2sp->state == I2S_STOP) {
+
+#if STM32_I2S_USE_SPI1
+ if (&I2SD1 == i2sp) {
+
+ /* Enabling I2S unit clock.*/
+ rccEnableSPI1(true);
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+ i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI1_RX_DMA_STREAM,
+ STM32_I2S_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+ i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI1_TX_DMA_STREAM,
+ STM32_I2S_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
+#endif
+ }
+#endif
+
+#if STM32_I2S_USE_SPI2
+ if (&I2SD2 == i2sp) {
+
+ /* Enabling I2S unit clock.*/
+ rccEnableSPI2(true);
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+ i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI2_RX_DMA_STREAM,
+ STM32_I2S_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+ i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI2_TX_DMA_STREAM,
+ STM32_I2S_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
+#endif
+ }
+#endif
+
+#if STM32_I2S_USE_SPI3
+ if (&I2SD3 == i2sp) {
+
+ /* Enabling I2S unit clock.*/
+ rccEnableSPI3(true);
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+ i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI3_RX_DMA_STREAM,
+ STM32_I2S_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+ i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI3_TX_DMA_STREAM,
+ STM32_I2S_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
+#endif
+ }
+#endif
+ }
+
+ /* I2S (re)configuration.*/
+ i2sp->spi->I2SPR = i2sp->config->i2spr;
+ i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD;
+}
+
+/**
+ * @brief Deactivates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_stop(I2SDriver *i2sp) {
+
+ /* If in ready state then disables the SPI clock.*/
+ if (i2sp->state == I2S_READY) {
+
+ /* SPI disable.*/
+ i2sp->spi->CR2 = 0;
+ if (NULL != i2sp->dmarx) {
+ dmaStreamFreeI(i2sp->dmarx);
+ i2sp->dmarx = NULL;
+ }
+ if (NULL != i2sp->dmatx) {
+ dmaStreamFreeI(i2sp->dmatx);
+ i2sp->dmatx = NULL;
+ }
+
+#if STM32_I2S_USE_SPI1
+ if (&I2SD1 == i2sp)
+ rccDisableSPI1();
+#endif
+
+#if STM32_I2S_USE_SPI2
+ if (&I2SD2 == i2sp)
+ rccDisableSPI2();
+#endif
+
+#if STM32_I2S_USE_SPI3
+ if (&I2SD3 == i2sp)
+ rccDisableSPI3();
+#endif
+ }
+}
+
+/**
+ * @brief Starts a I2S data exchange.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start_exchange(I2SDriver *i2sp) {
+ size_t size = i2sp->config->size;
+
+ /* In 32 bit modes the DMA has to perform double operations because fetches
+ are always performed using 16 bit accesses.
+ DATLEN CHLEN SIZE
+ 00 (16) 0 (16) 16
+ 00 (16) 1 (32) 16
+ 01 (24) X 32
+ 10 (32) X 32
+ 11 (NA) X NA
+ */
+ if ((i2sp->config->i2scfgr & SPI_I2SCFGR_DATLEN) != 0)
+ size *= 2;
+
+ /* RX DMA setup.*/
+ if (NULL != i2sp->dmarx) {
+ dmaStreamSetMode(i2sp->dmarx, i2sp->rxdmamode);
+ dmaStreamSetPeripheral(i2sp->dmarx, &i2sp->spi->DR);
+ dmaStreamSetMemory0(i2sp->dmarx, i2sp->config->rx_buffer);
+ dmaStreamSetTransactionSize(i2sp->dmarx, size);
+ dmaStreamEnable(i2sp->dmarx);
+ }
+
+ /* TX DMA setup.*/
+ if (NULL != i2sp->dmatx) {
+ dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode);
+ dmaStreamSetPeripheral(i2sp->dmatx, &i2sp->spi->DR);
+ dmaStreamSetMemory0(i2sp->dmatx, i2sp->config->tx_buffer);
+ dmaStreamSetTransactionSize(i2sp->dmatx, size);
+ dmaStreamEnable(i2sp->dmatx);
+ }
+
+ /* Starting transfer.*/
+ i2sp->spi->I2SCFGR |= SPI_I2SCFGR_I2SE;
+}
+
+/**
+ * @brief Stops the ongoing data exchange.
+ * @details The ongoing data exchange, if any, is stopped, if the driver
+ * was not active the function does nothing.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_stop_exchange(I2SDriver *i2sp) {
+
+ /* Stop TX DMA, if enabled.*/
+ if (NULL != i2sp->dmatx) {
+ dmaStreamDisable(i2sp->dmatx);
+
+ /* From the RM: To switch off the I2S, by clearing I2SE, it is mandatory
+ to wait for TXE = 1 and BSY = 0.*/
+ while ((i2sp->spi->SR & (SPI_SR_TXE | SPI_SR_BSY)) != SPI_SR_TXE)
+ ;
+
+ /* Stop SPI/I2S peripheral.*/
+ i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
+ }
+
+ /* Stop RX DMA, if enabled then draining the RX DR.*/
+ if (NULL != i2sp->dmarx) {
+ dmaStreamDisable(i2sp->dmarx);
+
+ /* Waiting for some data to be present in RX DR.*/
+ while ((i2sp->spi->SR & SPI_SR_RXNE) != SPI_SR_RXNE)
+ ;
+
+ /* Stop SPI/I2S peripheral.*/
+ i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
+
+ /* Purging data in DR.*/
+ while ((i2sp->spi->SR & SPI_SR_RXNE) != 0)
+ (void) i2sp->spi->DR;
+ }
+}
+
+#endif /* HAL_USE_I2S */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.h b/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.h
index 37b3f2ac51..70735a772d 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv1/hal_i2s_lld.h
@@ -1,371 +1,371 @@
-/*
- 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 SPIv1/hal_i2s_lld.h
- * @brief STM32 I2S subsystem low level driver header.
- *
- * @addtogroup I2S
- * @{
- */
-
-#ifndef HAL_I2S_LLD_H
-#define HAL_I2S_LLD_H
-
-#if HAL_USE_I2S || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Static I2S modes
- * @{
- */
-#define STM32_I2S_MODE_SLAVE 0
-#define STM32_I2S_MODE_MASTER 1
-#define STM32_I2S_MODE_RX 2
-#define STM32_I2S_MODE_TX 4
-#define STM32_I2S_MODE_RXTX (STM32_I2S_MODE_RX | \
- STM32_I2S_MODE_TX)
-/** @} */
-
-/**
- * @name Mode checks
- * @{
- */
-#define STM32_I2S_IS_MASTER(mode) ((mode) & STM32_I2S_MODE_MASTER)
-#define STM32_I2S_RX_ENABLED(mode) ((mode) & STM32_I2S_MODE_RX)
-#define STM32_I2S_TX_ENABLED(mode) ((mode) & STM32_I2S_MODE_TX)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief I2S1 driver enable switch.
- * @details If set to @p TRUE the support for I2S1 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_I2S_USE_SPI1) || defined(__DOXYGEN__)
-#define STM32_I2S_USE_SPI1 FALSE
-#endif
-
-/**
- * @brief I2S2 driver enable switch.
- * @details If set to @p TRUE the support for I2S2 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_I2S_USE_SPI2) || defined(__DOXYGEN__)
-#define STM32_I2S_USE_SPI2 FALSE
-#endif
-
-/**
- * @brief I2S3 driver enable switch.
- * @details If set to @p TRUE the support for I2S3 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_I2S_USE_SPI3) || defined(__DOXYGEN__)
-#define STM32_I2S_USE_SPI3 FALSE
-#endif
-
-/**
- * @brief I2S1 mode.
- */
-#if !defined(STM32_I2S_SPI1_MODE) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \
- STM32_I2S_MODE_RX)
-#endif
-
-/**
- * @brief I2S2 mode.
- */
-#if !defined(STM32_I2S_SPI2_MODE) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_MASTER | \
- STM32_I2S_MODE_RX)
-#endif
-
-/**
- * @brief I2S3 mode.
- */
-#if !defined(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI3_MODE (STM32_I2S_MODE_MASTER | \
- STM32_I2S_MODE_RX)
-#endif
-
-/**
- * @brief I2S1 interrupt priority level setting.
- */
-#if !defined(STM32_I2S_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2S2 interrupt priority level setting.
- */
-#if !defined(STM32_I2S_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2S3 interrupt priority level setting.
- */
-#if !defined(STM32_I2S_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2S1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_I2S_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2S2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_I2S_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2S3 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_I2S_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2S DMA error hook.
- */
-#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_I2S_USE_SPI1 && !STM32_SPI1_SUPPORTS_I2S
-#error "SPI1 does not support I2S mode"
-#endif
-
-#if STM32_I2S_USE_SPI2 && !STM32_SPI2_SUPPORTS_I2S
-#error "SPI2 does not support I2S mode"
-#endif
-
-#if STM32_I2S_USE_SPI3 && !STM32_SPI3_SUPPORTS_I2S
-#error "SPI3 does not support I2S mode"
-#endif
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) && \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
-#error "I2S1 RX and TX mode not supported in this driver implementation"
-#endif
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) && \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
-#error "I2S2 RX and TX mode not supported in this driver implementation"
-#endif
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) && \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
-#error "I2S3 RX and TX mode not supported in this driver implementation"
-#endif
-
-#if STM32_I2S_USE_SPI1 && !STM32_HAS_SPI1
-#error "SPI1 not present in the selected device"
-#endif
-
-#if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2
-#error "SPI2 not present in the selected device"
-#endif
-
-#if STM32_I2S_USE_SPI3 && !STM32_HAS_SPI3
-#error "SPI3 not present in the selected device"
-#endif
-
-#if !STM32_I2S_USE_SPI1 && !STM32_I2S_USE_SPI2 && !STM32_I2S_USE_SPI3
-#error "I2S driver activated but no SPI peripheral assigned"
-#endif
-
-#if STM32_I2S_USE_SPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI1"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI2"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI3"
-#endif
-
-#if STM32_I2S_USE_SPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI1"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI2"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI3"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_I2S_USE_SPI1 && (!defined(STM32_I2S_SPI1_RX_DMA_STREAM) || \
- !defined(STM32_I2S_SPI1_TX_DMA_STREAM))
-#error "SPI1 DMA streams not defined"
-#endif
-
-#if STM32_I2S_USE_SPI2 && (!defined(STM32_I2S_SPI2_RX_DMA_STREAM) || \
- !defined(STM32_I2S_SPI2_TX_DMA_STREAM))
-#error "SPI2 DMA streams not defined"
-#endif
-
-#if STM32_I2S_USE_SPI3 && (!defined(STM32_I2S_SPI3_RX_DMA_STREAM) || \
- !defined(STM32_I2S_SPI3_TX_DMA_STREAM))
-#error "SPI3 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_I2S_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 RX"
-#endif
-
-#if STM32_I2S_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 TX"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 RX"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 TX"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 RX"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 TX"
-#endif
-#endif /* STM32_ADVANCED_DMA */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the I2S driver structure.
- */
-#define i2s_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /* Calculated part of the I2SCFGR register.*/ \
- uint16_t cfg; \
- /* Receive DMA stream or @p NULL.*/ \
- const stm32_dma_stream_t *dmarx; \
- /* Transmit DMA stream or @p NULL.*/ \
- const stm32_dma_stream_t *dmatx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-
-/**
- * @brief Low level fields of the I2S configuration structure.
- */
-#define i2s_lld_config_fields \
- /* Configuration of the I2SCFGR register. \
- NOTE: See the STM32 reference manual, this register is used for \
- the I2S configuration, the following bits must not be \
- specified because handled directly by the driver: \
- - I2SMOD \
- - I2SE \
- - I2SCFG \
- */ \
- int16_t i2scfgr; \
- /* Configuration of the I2SPR register. \
- NOTE: See the STM32 reference manual, this register is used for \
- the I2S clock setup.*/ \
- int16_t i2spr
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_I2S_USE_SPI1 && !defined(__DOXYGEN__)
-extern I2SDriver I2SD1;
-#endif
-
-#if STM32_I2S_USE_SPI2 && !defined(__DOXYGEN__)
-extern I2SDriver I2SD2;
-#endif
-
-#if STM32_I2S_USE_SPI3 && !defined(__DOXYGEN__)
-extern I2SDriver I2SD3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void i2s_lld_init(void);
- void i2s_lld_start(I2SDriver *i2sp);
- void i2s_lld_stop(I2SDriver *i2sp);
- void i2s_lld_start_exchange(I2SDriver *i2sp);
- void i2s_lld_stop_exchange(I2SDriver *i2sp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_I2S */
-
-#endif /* HAL_I2S_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 SPIv1/hal_i2s_lld.h
+ * @brief STM32 I2S subsystem low level driver header.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#ifndef HAL_I2S_LLD_H
+#define HAL_I2S_LLD_H
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Static I2S modes
+ * @{
+ */
+#define STM32_I2S_MODE_SLAVE 0
+#define STM32_I2S_MODE_MASTER 1
+#define STM32_I2S_MODE_RX 2
+#define STM32_I2S_MODE_TX 4
+#define STM32_I2S_MODE_RXTX (STM32_I2S_MODE_RX | \
+ STM32_I2S_MODE_TX)
+/** @} */
+
+/**
+ * @name Mode checks
+ * @{
+ */
+#define STM32_I2S_IS_MASTER(mode) ((mode) & STM32_I2S_MODE_MASTER)
+#define STM32_I2S_RX_ENABLED(mode) ((mode) & STM32_I2S_MODE_RX)
+#define STM32_I2S_TX_ENABLED(mode) ((mode) & STM32_I2S_MODE_TX)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2S1 driver enable switch.
+ * @details If set to @p TRUE the support for I2S1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_SPI1) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_SPI1 FALSE
+#endif
+
+/**
+ * @brief I2S2 driver enable switch.
+ * @details If set to @p TRUE the support for I2S2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_SPI2) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_SPI2 FALSE
+#endif
+
+/**
+ * @brief I2S3 driver enable switch.
+ * @details If set to @p TRUE the support for I2S3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_SPI3) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_SPI3 FALSE
+#endif
+
+/**
+ * @brief I2S1 mode.
+ */
+#if !defined(STM32_I2S_SPI1_MODE) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \
+ STM32_I2S_MODE_RX)
+#endif
+
+/**
+ * @brief I2S2 mode.
+ */
+#if !defined(STM32_I2S_SPI2_MODE) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_MASTER | \
+ STM32_I2S_MODE_RX)
+#endif
+
+/**
+ * @brief I2S3 mode.
+ */
+#if !defined(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI3_MODE (STM32_I2S_MODE_MASTER | \
+ STM32_I2S_MODE_RX)
+#endif
+
+/**
+ * @brief I2S1 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S2 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S3 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S DMA error hook.
+ */
+#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_I2S_USE_SPI1 && !STM32_SPI1_SUPPORTS_I2S
+#error "SPI1 does not support I2S mode"
+#endif
+
+#if STM32_I2S_USE_SPI2 && !STM32_SPI2_SUPPORTS_I2S
+#error "SPI2 does not support I2S mode"
+#endif
+
+#if STM32_I2S_USE_SPI3 && !STM32_SPI3_SUPPORTS_I2S
+#error "SPI3 does not support I2S mode"
+#endif
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) && \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+#error "I2S1 RX and TX mode not supported in this driver implementation"
+#endif
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) && \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+#error "I2S2 RX and TX mode not supported in this driver implementation"
+#endif
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) && \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+#error "I2S3 RX and TX mode not supported in this driver implementation"
+#endif
+
+#if STM32_I2S_USE_SPI1 && !STM32_HAS_SPI1
+#error "SPI1 not present in the selected device"
+#endif
+
+#if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2
+#error "SPI2 not present in the selected device"
+#endif
+
+#if STM32_I2S_USE_SPI3 && !STM32_HAS_SPI3
+#error "SPI3 not present in the selected device"
+#endif
+
+#if !STM32_I2S_USE_SPI1 && !STM32_I2S_USE_SPI2 && !STM32_I2S_USE_SPI3
+#error "I2S driver activated but no SPI peripheral assigned"
+#endif
+
+#if STM32_I2S_USE_SPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI1"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI2"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI3"
+#endif
+
+#if STM32_I2S_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI1"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI2"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI3"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_I2S_USE_SPI1 && (!defined(STM32_I2S_SPI1_RX_DMA_STREAM) || \
+ !defined(STM32_I2S_SPI1_TX_DMA_STREAM))
+#error "SPI1 DMA streams not defined"
+#endif
+
+#if STM32_I2S_USE_SPI2 && (!defined(STM32_I2S_SPI2_RX_DMA_STREAM) || \
+ !defined(STM32_I2S_SPI2_TX_DMA_STREAM))
+#error "SPI2 DMA streams not defined"
+#endif
+
+#if STM32_I2S_USE_SPI3 && (!defined(STM32_I2S_SPI3_RX_DMA_STREAM) || \
+ !defined(STM32_I2S_SPI3_TX_DMA_STREAM))
+#error "SPI3 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_I2S_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 RX"
+#endif
+
+#if STM32_I2S_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 TX"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 RX"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 TX"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 RX"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 TX"
+#endif
+#endif /* STM32_ADVANCED_DMA */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the I2S driver structure.
+ */
+#define i2s_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /* Calculated part of the I2SCFGR register.*/ \
+ uint16_t cfg; \
+ /* Receive DMA stream or @p NULL.*/ \
+ const stm32_dma_stream_t *dmarx; \
+ /* Transmit DMA stream or @p NULL.*/ \
+ const stm32_dma_stream_t *dmatx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+
+/**
+ * @brief Low level fields of the I2S configuration structure.
+ */
+#define i2s_lld_config_fields \
+ /* Configuration of the I2SCFGR register. \
+ NOTE: See the STM32 reference manual, this register is used for \
+ the I2S configuration, the following bits must not be \
+ specified because handled directly by the driver: \
+ - I2SMOD \
+ - I2SE \
+ - I2SCFG \
+ */ \
+ int16_t i2scfgr; \
+ /* Configuration of the I2SPR register. \
+ NOTE: See the STM32 reference manual, this register is used for \
+ the I2S clock setup.*/ \
+ int16_t i2spr
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_I2S_USE_SPI1 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD1;
+#endif
+
+#if STM32_I2S_USE_SPI2 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD2;
+#endif
+
+#if STM32_I2S_USE_SPI3 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2s_lld_init(void);
+ void i2s_lld_start(I2SDriver *i2sp);
+ void i2s_lld_stop(I2SDriver *i2sp);
+ void i2s_lld_start_exchange(I2SDriver *i2sp);
+ void i2s_lld_stop_exchange(I2SDriver *i2sp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2S */
+
+#endif /* HAL_I2S_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
index 459e6b98b5..0f5d6904ee 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
@@ -1,679 +1,679 @@
-/*
- 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 SPIv1/hal_spi_lld.c
- * @brief STM32 SPI subsystem low level driver source.
- *
- * @addtogroup SPI
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_SPI || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define SPI1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_RX_DMA_STREAM, \
- STM32_SPI1_RX_DMA_CHN)
-
-#define SPI1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_TX_DMA_STREAM, \
- STM32_SPI1_TX_DMA_CHN)
-
-#define SPI2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_RX_DMA_STREAM, \
- STM32_SPI2_RX_DMA_CHN)
-
-#define SPI2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_TX_DMA_STREAM, \
- STM32_SPI2_TX_DMA_CHN)
-
-#define SPI3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_RX_DMA_STREAM, \
- STM32_SPI3_RX_DMA_CHN)
-
-#define SPI3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \
- STM32_SPI3_TX_DMA_CHN)
-
-#define SPI4_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_RX_DMA_STREAM, \
- STM32_SPI4_RX_DMA_CHN)
-
-#define SPI4_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_TX_DMA_STREAM, \
- STM32_SPI4_TX_DMA_CHN)
-
-#define SPI5_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_RX_DMA_STREAM, \
- STM32_SPI5_RX_DMA_CHN)
-
-#define SPI5_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_TX_DMA_STREAM, \
- STM32_SPI5_TX_DMA_CHN)
-
-#define SPI6_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_RX_DMA_STREAM, \
- STM32_SPI6_RX_DMA_CHN)
-
-#define SPI6_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_TX_DMA_STREAM, \
- STM32_SPI6_TX_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SPI1 driver identifier.*/
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
-SPIDriver SPID1;
-#endif
-
-/** @brief SPI2 driver identifier.*/
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-SPIDriver SPID2;
-#endif
-
-/** @brief SPI3 driver identifier.*/
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-SPIDriver SPID3;
-#endif
-
-/** @brief SPI4 driver identifier.*/
-#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
-SPIDriver SPID4;
-#endif
-
-/** @brief SPI5 driver identifier.*/
-#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
-SPIDriver SPID5;
-#endif
-
-/** @brief SPI6 driver identifier.*/
-#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
-SPIDriver SPID6;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint16_t dummytx = 0xFFFFU;
-static uint16_t dummyrx;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Shared end-of-rx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)flags;
-#endif
-
- if (spip->config->circular) {
- if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
- /* Half buffer interrupt.*/
- _spi_isr_half_code(spip);
- }
- if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
- /* End buffer interrupt.*/
- _spi_isr_full_code(spip);
- }
- }
- else {
- /* Stopping DMAs.*/
- dmaStreamDisable(spip->dmatx);
- dmaStreamDisable(spip->dmarx);
-
- /* Portable SPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _spi_isr_code(spip);
- }
-}
-
-/**
- * @brief Shared end-of-tx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- (void)spip;
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)spip;
- (void)flags;
-#endif
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SPI driver initialization.
- *
- * @notapi
- */
-void spi_lld_init(void) {
-
-#if STM32_SPI_USE_SPI1
- spiObjectInit(&SPID1);
- SPID1.spi = SPI1;
- SPID1.dmarx = NULL;
- SPID1.dmatx = NULL;
- SPID1.rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID1.txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI2
- spiObjectInit(&SPID2);
- SPID2.spi = SPI2;
- SPID2.dmarx = NULL;
- SPID2.dmatx = NULL;
- SPID2.rxdmamode = STM32_DMA_CR_CHSEL(SPI2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID2.txdmamode = STM32_DMA_CR_CHSEL(SPI2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI3
- spiObjectInit(&SPID3);
- SPID3.spi = SPI3;
- SPID3.dmarx = NULL;
- SPID3.dmatx = NULL;
- SPID3.rxdmamode = STM32_DMA_CR_CHSEL(SPI3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID3.txdmamode = STM32_DMA_CR_CHSEL(SPI3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI4
- spiObjectInit(&SPID4);
- SPID4.spi = SPI4;
- SPID4.dmarx = NULL;
- SPID4.dmatx = NULL;
- SPID4.rxdmamode = STM32_DMA_CR_CHSEL(SPI4_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID4.txdmamode = STM32_DMA_CR_CHSEL(SPI4_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI5
- spiObjectInit(&SPID5);
- SPID5.spi = SPI5;
- SPID5.dmarx = NULL;
- SPID5.dmatx = NULL;
- SPID5.rxdmamode = STM32_DMA_CR_CHSEL(SPI5_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID5.txdmamode = STM32_DMA_CR_CHSEL(SPI5_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI6
- spiObjectInit(&SPID6);
- SPID6.spi = SPI6;
- SPID6.dmarx = NULL;
- SPID6.dmatx = NULL;
- SPID6.rxdmamode = STM32_DMA_CR_CHSEL(SPI6_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID6.txdmamode = STM32_DMA_CR_CHSEL(SPI6_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-}
-
-/**
- * @brief Configures and activates the SPI peripheral.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_start(SPIDriver *spip) {
-
- /* If in stopped state then enables the SPI and DMA clocks.*/
- if (spip->state == SPI_STOP) {
-#if STM32_SPI_USE_SPI1
- if (&SPID1 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
- STM32_SPI_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
- STM32_SPI_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI1(true);
- }
-#endif
-#if STM32_SPI_USE_SPI2
- if (&SPID2 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
- STM32_SPI_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
- STM32_SPI_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI2(true);
- }
-#endif
-#if STM32_SPI_USE_SPI3
- if (&SPID3 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
- STM32_SPI_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
- STM32_SPI_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI3(true);
- }
-#endif
-#if STM32_SPI_USE_SPI4
- if (&SPID4 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
- STM32_SPI_SPI4_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
- STM32_SPI_SPI4_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI4(true);
- }
-#endif
-#if STM32_SPI_USE_SPI5
- if (&SPID5 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
- STM32_SPI_SPI5_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
- STM32_SPI_SPI5_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI5(true);
- }
-#endif
-#if STM32_SPI_USE_SPI6
- if (&SPID6 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI6_RX_DMA_STREAM,
- STM32_SPI_SPI6_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI6_TX_DMA_STREAM,
- STM32_SPI_SPI6_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI6(true);
- }
-#endif
-
- /* DMA setup.*/
- dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
- dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
- }
-
- /* Configuration-specific DMA setup.*/
- if ((spip->config->cr1 & SPI_CR1_DFF) == 0) {
- /* Frame width is 8 bits or smaller.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
- }
- else {
- /* Frame width is larger than 8 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- }
-
- if (spip->config->circular) {
- spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- }
- else {
- spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- }
-
- /* SPI setup and enable.*/
- spip->spi->CR1 &= ~SPI_CR1_SPE;
- spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM |
- SPI_CR1_SSI;
- spip->spi->CR2 = spip->config->cr2 | SPI_CR2_SSOE | SPI_CR2_RXDMAEN |
- SPI_CR2_TXDMAEN;
- spip->spi->CR1 |= SPI_CR1_SPE;
-}
-
-/**
- * @brief Deactivates the SPI peripheral.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_stop(SPIDriver *spip) {
-
- /* If in ready state then disables the SPI clock.*/
- if (spip->state == SPI_READY) {
-
- /* SPI disable.*/
- spip->spi->CR1 &= ~SPI_CR1_SPE;
- spip->spi->CR1 = 0;
- spip->spi->CR2 = 0;
- dmaStreamFreeI(spip->dmarx);
- dmaStreamFreeI(spip->dmatx);
- spip->dmarx = NULL;
- spip->dmatx = NULL;
-
-#if STM32_SPI_USE_SPI1
- if (&SPID1 == spip)
- rccDisableSPI1();
-#endif
-#if STM32_SPI_USE_SPI2
- if (&SPID2 == spip)
- rccDisableSPI2();
-#endif
-#if STM32_SPI_USE_SPI3
- if (&SPID3 == spip)
- rccDisableSPI3();
-#endif
-#if STM32_SPI_USE_SPI4
- if (&SPID4 == spip)
- rccDisableSPI4();
-#endif
-#if STM32_SPI_USE_SPI5
- if (&SPID5 == spip)
- rccDisableSPI5();
-#endif
-#if STM32_SPI_USE_SPI6
- if (&SPID6 == spip)
- rccDisableSPI6();
-#endif
- }
-}
-
-#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
-/**
- * @brief Asserts the slave select signal and prepares for transfers.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_select(SPIDriver *spip) {
-
- /* No implementation on STM32.*/
-}
-
-/**
- * @brief Deasserts the slave select signal.
- * @details The previously selected peripheral is unselected.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_unselect(SPIDriver *spip) {
-
- /* No implementation on STM32.*/
-}
-#endif
-
-/**
- * @brief Ignores data on the SPI bus.
- * @details This asynchronous function starts the transmission of a series of
- * idle words on the SPI bus and ignores the received data.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to be ignored
- *
- * @notapi
- */
-void spi_lld_ignore(SPIDriver *spip, size_t n) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, &dummyrx);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
-
- dmaStreamSetMemory0(spip->dmatx, &dummytx);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-/**
- * @brief Exchanges data on the SPI bus.
- * @details This asynchronous function starts a simultaneous transmit/receive
- * operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to be exchanged
- * @param[in] txbuf the pointer to the transmit buffer
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void spi_lld_exchange(SPIDriver *spip, size_t n,
- const void *txbuf, void *rxbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, rxbuf);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode| STM32_DMA_CR_MINC);
-
- dmaStreamSetMemory0(spip->dmatx, txbuf);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-/**
- * @brief Sends data over the SPI bus.
- * @details This asynchronous function starts a transmit operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, &dummyrx);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
-
- dmaStreamSetMemory0(spip->dmatx, txbuf);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-/**
- * @brief Receives data from the SPI bus.
- * @details This asynchronous function starts a receive operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to receive
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, rxbuf);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamSetMemory0(spip->dmatx, &dummytx);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Aborts the ongoing SPI operation, if any.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_abort(SPIDriver *spip) {
-
- /* Stopping DMAs.*/
- dmaStreamDisable(spip->dmatx);
- dmaStreamDisable(spip->dmarx);
-}
-#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
-
-/**
- * @brief Exchanges one frame using a polled wait.
- * @details This synchronous function exchanges one frame using a polled
- * synchronization method. This function is useful when exchanging
- * small amount of data on high speed channels, usually in this
- * situation is much more efficient just wait for completion using
- * polling than suspending the thread waiting for an interrupt.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] frame the data frame to send over the SPI bus
- * @return The received data frame from the SPI bus.
- */
-uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
-
- spip->spi->DR = frame;
- while ((spip->spi->SR & SPI_SR_RXNE) == 0)
- ;
- return spip->spi->DR;
-}
-
-#endif /* HAL_USE_SPI */
-
-/** @} */
+/*
+ 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 SPIv1/hal_spi_lld.c
+ * @brief STM32 SPI subsystem low level driver source.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define SPI1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_RX_DMA_STREAM, \
+ STM32_SPI1_RX_DMA_CHN)
+
+#define SPI1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_TX_DMA_STREAM, \
+ STM32_SPI1_TX_DMA_CHN)
+
+#define SPI2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_RX_DMA_STREAM, \
+ STM32_SPI2_RX_DMA_CHN)
+
+#define SPI2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_TX_DMA_STREAM, \
+ STM32_SPI2_TX_DMA_CHN)
+
+#define SPI3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_RX_DMA_STREAM, \
+ STM32_SPI3_RX_DMA_CHN)
+
+#define SPI3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \
+ STM32_SPI3_TX_DMA_CHN)
+
+#define SPI4_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_RX_DMA_STREAM, \
+ STM32_SPI4_RX_DMA_CHN)
+
+#define SPI4_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_TX_DMA_STREAM, \
+ STM32_SPI4_TX_DMA_CHN)
+
+#define SPI5_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_RX_DMA_STREAM, \
+ STM32_SPI5_RX_DMA_CHN)
+
+#define SPI5_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_TX_DMA_STREAM, \
+ STM32_SPI5_TX_DMA_CHN)
+
+#define SPI6_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_RX_DMA_STREAM, \
+ STM32_SPI6_RX_DMA_CHN)
+
+#define SPI6_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_TX_DMA_STREAM, \
+ STM32_SPI6_TX_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SPI1 driver identifier.*/
+#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
+SPIDriver SPID1;
+#endif
+
+/** @brief SPI2 driver identifier.*/
+#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
+SPIDriver SPID2;
+#endif
+
+/** @brief SPI3 driver identifier.*/
+#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
+SPIDriver SPID3;
+#endif
+
+/** @brief SPI4 driver identifier.*/
+#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
+SPIDriver SPID4;
+#endif
+
+/** @brief SPI5 driver identifier.*/
+#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
+SPIDriver SPID5;
+#endif
+
+/** @brief SPI6 driver identifier.*/
+#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
+SPIDriver SPID6;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const uint16_t dummytx = 0xFFFFU;
+static uint16_t dummyrx;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared end-of-rx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (spip->config->circular) {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
+ /* Half buffer interrupt.*/
+ _spi_isr_half_code(spip);
+ }
+ if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
+ /* End buffer interrupt.*/
+ _spi_isr_full_code(spip);
+ }
+ }
+ else {
+ /* Stopping DMAs.*/
+ dmaStreamDisable(spip->dmatx);
+ dmaStreamDisable(spip->dmarx);
+
+ /* Portable SPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _spi_isr_code(spip);
+ }
+}
+
+/**
+ * @brief Shared end-of-tx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ (void)spip;
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)spip;
+ (void)flags;
+#endif
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SPI driver initialization.
+ *
+ * @notapi
+ */
+void spi_lld_init(void) {
+
+#if STM32_SPI_USE_SPI1
+ spiObjectInit(&SPID1);
+ SPID1.spi = SPI1;
+ SPID1.dmarx = NULL;
+ SPID1.dmatx = NULL;
+ SPID1.rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID1.txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI2
+ spiObjectInit(&SPID2);
+ SPID2.spi = SPI2;
+ SPID2.dmarx = NULL;
+ SPID2.dmatx = NULL;
+ SPID2.rxdmamode = STM32_DMA_CR_CHSEL(SPI2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID2.txdmamode = STM32_DMA_CR_CHSEL(SPI2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI3
+ spiObjectInit(&SPID3);
+ SPID3.spi = SPI3;
+ SPID3.dmarx = NULL;
+ SPID3.dmatx = NULL;
+ SPID3.rxdmamode = STM32_DMA_CR_CHSEL(SPI3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID3.txdmamode = STM32_DMA_CR_CHSEL(SPI3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI4
+ spiObjectInit(&SPID4);
+ SPID4.spi = SPI4;
+ SPID4.dmarx = NULL;
+ SPID4.dmatx = NULL;
+ SPID4.rxdmamode = STM32_DMA_CR_CHSEL(SPI4_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID4.txdmamode = STM32_DMA_CR_CHSEL(SPI4_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI5
+ spiObjectInit(&SPID5);
+ SPID5.spi = SPI5;
+ SPID5.dmarx = NULL;
+ SPID5.dmatx = NULL;
+ SPID5.rxdmamode = STM32_DMA_CR_CHSEL(SPI5_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID5.txdmamode = STM32_DMA_CR_CHSEL(SPI5_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI6
+ spiObjectInit(&SPID6);
+ SPID6.spi = SPI6;
+ SPID6.dmarx = NULL;
+ SPID6.dmatx = NULL;
+ SPID6.rxdmamode = STM32_DMA_CR_CHSEL(SPI6_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID6.txdmamode = STM32_DMA_CR_CHSEL(SPI6_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+}
+
+/**
+ * @brief Configures and activates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_start(SPIDriver *spip) {
+
+ /* If in stopped state then enables the SPI and DMA clocks.*/
+ if (spip->state == SPI_STOP) {
+#if STM32_SPI_USE_SPI1
+ if (&SPID1 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
+ STM32_SPI_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
+ STM32_SPI_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI1(true);
+ }
+#endif
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
+ STM32_SPI_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
+ STM32_SPI_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI2(true);
+ }
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
+ STM32_SPI_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
+ STM32_SPI_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI3(true);
+ }
+#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI4(true);
+ }
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI5(true);
+ }
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI6_RX_DMA_STREAM,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI6_TX_DMA_STREAM,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI6(true);
+ }
+#endif
+
+ /* DMA setup.*/
+ dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
+ dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
+ }
+
+ /* Configuration-specific DMA setup.*/
+ if ((spip->config->cr1 & SPI_CR1_DFF) == 0) {
+ /* Frame width is 8 bits or smaller.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+ }
+ else {
+ /* Frame width is larger than 8 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ }
+
+ if (spip->config->circular) {
+ spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ }
+ else {
+ spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ }
+
+ /* SPI setup and enable.*/
+ spip->spi->CR1 &= ~SPI_CR1_SPE;
+ spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR | SPI_CR1_SSM |
+ SPI_CR1_SSI;
+ spip->spi->CR2 = spip->config->cr2 | SPI_CR2_SSOE | SPI_CR2_RXDMAEN |
+ SPI_CR2_TXDMAEN;
+ spip->spi->CR1 |= SPI_CR1_SPE;
+}
+
+/**
+ * @brief Deactivates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_stop(SPIDriver *spip) {
+
+ /* If in ready state then disables the SPI clock.*/
+ if (spip->state == SPI_READY) {
+
+ /* SPI disable.*/
+ spip->spi->CR1 &= ~SPI_CR1_SPE;
+ spip->spi->CR1 = 0;
+ spip->spi->CR2 = 0;
+ dmaStreamFreeI(spip->dmarx);
+ dmaStreamFreeI(spip->dmatx);
+ spip->dmarx = NULL;
+ spip->dmatx = NULL;
+
+#if STM32_SPI_USE_SPI1
+ if (&SPID1 == spip)
+ rccDisableSPI1();
+#endif
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip)
+ rccDisableSPI2();
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip)
+ rccDisableSPI3();
+#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip)
+ rccDisableSPI4();
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip)
+ rccDisableSPI5();
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip)
+ rccDisableSPI6();
+#endif
+ }
+}
+
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
+/**
+ * @brief Asserts the slave select signal and prepares for transfers.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_select(SPIDriver *spip) {
+
+ /* No implementation on STM32.*/
+}
+
+/**
+ * @brief Deasserts the slave select signal.
+ * @details The previously selected peripheral is unselected.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_unselect(SPIDriver *spip) {
+
+ /* No implementation on STM32.*/
+}
+#endif
+
+/**
+ * @brief Ignores data on the SPI bus.
+ * @details This asynchronous function starts the transmission of a series of
+ * idle words on the SPI bus and ignores the received data.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be ignored
+ *
+ * @notapi
+ */
+void spi_lld_ignore(SPIDriver *spip, size_t n) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, &dummyrx);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
+
+ dmaStreamSetMemory0(spip->dmatx, &dummytx);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+/**
+ * @brief Exchanges data on the SPI bus.
+ * @details This asynchronous function starts a simultaneous transmit/receive
+ * operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be exchanged
+ * @param[in] txbuf the pointer to the transmit buffer
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode| STM32_DMA_CR_MINC);
+
+ dmaStreamSetMemory0(spip->dmatx, txbuf);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+/**
+ * @brief Sends data over the SPI bus.
+ * @details This asynchronous function starts a transmit operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, &dummyrx);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
+
+ dmaStreamSetMemory0(spip->dmatx, txbuf);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+/**
+ * @brief Receives data from the SPI bus.
+ * @details This asynchronous function starts a receive operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to receive
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamSetMemory0(spip->dmatx, &dummytx);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Aborts the ongoing SPI operation, if any.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_abort(SPIDriver *spip) {
+
+ /* Stopping DMAs.*/
+ dmaStreamDisable(spip->dmatx);
+ dmaStreamDisable(spip->dmarx);
+}
+#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
+
+/**
+ * @brief Exchanges one frame using a polled wait.
+ * @details This synchronous function exchanges one frame using a polled
+ * synchronization method. This function is useful when exchanging
+ * small amount of data on high speed channels, usually in this
+ * situation is much more efficient just wait for completion using
+ * polling than suspending the thread waiting for an interrupt.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] frame the data frame to send over the SPI bus
+ * @return The received data frame from the SPI bus.
+ */
+uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
+
+ spip->spi->DR = frame;
+ while ((spip->spi->SR & SPI_SR_RXNE) == 0)
+ ;
+ return spip->spi->DR;
+}
+
+#endif /* HAL_USE_SPI */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h
index 09a6eec01d..f6841feb0b 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h
@@ -1,495 +1,495 @@
-/*
- 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 SPIv1/hal_spi_lld.h
- * @brief STM32 SPI subsystem low level driver header.
- *
- * @addtogroup SPI
- * @{
- */
-
-#ifndef HAL_SPI_LLD_H
-#define HAL_SPI_LLD_H
-
-#if HAL_USE_SPI || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Circular mode support flag.
- */
-#define SPI_SUPPORTS_CIRCULAR TRUE
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SPI1 driver enable switch.
- * @details If set to @p TRUE the support for SPI1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI1 FALSE
-#endif
-
-/**
- * @brief SPI2 driver enable switch.
- * @details If set to @p TRUE the support for SPI2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI2 FALSE
-#endif
-
-/**
- * @brief SPI3 driver enable switch.
- * @details If set to @p TRUE the support for SPI3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI3 FALSE
-#endif
-
-/**
- * @brief SPI4 driver enable switch.
- * @details If set to @p TRUE the support for SPI4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI4 FALSE
-#endif
-
-/**
- * @brief SPI5 driver enable switch.
- * @details If set to @p TRUE the support for SPI5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI5 FALSE
-#endif
-
-/**
- * @brief SPI6 driver enable switch.
- * @details If set to @p TRUE the support for SPI6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI6 FALSE
-#endif
-
-/**
- * @brief SPI1 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI2 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI3 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI4 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI4_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI5 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI5_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI6 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI6_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI4_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI5 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI5_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI6 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI6_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI DMA error hook.
- */
-#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
-#error "SPI1 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
-#error "SPI2 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
-#error "SPI3 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
-#error "SPI4 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
-#error "SPI5 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
-#error "SPI6 not present in the selected device"
-#endif
-
-#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
- !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
-#error "SPI driver activated but no SPI peripheral assigned"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI1"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI2"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI3"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI4"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI5"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI6"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI1"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI2"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI3"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI4"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI5"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI6"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI1_TX_DMA_STREAM))
-#error "SPI1 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI2_TX_DMA_STREAM))
-#error "SPI2 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI3_TX_DMA_STREAM))
-#error "SPI3 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
-#error "SPI4 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
-#error "SPI5 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI6_TX_DMA_STREAM))
-#error "SPI6 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 RX"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 TX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 RX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 TX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 RX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 TX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI4 RX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI4 TX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI5 RX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI5 TX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI6 RX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI6 TX"
-#endif
-#endif /* STM32_ADVANCED_DMA */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
-#error "SPI_SELECT_MODE_LLD not supported by this driver"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the SPI driver structure.
- */
-#define spi_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /* Receive DMA stream.*/ \
- const stm32_dma_stream_t *dmarx; \
- /* Transmit DMA stream.*/ \
- const stm32_dma_stream_t *dmatx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-
-/**
- * @brief Low level fields of the SPI configuration structure.
- */
-#define spi_lld_config_fields \
- /* SPI CR1 register initialization data.*/ \
- uint16_t cr1; \
- /* SPI CR2 register initialization data.*/ \
- uint16_t cr2
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
-extern SPIDriver SPID1;
-#endif
-
-#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
-extern SPIDriver SPID2;
-#endif
-
-#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
-extern SPIDriver SPID3;
-#endif
-
-#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
-extern SPIDriver SPID4;
-#endif
-
-#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
-extern SPIDriver SPID5;
-#endif
-
-#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
-extern SPIDriver SPID6;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void spi_lld_init(void);
- void spi_lld_start(SPIDriver *spip);
- void spi_lld_stop(SPIDriver *spip);
-#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
- void spi_lld_select(SPIDriver *spip);
- void spi_lld_unselect(SPIDriver *spip);
-#endif
- void spi_lld_ignore(SPIDriver *spip, size_t n);
- void spi_lld_exchange(SPIDriver *spip, size_t n,
- const void *txbuf, void *rxbuf);
- void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
- void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
-#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
- void spi_lld_abort(SPIDriver *spip);
-#endif
- uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SPI */
-
-#endif /* HAL_SPI_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 SPIv1/hal_spi_lld.h
+ * @brief STM32 SPI subsystem low level driver header.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#ifndef HAL_SPI_LLD_H
+#define HAL_SPI_LLD_H
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Circular mode support flag.
+ */
+#define SPI_SUPPORTS_CIRCULAR TRUE
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SPI1 driver enable switch.
+ * @details If set to @p TRUE the support for SPI1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI1 FALSE
+#endif
+
+/**
+ * @brief SPI2 driver enable switch.
+ * @details If set to @p TRUE the support for SPI2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI2 FALSE
+#endif
+
+/**
+ * @brief SPI3 driver enable switch.
+ * @details If set to @p TRUE the support for SPI3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI3 FALSE
+#endif
+
+/**
+ * @brief SPI4 driver enable switch.
+ * @details If set to @p TRUE the support for SPI4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI4 FALSE
+#endif
+
+/**
+ * @brief SPI5 driver enable switch.
+ * @details If set to @p TRUE the support for SPI5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI5 FALSE
+#endif
+
+/**
+ * @brief SPI6 driver enable switch.
+ * @details If set to @p TRUE the support for SPI6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI6 FALSE
+#endif
+
+/**
+ * @brief SPI1 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI2 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI3 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI4 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI5 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI6 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI5 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI6 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI DMA error hook.
+ */
+#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
+#error "SPI1 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
+#error "SPI2 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
+#error "SPI3 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
+#error "SPI4 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
+#error "SPI5 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
+#error "SPI6 not present in the selected device"
+#endif
+
+#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
+ !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
+#error "SPI driver activated but no SPI peripheral assigned"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI1"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI2"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI3"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI6"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI1"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI2"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI3"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI6"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI1_TX_DMA_STREAM))
+#error "SPI1 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI2_TX_DMA_STREAM))
+#error "SPI2 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI3_TX_DMA_STREAM))
+#error "SPI3 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
+#error "SPI4 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
+#error "SPI5 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI6_TX_DMA_STREAM))
+#error "SPI6 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 RX"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 TX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 RX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 TX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 RX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 TX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI4 RX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI4 TX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI5 RX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI5 TX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI6 RX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI6 TX"
+#endif
+#endif /* STM32_ADVANCED_DMA */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
+#error "SPI_SELECT_MODE_LLD not supported by this driver"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the SPI driver structure.
+ */
+#define spi_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /* Receive DMA stream.*/ \
+ const stm32_dma_stream_t *dmarx; \
+ /* Transmit DMA stream.*/ \
+ const stm32_dma_stream_t *dmatx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+
+/**
+ * @brief Low level fields of the SPI configuration structure.
+ */
+#define spi_lld_config_fields \
+ /* SPI CR1 register initialization data.*/ \
+ uint16_t cr1; \
+ /* SPI CR2 register initialization data.*/ \
+ uint16_t cr2
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
+extern SPIDriver SPID1;
+#endif
+
+#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
+extern SPIDriver SPID2;
+#endif
+
+#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
+extern SPIDriver SPID3;
+#endif
+
+#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
+extern SPIDriver SPID4;
+#endif
+
+#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
+extern SPIDriver SPID5;
+#endif
+
+#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
+extern SPIDriver SPID6;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void spi_lld_init(void);
+ void spi_lld_start(SPIDriver *spip);
+ void spi_lld_stop(SPIDriver *spip);
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
+ void spi_lld_select(SPIDriver *spip);
+ void spi_lld_unselect(SPIDriver *spip);
+#endif
+ void spi_lld_ignore(SPIDriver *spip, size_t n);
+ void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf);
+ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
+ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
+ void spi_lld_abort(SPIDriver *spip);
+#endif
+ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SPI */
+
+#endif /* HAL_SPI_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv2/driver.mk b/os/hal/ports/STM32/LLD/SPIv2/driver.mk
index 2e1bae4f49..d18ea35c00 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/SPIv2/driver.mk
@@ -1,13 +1,13 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_I2S TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
-endif
-ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_I2S TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
+endif
+ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2
diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c b/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
index aa437dafbf..bf871ef00a 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.c
@@ -1,572 +1,572 @@
-/*
- 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 SPIv2/hal_i2s_lld.c
- * @brief STM32 I2S subsystem low level driver source.
- *
- * @addtogroup I2S
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_I2S || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define I2S1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_RX_DMA_STREAM, \
- STM32_SPI1_RX_DMA_CHN)
-
-#define I2S1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_TX_DMA_STREAM, \
- STM32_SPI1_TX_DMA_CHN)
-
-#define I2S2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_RX_DMA_STREAM, \
- STM32_SPI2_RX_DMA_CHN)
-
-#define I2S2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_TX_DMA_STREAM, \
- STM32_SPI2_TX_DMA_CHN)
-
-#define I2S3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_RX_DMA_STREAM, \
- STM32_SPI3_RX_DMA_CHN)
-
-#define I2S3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_TX_DMA_STREAM, \
- STM32_SPI3_TX_DMA_CHN)
-
-/*
- * Static I2S settings for I2S1.
- */
-#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE)
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG 0
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
-#endif
-#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
-#define STM32_I2S1_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
- SPI_I2SCFGR_I2SCFG_0)
-#endif
-#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
-
-/*
- * Static I2S settings for I2S2.
- */
-#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE)
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG 0
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
-#endif
-#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
-#define STM32_I2S2_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
- SPI_I2SCFGR_I2SCFG_0)
-#endif
-#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
-
-/*
- * Static I2S settings for I2S3.
- */
-#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE)
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG 0
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
-#endif
-#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
-#endif
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
-#define STM32_I2S3_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
- SPI_I2SCFGR_I2SCFG_0)
-#endif
-#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief I2S1 driver identifier.*/
-#if STM32_I2S_USE_SPI1 || defined(__DOXYGEN__)
-I2SDriver I2SD1;
-#endif
-
-/** @brief I2S2 driver identifier.*/
-#if STM32_I2S_USE_SPI2 || defined(__DOXYGEN__)
-I2SDriver I2SD2;
-#endif
-
-/** @brief I2S3 driver identifier.*/
-#if STM32_I2S_USE_SPI3 || defined(__DOXYGEN__)
-I2SDriver I2SD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) || \
- STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) || \
- STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
-/**
- * @brief Shared end-of-rx service routine.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) {
-
- (void)i2sp;
-
- /* DMA errors handling.*/
-#if defined(STM32_I2S_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_I2S_DMA_ERROR_HOOK(i2sp);
- }
-#endif
-
- /* Callbacks handling, note it is portable code defined in the high
- level driver.*/
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _i2s_isr_full_code(i2sp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _i2s_isr_half_code(i2sp);
- }
-}
-#endif
-
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE) || \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE) || \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
-/**
- * @brief Shared end-of-tx service routine.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) {
-
- (void)i2sp;
-
- /* DMA errors handling.*/
-#if defined(STM32_I2S_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_I2S_DMA_ERROR_HOOK(i2sp);
- }
-#endif
-
- /* Callbacks handling, note it is portable code defined in the high
- level driver.*/
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _i2s_isr_full_code(i2sp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _i2s_isr_half_code(i2sp);
- }
-}
-#endif
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level I2S driver initialization.
- *
- * @notapi
- */
-void i2s_lld_init(void) {
-
-#if STM32_I2S_USE_SPI1
- i2sObjectInit(&I2SD1);
- I2SD1.spi = SPI1;
- I2SD1.cfg = STM32_I2S1_CFGR_CFG;
- I2SD1.dmarx = NULL;
- I2SD1.dmatx = NULL;
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
- I2SD1.rxdmamode = STM32_DMA_CR_CHSEL(I2S1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD1.rxdmamode = 0;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
- I2SD1.txdmamode = STM32_DMA_CR_CHSEL(I2S1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD1.txdmamode = 0;
-#endif
-#endif
-
-#if STM32_I2S_USE_SPI2
- i2sObjectInit(&I2SD2);
- I2SD2.spi = SPI2;
- I2SD2.cfg = STM32_I2S2_CFGR_CFG;
- I2SD2.dmarx = NULL;
- I2SD2.dmatx = NULL;
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
- I2SD2.rxdmamode = STM32_DMA_CR_CHSEL(I2S2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD2.rxdmamode = 0;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
- I2SD2.txdmamode = STM32_DMA_CR_CHSEL(I2S2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD2.txdmamode = 0;
-#endif
-#endif
-
-#if STM32_I2S_USE_SPI3
- i2sObjectInit(&I2SD3);
- I2SD3.spi = SPI3;
- I2SD3.cfg = STM32_I2S3_CFGR_CFG;
- I2SD3.dmarx = NULL;
- I2SD3.dmatx = NULL;
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
- I2SD3.rxdmamode = STM32_DMA_CR_CHSEL(I2S3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD3.rxdmamode = 0;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
- I2SD3.txdmamode = STM32_DMA_CR_CHSEL(I2S3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MSIZE_HWORD |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC |
- STM32_DMA_CR_CIRC |
- STM32_DMA_CR_HTIE |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#else
- I2SD3.txdmamode = 0;
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the I2S peripheral.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_start(I2SDriver *i2sp) {
-
- /* If in stopped state then enables the SPI and DMA clocks.*/
- if (i2sp->state == I2S_STOP) {
-
-#if STM32_I2S_USE_SPI1
- if (&I2SD1 == i2sp) {
-
- /* Enabling I2S unit clock.*/
- rccEnableSPI1(true);
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
- i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI1_RX_DMA_STREAM,
- STM32_I2S_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
- i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI1_TX_DMA_STREAM,
- STM32_I2S_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
-#endif
- }
-#endif
-
-#if STM32_I2S_USE_SPI2
- if (&I2SD2 == i2sp) {
-
- /* Enabling I2S unit clock.*/
- rccEnableSPI2(true);
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
- i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI2_RX_DMA_STREAM,
- STM32_I2S_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
- i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI2_TX_DMA_STREAM,
- STM32_I2S_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
-#endif
- }
-#endif
-
-#if STM32_I2S_USE_SPI3
- if (&I2SD3 == i2sp) {
-
- /* Enabling I2S unit clock.*/
- rccEnableSPI3(true);
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
- i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI3_RX_DMA_STREAM,
- STM32_I2S_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
-#endif
-#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
- i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI3_TX_DMA_STREAM,
- STM32_I2S_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
- (void *)i2sp);
- osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
-
- /* CRs settings are done here because those never changes until
- the driver is stopped.*/
- i2sp->spi->CR1 = 0;
- i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
-#endif
- }
-#endif
- }
-
- /* I2S (re)configuration.*/
- i2sp->spi->I2SPR = i2sp->config->i2spr;
- i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD;
-}
-
-/**
- * @brief Deactivates the I2S peripheral.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_stop(I2SDriver *i2sp) {
-
- /* If in ready state then disables the SPI clock.*/
- if (i2sp->state == I2S_READY) {
-
- /* SPI disable.*/
- i2sp->spi->CR2 = 0;
- if (NULL != i2sp->dmarx) {
- dmaStreamFreeI(i2sp->dmarx);
- i2sp->dmarx = NULL;
- }
- if (NULL != i2sp->dmatx) {
- dmaStreamFreeI(i2sp->dmatx);
- i2sp->dmatx = NULL;
- }
-
-#if STM32_I2S_USE_SPI1
- if (&I2SD1 == i2sp)
- rccDisableSPI1();
-#endif
-
-#if STM32_I2S_USE_SPI2
- if (&I2SD2 == i2sp)
- rccDisableSPI2();
-#endif
-
-#if STM32_I2S_USE_SPI3
- if (&I2SD3 == i2sp)
- rccDisableSPI3();
-#endif
- }
-}
-
-/**
- * @brief Starts a I2S data exchange.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_start_exchange(I2SDriver *i2sp) {
- size_t size = i2sp->config->size;
-
- /* In 32 bit modes the DMA has to perform double operations because fetches
- are always performed using 16 bit accesses.
- DATLEN CHLEN SIZE
- 00 (16) 0 (16) 16
- 00 (16) 1 (32) 16
- 01 (24) X 32
- 10 (32) X 32
- 11 (NA) X NA
- */
- if ((i2sp->config->i2scfgr & SPI_I2SCFGR_DATLEN) != 0)
- size *= 2;
-
- /* RX DMA setup.*/
- if (NULL != i2sp->dmarx) {
- dmaStreamSetMode(i2sp->dmarx, i2sp->rxdmamode);
- dmaStreamSetPeripheral(i2sp->dmarx, &i2sp->spi->DR);
- dmaStreamSetMemory0(i2sp->dmarx, i2sp->config->rx_buffer);
- dmaStreamSetTransactionSize(i2sp->dmarx, size);
- dmaStreamEnable(i2sp->dmarx);
- }
-
- /* TX DMA setup.*/
- if (NULL != i2sp->dmatx) {
- dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode);
- dmaStreamSetPeripheral(i2sp->dmatx, &i2sp->spi->DR);
- dmaStreamSetMemory0(i2sp->dmatx, i2sp->config->tx_buffer);
- dmaStreamSetTransactionSize(i2sp->dmatx, size);
- dmaStreamEnable(i2sp->dmatx);
- }
-
- /* Starting transfer.*/
- i2sp->spi->I2SCFGR |= SPI_I2SCFGR_I2SE;
-}
-
-/**
- * @brief Stops the ongoing data exchange.
- * @details The ongoing data exchange, if any, is stopped, if the driver
- * was not active the function does nothing.
- *
- * @param[in] i2sp pointer to the @p I2SDriver object
- *
- * @notapi
- */
-void i2s_lld_stop_exchange(I2SDriver *i2sp) {
-
- /* Stop TX DMA, if enabled.*/
- if (NULL != i2sp->dmatx) {
- dmaStreamDisable(i2sp->dmatx);
-
- /* From the RM: To switch off the I2S, by clearing I2SE, it is mandatory
- to wait for TXE = 1 and BSY = 0.*/
- while ((i2sp->spi->SR & (SPI_SR_TXE | SPI_SR_BSY)) != SPI_SR_TXE)
- ;
- }
-
- /* Stop SPI/I2S peripheral.*/
- i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
-
- /* Stop RX DMA, if enabled.*/
- if (NULL != i2sp->dmarx)
- dmaStreamDisable(i2sp->dmarx);
-}
-
-#endif /* HAL_USE_I2S */
-
-/** @} */
+/*
+ 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 SPIv2/hal_i2s_lld.c
+ * @brief STM32 I2S subsystem low level driver source.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define I2S1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_RX_DMA_STREAM, \
+ STM32_SPI1_RX_DMA_CHN)
+
+#define I2S1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI1_TX_DMA_STREAM, \
+ STM32_SPI1_TX_DMA_CHN)
+
+#define I2S2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_RX_DMA_STREAM, \
+ STM32_SPI2_RX_DMA_CHN)
+
+#define I2S2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI2_TX_DMA_STREAM, \
+ STM32_SPI2_TX_DMA_CHN)
+
+#define I2S3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_RX_DMA_STREAM, \
+ STM32_SPI3_RX_DMA_CHN)
+
+#define I2S3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_I2S_SPI3_TX_DMA_STREAM, \
+ STM32_SPI3_TX_DMA_CHN)
+
+/*
+ * Static I2S settings for I2S1.
+ */
+#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE)
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG 0
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
+#endif
+#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+#define STM32_I2S1_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
+ SPI_I2SCFGR_I2SCFG_0)
+#endif
+#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI1_MODE) */
+
+/*
+ * Static I2S settings for I2S2.
+ */
+#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE)
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG 0
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
+#endif
+#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+#define STM32_I2S2_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
+ SPI_I2SCFGR_I2SCFG_0)
+#endif
+#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI2_MODE) */
+
+/*
+ * Static I2S settings for I2S3.
+ */
+#if !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE)
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG 0
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_0
+#endif
+#else /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG SPI_I2SCFGR_I2SCFG_1
+#endif
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+#define STM32_I2S3_CFGR_CFG (SPI_I2SCFGR_I2SCFG_1 | \
+ SPI_I2SCFGR_I2SCFG_0)
+#endif
+#endif /* !STM32_I2S_IS_MASTER(STM32_I2S_SPI3_MODE) */
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief I2S1 driver identifier.*/
+#if STM32_I2S_USE_SPI1 || defined(__DOXYGEN__)
+I2SDriver I2SD1;
+#endif
+
+/** @brief I2S2 driver identifier.*/
+#if STM32_I2S_USE_SPI2 || defined(__DOXYGEN__)
+I2SDriver I2SD2;
+#endif
+
+/** @brief I2S3 driver identifier.*/
+#if STM32_I2S_USE_SPI3 || defined(__DOXYGEN__)
+I2SDriver I2SD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) || \
+ STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) || \
+ STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
+/**
+ * @brief Shared end-of-rx service routine.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void i2s_lld_serve_rx_interrupt(I2SDriver *i2sp, uint32_t flags) {
+
+ (void)i2sp;
+
+ /* DMA errors handling.*/
+#if defined(STM32_I2S_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_I2S_DMA_ERROR_HOOK(i2sp);
+ }
+#endif
+
+ /* Callbacks handling, note it is portable code defined in the high
+ level driver.*/
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _i2s_isr_full_code(i2sp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _i2s_isr_half_code(i2sp);
+ }
+}
+#endif
+
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE) || \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE) || \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
+/**
+ * @brief Shared end-of-tx service routine.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void i2s_lld_serve_tx_interrupt(I2SDriver *i2sp, uint32_t flags) {
+
+ (void)i2sp;
+
+ /* DMA errors handling.*/
+#if defined(STM32_I2S_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_I2S_DMA_ERROR_HOOK(i2sp);
+ }
+#endif
+
+ /* Callbacks handling, note it is portable code defined in the high
+ level driver.*/
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _i2s_isr_full_code(i2sp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _i2s_isr_half_code(i2sp);
+ }
+}
+#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level I2S driver initialization.
+ *
+ * @notapi
+ */
+void i2s_lld_init(void) {
+
+#if STM32_I2S_USE_SPI1
+ i2sObjectInit(&I2SD1);
+ I2SD1.spi = SPI1;
+ I2SD1.cfg = STM32_I2S1_CFGR_CFG;
+ I2SD1.dmarx = NULL;
+ I2SD1.dmatx = NULL;
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+ I2SD1.rxdmamode = STM32_DMA_CR_CHSEL(I2S1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD1.rxdmamode = 0;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+ I2SD1.txdmamode = STM32_DMA_CR_CHSEL(I2S1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD1.txdmamode = 0;
+#endif
+#endif
+
+#if STM32_I2S_USE_SPI2
+ i2sObjectInit(&I2SD2);
+ I2SD2.spi = SPI2;
+ I2SD2.cfg = STM32_I2S2_CFGR_CFG;
+ I2SD2.dmarx = NULL;
+ I2SD2.dmatx = NULL;
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+ I2SD2.rxdmamode = STM32_DMA_CR_CHSEL(I2S2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD2.rxdmamode = 0;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+ I2SD2.txdmamode = STM32_DMA_CR_CHSEL(I2S2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD2.txdmamode = 0;
+#endif
+#endif
+
+#if STM32_I2S_USE_SPI3
+ i2sObjectInit(&I2SD3);
+ I2SD3.spi = SPI3;
+ I2SD3.cfg = STM32_I2S3_CFGR_CFG;
+ I2SD3.dmarx = NULL;
+ I2SD3.dmatx = NULL;
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+ I2SD3.rxdmamode = STM32_DMA_CR_CHSEL(I2S3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD3.rxdmamode = 0;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+ I2SD3.txdmamode = STM32_DMA_CR_CHSEL(I2S3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_I2S_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MSIZE_HWORD |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC |
+ STM32_DMA_CR_CIRC |
+ STM32_DMA_CR_HTIE |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#else
+ I2SD3.txdmamode = 0;
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start(I2SDriver *i2sp) {
+
+ /* If in stopped state then enables the SPI and DMA clocks.*/
+ if (i2sp->state == I2S_STOP) {
+
+#if STM32_I2S_USE_SPI1
+ if (&I2SD1 == i2sp) {
+
+ /* Enabling I2S unit clock.*/
+ rccEnableSPI1(true);
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE)
+ i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI1_RX_DMA_STREAM,
+ STM32_I2S_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+ i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI1_TX_DMA_STREAM,
+ STM32_I2S_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
+#endif
+ }
+#endif
+
+#if STM32_I2S_USE_SPI2
+ if (&I2SD2 == i2sp) {
+
+ /* Enabling I2S unit clock.*/
+ rccEnableSPI2(true);
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE)
+ i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI2_RX_DMA_STREAM,
+ STM32_I2S_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+ i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI2_TX_DMA_STREAM,
+ STM32_I2S_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
+#endif
+ }
+#endif
+
+#if STM32_I2S_USE_SPI3
+ if (&I2SD3 == i2sp) {
+
+ /* Enabling I2S unit clock.*/
+ rccEnableSPI3(true);
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE)
+ i2sp->dmarx = dmaStreamAllocI(STM32_I2S_SPI3_RX_DMA_STREAM,
+ STM32_I2S_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_rx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmarx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_RXDMAEN;
+#endif
+#if STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+ i2sp->dmatx = dmaStreamAllocI(STM32_I2S_SPI3_TX_DMA_STREAM,
+ STM32_I2S_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)i2s_lld_serve_tx_interrupt,
+ (void *)i2sp);
+ osalDbgAssert(i2sp->dmatx != NULL, "unable to allocate stream");
+
+ /* CRs settings are done here because those never changes until
+ the driver is stopped.*/
+ i2sp->spi->CR1 = 0;
+ i2sp->spi->CR2 = SPI_CR2_TXDMAEN;
+#endif
+ }
+#endif
+ }
+
+ /* I2S (re)configuration.*/
+ i2sp->spi->I2SPR = i2sp->config->i2spr;
+ i2sp->spi->I2SCFGR = i2sp->config->i2scfgr | i2sp->cfg | SPI_I2SCFGR_I2SMOD;
+}
+
+/**
+ * @brief Deactivates the I2S peripheral.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_stop(I2SDriver *i2sp) {
+
+ /* If in ready state then disables the SPI clock.*/
+ if (i2sp->state == I2S_READY) {
+
+ /* SPI disable.*/
+ i2sp->spi->CR2 = 0;
+ if (NULL != i2sp->dmarx) {
+ dmaStreamFreeI(i2sp->dmarx);
+ i2sp->dmarx = NULL;
+ }
+ if (NULL != i2sp->dmatx) {
+ dmaStreamFreeI(i2sp->dmatx);
+ i2sp->dmatx = NULL;
+ }
+
+#if STM32_I2S_USE_SPI1
+ if (&I2SD1 == i2sp)
+ rccDisableSPI1();
+#endif
+
+#if STM32_I2S_USE_SPI2
+ if (&I2SD2 == i2sp)
+ rccDisableSPI2();
+#endif
+
+#if STM32_I2S_USE_SPI3
+ if (&I2SD3 == i2sp)
+ rccDisableSPI3();
+#endif
+ }
+}
+
+/**
+ * @brief Starts a I2S data exchange.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_start_exchange(I2SDriver *i2sp) {
+ size_t size = i2sp->config->size;
+
+ /* In 32 bit modes the DMA has to perform double operations because fetches
+ are always performed using 16 bit accesses.
+ DATLEN CHLEN SIZE
+ 00 (16) 0 (16) 16
+ 00 (16) 1 (32) 16
+ 01 (24) X 32
+ 10 (32) X 32
+ 11 (NA) X NA
+ */
+ if ((i2sp->config->i2scfgr & SPI_I2SCFGR_DATLEN) != 0)
+ size *= 2;
+
+ /* RX DMA setup.*/
+ if (NULL != i2sp->dmarx) {
+ dmaStreamSetMode(i2sp->dmarx, i2sp->rxdmamode);
+ dmaStreamSetPeripheral(i2sp->dmarx, &i2sp->spi->DR);
+ dmaStreamSetMemory0(i2sp->dmarx, i2sp->config->rx_buffer);
+ dmaStreamSetTransactionSize(i2sp->dmarx, size);
+ dmaStreamEnable(i2sp->dmarx);
+ }
+
+ /* TX DMA setup.*/
+ if (NULL != i2sp->dmatx) {
+ dmaStreamSetMode(i2sp->dmatx, i2sp->txdmamode);
+ dmaStreamSetPeripheral(i2sp->dmatx, &i2sp->spi->DR);
+ dmaStreamSetMemory0(i2sp->dmatx, i2sp->config->tx_buffer);
+ dmaStreamSetTransactionSize(i2sp->dmatx, size);
+ dmaStreamEnable(i2sp->dmatx);
+ }
+
+ /* Starting transfer.*/
+ i2sp->spi->I2SCFGR |= SPI_I2SCFGR_I2SE;
+}
+
+/**
+ * @brief Stops the ongoing data exchange.
+ * @details The ongoing data exchange, if any, is stopped, if the driver
+ * was not active the function does nothing.
+ *
+ * @param[in] i2sp pointer to the @p I2SDriver object
+ *
+ * @notapi
+ */
+void i2s_lld_stop_exchange(I2SDriver *i2sp) {
+
+ /* Stop TX DMA, if enabled.*/
+ if (NULL != i2sp->dmatx) {
+ dmaStreamDisable(i2sp->dmatx);
+
+ /* From the RM: To switch off the I2S, by clearing I2SE, it is mandatory
+ to wait for TXE = 1 and BSY = 0.*/
+ while ((i2sp->spi->SR & (SPI_SR_TXE | SPI_SR_BSY)) != SPI_SR_TXE)
+ ;
+ }
+
+ /* Stop SPI/I2S peripheral.*/
+ i2sp->spi->I2SCFGR &= ~SPI_I2SCFGR_I2SE;
+
+ /* Stop RX DMA, if enabled.*/
+ if (NULL != i2sp->dmarx)
+ dmaStreamDisable(i2sp->dmarx);
+}
+
+#endif /* HAL_USE_I2S */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.h b/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.h
index acf92e1d8f..393163c5e4 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv2/hal_i2s_lld.h
@@ -1,371 +1,371 @@
-/*
- 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 SPIv2/hal_i2s_lld.h
- * @brief STM32 I2S subsystem low level driver header.
- *
- * @addtogroup I2S
- * @{
- */
-
-#ifndef HAL_I2S_LLD_H
-#define HAL_I2S_LLD_H
-
-#if HAL_USE_I2S || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Static I2S modes
- * @{
- */
-#define STM32_I2S_MODE_SLAVE 0
-#define STM32_I2S_MODE_MASTER 1
-#define STM32_I2S_MODE_RX 2
-#define STM32_I2S_MODE_TX 4
-#define STM32_I2S_MODE_RXTX (STM32_I2S_MODE_RX | \
- STM32_I2S_MODE_TX)
-/** @} */
-
-/**
- * @name Mode checks
- * @{
- */
-#define STM32_I2S_IS_MASTER(mode) ((mode) & STM32_I2S_MODE_MASTER)
-#define STM32_I2S_RX_ENABLED(mode) ((mode) & STM32_I2S_MODE_RX)
-#define STM32_I2S_TX_ENABLED(mode) ((mode) & STM32_I2S_MODE_TX)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief I2S1 driver enable switch.
- * @details If set to @p TRUE the support for I2S1 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_I2S_USE_SPI1) || defined(__DOXYGEN__)
-#define STM32_I2S_USE_SPI1 FALSE
-#endif
-
-/**
- * @brief I2S2 driver enable switch.
- * @details If set to @p TRUE the support for I2S2 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_I2S_USE_SPI2) || defined(__DOXYGEN__)
-#define STM32_I2S_USE_SPI2 FALSE
-#endif
-
-/**
- * @brief I2S3 driver enable switch.
- * @details If set to @p TRUE the support for I2S3 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_I2S_USE_SPI3) || defined(__DOXYGEN__)
-#define STM32_I2S_USE_SPI3 FALSE
-#endif
-
-/**
- * @brief I2S1 mode.
- */
-#if !defined(STM32_I2S_SPI1_MODE) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \
- STM32_I2S_MODE_RX)
-#endif
-
-/**
- * @brief I2S2 mode.
- */
-#if !defined(STM32_I2S_SPI2_MODE) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_MASTER | \
- STM32_I2S_MODE_RX)
-#endif
-
-/**
- * @brief I2S3 mode.
- */
-#if !defined(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI3_MODE (STM32_I2S_MODE_MASTER | \
- STM32_I2S_MODE_RX)
-#endif
-
-/**
- * @brief I2S1 interrupt priority level setting.
- */
-#if !defined(STM32_I2S_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2S2 interrupt priority level setting.
- */
-#if !defined(STM32_I2S_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2S3 interrupt priority level setting.
- */
-#if !defined(STM32_I2S_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief I2S1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_I2S_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2S2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_I2S_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2S3 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_I2S_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_I2S_SPI3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief I2S DMA error hook.
- */
-#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_I2S_USE_SPI1 && !STM32_SPI1_SUPPORTS_I2S
-#error "SPI1 does not support I2S mode"
-#endif
-
-#if STM32_I2S_USE_SPI2 && !STM32_SPI2_SUPPORTS_I2S
-#error "SPI2 does not support I2S mode"
-#endif
-
-#if STM32_I2S_USE_SPI3 && !STM32_SPI3_SUPPORTS_I2S
-#error "SPI3 does not support I2S mode"
-#endif
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) && \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
-#error "I2S1 RX and TX mode not supported in this driver implementation"
-#endif
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) && \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
-#error "I2S2 RX and TX mode not supported in this driver implementation"
-#endif
-
-#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) && \
- STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
-#error "I2S3 RX and TX mode not supported in this driver implementation"
-#endif
-
-#if STM32_I2S_USE_SPI1 && !STM32_HAS_SPI1
-#error "SPI1 not present in the selected device"
-#endif
-
-#if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2
-#error "SPI2 not present in the selected device"
-#endif
-
-#if STM32_I2S_USE_SPI3 && !STM32_HAS_SPI3
-#error "SPI3 not present in the selected device"
-#endif
-
-#if !STM32_I2S_USE_SPI1 && !STM32_I2S_USE_SPI2 && !STM32_I2S_USE_SPI3
-#error "I2S driver activated but no SPI peripheral assigned"
-#endif
-
-#if STM32_I2S_USE_SPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI1"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI2"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI3"
-#endif
-
-#if STM32_I2S_USE_SPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI1"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI2"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI3"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_I2S_USE_SPI1 && (!defined(STM32_I2S_SPI1_RX_DMA_STREAM) || \
- !defined(STM32_I2S_SPI1_TX_DMA_STREAM))
-#error "SPI1 DMA streams not defined"
-#endif
-
-#if STM32_I2S_USE_SPI2 && (!defined(STM32_I2S_SPI2_RX_DMA_STREAM) || \
- !defined(STM32_I2S_SPI2_TX_DMA_STREAM))
-#error "SPI2 DMA streams not defined"
-#endif
-
-#if STM32_I2S_USE_SPI3 && (!defined(STM32_I2S_SPI3_RX_DMA_STREAM) || \
- !defined(STM32_I2S_SPI3_TX_DMA_STREAM))
-#error "SPI3 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_I2S_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 RX"
-#endif
-
-#if STM32_I2S_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 TX"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 RX"
-#endif
-
-#if STM32_I2S_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 TX"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 RX"
-#endif
-
-#if STM32_I2S_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 TX"
-#endif
-#endif /* STM32_ADVANCED_DMA */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the I2S driver structure.
- */
-#define i2s_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /* Calculated part of the I2SCFGR register.*/ \
- uint16_t cfg; \
- /* Receive DMA stream or @p NULL.*/ \
- const stm32_dma_stream_t *dmarx; \
- /* Transmit DMA stream or @p NULL.*/ \
- const stm32_dma_stream_t *dmatx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-
-/**
- * @brief Low level fields of the I2S configuration structure.
- */
-#define i2s_lld_config_fields \
- /* Configuration of the I2SCFGR register. \
- NOTE: See the STM32 reference manual, this register is used for \
- the I2S configuration, the following bits must not be \
- specified because handled directly by the driver: \
- - I2SMOD \
- - I2SE \
- - I2SCFG \
- */ \
- int16_t i2scfgr; \
- /* Configuration of the I2SPR register. \
- NOTE: See the STM32 reference manual, this register is used for \
- the I2S clock setup.*/ \
- int16_t i2spr
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_I2S_USE_SPI1 && !defined(__DOXYGEN__)
-extern I2SDriver I2SD1;
-#endif
-
-#if STM32_I2S_USE_SPI2 && !defined(__DOXYGEN__)
-extern I2SDriver I2SD2;
-#endif
-
-#if STM32_I2S_USE_SPI3 && !defined(__DOXYGEN__)
-extern I2SDriver I2SD3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void i2s_lld_init(void);
- void i2s_lld_start(I2SDriver *i2sp);
- void i2s_lld_stop(I2SDriver *i2sp);
- void i2s_lld_start_exchange(I2SDriver *i2sp);
- void i2s_lld_stop_exchange(I2SDriver *i2sp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_I2S */
-
-#endif /* HAL_I2S_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 SPIv2/hal_i2s_lld.h
+ * @brief STM32 I2S subsystem low level driver header.
+ *
+ * @addtogroup I2S
+ * @{
+ */
+
+#ifndef HAL_I2S_LLD_H
+#define HAL_I2S_LLD_H
+
+#if HAL_USE_I2S || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Static I2S modes
+ * @{
+ */
+#define STM32_I2S_MODE_SLAVE 0
+#define STM32_I2S_MODE_MASTER 1
+#define STM32_I2S_MODE_RX 2
+#define STM32_I2S_MODE_TX 4
+#define STM32_I2S_MODE_RXTX (STM32_I2S_MODE_RX | \
+ STM32_I2S_MODE_TX)
+/** @} */
+
+/**
+ * @name Mode checks
+ * @{
+ */
+#define STM32_I2S_IS_MASTER(mode) ((mode) & STM32_I2S_MODE_MASTER)
+#define STM32_I2S_RX_ENABLED(mode) ((mode) & STM32_I2S_MODE_RX)
+#define STM32_I2S_TX_ENABLED(mode) ((mode) & STM32_I2S_MODE_TX)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief I2S1 driver enable switch.
+ * @details If set to @p TRUE the support for I2S1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_SPI1) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_SPI1 FALSE
+#endif
+
+/**
+ * @brief I2S2 driver enable switch.
+ * @details If set to @p TRUE the support for I2S2 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_SPI2) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_SPI2 FALSE
+#endif
+
+/**
+ * @brief I2S3 driver enable switch.
+ * @details If set to @p TRUE the support for I2S3 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_I2S_USE_SPI3) || defined(__DOXYGEN__)
+#define STM32_I2S_USE_SPI3 FALSE
+#endif
+
+/**
+ * @brief I2S1 mode.
+ */
+#if !defined(STM32_I2S_SPI1_MODE) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI1_MODE (STM32_I2S_MODE_MASTER | \
+ STM32_I2S_MODE_RX)
+#endif
+
+/**
+ * @brief I2S2 mode.
+ */
+#if !defined(STM32_I2S_SPI2_MODE) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI2_MODE (STM32_I2S_MODE_MASTER | \
+ STM32_I2S_MODE_RX)
+#endif
+
+/**
+ * @brief I2S3 mode.
+ */
+#if !defined(STM32_I2S_SPI3_MODE) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI3_MODE (STM32_I2S_MODE_MASTER | \
+ STM32_I2S_MODE_RX)
+#endif
+
+/**
+ * @brief I2S1 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S2 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S3 interrupt priority level setting.
+ */
+#if !defined(STM32_I2S_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief I2S1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_I2S_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_I2S_SPI3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief I2S DMA error hook.
+ */
+#if !defined(STM32_I2S_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_I2S_DMA_ERROR_HOOK(i2sp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_I2S_USE_SPI1 && !STM32_SPI1_SUPPORTS_I2S
+#error "SPI1 does not support I2S mode"
+#endif
+
+#if STM32_I2S_USE_SPI2 && !STM32_SPI2_SUPPORTS_I2S
+#error "SPI2 does not support I2S mode"
+#endif
+
+#if STM32_I2S_USE_SPI3 && !STM32_SPI3_SUPPORTS_I2S
+#error "SPI3 does not support I2S mode"
+#endif
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI1_MODE) && \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI1_MODE)
+#error "I2S1 RX and TX mode not supported in this driver implementation"
+#endif
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI2_MODE) && \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI2_MODE)
+#error "I2S2 RX and TX mode not supported in this driver implementation"
+#endif
+
+#if STM32_I2S_RX_ENABLED(STM32_I2S_SPI3_MODE) && \
+ STM32_I2S_TX_ENABLED(STM32_I2S_SPI3_MODE)
+#error "I2S3 RX and TX mode not supported in this driver implementation"
+#endif
+
+#if STM32_I2S_USE_SPI1 && !STM32_HAS_SPI1
+#error "SPI1 not present in the selected device"
+#endif
+
+#if STM32_I2S_USE_SPI2 && !STM32_HAS_SPI2
+#error "SPI2 not present in the selected device"
+#endif
+
+#if STM32_I2S_USE_SPI3 && !STM32_HAS_SPI3
+#error "SPI3 not present in the selected device"
+#endif
+
+#if !STM32_I2S_USE_SPI1 && !STM32_I2S_USE_SPI2 && !STM32_I2S_USE_SPI3
+#error "I2S driver activated but no SPI peripheral assigned"
+#endif
+
+#if STM32_I2S_USE_SPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI1"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI2"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_I2S_SPI3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI3"
+#endif
+
+#if STM32_I2S_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI1"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI2"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_I2S_SPI3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI3"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_I2S_USE_SPI1 && (!defined(STM32_I2S_SPI1_RX_DMA_STREAM) || \
+ !defined(STM32_I2S_SPI1_TX_DMA_STREAM))
+#error "SPI1 DMA streams not defined"
+#endif
+
+#if STM32_I2S_USE_SPI2 && (!defined(STM32_I2S_SPI2_RX_DMA_STREAM) || \
+ !defined(STM32_I2S_SPI2_TX_DMA_STREAM))
+#error "SPI2 DMA streams not defined"
+#endif
+
+#if STM32_I2S_USE_SPI3 && (!defined(STM32_I2S_SPI3_RX_DMA_STREAM) || \
+ !defined(STM32_I2S_SPI3_TX_DMA_STREAM))
+#error "SPI3 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_I2S_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 RX"
+#endif
+
+#if STM32_I2S_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 TX"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 RX"
+#endif
+
+#if STM32_I2S_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 TX"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 RX"
+#endif
+
+#if STM32_I2S_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_I2S_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 TX"
+#endif
+#endif /* STM32_ADVANCED_DMA */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the I2S driver structure.
+ */
+#define i2s_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /* Calculated part of the I2SCFGR register.*/ \
+ uint16_t cfg; \
+ /* Receive DMA stream or @p NULL.*/ \
+ const stm32_dma_stream_t *dmarx; \
+ /* Transmit DMA stream or @p NULL.*/ \
+ const stm32_dma_stream_t *dmatx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+
+/**
+ * @brief Low level fields of the I2S configuration structure.
+ */
+#define i2s_lld_config_fields \
+ /* Configuration of the I2SCFGR register. \
+ NOTE: See the STM32 reference manual, this register is used for \
+ the I2S configuration, the following bits must not be \
+ specified because handled directly by the driver: \
+ - I2SMOD \
+ - I2SE \
+ - I2SCFG \
+ */ \
+ int16_t i2scfgr; \
+ /* Configuration of the I2SPR register. \
+ NOTE: See the STM32 reference manual, this register is used for \
+ the I2S clock setup.*/ \
+ int16_t i2spr
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_I2S_USE_SPI1 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD1;
+#endif
+
+#if STM32_I2S_USE_SPI2 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD2;
+#endif
+
+#if STM32_I2S_USE_SPI3 && !defined(__DOXYGEN__)
+extern I2SDriver I2SD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void i2s_lld_init(void);
+ void i2s_lld_start(I2SDriver *i2sp);
+ void i2s_lld_stop(I2SDriver *i2sp);
+ void i2s_lld_start_exchange(I2SDriver *i2sp);
+ void i2s_lld_stop_exchange(I2SDriver *i2sp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_I2S */
+
+#endif /* HAL_I2S_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
index 02bc9a07bc..69d54d99ee 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
@@ -1,720 +1,720 @@
-/*
- 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 SPIv2/hal_spi_lld.c
- * @brief STM32 SPI subsystem low level driver source.
- *
- * @addtogroup SPI
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_SPI || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define SPI1_RX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_RX_DMA_STREAM, \
- STM32_SPI1_RX_DMA_CHN)
-
-#define SPI1_TX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_TX_DMA_STREAM, \
- STM32_SPI1_TX_DMA_CHN)
-
-#define SPI2_RX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_RX_DMA_STREAM, \
- STM32_SPI2_RX_DMA_CHN)
-
-#define SPI2_TX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_TX_DMA_STREAM, \
- STM32_SPI2_TX_DMA_CHN)
-
-#define SPI3_RX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_RX_DMA_STREAM, \
- STM32_SPI3_RX_DMA_CHN)
-
-#define SPI3_TX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \
- STM32_SPI3_TX_DMA_CHN)
-
-#define SPI4_RX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_RX_DMA_STREAM, \
- STM32_SPI4_RX_DMA_CHN)
-
-#define SPI4_TX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_TX_DMA_STREAM, \
- STM32_SPI4_TX_DMA_CHN)
-
-#define SPI5_RX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_RX_DMA_STREAM, \
- STM32_SPI5_RX_DMA_CHN)
-
-#define SPI5_TX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_TX_DMA_STREAM, \
- STM32_SPI5_TX_DMA_CHN)
-
-#define SPI6_RX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_RX_DMA_STREAM, \
- STM32_SPI6_RX_DMA_CHN)
-
-#define SPI6_TX_DMA_STREAM \
- STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_TX_DMA_STREAM, \
- STM32_SPI6_TX_DMA_CHN)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SPI1 driver identifier.*/
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
-SPIDriver SPID1;
-#endif
-
-/** @brief SPI2 driver identifier.*/
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-SPIDriver SPID2;
-#endif
-
-/** @brief SPI3 driver identifier.*/
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-SPIDriver SPID3;
-#endif
-
-/** @brief SPI4 driver identifier.*/
-#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
-SPIDriver SPID4;
-#endif
-
-/** @brief SPI5 driver identifier.*/
-#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
-SPIDriver SPID5;
-#endif
-
-/** @brief SPI6 driver identifier.*/
-#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
-SPIDriver SPID6;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint16_t dummytx = 0xFFFFU;
-static uint16_t dummyrx;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Shared end-of-rx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)flags;
-#endif
-
- if (spip->config->circular) {
- if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
- /* Half buffer interrupt.*/
- _spi_isr_half_code(spip);
- }
- if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
- /* End buffer interrupt.*/
- _spi_isr_full_code(spip);
- }
- }
- else {
- /* Stopping DMAs.*/
- dmaStreamDisable(spip->dmatx);
- dmaStreamDisable(spip->dmarx);
-
- /* Portable SPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _spi_isr_code(spip);
- }
-}
-
-/**
- * @brief Shared end-of-tx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- (void)spip;
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)spip;
- (void)flags;
-#endif
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SPI driver initialization.
- *
- * @notapi
- */
-void spi_lld_init(void) {
-
-#if STM32_SPI_USE_SPI1
- spiObjectInit(&SPID1);
- SPID1.spi = SPI1;
- SPID1.dmarx = NULL;
- SPID1.dmatx = NULL;
- SPID1.rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID1.txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI2
- spiObjectInit(&SPID2);
- SPID2.spi = SPI2;
- SPID2.dmarx = NULL;
- SPID2.dmatx = NULL;
- SPID2.rxdmamode = STM32_DMA_CR_CHSEL(SPI2_RX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID2.txdmamode = STM32_DMA_CR_CHSEL(SPI2_TX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI3
- spiObjectInit(&SPID3);
- SPID3.spi = SPI3;
- SPID3.dmarx = NULL;
- SPID3.dmatx = NULL;
- SPID3.rxdmamode = STM32_DMA_CR_CHSEL(SPI3_RX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID3.txdmamode = STM32_DMA_CR_CHSEL(SPI3_TX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI4
- spiObjectInit(&SPID4);
- SPID4.spi = SPI4;
- SPID4.dmarx = NULL;
- SPID4.dmatx = NULL;
- SPID4.rxdmamode = STM32_DMA_CR_CHSEL(SPI4_RX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID4.txdmamode = STM32_DMA_CR_CHSEL(SPI4_TX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI5
- spiObjectInit(&SPID5);
- SPID5.spi = SPI5;
- SPID5.dmarx = NULL;
- SPID5.dmatx = NULL;
- SPID5.rxdmamode = STM32_DMA_CR_CHSEL(SPI5_RX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID5.txdmamode = STM32_DMA_CR_CHSEL(SPI5_TX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-
-#if STM32_SPI_USE_SPI6
- spiObjectInit(&SPID6);
- SPID6.spi = SPI6;
- SPID6.dmarx = NULL;
- SPID6.dmatx = NULL;
- SPID6.rxdmamode = STM32_DMA_CR_CHSEL(SPI6_RX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID6.txdmamode = STM32_DMA_CR_CHSEL(SPI6_TX_DMA_STREAM) |
- STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#endif
-}
-
-/**
- * @brief Configures and activates the SPI peripheral.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_start(SPIDriver *spip) {
- uint32_t ds;
-
- /* If in stopped state then enables the SPI and DMA clocks.*/
- if (spip->state == SPI_STOP) {
-#if STM32_SPI_USE_SPI1
- if (&SPID1 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
- STM32_SPI_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
- STM32_SPI_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI1(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX);
- dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX);
-#endif
- }
-#endif
-#if STM32_SPI_USE_SPI2
- if (&SPID2 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
- STM32_SPI_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
- STM32_SPI_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI2(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX);
- dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX);
-#endif
- }
-#endif
-#if STM32_SPI_USE_SPI3
- if (&SPID3 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
- STM32_SPI_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
- STM32_SPI_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI3(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX);
- dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX);
-#endif
- }
-#endif
-#if STM32_SPI_USE_SPI4
- if (&SPID4 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
- STM32_SPI_SPI4_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
- STM32_SPI_SPI4_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI4(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX);
- dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX);
-#endif
- }
-#endif
-#if STM32_SPI_USE_SPI5
- if (&SPID5 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
- STM32_SPI_SPI5_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
- STM32_SPI_SPI5_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI5(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX);
- dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX);
-#endif
- }
-#endif
-#if STM32_SPI_USE_SPI6
- if (&SPID6 == spip) {
- spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI6_RX_DMA_STREAM,
- STM32_SPI_SPI6_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
- spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI6_TX_DMA_STREAM,
- STM32_SPI_SPI6_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
- rccEnableSPI6(true);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX);
- dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX);
-#endif
- }
-#endif
-
- /* DMA setup.*/
- dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
- dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
- }
-
- /* Configuration-specific DMA setup.*/
- ds = spip->config->cr2 & SPI_CR2_DS;
- if (!ds || (ds <= (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0))) {
- /* Frame width is 8 bits or smaller.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
- }
- else {
- /* Frame width is larger than 8 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- }
-
- if (spip->config->circular) {
- spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- }
- else {
- spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- }
-
- /* SPI setup and enable.*/
- spip->spi->CR1 &= ~SPI_CR1_SPE;
- spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR;
- spip->spi->CR2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_SSOE |
- SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
- spip->spi->CR1 |= SPI_CR1_SPE;
-}
-
-/**
- * @brief Deactivates the SPI peripheral.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_stop(SPIDriver *spip) {
-
- /* If in ready state then disables the SPI clock.*/
- if (spip->state == SPI_READY) {
-
- /* SPI disable.*/
- spip->spi->CR1 &= ~SPI_CR1_SPE;
- spip->spi->CR1 = 0;
- spip->spi->CR2 = 0;
- dmaStreamFreeI(spip->dmarx);
- dmaStreamFreeI(spip->dmatx);
- spip->dmarx = NULL;
- spip->dmatx = NULL;
-
-#if STM32_SPI_USE_SPI1
- if (&SPID1 == spip)
- rccDisableSPI1();
-#endif
-#if STM32_SPI_USE_SPI2
- if (&SPID2 == spip)
- rccDisableSPI2();
-#endif
-#if STM32_SPI_USE_SPI3
- if (&SPID3 == spip)
- rccDisableSPI3();
-#endif
-#if STM32_SPI_USE_SPI4
- if (&SPID4 == spip)
- rccDisableSPI4();
-#endif
-#if STM32_SPI_USE_SPI5
- if (&SPID5 == spip)
- rccDisableSPI5();
-#endif
-#if STM32_SPI_USE_SPI6
- if (&SPID6 == spip)
- rccDisableSPI6();
-#endif
- }
-}
-
-#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
-/**
- * @brief Asserts the slave select signal and prepares for transfers.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_select(SPIDriver *spip) {
-
- /* No implementation on STM32.*/
-}
-
-/**
- * @brief Deasserts the slave select signal.
- * @details The previously selected peripheral is unselected.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_unselect(SPIDriver *spip) {
-
- /* No implementation on STM32.*/
-}
-#endif
-
-/**
- * @brief Ignores data on the SPI bus.
- * @details This asynchronous function starts the transmission of a series of
- * idle words on the SPI bus and ignores the received data.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to be ignored
- *
- * @notapi
- */
-void spi_lld_ignore(SPIDriver *spip, size_t n) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, &dummyrx);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
-
- dmaStreamSetMemory0(spip->dmatx, &dummytx);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-/**
- * @brief Exchanges data on the SPI bus.
- * @details This asynchronous function starts a simultaneous transmit/receive
- * operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to be exchanged
- * @param[in] txbuf the pointer to the transmit buffer
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void spi_lld_exchange(SPIDriver *spip, size_t n,
- const void *txbuf, void *rxbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, rxbuf);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamSetMemory0(spip->dmatx, txbuf);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-/**
- * @brief Sends data over the SPI bus.
- * @details This asynchronous function starts a transmit operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, &dummyrx);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
-
- dmaStreamSetMemory0(spip->dmatx, txbuf);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-/**
- * @brief Receives data from the SPI bus.
- * @details This asynchronous function starts a receive operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to receive
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- dmaStreamSetMemory0(spip->dmarx, rxbuf);
- dmaStreamSetTransactionSize(spip->dmarx, n);
- dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamSetMemory0(spip->dmatx, &dummytx);
- dmaStreamSetTransactionSize(spip->dmatx, n);
- dmaStreamSetMode(spip->dmatx, spip->txdmamode);
-
- dmaStreamEnable(spip->dmarx);
- dmaStreamEnable(spip->dmatx);
-}
-
-#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Aborts the ongoing SPI operation, if any.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_abort(SPIDriver *spip) {
-
- /* Stopping DMAs.*/
- dmaStreamDisable(spip->dmatx);
- dmaStreamDisable(spip->dmarx);
-}
-#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
-
-/**
- * @brief Exchanges one frame using a polled wait.
- * @details This synchronous function exchanges one frame using a polled
- * synchronization method. This function is useful when exchanging
- * small amount of data on high speed channels, usually in this
- * situation is much more efficient just wait for completion using
- * polling than suspending the thread waiting for an interrupt.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] frame the data frame to send over the SPI bus
- * @return The received data frame from the SPI bus.
- */
-uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
-
- /*
- * Data register must be accessed with the appropriate data size.
- * Byte size access (uint8_t *) for transactions that are <= 8-bit.
- * Halfword size access (uint16_t) for transactions that are <= 8-bit.
- */
- if ((spip->config->cr2 & SPI_CR2_DS) <= (SPI_CR2_DS_2 |
- SPI_CR2_DS_1 |
- SPI_CR2_DS_0)) {
- volatile uint8_t *spidr = (volatile uint8_t *)&spip->spi->DR;
- *spidr = (uint8_t)frame;
- while ((spip->spi->SR & SPI_SR_RXNE) == 0)
- ;
- return (uint16_t)*spidr;
- }
- else {
- spip->spi->DR = frame;
- while ((spip->spi->SR & SPI_SR_RXNE) == 0)
- ;
- return spip->spi->DR;
- }
-}
-
-#endif /* HAL_USE_SPI */
-
-/** @} */
+/*
+ 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 SPIv2/hal_spi_lld.c
+ * @brief STM32 SPI subsystem low level driver source.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define SPI1_RX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_RX_DMA_STREAM, \
+ STM32_SPI1_RX_DMA_CHN)
+
+#define SPI1_TX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI1_TX_DMA_STREAM, \
+ STM32_SPI1_TX_DMA_CHN)
+
+#define SPI2_RX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_RX_DMA_STREAM, \
+ STM32_SPI2_RX_DMA_CHN)
+
+#define SPI2_TX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI2_TX_DMA_STREAM, \
+ STM32_SPI2_TX_DMA_CHN)
+
+#define SPI3_RX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_RX_DMA_STREAM, \
+ STM32_SPI3_RX_DMA_CHN)
+
+#define SPI3_TX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \
+ STM32_SPI3_TX_DMA_CHN)
+
+#define SPI4_RX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_RX_DMA_STREAM, \
+ STM32_SPI4_RX_DMA_CHN)
+
+#define SPI4_TX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI4_TX_DMA_STREAM, \
+ STM32_SPI4_TX_DMA_CHN)
+
+#define SPI5_RX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_RX_DMA_STREAM, \
+ STM32_SPI5_RX_DMA_CHN)
+
+#define SPI5_TX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI5_TX_DMA_STREAM, \
+ STM32_SPI5_TX_DMA_CHN)
+
+#define SPI6_RX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_RX_DMA_STREAM, \
+ STM32_SPI6_RX_DMA_CHN)
+
+#define SPI6_TX_DMA_STREAM \
+ STM32_DMA_GETCHANNEL(STM32_SPI_SPI6_TX_DMA_STREAM, \
+ STM32_SPI6_TX_DMA_CHN)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SPI1 driver identifier.*/
+#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
+SPIDriver SPID1;
+#endif
+
+/** @brief SPI2 driver identifier.*/
+#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
+SPIDriver SPID2;
+#endif
+
+/** @brief SPI3 driver identifier.*/
+#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
+SPIDriver SPID3;
+#endif
+
+/** @brief SPI4 driver identifier.*/
+#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
+SPIDriver SPID4;
+#endif
+
+/** @brief SPI5 driver identifier.*/
+#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
+SPIDriver SPID5;
+#endif
+
+/** @brief SPI6 driver identifier.*/
+#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
+SPIDriver SPID6;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const uint16_t dummytx = 0xFFFFU;
+static uint16_t dummyrx;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared end-of-rx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (spip->config->circular) {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
+ /* Half buffer interrupt.*/
+ _spi_isr_half_code(spip);
+ }
+ if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
+ /* End buffer interrupt.*/
+ _spi_isr_full_code(spip);
+ }
+ }
+ else {
+ /* Stopping DMAs.*/
+ dmaStreamDisable(spip->dmatx);
+ dmaStreamDisable(spip->dmarx);
+
+ /* Portable SPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _spi_isr_code(spip);
+ }
+}
+
+/**
+ * @brief Shared end-of-tx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_tx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ (void)spip;
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)spip;
+ (void)flags;
+#endif
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SPI driver initialization.
+ *
+ * @notapi
+ */
+void spi_lld_init(void) {
+
+#if STM32_SPI_USE_SPI1
+ spiObjectInit(&SPID1);
+ SPID1.spi = SPI1;
+ SPID1.dmarx = NULL;
+ SPID1.dmatx = NULL;
+ SPID1.rxdmamode = STM32_DMA_CR_CHSEL(SPI1_RX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID1.txdmamode = STM32_DMA_CR_CHSEL(SPI1_TX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI2
+ spiObjectInit(&SPID2);
+ SPID2.spi = SPI2;
+ SPID2.dmarx = NULL;
+ SPID2.dmatx = NULL;
+ SPID2.rxdmamode = STM32_DMA_CR_CHSEL(SPI2_RX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID2.txdmamode = STM32_DMA_CR_CHSEL(SPI2_TX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI3
+ spiObjectInit(&SPID3);
+ SPID3.spi = SPI3;
+ SPID3.dmarx = NULL;
+ SPID3.dmatx = NULL;
+ SPID3.rxdmamode = STM32_DMA_CR_CHSEL(SPI3_RX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID3.txdmamode = STM32_DMA_CR_CHSEL(SPI3_TX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI4
+ spiObjectInit(&SPID4);
+ SPID4.spi = SPI4;
+ SPID4.dmarx = NULL;
+ SPID4.dmatx = NULL;
+ SPID4.rxdmamode = STM32_DMA_CR_CHSEL(SPI4_RX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID4.txdmamode = STM32_DMA_CR_CHSEL(SPI4_TX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI5
+ spiObjectInit(&SPID5);
+ SPID5.spi = SPI5;
+ SPID5.dmarx = NULL;
+ SPID5.dmatx = NULL;
+ SPID5.rxdmamode = STM32_DMA_CR_CHSEL(SPI5_RX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID5.txdmamode = STM32_DMA_CR_CHSEL(SPI5_TX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+
+#if STM32_SPI_USE_SPI6
+ spiObjectInit(&SPID6);
+ SPID6.spi = SPI6;
+ SPID6.dmarx = NULL;
+ SPID6.dmatx = NULL;
+ SPID6.rxdmamode = STM32_DMA_CR_CHSEL(SPI6_RX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID6.txdmamode = STM32_DMA_CR_CHSEL(SPI6_TX_DMA_STREAM) |
+ STM32_DMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#endif
+}
+
+/**
+ * @brief Configures and activates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_start(SPIDriver *spip) {
+ uint32_t ds;
+
+ /* If in stopped state then enables the SPI and DMA clocks.*/
+ if (spip->state == SPI_STOP) {
+#if STM32_SPI_USE_SPI1
+ if (&SPID1 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
+ STM32_SPI_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
+ STM32_SPI_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI1(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX);
+ dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX);
+#endif
+ }
+#endif
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
+ STM32_SPI_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
+ STM32_SPI_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI2(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX);
+ dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX);
+#endif
+ }
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
+ STM32_SPI_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
+ STM32_SPI_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI3(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX);
+ dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX);
+#endif
+ }
+#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI4(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX);
+ dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX);
+#endif
+ }
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI5(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX);
+ dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX);
+#endif
+ }
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip) {
+ spip->dmarx = dmaStreamAllocI(STM32_SPI_SPI6_RX_DMA_STREAM,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmarx != NULL, "unable to allocate stream");
+ spip->dmatx = dmaStreamAllocI(STM32_SPI_SPI6_TX_DMA_STREAM,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->dmatx != NULL, "unable to allocate stream");
+ rccEnableSPI6(true);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX);
+ dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX);
+#endif
+ }
+#endif
+
+ /* DMA setup.*/
+ dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
+ dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
+ }
+
+ /* Configuration-specific DMA setup.*/
+ ds = spip->config->cr2 & SPI_CR2_DS;
+ if (!ds || (ds <= (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0))) {
+ /* Frame width is 8 bits or smaller.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+ }
+ else {
+ /* Frame width is larger than 8 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ }
+
+ if (spip->config->circular) {
+ spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ }
+ else {
+ spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ }
+
+ /* SPI setup and enable.*/
+ spip->spi->CR1 &= ~SPI_CR1_SPE;
+ spip->spi->CR1 = spip->config->cr1 | SPI_CR1_MSTR;
+ spip->spi->CR2 = spip->config->cr2 | SPI_CR2_FRXTH | SPI_CR2_SSOE |
+ SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN;
+ spip->spi->CR1 |= SPI_CR1_SPE;
+}
+
+/**
+ * @brief Deactivates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_stop(SPIDriver *spip) {
+
+ /* If in ready state then disables the SPI clock.*/
+ if (spip->state == SPI_READY) {
+
+ /* SPI disable.*/
+ spip->spi->CR1 &= ~SPI_CR1_SPE;
+ spip->spi->CR1 = 0;
+ spip->spi->CR2 = 0;
+ dmaStreamFreeI(spip->dmarx);
+ dmaStreamFreeI(spip->dmatx);
+ spip->dmarx = NULL;
+ spip->dmatx = NULL;
+
+#if STM32_SPI_USE_SPI1
+ if (&SPID1 == spip)
+ rccDisableSPI1();
+#endif
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip)
+ rccDisableSPI2();
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip)
+ rccDisableSPI3();
+#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip)
+ rccDisableSPI4();
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip)
+ rccDisableSPI5();
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip)
+ rccDisableSPI6();
+#endif
+ }
+}
+
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
+/**
+ * @brief Asserts the slave select signal and prepares for transfers.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_select(SPIDriver *spip) {
+
+ /* No implementation on STM32.*/
+}
+
+/**
+ * @brief Deasserts the slave select signal.
+ * @details The previously selected peripheral is unselected.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_unselect(SPIDriver *spip) {
+
+ /* No implementation on STM32.*/
+}
+#endif
+
+/**
+ * @brief Ignores data on the SPI bus.
+ * @details This asynchronous function starts the transmission of a series of
+ * idle words on the SPI bus and ignores the received data.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be ignored
+ *
+ * @notapi
+ */
+void spi_lld_ignore(SPIDriver *spip, size_t n) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, &dummyrx);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
+
+ dmaStreamSetMemory0(spip->dmatx, &dummytx);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+/**
+ * @brief Exchanges data on the SPI bus.
+ * @details This asynchronous function starts a simultaneous transmit/receive
+ * operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be exchanged
+ * @param[in] txbuf the pointer to the transmit buffer
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamSetMemory0(spip->dmatx, txbuf);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+/**
+ * @brief Sends data over the SPI bus.
+ * @details This asynchronous function starts a transmit operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, &dummyrx);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode);
+
+ dmaStreamSetMemory0(spip->dmatx, txbuf);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+/**
+ * @brief Receives data from the SPI bus.
+ * @details This asynchronous function starts a receive operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to receive
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ dmaStreamSetMemory0(spip->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(spip->dmarx, n);
+ dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamSetMemory0(spip->dmatx, &dummytx);
+ dmaStreamSetTransactionSize(spip->dmatx, n);
+ dmaStreamSetMode(spip->dmatx, spip->txdmamode);
+
+ dmaStreamEnable(spip->dmarx);
+ dmaStreamEnable(spip->dmatx);
+}
+
+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Aborts the ongoing SPI operation, if any.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_abort(SPIDriver *spip) {
+
+ /* Stopping DMAs.*/
+ dmaStreamDisable(spip->dmatx);
+ dmaStreamDisable(spip->dmarx);
+}
+#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
+
+/**
+ * @brief Exchanges one frame using a polled wait.
+ * @details This synchronous function exchanges one frame using a polled
+ * synchronization method. This function is useful when exchanging
+ * small amount of data on high speed channels, usually in this
+ * situation is much more efficient just wait for completion using
+ * polling than suspending the thread waiting for an interrupt.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] frame the data frame to send over the SPI bus
+ * @return The received data frame from the SPI bus.
+ */
+uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
+
+ /*
+ * Data register must be accessed with the appropriate data size.
+ * Byte size access (uint8_t *) for transactions that are <= 8-bit.
+ * Halfword size access (uint16_t) for transactions that are <= 8-bit.
+ */
+ if ((spip->config->cr2 & SPI_CR2_DS) <= (SPI_CR2_DS_2 |
+ SPI_CR2_DS_1 |
+ SPI_CR2_DS_0)) {
+ volatile uint8_t *spidr = (volatile uint8_t *)&spip->spi->DR;
+ *spidr = (uint8_t)frame;
+ while ((spip->spi->SR & SPI_SR_RXNE) == 0)
+ ;
+ return (uint16_t)*spidr;
+ }
+ else {
+ spip->spi->DR = frame;
+ while ((spip->spi->SR & SPI_SR_RXNE) == 0)
+ ;
+ return spip->spi->DR;
+ }
+}
+
+#endif /* HAL_USE_SPI */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h
index ec3374d99e..309f94a54f 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h
@@ -1,557 +1,557 @@
-/*
- 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 SPIv2/hal_spi_lld.h
- * @brief STM32 SPI subsystem low level driver header.
- *
- * @addtogroup SPI
- * @{
- */
-
-#ifndef HAL_SPI_LLD_H
-#define HAL_SPI_LLD_H
-
-#if HAL_USE_SPI || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Circular mode support flag.
- */
-#define SPI_SUPPORTS_CIRCULAR TRUE
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SPI1 driver enable switch.
- * @details If set to @p TRUE the support for SPI1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI1 FALSE
-#endif
-
-/**
- * @brief SPI2 driver enable switch.
- * @details If set to @p TRUE the support for SPI2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI2 FALSE
-#endif
-
-/**
- * @brief SPI3 driver enable switch.
- * @details If set to @p TRUE the support for SPI3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI3 FALSE
-#endif
-
-/**
- * @brief SPI4 driver enable switch.
- * @details If set to @p TRUE the support for SPI4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI4 FALSE
-#endif
-
-/**
- * @brief SPI5 driver enable switch.
- * @details If set to @p TRUE the support for SPI5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI5 FALSE
-#endif
-
-/**
- * @brief SPI6 driver enable switch.
- * @details If set to @p TRUE the support for SPI6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI6 FALSE
-#endif
-
-/**
- * @brief SPI1 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI2 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI3 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI4 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI4_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI5 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI5_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI6 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI6_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI4_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI5 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI5_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI6 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI6_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI DMA error hook.
- */
-#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
-#error "SPI1 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
-#error "SPI2 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
-#error "SPI3 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
-#error "SPI4 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
-#error "SPI5 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
-#error "SPI6 not present in the selected device"
-#endif
-
-#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
- !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
-#error "SPI driver activated but no SPI peripheral assigned"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI1"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI2"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI3"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI4"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI5"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI6"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI1"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI2"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI3"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI4"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI5"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI6"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI1_TX_DMA_STREAM))
-#error "SPI1 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI2_TX_DMA_STREAM))
-#error "SPI2 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI3_TX_DMA_STREAM))
-#error "SPI3 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
-#error "SPI4 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
-#error "SPI5 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI6_TX_DMA_STREAM))
-#error "SPI6 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI1 RX"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI1 TX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI2 RX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI2 TX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI3 RX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI3 TX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI4 RX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI4 TX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI5 RX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI5 TX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI6_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI6 RX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI6_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to SPI6 TX"
-#endif
-
-/* Devices without DMAMUX require an additional check.*/
-#if STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 RX"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI1 TX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 RX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI2 TX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 RX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI3 TX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI4 RX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI4 TX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI5 RX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI5 TX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK)
-#error "invalid DMA stream associated to SPI6 RX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK)
-#error "invalid DMA stream associated to SPI6 TX"
-#endif
-
-#endif /* STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
-#error "SPI_SELECT_MODE_LLD not supported by this driver"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the SPI driver structure.
- */
-#define spi_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /* Receive DMA stream.*/ \
- const stm32_dma_stream_t *dmarx; \
- /* Transmit DMA stream.*/ \
- const stm32_dma_stream_t *dmatx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-
-/**
- * @brief Low level fields of the SPI configuration structure.
- */
-#define spi_lld_config_fields \
- /* SPI CR1 register initialization data.*/ \
- uint16_t cr1; \
- /* SPI CR2 register initialization data.*/ \
- uint16_t cr2
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
-extern SPIDriver SPID1;
-#endif
-
-#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
-extern SPIDriver SPID2;
-#endif
-
-#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
-extern SPIDriver SPID3;
-#endif
-
-#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
-extern SPIDriver SPID4;
-#endif
-
-#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
-extern SPIDriver SPID5;
-#endif
-
-#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
-extern SPIDriver SPID6;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void spi_lld_init(void);
- void spi_lld_start(SPIDriver *spip);
- void spi_lld_stop(SPIDriver *spip);
-#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
- void spi_lld_select(SPIDriver *spip);
- void spi_lld_unselect(SPIDriver *spip);
-#endif
- void spi_lld_ignore(SPIDriver *spip, size_t n);
- void spi_lld_exchange(SPIDriver *spip, size_t n,
- const void *txbuf, void *rxbuf);
- void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
- void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
-#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
- void spi_lld_abort(SPIDriver *spip);
-#endif
- uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SPI */
-
-#endif /* HAL_SPI_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 SPIv2/hal_spi_lld.h
+ * @brief STM32 SPI subsystem low level driver header.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#ifndef HAL_SPI_LLD_H
+#define HAL_SPI_LLD_H
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Circular mode support flag.
+ */
+#define SPI_SUPPORTS_CIRCULAR TRUE
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SPI1 driver enable switch.
+ * @details If set to @p TRUE the support for SPI1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI1 FALSE
+#endif
+
+/**
+ * @brief SPI2 driver enable switch.
+ * @details If set to @p TRUE the support for SPI2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI2 FALSE
+#endif
+
+/**
+ * @brief SPI3 driver enable switch.
+ * @details If set to @p TRUE the support for SPI3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI3 FALSE
+#endif
+
+/**
+ * @brief SPI4 driver enable switch.
+ * @details If set to @p TRUE the support for SPI4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI4 FALSE
+#endif
+
+/**
+ * @brief SPI5 driver enable switch.
+ * @details If set to @p TRUE the support for SPI5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI5 FALSE
+#endif
+
+/**
+ * @brief SPI6 driver enable switch.
+ * @details If set to @p TRUE the support for SPI6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI6 FALSE
+#endif
+
+/**
+ * @brief SPI1 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI2 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI3 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI4 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI5 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI6 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI5 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI6 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI DMA error hook.
+ */
+#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
+#error "SPI1 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
+#error "SPI2 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
+#error "SPI3 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
+#error "SPI4 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
+#error "SPI5 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
+#error "SPI6 not present in the selected device"
+#endif
+
+#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
+ !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
+#error "SPI driver activated but no SPI peripheral assigned"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI1"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI2"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI3"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI6"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI1"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI2"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI3"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI6"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI1_TX_DMA_STREAM))
+#error "SPI1 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI2_TX_DMA_STREAM))
+#error "SPI2 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI3_TX_DMA_STREAM))
+#error "SPI3 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
+#error "SPI4 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
+#error "SPI5 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI6_TX_DMA_STREAM))
+#error "SPI6 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI1 RX"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI1 TX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI2 RX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI2 TX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI3 RX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI3 TX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI4 RX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI4 TX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI5 RX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI5 TX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI6_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI6 RX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI6_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to SPI6 TX"
+#endif
+
+/* Devices without DMAMUX require an additional check.*/
+#if STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 RX"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_TX_DMA_STREAM, STM32_SPI1_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI1 TX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_RX_DMA_STREAM, STM32_SPI2_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 RX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI2_TX_DMA_STREAM, STM32_SPI2_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI2 TX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_RX_DMA_STREAM, STM32_SPI3_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 RX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI3_TX_DMA_STREAM, STM32_SPI3_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI3 TX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_RX_DMA_STREAM, STM32_SPI4_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI4 RX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI4_TX_DMA_STREAM, STM32_SPI4_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI4 TX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_RX_DMA_STREAM, STM32_SPI5_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI5 RX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI5_TX_DMA_STREAM, STM32_SPI5_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI5 TX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_RX_DMA_STREAM, STM32_SPI6_RX_DMA_MSK)
+#error "invalid DMA stream associated to SPI6 RX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI6_TX_DMA_STREAM, STM32_SPI6_TX_DMA_MSK)
+#error "invalid DMA stream associated to SPI6 TX"
+#endif
+
+#endif /* STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
+#error "SPI_SELECT_MODE_LLD not supported by this driver"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the SPI driver structure.
+ */
+#define spi_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /* Receive DMA stream.*/ \
+ const stm32_dma_stream_t *dmarx; \
+ /* Transmit DMA stream.*/ \
+ const stm32_dma_stream_t *dmatx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+
+/**
+ * @brief Low level fields of the SPI configuration structure.
+ */
+#define spi_lld_config_fields \
+ /* SPI CR1 register initialization data.*/ \
+ uint16_t cr1; \
+ /* SPI CR2 register initialization data.*/ \
+ uint16_t cr2
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
+extern SPIDriver SPID1;
+#endif
+
+#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
+extern SPIDriver SPID2;
+#endif
+
+#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
+extern SPIDriver SPID3;
+#endif
+
+#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
+extern SPIDriver SPID4;
+#endif
+
+#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
+extern SPIDriver SPID5;
+#endif
+
+#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
+extern SPIDriver SPID6;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void spi_lld_init(void);
+ void spi_lld_start(SPIDriver *spip);
+ void spi_lld_stop(SPIDriver *spip);
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
+ void spi_lld_select(SPIDriver *spip);
+ void spi_lld_unselect(SPIDriver *spip);
+#endif
+ void spi_lld_ignore(SPIDriver *spip, size_t n);
+ void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf);
+ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
+ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
+ void spi_lld_abort(SPIDriver *spip);
+#endif
+ uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SPI */
+
+#endif /* HAL_SPI_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv3/driver.mk b/os/hal/ports/STM32/LLD/SPIv3/driver.mk
index b29942c10d..ace402b9ce 100644
--- a/os/hal/ports/STM32/LLD/SPIv3/driver.mk
+++ b/os/hal/ports/STM32/LLD/SPIv3/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3
diff --git a/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c b/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
index f0ef28d6da..cf1995cf84 100644
--- a/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.c
@@ -1,1142 +1,1142 @@
-/*
- 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 SPIv3/hal_spi_lld.c
- * @brief STM32 SPI subsystem low level driver source.
- *
- * @addtogroup SPI
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_SPI || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SPI1 driver identifier.*/
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
-SPIDriver SPID1;
-#endif
-
-/** @brief SPI2 driver identifier.*/
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-SPIDriver SPID2;
-#endif
-
-/** @brief SPI3 driver identifier.*/
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-SPIDriver SPID3;
-#endif
-
-/** @brief SPI4 driver identifier.*/
-#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
-SPIDriver SPID4;
-#endif
-
-/** @brief SPI5 driver identifier.*/
-#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
-SPIDriver SPID5;
-#endif
-
-/** @brief SPI6 driver identifier.*/
-#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
-SPIDriver SPID6;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const uint32_t dummytx = STM32_SPI_FILLER_PATTERN;
-static uint32_t dummyrx;
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static void spi_lld_wait_complete(SPIDriver *spip) {
-
- while ((spip->spi->CR1 & SPI_CR1_CSTART) != 0) {
- }
- spip->spi->IFCR = 0xFFFFFFFF;
-}
-
-#if defined(STM32_SPI_BDMA_REQUIRED)
-/**
- * @brief Shared DMA end-of-rx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_bdma_rx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- if ((flags & STM32_BDMA_ISR_TEIF) != 0U) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)flags;
-#endif
-
- if (spip->config->circular) {
- if ((flags & STM32_BDMA_ISR_HTIF) != 0U) {
- /* Half buffer interrupt.*/
- _spi_isr_half_code(spip);
- }
- if ((flags & STM32_BDMA_ISR_TCIF) != 0U) {
- /* End buffer interrupt.*/
- _spi_isr_full_code(spip);
- }
- }
- else {
- /* Stopping SPI.*/
- spip->spi->CR1 |= SPI_CR1_CSUSP;
-
- /* Stopping DMAs.*/
- bdmaStreamDisable(spip->tx.bdma);
- bdmaStreamDisable(spip->rx.bdma);
-
- /* Portable SPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _spi_isr_code(spip);
- }
-}
-
-/**
- * @brief Shared BDMA end-of-tx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_bdma_tx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- (void)spip;
- if ((flags & STM32_BDMA_ISR_TEIF) != 0) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)spip;
- (void)flags;
-#endif
-}
-#endif /* defined(STM32_SPI_BDMA_REQUIRED) */
-
-#if defined(STM32_SPI_DMA_REQUIRED)
-/**
- * @brief Shared DMA end-of-rx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_dma_rx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)flags;
-#endif
-
- if (spip->config->circular) {
- if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
- /* Half buffer interrupt.*/
- _spi_isr_half_code(spip);
- }
- if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
- /* End buffer interrupt.*/
- _spi_isr_full_code(spip);
- }
- }
- else {
- /* Stopping SPI.*/
- spip->spi->CR1 |= SPI_CR1_CSUSP;
-
- /* Stopping DMAs.*/
- dmaStreamDisable(spip->tx.dma);
- dmaStreamDisable(spip->rx.dma);
-
- /* Portable SPI ISR code defined in the high level driver, note, it is
- a macro.*/
- _spi_isr_code(spip);
- }
-}
-
-/**
- * @brief Shared DMA end-of-tx service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void spi_lld_serve_dma_tx_interrupt(SPIDriver *spip, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_SPI_DMA_ERROR_HOOK)
- (void)spip;
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_SPI_DMA_ERROR_HOOK(spip);
- }
-#else
- (void)spip;
- (void)flags;
-#endif
-}
-#endif /* defined(STM32_SPI_DMA_REQUIRED) */
-
-/**
- * @brief Shared SPI service routine.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- */
-static void spi_lld_serve_interrupt(SPIDriver *spip) {
- uint32_t sr;
-
- sr = spip->spi->SR & spip->spi->IER;
- spip->spi->IFCR = sr;
-
- if ((sr & SPI_SR_OVR) != 0U) {
- /* CHTODO: fault notification.*/
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
-#if !defined(STM32_SPI1_SUPPRESS_ISR)
-#if !defined(STM32_SPI1_HANDLER)
-#error "STM32_SPI1_HANDLER not defined"
-#endif
-/**
- * @brief SPI1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SPI1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- spi_lld_serve_interrupt(&SPID1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_SPI1_SUPPRESS_ISR) */
-#endif /* STM32_SPI_USE_SPI1 */
-
-#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
-#if !defined(STM32_SPI2_SUPPRESS_ISR)
-#if !defined(STM32_SPI2_HANDLER)
-#error "STM32_SPI2_HANDLER not defined"
-#endif
-/**
- * @brief SPI2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SPI2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- spi_lld_serve_interrupt(&SPID2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_SPI2_SUPPRESS_ISR) */
-#endif /* STM32_SPI_USE_SPI2 */
-
-#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
-#if !defined(STM32_SPI3_SUPPRESS_ISR)
-#if !defined(STM32_SPI3_HANDLER)
-#error "STM32_SPI3_HANDLER not defined"
-#endif
-/**
- * @brief SPI3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SPI3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- spi_lld_serve_interrupt(&SPID3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_SPI3_SUPPRESS_ISR) */
-#endif /* STM32_SPI_USE_SPI3 */
-
-#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
-#if !defined(STM32_SPI4_SUPPRESS_ISR)
-#if !defined(STM32_SPI4_HANDLER)
-#error "STM32_SPI4_HANDLER not defined"
-#endif
-/**
- * @brief SPI4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SPI4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- spi_lld_serve_interrupt(&SPID4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_SPI4_SUPPRESS_ISR) */
-#endif /* STM32_SPI_USE_SPI4 */
-
-#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
-#if !defined(STM32_SPI5_SUPPRESS_ISR)
-#if !defined(STM32_SPI5_HANDLER)
-#error "STM32_SPI5_HANDLER not defined"
-#endif
-/**
- * @brief SPI5 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SPI5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- spi_lld_serve_interrupt(&SPID5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_SPI5_SUPPRESS_ISR) */
-#endif /* STM32_SPI_USE_SPI5 */
-
-#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
-#if !defined(STM32_SPI6_SUPPRESS_ISR)
-#if !defined(STM32_SPI6_HANDLER)
-#error "STM32_SPI6_HANDLER not defined"
-#endif
-/**
- * @brief SPI6 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_SPI6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- spi_lld_serve_interrupt(&SPID6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_SPI6_SUPPRESS_ISR) */
-#endif /* STM32_SPI_USE_SPI6 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SPI driver initialization.
- *
- * @notapi
- */
-void spi_lld_init(void) {
-
-#if STM32_SPI_USE_SPI1
- spiObjectInit(&SPID1);
- SPID1.spi = SPI1;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- SPID1.is_bdma = false;
-#endif
- SPID1.rx.dma = NULL;
- SPID1.tx.dma = NULL;
- SPID1.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID1.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#if !defined(STM32_SPI1_SUPPRESS_ISR)
- nvicEnableVector(STM32_SPI1_NUMBER, STM32_SPI_SPI1_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_SPI_USE_SPI2
- spiObjectInit(&SPID2);
- SPID2.spi = SPI2;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- SPID2.is_bdma = false;
-#endif
- SPID2.rx.dma = NULL;
- SPID2.tx.dma = NULL;
- SPID2.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID2.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#if !defined(STM32_SPI2_SUPPRESS_ISR)
- nvicEnableVector(STM32_SPI2_NUMBER, STM32_SPI_SPI2_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_SPI_USE_SPI3
- spiObjectInit(&SPID3);
- SPID3.spi = SPI3;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- SPID3.is_bdma = false;
-#endif
- SPID3.rx.dma = NULL;
- SPID3.tx.dma = NULL;
- SPID3.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID3.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#if !defined(STM32_SPI3_SUPPRESS_ISR)
- nvicEnableVector(STM32_SPI3_NUMBER, STM32_SPI_SPI3_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_SPI_USE_SPI4
- spiObjectInit(&SPID4);
- SPID4.spi = SPI4;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- SPID4.is_bdma = false;
-#endif
- SPID4.rx.dma = NULL;
- SPID4.tx.dma = NULL;
- SPID4.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID4.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#if !defined(STM32_SPI4_SUPPRESS_ISR)
- nvicEnableVector(STM32_SPI4_NUMBER, STM32_SPI_SPI4_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_SPI_USE_SPI5
- spiObjectInit(&SPID5);
- SPID5.spi = SPI5;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- SPID5.is_bdma = false;
-#endif
- SPID5.rx.dma = NULL;
- SPID5.tx.dma = NULL;
- SPID5.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
- SPID5.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_DMEIE |
- STM32_DMA_CR_TEIE;
-#if !defined(STM32_SPI5_SUPPRESS_ISR)
- nvicEnableVector(STM32_SPI5_NUMBER, STM32_SPI_SPI5_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_SPI_USE_SPI6
- spiObjectInit(&SPID6);
- SPID6.spi = SPI6;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- SPID6.is_bdma = true;
-#endif
- SPID6.rx.bdma = NULL;
- SPID6.tx.bdma = NULL;
- SPID6.rxdmamode = STM32_BDMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
- STM32_BDMA_CR_DIR_P2M |
- STM32_BDMA_CR_TCIE |
- STM32_BDMA_CR_TEIE;
- SPID6.txdmamode = STM32_BDMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
- STM32_BDMA_CR_DIR_M2P |
- STM32_BDMA_CR_TEIE;
-#if !defined(STM32_SPI6_SUPPRESS_ISR)
- nvicEnableVector(STM32_SPI6_NUMBER, STM32_SPI_SPI6_IRQ_PRIORITY);
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the SPI peripheral.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_start(SPIDriver *spip) {
- uint32_t dsize;
-
- /* If in stopped state then enables the SPI and DMA clocks.*/
- if (spip->state == SPI_STOP) {
-#if STM32_SPI_USE_SPI1
- if (&SPID1 == spip) {
- spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
- STM32_SPI_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
- spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
- STM32_SPI_SPI1_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
- rccEnableSPI1(true);
- dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI1_RX);
- dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI1_TX);
- }
-#endif
-#if STM32_SPI_USE_SPI2
- if (&SPID2 == spip) {
- spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
- STM32_SPI_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
- spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
- STM32_SPI_SPI2_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
- rccEnableSPI2(true);
- dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI2_RX);
- dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI2_TX);
- }
-#endif
-#if STM32_SPI_USE_SPI3
- if (&SPID3 == spip) {
- spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
- STM32_SPI_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
- spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
- STM32_SPI_SPI3_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
- rccEnableSPI3(true);
- dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI3_RX);
- dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI3_TX);
- }
-#endif
-#if STM32_SPI_USE_SPI4
- if (&SPID4 == spip) {
- spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
- STM32_SPI_SPI4_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
- spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
- STM32_SPI_SPI4_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
- rccEnableSPI4(true);
- dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI4_RX);
- dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI4_TX);
- }
-#endif
-#if STM32_SPI_USE_SPI5
- if (&SPID5 == spip) {
- spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
- STM32_SPI_SPI5_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
- spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
- STM32_SPI_SPI5_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
- rccEnableSPI5(true);
- dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI5_RX);
- dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI5_TX);
- }
-#endif
-#if STM32_SPI_USE_SPI6
- if (&SPID6 == spip) {
- spip->rx.bdma = bdmaStreamAllocI(STM32_SPI_SPI6_RX_BDMA_STREAM,
- STM32_SPI_SPI6_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_bdma_rx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
- spip->tx.bdma = bdmaStreamAllocI(STM32_SPI_SPI6_TX_BDMA_STREAM,
- STM32_SPI_SPI6_IRQ_PRIORITY,
- (stm32_dmaisr_t)spi_lld_serve_bdma_tx_interrupt,
- (void *)spip);
- osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
- rccEnableSPI6(true);
- bdmaSetRequestSource(spip->rx.bdma, STM32_DMAMUX2_SPI6_RX);
- bdmaSetRequestSource(spip->tx.bdma, STM32_DMAMUX2_SPI6_TX);
- }
-#endif
-
- /* DMA setup.*/
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamSetPeripheral(spip->rx.bdma, &spip->spi->RXDR);
- bdmaStreamSetPeripheral(spip->tx.bdma, &spip->spi->TXDR);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamSetPeripheral(spip->rx.dma, &spip->spi->RXDR);
- dmaStreamSetPeripheral(spip->tx.dma, &spip->spi->TXDR);
- }
-#endif
- }
-
- /* Configuration-specific DMA setup.*/
- dsize = (spip->config->cfg1 & SPI_CFG1_DSIZE_Msk) + 1U;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- if (dsize <= 8U) {
- /* Frame width is between 4 and 8 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
- STM32_BDMA_CR_PSIZE_BYTE | STM32_BDMA_CR_MSIZE_BYTE;
- spip->txdmamode = (spip->txdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
- STM32_BDMA_CR_PSIZE_BYTE | STM32_BDMA_CR_MSIZE_BYTE;
- }
- else if (dsize <= 16U) {
- /* Frame width is between 9 and 16 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
- STM32_BDMA_CR_PSIZE_HWORD | STM32_BDMA_CR_MSIZE_HWORD;
- spip->txdmamode = (spip->txdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
- STM32_BDMA_CR_PSIZE_HWORD | STM32_BDMA_CR_MSIZE_HWORD;
- }
- else {
- /* Frame width is between 16 and 32 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
- STM32_BDMA_CR_PSIZE_WORD | STM32_BDMA_CR_MSIZE_WORD;
- spip->txdmamode = (spip->txdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
- STM32_BDMA_CR_PSIZE_WORD | STM32_BDMA_CR_MSIZE_WORD;
- }
- if (spip->config->circular) {
- spip->rxdmamode |= (STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
- spip->txdmamode |= (STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
- }
- else {
- spip->rxdmamode &= ~(STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
- spip->txdmamode &= ~(STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
- }
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- if (dsize <= 8U) {
- /* Frame width is between 4 and 8 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
- }
- else if (dsize <= 16U) {
- /* Frame width is between 9 and 16 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- }
- else {
- /* Frame width is between 16 and 32 bits.*/
- spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
- spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
- STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
- }
- if (spip->config->circular) {
- spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- }
- else {
- spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
- }
- }
-#endif
-
- /* SPI setup and enable.*/
- spip->spi->CR1 &= ~SPI_CR1_SPE;
- spip->spi->CR1 = SPI_CR1_MASRX;
- spip->spi->CR2 = 0U;
- spip->spi->CFG1 = (spip->config->cfg1 & ~SPI_CFG1_FTHLV_Msk) |
- SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN;
- spip->spi->CFG2 = (spip->config->cfg2 | SPI_CFG2_MASTER | SPI_CFG2_SSOE) &
- ~SPI_CFG2_COMM_Msk;
- spip->spi->IER = SPI_IER_OVRIE;
- spip->spi->IFCR = 0xFFFFFFFFU;
- spip->spi->CR1 |= SPI_CR1_SPE;
-}
-
-/**
- * @brief Deactivates the SPI peripheral.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_stop(SPIDriver *spip) {
-
- /* If in ready state then disables the SPI clock.*/
- if (spip->state == SPI_READY) {
-
- /* SPI disable.*/
- spip->spi->CR1 &= ~SPI_CR1_SPE;
- spip->spi->CR1 = 0U;
- spip->spi->CR2 = 0U;
- spip->spi->CFG1 = 0U;
- spip->spi->CFG2 = 0U;
- spip->spi->IER = 0U;
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamFreeI(spip->rx.bdma);
- bdmaStreamFreeI(spip->tx.bdma);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamFreeI(spip->rx.dma);
- dmaStreamFreeI(spip->tx.dma);
- }
-#endif
-
-#if STM32_SPI_USE_SPI1
- if (&SPID1 == spip)
- rccDisableSPI1();
-#endif
-#if STM32_SPI_USE_SPI2
- if (&SPID2 == spip)
- rccDisableSPI2();
-#endif
-#if STM32_SPI_USE_SPI3
- if (&SPID3 == spip)
- rccDisableSPI3();
-#endif
-#if STM32_SPI_USE_SPI4
- if (&SPID4 == spip)
- rccDisableSPI4();
-#endif
-#if STM32_SPI_USE_SPI5
- if (&SPID5 == spip)
- rccDisableSPI5();
-#endif
-#if STM32_SPI_USE_SPI6
- if (&SPID6 == spip)
- rccDisableSPI6();
-#endif
- }
-}
-
-#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
-/**
- * @brief Asserts the slave select signal and prepares for transfers.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_select(SPIDriver *spip) {
-
- /* No implementation on STM32.*/
-}
-
-/**
- * @brief Deasserts the slave select signal.
- * @details The previously selected peripheral is unselected.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_unselect(SPIDriver *spip) {
-
- /* No implementation on STM32.*/
-}
-#endif
-
-/**
- * @brief Ignores data on the SPI bus.
- * @details This asynchronous function starts the transmission of a series of
- * idle words on the SPI bus and ignores the received data.
- * @post At the end of the operation the configured callback is invoked.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to be ignored
- *
- * @notapi
- */
-void spi_lld_ignore(SPIDriver *spip, size_t n) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- spi_lld_wait_complete(spip);
-
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamSetMemory(spip->rx.bdma, &dummyrx);
- bdmaStreamSetTransactionSize(spip->rx.bdma, n);
- bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode);
-
- bdmaStreamSetMemory(spip->tx.bdma, &dummytx);
- bdmaStreamSetTransactionSize(spip->tx.bdma, n);
- bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode);
-
- bdmaStreamEnable(spip->rx.bdma);
- bdmaStreamEnable(spip->tx.bdma);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamSetMemory0(spip->rx.dma, &dummyrx);
- dmaStreamSetTransactionSize(spip->rx.dma, n);
- dmaStreamSetMode(spip->rx.dma, spip->rxdmamode);
-
- dmaStreamSetMemory0(spip->tx.dma, &dummytx);
- dmaStreamSetTransactionSize(spip->tx.dma, n);
- dmaStreamSetMode(spip->tx.dma, spip->txdmamode);
-
- dmaStreamEnable(spip->rx.dma);
- dmaStreamEnable(spip->tx.dma);
- }
-#endif
-
- spip->spi->CR1 |= SPI_CR1_CSTART;
-}
-
-/**
- * @brief Exchanges data on the SPI bus.
- * @details This asynchronous function starts a simultaneous transmit/receive
- * operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to be exchanged
- * @param[in] txbuf the pointer to the transmit buffer
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void spi_lld_exchange(SPIDriver *spip, size_t n,
- const void *txbuf, void *rxbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- spi_lld_wait_complete(spip);
-
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamSetMemory(spip->rx.bdma, rxbuf);
- bdmaStreamSetTransactionSize(spip->rx.bdma, n);
- bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode | STM32_BDMA_CR_MINC);
-
- bdmaStreamSetMemory(spip->tx.bdma, txbuf);
- bdmaStreamSetTransactionSize(spip->tx.bdma, n);
- bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode | STM32_BDMA_CR_MINC);
-
- bdmaStreamEnable(spip->rx.bdma);
- bdmaStreamEnable(spip->tx.bdma);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamSetMemory0(spip->rx.dma, rxbuf);
- dmaStreamSetTransactionSize(spip->rx.dma, n);
- dmaStreamSetMode(spip->rx.dma, spip->rxdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamSetMemory0(spip->tx.dma, txbuf);
- dmaStreamSetTransactionSize(spip->tx.dma, n);
- dmaStreamSetMode(spip->tx.dma, spip->txdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamEnable(spip->rx.dma);
- dmaStreamEnable(spip->tx.dma);
- }
-#endif
-
- spip->spi->CR1 |= SPI_CR1_CSTART;
-}
-
-/**
- * @brief Sends data over the SPI bus.
- * @details This asynchronous function starts a transmit operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- spi_lld_wait_complete(spip);
-
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamSetMemory(spip->rx.bdma, &dummyrx);
- bdmaStreamSetTransactionSize(spip->rx.bdma, n);
- bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode);
-
- bdmaStreamSetMemory(spip->tx.bdma, txbuf);
- bdmaStreamSetTransactionSize(spip->tx.bdma, n);
- bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode | STM32_BDMA_CR_MINC);
-
- bdmaStreamEnable(spip->rx.bdma);
- bdmaStreamEnable(spip->tx.bdma);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamSetMemory0(spip->rx.dma, &dummyrx);
- dmaStreamSetTransactionSize(spip->rx.dma, n);
- dmaStreamSetMode(spip->rx.dma, spip->rxdmamode);
-
- dmaStreamSetMemory0(spip->tx.dma, txbuf);
- dmaStreamSetTransactionSize(spip->tx.dma, n);
- dmaStreamSetMode(spip->tx.dma, spip->txdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamEnable(spip->rx.dma);
- dmaStreamEnable(spip->tx.dma);
- }
-#endif
-
- spip->spi->CR1 |= SPI_CR1_CSTART;
-}
-
-/**
- * @brief Receives data from the SPI bus.
- * @details This asynchronous function starts a receive operation.
- * @post At the end of the operation the configured callback is invoked.
- * @note The buffers are organized as uint8_t arrays for data sizes below or
- * equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] n number of words to receive
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
-
- osalDbgAssert(n < 65536, "unsupported DMA transfer size");
-
- spi_lld_wait_complete(spip);
-
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamSetMemory(spip->rx.bdma, rxbuf);
- bdmaStreamSetTransactionSize(spip->rx.bdma, n);
- bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode | STM32_BDMA_CR_MINC);
-
- bdmaStreamSetMemory(spip->tx.bdma, &dummytx);
- bdmaStreamSetTransactionSize(spip->tx.bdma, n);
- bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode);
-
- bdmaStreamEnable(spip->rx.bdma);
- bdmaStreamEnable(spip->tx.bdma);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamSetMemory0(spip->rx.dma, rxbuf);
- dmaStreamSetTransactionSize(spip->rx.dma, n);
- dmaStreamSetMode(spip->rx.dma, spip->rxdmamode | STM32_DMA_CR_MINC);
-
- dmaStreamSetMemory0(spip->tx.dma, &dummytx);
- dmaStreamSetTransactionSize(spip->tx.dma, n);
- dmaStreamSetMode(spip->tx.dma, spip->txdmamode);
-
- dmaStreamEnable(spip->rx.dma);
- dmaStreamEnable(spip->tx.dma);
- }
-#endif
-
- spip->spi->CR1 |= SPI_CR1_CSTART;
-}
-
-#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
-/**
- * @brief Aborts the ongoing SPI operation, if any.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- *
- * @notapi
- */
-void spi_lld_abort(SPIDriver *spip) {
-
- /* Stopping SPI.*/
- spip->spi->CR1 |= SPI_CR1_CSUSP;
-
- spi_lld_wait_complete(spip);
-
- /* Stopping DMAs.*/
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- if (spip->is_bdma)
-#endif
-#if defined(STM32_SPI_BDMA_REQUIRED)
- {
- bdmaStreamDisable(spip->tx.bdma);
- bdmaStreamDisable(spip->rx.bdma);
- }
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
- else
-#endif
-#if defined(STM32_SPI_DMA_REQUIRED)
- {
- dmaStreamDisable(spip->tx.dma);
- dmaStreamDisable(spip->rx.dma);
- }
-#endif
-}
-#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
-
-/**
- * @brief Exchanges one frame using a polled wait.
- * @details This synchronous function exchanges one frame using a polled
- * synchronization method. This function is useful when exchanging
- * small amount of data on high speed channels, usually in this
- * situation is much more efficient just wait for completion using
- * polling than suspending the thread waiting for an interrupt.
- *
- * @param[in] spip pointer to the @p SPIDriver object
- * @param[in] frame the data frame to send over the SPI bus
- * @return The received data frame from the SPI bus.
- *
- * @notapi
- */
-uint32_t spi_lld_polled_exchange(SPIDriver *spip, uint32_t frame) {
- uint32_t dsize = (spip->spi->CFG1 & SPI_CFG1_DSIZE_Msk) + 1U;
- uint32_t rxframe;
-
- spi_lld_wait_complete(spip);
-
- spip->spi->CR1 |= SPI_CR1_CSTART;
-
- /* wait for room in TX FIFO.*/
- while ((spip->spi->SR & SPI_SR_TXP) == 0U)
- ;
-
- /* Data register must be accessed with the appropriate data size.
- Byte size access (uint8_t *) for transactions that are <= 8-bit etc.*/
- if (dsize <= 8U) {
- /* Frame width is between 4 and 8 bits.*/
- volatile uint8_t *txdrp8 = (volatile uint8_t *)&spip->spi->TXDR;
- volatile uint8_t *rxdrp8 = (volatile uint8_t *)&spip->spi->RXDR;
- *txdrp8 = (uint8_t)frame;
- while ((spip->spi->SR & SPI_SR_RXP) == 0U)
- ;
- rxframe = (uint32_t)*rxdrp8;
- }
- else if (dsize <= 16U) {
- /* Frame width is between 9 and 16 bits.*/
- volatile uint16_t *txdrp16 = (volatile uint16_t *)&spip->spi->TXDR;
- volatile uint16_t *rxdrp16 = (volatile uint16_t *)&spip->spi->RXDR;
- *txdrp16 = (uint16_t)frame;
- while ((spip->spi->SR & SPI_SR_RXP) == 0U)
- ;
- rxframe = (uint32_t)*rxdrp16;
- }
- else {
- /* Frame width is between 16 and 32 bits.*/
- spip->spi->TXDR = frame;
- while ((spip->spi->SR & SPI_SR_RXP) == 0U)
- ;
- rxframe = spip->spi->RXDR;
- }
-
- spip->spi->CR1 |= SPI_CR1_CSUSP;
-
- return rxframe;
-}
-
-#endif /* HAL_USE_SPI */
-
-/** @} */
+/*
+ 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 SPIv3/hal_spi_lld.c
+ * @brief STM32 SPI subsystem low level driver source.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief SPI1 driver identifier.*/
+#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
+SPIDriver SPID1;
+#endif
+
+/** @brief SPI2 driver identifier.*/
+#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
+SPIDriver SPID2;
+#endif
+
+/** @brief SPI3 driver identifier.*/
+#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
+SPIDriver SPID3;
+#endif
+
+/** @brief SPI4 driver identifier.*/
+#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
+SPIDriver SPID4;
+#endif
+
+/** @brief SPI5 driver identifier.*/
+#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
+SPIDriver SPID5;
+#endif
+
+/** @brief SPI6 driver identifier.*/
+#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
+SPIDriver SPID6;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const uint32_t dummytx = STM32_SPI_FILLER_PATTERN;
+static uint32_t dummyrx;
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+static void spi_lld_wait_complete(SPIDriver *spip) {
+
+ while ((spip->spi->CR1 & SPI_CR1_CSTART) != 0) {
+ }
+ spip->spi->IFCR = 0xFFFFFFFF;
+}
+
+#if defined(STM32_SPI_BDMA_REQUIRED)
+/**
+ * @brief Shared DMA end-of-rx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_bdma_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & STM32_BDMA_ISR_TEIF) != 0U) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (spip->config->circular) {
+ if ((flags & STM32_BDMA_ISR_HTIF) != 0U) {
+ /* Half buffer interrupt.*/
+ _spi_isr_half_code(spip);
+ }
+ if ((flags & STM32_BDMA_ISR_TCIF) != 0U) {
+ /* End buffer interrupt.*/
+ _spi_isr_full_code(spip);
+ }
+ }
+ else {
+ /* Stopping SPI.*/
+ spip->spi->CR1 |= SPI_CR1_CSUSP;
+
+ /* Stopping DMAs.*/
+ bdmaStreamDisable(spip->tx.bdma);
+ bdmaStreamDisable(spip->rx.bdma);
+
+ /* Portable SPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _spi_isr_code(spip);
+ }
+}
+
+/**
+ * @brief Shared BDMA end-of-tx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_bdma_tx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ (void)spip;
+ if ((flags & STM32_BDMA_ISR_TEIF) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)spip;
+ (void)flags;
+#endif
+}
+#endif /* defined(STM32_SPI_BDMA_REQUIRED) */
+
+#if defined(STM32_SPI_DMA_REQUIRED)
+/**
+ * @brief Shared DMA end-of-rx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_dma_rx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0U) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (spip->config->circular) {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0U) {
+ /* Half buffer interrupt.*/
+ _spi_isr_half_code(spip);
+ }
+ if ((flags & STM32_DMA_ISR_TCIF) != 0U) {
+ /* End buffer interrupt.*/
+ _spi_isr_full_code(spip);
+ }
+ }
+ else {
+ /* Stopping SPI.*/
+ spip->spi->CR1 |= SPI_CR1_CSUSP;
+
+ /* Stopping DMAs.*/
+ dmaStreamDisable(spip->tx.dma);
+ dmaStreamDisable(spip->rx.dma);
+
+ /* Portable SPI ISR code defined in the high level driver, note, it is
+ a macro.*/
+ _spi_isr_code(spip);
+ }
+}
+
+/**
+ * @brief Shared DMA end-of-tx service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void spi_lld_serve_dma_tx_interrupt(SPIDriver *spip, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_SPI_DMA_ERROR_HOOK)
+ (void)spip;
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_SPI_DMA_ERROR_HOOK(spip);
+ }
+#else
+ (void)spip;
+ (void)flags;
+#endif
+}
+#endif /* defined(STM32_SPI_DMA_REQUIRED) */
+
+/**
+ * @brief Shared SPI service routine.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ */
+static void spi_lld_serve_interrupt(SPIDriver *spip) {
+ uint32_t sr;
+
+ sr = spip->spi->SR & spip->spi->IER;
+ spip->spi->IFCR = sr;
+
+ if ((sr & SPI_SR_OVR) != 0U) {
+ /* CHTODO: fault notification.*/
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 || defined(__DOXYGEN__)
+#if !defined(STM32_SPI1_SUPPRESS_ISR)
+#if !defined(STM32_SPI1_HANDLER)
+#error "STM32_SPI1_HANDLER not defined"
+#endif
+/**
+ * @brief SPI1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SPI1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ spi_lld_serve_interrupt(&SPID1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_SPI1_SUPPRESS_ISR) */
+#endif /* STM32_SPI_USE_SPI1 */
+
+#if STM32_SPI_USE_SPI2 || defined(__DOXYGEN__)
+#if !defined(STM32_SPI2_SUPPRESS_ISR)
+#if !defined(STM32_SPI2_HANDLER)
+#error "STM32_SPI2_HANDLER not defined"
+#endif
+/**
+ * @brief SPI2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SPI2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ spi_lld_serve_interrupt(&SPID2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_SPI2_SUPPRESS_ISR) */
+#endif /* STM32_SPI_USE_SPI2 */
+
+#if STM32_SPI_USE_SPI3 || defined(__DOXYGEN__)
+#if !defined(STM32_SPI3_SUPPRESS_ISR)
+#if !defined(STM32_SPI3_HANDLER)
+#error "STM32_SPI3_HANDLER not defined"
+#endif
+/**
+ * @brief SPI3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SPI3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ spi_lld_serve_interrupt(&SPID3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_SPI3_SUPPRESS_ISR) */
+#endif /* STM32_SPI_USE_SPI3 */
+
+#if STM32_SPI_USE_SPI4 || defined(__DOXYGEN__)
+#if !defined(STM32_SPI4_SUPPRESS_ISR)
+#if !defined(STM32_SPI4_HANDLER)
+#error "STM32_SPI4_HANDLER not defined"
+#endif
+/**
+ * @brief SPI4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SPI4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ spi_lld_serve_interrupt(&SPID4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_SPI4_SUPPRESS_ISR) */
+#endif /* STM32_SPI_USE_SPI4 */
+
+#if STM32_SPI_USE_SPI5 || defined(__DOXYGEN__)
+#if !defined(STM32_SPI5_SUPPRESS_ISR)
+#if !defined(STM32_SPI5_HANDLER)
+#error "STM32_SPI5_HANDLER not defined"
+#endif
+/**
+ * @brief SPI5 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SPI5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ spi_lld_serve_interrupt(&SPID5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_SPI5_SUPPRESS_ISR) */
+#endif /* STM32_SPI_USE_SPI5 */
+
+#if STM32_SPI_USE_SPI6 || defined(__DOXYGEN__)
+#if !defined(STM32_SPI6_SUPPRESS_ISR)
+#if !defined(STM32_SPI6_HANDLER)
+#error "STM32_SPI6_HANDLER not defined"
+#endif
+/**
+ * @brief SPI6 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_SPI6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ spi_lld_serve_interrupt(&SPID6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_SPI6_SUPPRESS_ISR) */
+#endif /* STM32_SPI_USE_SPI6 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level SPI driver initialization.
+ *
+ * @notapi
+ */
+void spi_lld_init(void) {
+
+#if STM32_SPI_USE_SPI1
+ spiObjectInit(&SPID1);
+ SPID1.spi = SPI1;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ SPID1.is_bdma = false;
+#endif
+ SPID1.rx.dma = NULL;
+ SPID1.tx.dma = NULL;
+ SPID1.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID1.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#if !defined(STM32_SPI1_SUPPRESS_ISR)
+ nvicEnableVector(STM32_SPI1_NUMBER, STM32_SPI_SPI1_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_SPI_USE_SPI2
+ spiObjectInit(&SPID2);
+ SPID2.spi = SPI2;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ SPID2.is_bdma = false;
+#endif
+ SPID2.rx.dma = NULL;
+ SPID2.tx.dma = NULL;
+ SPID2.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID2.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#if !defined(STM32_SPI2_SUPPRESS_ISR)
+ nvicEnableVector(STM32_SPI2_NUMBER, STM32_SPI_SPI2_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_SPI_USE_SPI3
+ spiObjectInit(&SPID3);
+ SPID3.spi = SPI3;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ SPID3.is_bdma = false;
+#endif
+ SPID3.rx.dma = NULL;
+ SPID3.tx.dma = NULL;
+ SPID3.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID3.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#if !defined(STM32_SPI3_SUPPRESS_ISR)
+ nvicEnableVector(STM32_SPI3_NUMBER, STM32_SPI_SPI3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_SPI_USE_SPI4
+ spiObjectInit(&SPID4);
+ SPID4.spi = SPI4;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ SPID4.is_bdma = false;
+#endif
+ SPID4.rx.dma = NULL;
+ SPID4.tx.dma = NULL;
+ SPID4.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID4.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI4_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#if !defined(STM32_SPI4_SUPPRESS_ISR)
+ nvicEnableVector(STM32_SPI4_NUMBER, STM32_SPI_SPI4_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_SPI_USE_SPI5
+ spiObjectInit(&SPID5);
+ SPID5.spi = SPI5;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ SPID5.is_bdma = false;
+#endif
+ SPID5.rx.dma = NULL;
+ SPID5.tx.dma = NULL;
+ SPID5.rxdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+ SPID5.txdmamode = STM32_DMA_CR_PL(STM32_SPI_SPI5_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_DMEIE |
+ STM32_DMA_CR_TEIE;
+#if !defined(STM32_SPI5_SUPPRESS_ISR)
+ nvicEnableVector(STM32_SPI5_NUMBER, STM32_SPI_SPI5_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_SPI_USE_SPI6
+ spiObjectInit(&SPID6);
+ SPID6.spi = SPI6;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ SPID6.is_bdma = true;
+#endif
+ SPID6.rx.bdma = NULL;
+ SPID6.tx.bdma = NULL;
+ SPID6.rxdmamode = STM32_BDMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_BDMA_CR_DIR_P2M |
+ STM32_BDMA_CR_TCIE |
+ STM32_BDMA_CR_TEIE;
+ SPID6.txdmamode = STM32_BDMA_CR_PL(STM32_SPI_SPI6_DMA_PRIORITY) |
+ STM32_BDMA_CR_DIR_M2P |
+ STM32_BDMA_CR_TEIE;
+#if !defined(STM32_SPI6_SUPPRESS_ISR)
+ nvicEnableVector(STM32_SPI6_NUMBER, STM32_SPI_SPI6_IRQ_PRIORITY);
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_start(SPIDriver *spip) {
+ uint32_t dsize;
+
+ /* If in stopped state then enables the SPI and DMA clocks.*/
+ if (spip->state == SPI_STOP) {
+#if STM32_SPI_USE_SPI1
+ if (&SPID1 == spip) {
+ spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI1_RX_DMA_STREAM,
+ STM32_SPI_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
+ spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI1_TX_DMA_STREAM,
+ STM32_SPI_SPI1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
+ rccEnableSPI1(true);
+ dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI1_RX);
+ dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI1_TX);
+ }
+#endif
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip) {
+ spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI2_RX_DMA_STREAM,
+ STM32_SPI_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
+ spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI2_TX_DMA_STREAM,
+ STM32_SPI_SPI2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
+ rccEnableSPI2(true);
+ dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI2_RX);
+ dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI2_TX);
+ }
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip) {
+ spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI3_RX_DMA_STREAM,
+ STM32_SPI_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
+ spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI3_TX_DMA_STREAM,
+ STM32_SPI_SPI3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
+ rccEnableSPI3(true);
+ dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI3_RX);
+ dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI3_TX);
+ }
+#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip) {
+ spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI4_RX_DMA_STREAM,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
+ spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI4_TX_DMA_STREAM,
+ STM32_SPI_SPI4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
+ rccEnableSPI4(true);
+ dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI4_RX);
+ dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI4_TX);
+ }
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip) {
+ spip->rx.dma = dmaStreamAllocI(STM32_SPI_SPI5_RX_DMA_STREAM,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
+ spip->tx.dma = dmaStreamAllocI(STM32_SPI_SPI5_TX_DMA_STREAM,
+ STM32_SPI_SPI5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_dma_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
+ rccEnableSPI5(true);
+ dmaSetRequestSource(spip->rx.dma, STM32_DMAMUX1_SPI5_RX);
+ dmaSetRequestSource(spip->tx.dma, STM32_DMAMUX1_SPI5_TX);
+ }
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip) {
+ spip->rx.bdma = bdmaStreamAllocI(STM32_SPI_SPI6_RX_BDMA_STREAM,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_bdma_rx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->rx.dma != NULL, "unable to allocate stream");
+ spip->tx.bdma = bdmaStreamAllocI(STM32_SPI_SPI6_TX_BDMA_STREAM,
+ STM32_SPI_SPI6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)spi_lld_serve_bdma_tx_interrupt,
+ (void *)spip);
+ osalDbgAssert(spip->tx.dma != NULL, "unable to allocate stream");
+ rccEnableSPI6(true);
+ bdmaSetRequestSource(spip->rx.bdma, STM32_DMAMUX2_SPI6_RX);
+ bdmaSetRequestSource(spip->tx.bdma, STM32_DMAMUX2_SPI6_TX);
+ }
+#endif
+
+ /* DMA setup.*/
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamSetPeripheral(spip->rx.bdma, &spip->spi->RXDR);
+ bdmaStreamSetPeripheral(spip->tx.bdma, &spip->spi->TXDR);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamSetPeripheral(spip->rx.dma, &spip->spi->RXDR);
+ dmaStreamSetPeripheral(spip->tx.dma, &spip->spi->TXDR);
+ }
+#endif
+ }
+
+ /* Configuration-specific DMA setup.*/
+ dsize = (spip->config->cfg1 & SPI_CFG1_DSIZE_Msk) + 1U;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ if (dsize <= 8U) {
+ /* Frame width is between 4 and 8 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
+ STM32_BDMA_CR_PSIZE_BYTE | STM32_BDMA_CR_MSIZE_BYTE;
+ spip->txdmamode = (spip->txdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
+ STM32_BDMA_CR_PSIZE_BYTE | STM32_BDMA_CR_MSIZE_BYTE;
+ }
+ else if (dsize <= 16U) {
+ /* Frame width is between 9 and 16 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
+ STM32_BDMA_CR_PSIZE_HWORD | STM32_BDMA_CR_MSIZE_HWORD;
+ spip->txdmamode = (spip->txdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
+ STM32_BDMA_CR_PSIZE_HWORD | STM32_BDMA_CR_MSIZE_HWORD;
+ }
+ else {
+ /* Frame width is between 16 and 32 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
+ STM32_BDMA_CR_PSIZE_WORD | STM32_BDMA_CR_MSIZE_WORD;
+ spip->txdmamode = (spip->txdmamode & ~STM32_BDMA_CR_SIZE_MASK) |
+ STM32_BDMA_CR_PSIZE_WORD | STM32_BDMA_CR_MSIZE_WORD;
+ }
+ if (spip->config->circular) {
+ spip->rxdmamode |= (STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
+ spip->txdmamode |= (STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
+ }
+ else {
+ spip->rxdmamode &= ~(STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
+ spip->txdmamode &= ~(STM32_BDMA_CR_CIRC | STM32_BDMA_CR_HTIE);
+ }
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ if (dsize <= 8U) {
+ /* Frame width is between 4 and 8 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
+ }
+ else if (dsize <= 16U) {
+ /* Frame width is between 9 and 16 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ }
+ else {
+ /* Frame width is between 16 and 32 bits.*/
+ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
+ spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) |
+ STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
+ }
+ if (spip->config->circular) {
+ spip->rxdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ spip->txdmamode |= (STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ }
+ else {
+ spip->rxdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ spip->txdmamode &= ~(STM32_DMA_CR_CIRC | STM32_DMA_CR_HTIE);
+ }
+ }
+#endif
+
+ /* SPI setup and enable.*/
+ spip->spi->CR1 &= ~SPI_CR1_SPE;
+ spip->spi->CR1 = SPI_CR1_MASRX;
+ spip->spi->CR2 = 0U;
+ spip->spi->CFG1 = (spip->config->cfg1 & ~SPI_CFG1_FTHLV_Msk) |
+ SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN;
+ spip->spi->CFG2 = (spip->config->cfg2 | SPI_CFG2_MASTER | SPI_CFG2_SSOE) &
+ ~SPI_CFG2_COMM_Msk;
+ spip->spi->IER = SPI_IER_OVRIE;
+ spip->spi->IFCR = 0xFFFFFFFFU;
+ spip->spi->CR1 |= SPI_CR1_SPE;
+}
+
+/**
+ * @brief Deactivates the SPI peripheral.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_stop(SPIDriver *spip) {
+
+ /* If in ready state then disables the SPI clock.*/
+ if (spip->state == SPI_READY) {
+
+ /* SPI disable.*/
+ spip->spi->CR1 &= ~SPI_CR1_SPE;
+ spip->spi->CR1 = 0U;
+ spip->spi->CR2 = 0U;
+ spip->spi->CFG1 = 0U;
+ spip->spi->CFG2 = 0U;
+ spip->spi->IER = 0U;
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamFreeI(spip->rx.bdma);
+ bdmaStreamFreeI(spip->tx.bdma);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamFreeI(spip->rx.dma);
+ dmaStreamFreeI(spip->tx.dma);
+ }
+#endif
+
+#if STM32_SPI_USE_SPI1
+ if (&SPID1 == spip)
+ rccDisableSPI1();
+#endif
+#if STM32_SPI_USE_SPI2
+ if (&SPID2 == spip)
+ rccDisableSPI2();
+#endif
+#if STM32_SPI_USE_SPI3
+ if (&SPID3 == spip)
+ rccDisableSPI3();
+#endif
+#if STM32_SPI_USE_SPI4
+ if (&SPID4 == spip)
+ rccDisableSPI4();
+#endif
+#if STM32_SPI_USE_SPI5
+ if (&SPID5 == spip)
+ rccDisableSPI5();
+#endif
+#if STM32_SPI_USE_SPI6
+ if (&SPID6 == spip)
+ rccDisableSPI6();
+#endif
+ }
+}
+
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
+/**
+ * @brief Asserts the slave select signal and prepares for transfers.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_select(SPIDriver *spip) {
+
+ /* No implementation on STM32.*/
+}
+
+/**
+ * @brief Deasserts the slave select signal.
+ * @details The previously selected peripheral is unselected.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_unselect(SPIDriver *spip) {
+
+ /* No implementation on STM32.*/
+}
+#endif
+
+/**
+ * @brief Ignores data on the SPI bus.
+ * @details This asynchronous function starts the transmission of a series of
+ * idle words on the SPI bus and ignores the received data.
+ * @post At the end of the operation the configured callback is invoked.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be ignored
+ *
+ * @notapi
+ */
+void spi_lld_ignore(SPIDriver *spip, size_t n) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ spi_lld_wait_complete(spip);
+
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamSetMemory(spip->rx.bdma, &dummyrx);
+ bdmaStreamSetTransactionSize(spip->rx.bdma, n);
+ bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode);
+
+ bdmaStreamSetMemory(spip->tx.bdma, &dummytx);
+ bdmaStreamSetTransactionSize(spip->tx.bdma, n);
+ bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode);
+
+ bdmaStreamEnable(spip->rx.bdma);
+ bdmaStreamEnable(spip->tx.bdma);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamSetMemory0(spip->rx.dma, &dummyrx);
+ dmaStreamSetTransactionSize(spip->rx.dma, n);
+ dmaStreamSetMode(spip->rx.dma, spip->rxdmamode);
+
+ dmaStreamSetMemory0(spip->tx.dma, &dummytx);
+ dmaStreamSetTransactionSize(spip->tx.dma, n);
+ dmaStreamSetMode(spip->tx.dma, spip->txdmamode);
+
+ dmaStreamEnable(spip->rx.dma);
+ dmaStreamEnable(spip->tx.dma);
+ }
+#endif
+
+ spip->spi->CR1 |= SPI_CR1_CSTART;
+}
+
+/**
+ * @brief Exchanges data on the SPI bus.
+ * @details This asynchronous function starts a simultaneous transmit/receive
+ * operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to be exchanged
+ * @param[in] txbuf the pointer to the transmit buffer
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ spi_lld_wait_complete(spip);
+
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamSetMemory(spip->rx.bdma, rxbuf);
+ bdmaStreamSetTransactionSize(spip->rx.bdma, n);
+ bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode | STM32_BDMA_CR_MINC);
+
+ bdmaStreamSetMemory(spip->tx.bdma, txbuf);
+ bdmaStreamSetTransactionSize(spip->tx.bdma, n);
+ bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode | STM32_BDMA_CR_MINC);
+
+ bdmaStreamEnable(spip->rx.bdma);
+ bdmaStreamEnable(spip->tx.bdma);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamSetMemory0(spip->rx.dma, rxbuf);
+ dmaStreamSetTransactionSize(spip->rx.dma, n);
+ dmaStreamSetMode(spip->rx.dma, spip->rxdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamSetMemory0(spip->tx.dma, txbuf);
+ dmaStreamSetTransactionSize(spip->tx.dma, n);
+ dmaStreamSetMode(spip->tx.dma, spip->txdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamEnable(spip->rx.dma);
+ dmaStreamEnable(spip->tx.dma);
+ }
+#endif
+
+ spip->spi->CR1 |= SPI_CR1_CSTART;
+}
+
+/**
+ * @brief Sends data over the SPI bus.
+ * @details This asynchronous function starts a transmit operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ spi_lld_wait_complete(spip);
+
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamSetMemory(spip->rx.bdma, &dummyrx);
+ bdmaStreamSetTransactionSize(spip->rx.bdma, n);
+ bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode);
+
+ bdmaStreamSetMemory(spip->tx.bdma, txbuf);
+ bdmaStreamSetTransactionSize(spip->tx.bdma, n);
+ bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode | STM32_BDMA_CR_MINC);
+
+ bdmaStreamEnable(spip->rx.bdma);
+ bdmaStreamEnable(spip->tx.bdma);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamSetMemory0(spip->rx.dma, &dummyrx);
+ dmaStreamSetTransactionSize(spip->rx.dma, n);
+ dmaStreamSetMode(spip->rx.dma, spip->rxdmamode);
+
+ dmaStreamSetMemory0(spip->tx.dma, txbuf);
+ dmaStreamSetTransactionSize(spip->tx.dma, n);
+ dmaStreamSetMode(spip->tx.dma, spip->txdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamEnable(spip->rx.dma);
+ dmaStreamEnable(spip->tx.dma);
+ }
+#endif
+
+ spip->spi->CR1 |= SPI_CR1_CSTART;
+}
+
+/**
+ * @brief Receives data from the SPI bus.
+ * @details This asynchronous function starts a receive operation.
+ * @post At the end of the operation the configured callback is invoked.
+ * @note The buffers are organized as uint8_t arrays for data sizes below or
+ * equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] n number of words to receive
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
+
+ osalDbgAssert(n < 65536, "unsupported DMA transfer size");
+
+ spi_lld_wait_complete(spip);
+
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamSetMemory(spip->rx.bdma, rxbuf);
+ bdmaStreamSetTransactionSize(spip->rx.bdma, n);
+ bdmaStreamSetMode(spip->rx.bdma, spip->rxdmamode | STM32_BDMA_CR_MINC);
+
+ bdmaStreamSetMemory(spip->tx.bdma, &dummytx);
+ bdmaStreamSetTransactionSize(spip->tx.bdma, n);
+ bdmaStreamSetMode(spip->tx.bdma, spip->txdmamode);
+
+ bdmaStreamEnable(spip->rx.bdma);
+ bdmaStreamEnable(spip->tx.bdma);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamSetMemory0(spip->rx.dma, rxbuf);
+ dmaStreamSetTransactionSize(spip->rx.dma, n);
+ dmaStreamSetMode(spip->rx.dma, spip->rxdmamode | STM32_DMA_CR_MINC);
+
+ dmaStreamSetMemory0(spip->tx.dma, &dummytx);
+ dmaStreamSetTransactionSize(spip->tx.dma, n);
+ dmaStreamSetMode(spip->tx.dma, spip->txdmamode);
+
+ dmaStreamEnable(spip->rx.dma);
+ dmaStreamEnable(spip->tx.dma);
+ }
+#endif
+
+ spip->spi->CR1 |= SPI_CR1_CSTART;
+}
+
+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Aborts the ongoing SPI operation, if any.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ *
+ * @notapi
+ */
+void spi_lld_abort(SPIDriver *spip) {
+
+ /* Stopping SPI.*/
+ spip->spi->CR1 |= SPI_CR1_CSUSP;
+
+ spi_lld_wait_complete(spip);
+
+ /* Stopping DMAs.*/
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ if (spip->is_bdma)
+#endif
+#if defined(STM32_SPI_BDMA_REQUIRED)
+ {
+ bdmaStreamDisable(spip->tx.bdma);
+ bdmaStreamDisable(spip->rx.bdma);
+ }
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+ else
+#endif
+#if defined(STM32_SPI_DMA_REQUIRED)
+ {
+ dmaStreamDisable(spip->tx.dma);
+ dmaStreamDisable(spip->rx.dma);
+ }
+#endif
+}
+#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */
+
+/**
+ * @brief Exchanges one frame using a polled wait.
+ * @details This synchronous function exchanges one frame using a polled
+ * synchronization method. This function is useful when exchanging
+ * small amount of data on high speed channels, usually in this
+ * situation is much more efficient just wait for completion using
+ * polling than suspending the thread waiting for an interrupt.
+ *
+ * @param[in] spip pointer to the @p SPIDriver object
+ * @param[in] frame the data frame to send over the SPI bus
+ * @return The received data frame from the SPI bus.
+ *
+ * @notapi
+ */
+uint32_t spi_lld_polled_exchange(SPIDriver *spip, uint32_t frame) {
+ uint32_t dsize = (spip->spi->CFG1 & SPI_CFG1_DSIZE_Msk) + 1U;
+ uint32_t rxframe;
+
+ spi_lld_wait_complete(spip);
+
+ spip->spi->CR1 |= SPI_CR1_CSTART;
+
+ /* wait for room in TX FIFO.*/
+ while ((spip->spi->SR & SPI_SR_TXP) == 0U)
+ ;
+
+ /* Data register must be accessed with the appropriate data size.
+ Byte size access (uint8_t *) for transactions that are <= 8-bit etc.*/
+ if (dsize <= 8U) {
+ /* Frame width is between 4 and 8 bits.*/
+ volatile uint8_t *txdrp8 = (volatile uint8_t *)&spip->spi->TXDR;
+ volatile uint8_t *rxdrp8 = (volatile uint8_t *)&spip->spi->RXDR;
+ *txdrp8 = (uint8_t)frame;
+ while ((spip->spi->SR & SPI_SR_RXP) == 0U)
+ ;
+ rxframe = (uint32_t)*rxdrp8;
+ }
+ else if (dsize <= 16U) {
+ /* Frame width is between 9 and 16 bits.*/
+ volatile uint16_t *txdrp16 = (volatile uint16_t *)&spip->spi->TXDR;
+ volatile uint16_t *rxdrp16 = (volatile uint16_t *)&spip->spi->RXDR;
+ *txdrp16 = (uint16_t)frame;
+ while ((spip->spi->SR & SPI_SR_RXP) == 0U)
+ ;
+ rxframe = (uint32_t)*rxdrp16;
+ }
+ else {
+ /* Frame width is between 16 and 32 bits.*/
+ spip->spi->TXDR = frame;
+ while ((spip->spi->SR & SPI_SR_RXP) == 0U)
+ ;
+ rxframe = spip->spi->RXDR;
+ }
+
+ spip->spi->CR1 |= SPI_CR1_CSUSP;
+
+ return rxframe;
+}
+
+#endif /* HAL_USE_SPI */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.h b/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.h
index 133fedf4dc..13b420327f 100644
--- a/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv3/hal_spi_lld.h
@@ -1,590 +1,590 @@
-/*
- 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 SPIv3/hal_spi_lld.h
- * @brief STM32 SPI subsystem low level driver header.
- *
- * @addtogroup SPI
- * @{
- */
-
-#ifndef HAL_SPI_LLD_H
-#define HAL_SPI_LLD_H
-
-#if HAL_USE_SPI || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Circular mode support flag.
- */
-#define SPI_SUPPORTS_CIRCULAR TRUE
-
-/**
- * @name Register helpers not found in ST headers
- * @{
- */
-#define SPI_CFG1_MBR_VALUE(n) ((n) << SPI_CFG1_MBR_Pos)
-#define SPI_CFG1_MBR_DIV2 SPI_CFG1_MBR_VALUE(0)
-#define SPI_CFG1_MBR_DIV4 SPI_CFG1_MBR_VALUE(1)
-#define SPI_CFG1_MBR_DIV8 SPI_CFG1_MBR_VALUE(2)
-#define SPI_CFG1_MBR_DIV16 SPI_CFG1_MBR_VALUE(3)
-#define SPI_CFG1_MBR_DIV32 SPI_CFG1_MBR_VALUE(4)
-#define SPI_CFG1_MBR_DIV64 SPI_CFG1_MBR_VALUE(5)
-#define SPI_CFG1_MBR_DIV128 SPI_CFG1_MBR_VALUE(6)
-#define SPI_CFG1_MBR_DIV256 SPI_CFG1_MBR_VALUE(7)
-#define SPI_CFG1_CRCSIZE_VALUE(n) ((n) << SPI_CFG1_CRCSIZE_Pos)
-#define SPI_CFG1_UDRDET_VALUE(n) ((n) << SPI_CFG1_UDRDET_Pos)
-#define SPI_CFG1_UDRCFG_VALUE(n) ((n) << SPI_CFG1_UDRCFG_Pos)
-#define SPI_CFG1_FTHLV_VALUE(n) ((n) << SPI_CFG1_FTHLV_Pos)
-#define SPI_CFG1_DSIZE_VALUE(n) ((n) << SPI_CFG1_DSIZE_Pos)
-
-#define SPI_CFG2_SP_VALUE(n) ((n) << SPI_CFG2_SP_Pos)
-#define SPI_CFG2_COMM_VALUE(n) ((n) << SPI_CFG2_COMM_Pos)
-#define SPI_CFG2_COMM_FULL_DUPLEX SPI_CFG2_COMM_VALUE(0)
-#define SPI_CFG2_COMM_TRANSMITTER SPI_CFG2_COMM_VALUE(1)
-#define SPI_CFG2_COMM_RECEIVER SPI_CFG2_COMM_VALUE(2)
-#define SPI_CFG2_COMM_HALF_DUPLEX SPI_CFG2_COMM_VALUE(3)
-#define SPI_CFG2_MIDI_VALUE(n) ((n) << SPI_CFG2_MIDI_Pos)
-#define SPI_CFG2_MSSI_VALUE(n) ((n) << SPI_CFG2_MSSI_Pos)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SPI1 driver enable switch.
- * @details If set to @p TRUE the support for SPI1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI1 FALSE
-#endif
-
-/**
- * @brief SPI2 driver enable switch.
- * @details If set to @p TRUE the support for SPI2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI2 FALSE
-#endif
-
-/**
- * @brief SPI3 driver enable switch.
- * @details If set to @p TRUE the support for SPI3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI3 FALSE
-#endif
-
-/**
- * @brief SPI4 driver enable switch.
- * @details If set to @p TRUE the support for SPI4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI4 FALSE
-#endif
-
-/**
- * @brief SPI5 driver enable switch.
- * @details If set to @p TRUE the support for SPI5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI5 FALSE
-#endif
-
-/**
- * @brief SPI6 driver enable switch.
- * @details If set to @p TRUE the support for SPI6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
-#define STM32_SPI_USE_SPI6 FALSE
-#endif
-
-/**
- * @brief Filler pattern used when there is nothing to transmit.
- */
-#if !defined(STM32_SPI_FILLER_PATTERN) || defined(__DOXYGEN__)
-#define STM32_SPI_FILLER_PATTERN 0xFFFFFFFFU
-#endif
-
-/**
- * @brief SPI1 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI2 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI3 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI4 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI4_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI5 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI5_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI6 interrupt priority level setting.
- */
-#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI6_IRQ_PRIORITY 10
-#endif
-
-/**
- * @brief SPI1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI1_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI2_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI3_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI4_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI5 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI5_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI6 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA streams but
- * because of the streams ordering the RX stream has always priority
- * over the TX stream.
- */
-#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SPI_SPI6_DMA_PRIORITY 1
-#endif
-
-/**
- * @brief SPI DMA error hook.
- */
-#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
-#error "SPI1 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
-#error "SPI2 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
-#error "SPI3 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
-#error "SPI4 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
-#error "SPI5 not present in the selected device"
-#endif
-
-#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
-#error "SPI6 not present in the selected device"
-#endif
-
-#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
- !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
-#error "SPI driver activated but no SPI peripheral assigned"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI1"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI2"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI3"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI4"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI5"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SPI6"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI1_TX_DMA_STREAM))
-#error "SPI1 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI2_TX_DMA_STREAM))
-#error "SPI2 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI3_TX_DMA_STREAM))
-#error "SPI3 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
-#error "SPI4 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
- !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
-#error "SPI5 DMA streams not defined"
-#endif
-
-#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_BDMA_STREAM) || \
- !defined(STM32_SPI_SPI6_TX_BDMA_STREAM))
-#error "SPI6 BDMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA streams.*/
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI1 RX"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI1 TX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI2 RX"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI2 TX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI3 RX"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI3 TX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI4 RX"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI4 TX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI5 RX"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM)
-#error "Invalid DMA stream assigned to SPI5 TX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_BDMA_IS_VALID_STREAM(STM32_SPI_SPI6_RX_BDMA_STREAM)
-#error "Invalid BDMA stream assigned to SPI6 RX"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_BDMA_IS_VALID_STREAM(STM32_SPI_SPI6_TX_BDMA_STREAM)
-#error "Invalid BDMA stream assigned to SPI6 TX"
-#endif
-
-#if STM32_SPI_USE_SPI1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI1"
-#endif
-
-#if STM32_SPI_USE_SPI2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI2"
-#endif
-
-#if STM32_SPI_USE_SPI3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI3"
-#endif
-
-#if STM32_SPI_USE_SPI4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI4"
-#endif
-
-#if STM32_SPI_USE_SPI5 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI5"
-#endif
-
-#if STM32_SPI_USE_SPI6 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SPI6"
-#endif
-
-#if STM32_SPI_USE_SPI1 || STM32_SPI_USE_SPI2 || STM32_SPI_USE_SPI3 || \
- STM32_SPI_USE_SPI4 || STM32_SPI_USE_SPI5
-#define STM32_SPI_DMA_REQUIRED
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-#endif
-
-#if STM32_SPI_USE_SPI6
-#define STM32_SPI_BDMA_REQUIRED
-#if !defined(STM32_BDMA_REQUIRED)
-#define STM32_BDMA_REQUIRED
-#endif
-#endif
-
-#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
-#error "SPI_SELECT_MODE_LLD not supported by this driver"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-#if (defined(STM32_SPI_DMA_REQUIRED) && \
- defined(STM32_SPI_BDMA_REQUIRED)) || defined(__DOXYGEN__)
-#define spi_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /** DMA type for this instance.*/ \
- bool is_bdma; \
- /** Union of the RX DMA streams.*/ \
- union { \
- /* Receive DMA stream.*/ \
- const stm32_dma_stream_t *dma; \
- /* Receive BDMA stream.*/ \
- const stm32_bdma_stream_t *bdma; \
- } rx; \
- /* Union of the TX DMA streams.*/ \
- union { \
- /* Transmit DMA stream.*/ \
- const stm32_dma_stream_t *dma; \
- /* Transmit DMA stream.*/ \
- const stm32_bdma_stream_t *bdma; \
- } tx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-#endif
-
-#if defined(STM32_SPI_DMA_REQUIRED) && !defined(STM32_SPI_BDMA_REQUIRED)
-#define spi_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /** Union of the RX DMA streams.*/ \
- union { \
- /* Receive DMA stream.*/ \
- const stm32_dma_stream_t *dma; \
- } rx; \
- /* Union of the TX DMA streams.*/ \
- union { \
- /* Transmit DMA stream.*/ \
- const stm32_dma_stream_t *dma; \
- } tx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-#endif
-
-#if !defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
-#define spi_lld_driver_fields \
- /* Pointer to the SPIx registers block.*/ \
- SPI_TypeDef *spi; \
- /** Union of the RX DMA streams.*/ \
- union { \
- /* Receive BDMA stream.*/ \
- const stm32_bdma_stream_t *bdma; \
- } rx; \
- /* Union of the TX DMA streams.*/ \
- union { \
- /* Transmit DMA stream.*/ \
- const stm32_bdma_stream_t *bdma; \
- } tx; \
- /* RX DMA mode bit mask.*/ \
- uint32_t rxdmamode; \
- /* TX DMA mode bit mask.*/ \
- uint32_t txdmamode
-#endif
-
-/**
- * @brief Low level fields of the SPI configuration structure.
- */
-#define spi_lld_config_fields \
- /* SPI CFG1 register initialization data.*/ \
- uint32_t cfg1; \
- /* SPI CFG2 register initialization data.*/ \
- uint32_t cfg2
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
-extern SPIDriver SPID1;
-#endif
-
-#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
-extern SPIDriver SPID2;
-#endif
-
-#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
-extern SPIDriver SPID3;
-#endif
-
-#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
-extern SPIDriver SPID4;
-#endif
-
-#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
-extern SPIDriver SPID5;
-#endif
-
-#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
-extern SPIDriver SPID6;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void spi_lld_init(void);
- void spi_lld_start(SPIDriver *spip);
- void spi_lld_stop(SPIDriver *spip);
-#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
- void spi_lld_select(SPIDriver *spip);
- void spi_lld_unselect(SPIDriver *spip);
-#endif
- void spi_lld_ignore(SPIDriver *spip, size_t n);
- void spi_lld_exchange(SPIDriver *spip, size_t n,
- const void *txbuf, void *rxbuf);
- void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
- void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
-#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
- void spi_lld_abort(SPIDriver *spip);
-#endif
- uint32_t spi_lld_polled_exchange(SPIDriver *spip, uint32_t frame);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SPI */
-
-#endif /* HAL_SPI_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 SPIv3/hal_spi_lld.h
+ * @brief STM32 SPI subsystem low level driver header.
+ *
+ * @addtogroup SPI
+ * @{
+ */
+
+#ifndef HAL_SPI_LLD_H
+#define HAL_SPI_LLD_H
+
+#if HAL_USE_SPI || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Circular mode support flag.
+ */
+#define SPI_SUPPORTS_CIRCULAR TRUE
+
+/**
+ * @name Register helpers not found in ST headers
+ * @{
+ */
+#define SPI_CFG1_MBR_VALUE(n) ((n) << SPI_CFG1_MBR_Pos)
+#define SPI_CFG1_MBR_DIV2 SPI_CFG1_MBR_VALUE(0)
+#define SPI_CFG1_MBR_DIV4 SPI_CFG1_MBR_VALUE(1)
+#define SPI_CFG1_MBR_DIV8 SPI_CFG1_MBR_VALUE(2)
+#define SPI_CFG1_MBR_DIV16 SPI_CFG1_MBR_VALUE(3)
+#define SPI_CFG1_MBR_DIV32 SPI_CFG1_MBR_VALUE(4)
+#define SPI_CFG1_MBR_DIV64 SPI_CFG1_MBR_VALUE(5)
+#define SPI_CFG1_MBR_DIV128 SPI_CFG1_MBR_VALUE(6)
+#define SPI_CFG1_MBR_DIV256 SPI_CFG1_MBR_VALUE(7)
+#define SPI_CFG1_CRCSIZE_VALUE(n) ((n) << SPI_CFG1_CRCSIZE_Pos)
+#define SPI_CFG1_UDRDET_VALUE(n) ((n) << SPI_CFG1_UDRDET_Pos)
+#define SPI_CFG1_UDRCFG_VALUE(n) ((n) << SPI_CFG1_UDRCFG_Pos)
+#define SPI_CFG1_FTHLV_VALUE(n) ((n) << SPI_CFG1_FTHLV_Pos)
+#define SPI_CFG1_DSIZE_VALUE(n) ((n) << SPI_CFG1_DSIZE_Pos)
+
+#define SPI_CFG2_SP_VALUE(n) ((n) << SPI_CFG2_SP_Pos)
+#define SPI_CFG2_COMM_VALUE(n) ((n) << SPI_CFG2_COMM_Pos)
+#define SPI_CFG2_COMM_FULL_DUPLEX SPI_CFG2_COMM_VALUE(0)
+#define SPI_CFG2_COMM_TRANSMITTER SPI_CFG2_COMM_VALUE(1)
+#define SPI_CFG2_COMM_RECEIVER SPI_CFG2_COMM_VALUE(2)
+#define SPI_CFG2_COMM_HALF_DUPLEX SPI_CFG2_COMM_VALUE(3)
+#define SPI_CFG2_MIDI_VALUE(n) ((n) << SPI_CFG2_MIDI_Pos)
+#define SPI_CFG2_MSSI_VALUE(n) ((n) << SPI_CFG2_MSSI_Pos)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SPI1 driver enable switch.
+ * @details If set to @p TRUE the support for SPI1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI1) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI1 FALSE
+#endif
+
+/**
+ * @brief SPI2 driver enable switch.
+ * @details If set to @p TRUE the support for SPI2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI2) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI2 FALSE
+#endif
+
+/**
+ * @brief SPI3 driver enable switch.
+ * @details If set to @p TRUE the support for SPI3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI3) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI3 FALSE
+#endif
+
+/**
+ * @brief SPI4 driver enable switch.
+ * @details If set to @p TRUE the support for SPI4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI4) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI4 FALSE
+#endif
+
+/**
+ * @brief SPI5 driver enable switch.
+ * @details If set to @p TRUE the support for SPI5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI5) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI5 FALSE
+#endif
+
+/**
+ * @brief SPI6 driver enable switch.
+ * @details If set to @p TRUE the support for SPI6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SPI_USE_SPI6) || defined(__DOXYGEN__)
+#define STM32_SPI_USE_SPI6 FALSE
+#endif
+
+/**
+ * @brief Filler pattern used when there is nothing to transmit.
+ */
+#if !defined(STM32_SPI_FILLER_PATTERN) || defined(__DOXYGEN__)
+#define STM32_SPI_FILLER_PATTERN 0xFFFFFFFFU
+#endif
+
+/**
+ * @brief SPI1 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI1_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI2 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI2_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI3 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI3_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI4 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI5 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI6 interrupt priority level setting.
+ */
+#if !defined(STM32_SPI_SPI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_IRQ_PRIORITY 10
+#endif
+
+/**
+ * @brief SPI1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI4_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI5 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI5_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI6 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA streams but
+ * because of the streams ordering the RX stream has always priority
+ * over the TX stream.
+ */
+#if !defined(STM32_SPI_SPI6_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SPI_SPI6_DMA_PRIORITY 1
+#endif
+
+/**
+ * @brief SPI DMA error hook.
+ */
+#if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 && !STM32_HAS_SPI1
+#error "SPI1 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI2 && !STM32_HAS_SPI2
+#error "SPI2 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI3 && !STM32_HAS_SPI3
+#error "SPI3 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI4 && !STM32_HAS_SPI4
+#error "SPI4 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI5 && !STM32_HAS_SPI5
+#error "SPI5 not present in the selected device"
+#endif
+
+#if STM32_SPI_USE_SPI6 && !STM32_HAS_SPI6
+#error "SPI6 not present in the selected device"
+#endif
+
+#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3 && \
+ !STM32_SPI_USE_SPI4 && !STM32_SPI_USE_SPI5 && !STM32_SPI_USE_SPI6
+#error "SPI driver activated but no SPI peripheral assigned"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI1"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI2"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI3"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SPI_SPI6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SPI6"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_SPI_USE_SPI1 && (!defined(STM32_SPI_SPI1_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI1_TX_DMA_STREAM))
+#error "SPI1 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI2 && (!defined(STM32_SPI_SPI2_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI2_TX_DMA_STREAM))
+#error "SPI2 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI3 && (!defined(STM32_SPI_SPI3_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI3_TX_DMA_STREAM))
+#error "SPI3 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI4 && (!defined(STM32_SPI_SPI4_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI4_TX_DMA_STREAM))
+#error "SPI4 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI5 && (!defined(STM32_SPI_SPI5_RX_DMA_STREAM) || \
+ !defined(STM32_SPI_SPI5_TX_DMA_STREAM))
+#error "SPI5 DMA streams not defined"
+#endif
+
+#if STM32_SPI_USE_SPI6 && (!defined(STM32_SPI_SPI6_RX_BDMA_STREAM) || \
+ !defined(STM32_SPI_SPI6_TX_BDMA_STREAM))
+#error "SPI6 BDMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA streams.*/
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI1 RX"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI1_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI1 TX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI2 RX"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI2_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI2 TX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI3 RX"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI3 TX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI4 RX"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI4_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI4 TX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_RX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI5 RX"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_SPI_SPI5_TX_DMA_STREAM)
+#error "Invalid DMA stream assigned to SPI5 TX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_BDMA_IS_VALID_STREAM(STM32_SPI_SPI6_RX_BDMA_STREAM)
+#error "Invalid BDMA stream assigned to SPI6 RX"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_BDMA_IS_VALID_STREAM(STM32_SPI_SPI6_TX_BDMA_STREAM)
+#error "Invalid BDMA stream assigned to SPI6 TX"
+#endif
+
+#if STM32_SPI_USE_SPI1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI1"
+#endif
+
+#if STM32_SPI_USE_SPI2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI2"
+#endif
+
+#if STM32_SPI_USE_SPI3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI3"
+#endif
+
+#if STM32_SPI_USE_SPI4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI4"
+#endif
+
+#if STM32_SPI_USE_SPI5 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI5_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI5"
+#endif
+
+#if STM32_SPI_USE_SPI6 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI6_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SPI6"
+#endif
+
+#if STM32_SPI_USE_SPI1 || STM32_SPI_USE_SPI2 || STM32_SPI_USE_SPI3 || \
+ STM32_SPI_USE_SPI4 || STM32_SPI_USE_SPI5
+#define STM32_SPI_DMA_REQUIRED
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+#endif
+
+#if STM32_SPI_USE_SPI6
+#define STM32_SPI_BDMA_REQUIRED
+#if !defined(STM32_BDMA_REQUIRED)
+#define STM32_BDMA_REQUIRED
+#endif
+#endif
+
+#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
+#error "SPI_SELECT_MODE_LLD not supported by this driver"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+#if (defined(STM32_SPI_DMA_REQUIRED) && \
+ defined(STM32_SPI_BDMA_REQUIRED)) || defined(__DOXYGEN__)
+#define spi_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /** DMA type for this instance.*/ \
+ bool is_bdma; \
+ /** Union of the RX DMA streams.*/ \
+ union { \
+ /* Receive DMA stream.*/ \
+ const stm32_dma_stream_t *dma; \
+ /* Receive BDMA stream.*/ \
+ const stm32_bdma_stream_t *bdma; \
+ } rx; \
+ /* Union of the TX DMA streams.*/ \
+ union { \
+ /* Transmit DMA stream.*/ \
+ const stm32_dma_stream_t *dma; \
+ /* Transmit DMA stream.*/ \
+ const stm32_bdma_stream_t *bdma; \
+ } tx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+#endif
+
+#if defined(STM32_SPI_DMA_REQUIRED) && !defined(STM32_SPI_BDMA_REQUIRED)
+#define spi_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /** Union of the RX DMA streams.*/ \
+ union { \
+ /* Receive DMA stream.*/ \
+ const stm32_dma_stream_t *dma; \
+ } rx; \
+ /* Union of the TX DMA streams.*/ \
+ union { \
+ /* Transmit DMA stream.*/ \
+ const stm32_dma_stream_t *dma; \
+ } tx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+#endif
+
+#if !defined(STM32_SPI_DMA_REQUIRED) && defined(STM32_SPI_BDMA_REQUIRED)
+#define spi_lld_driver_fields \
+ /* Pointer to the SPIx registers block.*/ \
+ SPI_TypeDef *spi; \
+ /** Union of the RX DMA streams.*/ \
+ union { \
+ /* Receive BDMA stream.*/ \
+ const stm32_bdma_stream_t *bdma; \
+ } rx; \
+ /* Union of the TX DMA streams.*/ \
+ union { \
+ /* Transmit DMA stream.*/ \
+ const stm32_bdma_stream_t *bdma; \
+ } tx; \
+ /* RX DMA mode bit mask.*/ \
+ uint32_t rxdmamode; \
+ /* TX DMA mode bit mask.*/ \
+ uint32_t txdmamode
+#endif
+
+/**
+ * @brief Low level fields of the SPI configuration structure.
+ */
+#define spi_lld_config_fields \
+ /* SPI CFG1 register initialization data.*/ \
+ uint32_t cfg1; \
+ /* SPI CFG2 register initialization data.*/ \
+ uint32_t cfg2
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SPI_USE_SPI1 && !defined(__DOXYGEN__)
+extern SPIDriver SPID1;
+#endif
+
+#if STM32_SPI_USE_SPI2 && !defined(__DOXYGEN__)
+extern SPIDriver SPID2;
+#endif
+
+#if STM32_SPI_USE_SPI3 && !defined(__DOXYGEN__)
+extern SPIDriver SPID3;
+#endif
+
+#if STM32_SPI_USE_SPI4 && !defined(__DOXYGEN__)
+extern SPIDriver SPID4;
+#endif
+
+#if STM32_SPI_USE_SPI5 && !defined(__DOXYGEN__)
+extern SPIDriver SPID5;
+#endif
+
+#if STM32_SPI_USE_SPI6 && !defined(__DOXYGEN__)
+extern SPIDriver SPID6;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void spi_lld_init(void);
+ void spi_lld_start(SPIDriver *spip);
+ void spi_lld_stop(SPIDriver *spip);
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
+ void spi_lld_select(SPIDriver *spip);
+ void spi_lld_unselect(SPIDriver *spip);
+#endif
+ void spi_lld_ignore(SPIDriver *spip, size_t n);
+ void spi_lld_exchange(SPIDriver *spip, size_t n,
+ const void *txbuf, void *rxbuf);
+ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
+ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
+#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
+ void spi_lld_abort(SPIDriver *spip);
+#endif
+ uint32_t spi_lld_polled_exchange(SPIDriver *spip, uint32_t frame);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SPI */
+
+#endif /* HAL_SPI_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/driver.mk b/os/hal/ports/STM32/LLD/TIMv1/driver.mk
index 032d75a2db..2fcf8995b3 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/TIMv1/driver.mk
@@ -1,19 +1,19 @@
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c
-
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_GPT TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
-endif
-ifneq ($(findstring HAL_USE_ICU TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
-endif
-ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c
+
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_GPT TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
+endif
+ifneq ($(findstring HAL_USE_ICU TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
+endif
+ifneq ($(findstring HAL_USE_PWM TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
index f7c449edb8..9571ad2967 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.c
@@ -1,1153 +1,1153 @@
-/*
- 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 TIMv1/hal_gpt_lld.c
- * @brief STM32 GPT subsystem low level driver source.
- *
- * @addtogroup GPT
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_GPT || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief GPTD1 driver identifier.
- * @note The driver GPTD1 allocates the complex timer TIM1 when enabled.
- */
-#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
-GPTDriver GPTD1;
-#endif
-
-/**
- * @brief GPTD2 driver identifier.
- * @note The driver GPTD2 allocates the timer TIM2 when enabled.
- */
-#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
-GPTDriver GPTD2;
-#endif
-
-/**
- * @brief GPTD3 driver identifier.
- * @note The driver GPTD3 allocates the timer TIM3 when enabled.
- */
-#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
-GPTDriver GPTD3;
-#endif
-
-/**
- * @brief GPTD4 driver identifier.
- * @note The driver GPTD4 allocates the timer TIM4 when enabled.
- */
-#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
-GPTDriver GPTD4;
-#endif
-
-/**
- * @brief GPTD5 driver identifier.
- * @note The driver GPTD5 allocates the timer TIM5 when enabled.
- */
-#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
-GPTDriver GPTD5;
-#endif
-
-/**
- * @brief GPTD6 driver identifier.
- * @note The driver GPTD6 allocates the timer TIM6 when enabled.
- */
-#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__)
-GPTDriver GPTD6;
-#endif
-
-/**
- * @brief GPTD7 driver identifier.
- * @note The driver GPTD7 allocates the timer TIM7 when enabled.
- */
-#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__)
-GPTDriver GPTD7;
-#endif
-
-/**
- * @brief GPTD8 driver identifier.
- * @note The driver GPTD8 allocates the timer TIM8 when enabled.
- */
-#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__)
-GPTDriver GPTD8;
-#endif
-
-/**
- * @brief GPTD9 driver identifier.
- * @note The driver GPTD9 allocates the timer TIM9 when enabled.
- */
-#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__)
-GPTDriver GPTD9;
-#endif
-
-/**
- * @brief GPTD10 driver identifier.
- * @note The driver GPTD10 allocates the timer TIM10 when enabled.
- */
-#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__)
-GPTDriver GPTD10;
-#endif
-
-/**
- * @brief GPTD11 driver identifier.
- * @note The driver GPTD11 allocates the timer TIM11 when enabled.
- */
-#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__)
-GPTDriver GPTD11;
-#endif
-
-/**
- * @brief GPTD12 driver identifier.
- * @note The driver GPTD12 allocates the timer TIM12 when enabled.
- */
-#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__)
-GPTDriver GPTD12;
-#endif
-
-/**
- * @brief GPTD13 driver identifier.
- * @note The driver GPTD13 allocates the timer TIM13 when enabled.
- */
-#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__)
-GPTDriver GPTD13;
-#endif
-
-/**
- * @brief GPTD14 driver identifier.
- * @note The driver GPTD14 allocates the timer TIM14 when enabled.
- */
-#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__)
-GPTDriver GPTD14;
-#endif
-
-/**
- * @brief GPTD15 driver identifier.
- * @note The driver GPTD14 allocates the timer TIM14 when enabled.
- */
-#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__)
-GPTDriver GPTD15;
-#endif
-
-/**
- * @brief GPTD16 driver identifier.
- * @note The driver GPTD14 allocates the timer TIM14 when enabled.
- */
-#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__)
-GPTDriver GPTD16;
-#endif
-
-/**
- * @brief GPTD17 driver identifier.
- * @note The driver GPTD14 allocates the timer TIM14 when enabled.
- */
-#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__)
-GPTDriver GPTD17;
-#endif
-
-/**
- * @brief GPTD21 driver identifier.
- * @note The driver GPTD21 allocates the timer TIM21 when enabled.
- */
-#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__)
-GPTDriver GPTD21;
-#endif
-
-/**
- * @brief GPTD22 driver identifier.
- * @note The driver GPTD22 allocates the timer TIM22 when enabled.
- */
-#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__)
-GPTDriver GPTD22;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
-#if !defined(STM32_TIM1_UP_HANDLER)
-#error "STM32_TIM1_UP_HANDLER not defined"
-#endif
-/**
- * @brief TIM1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM1 */
-
-#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
-#if !defined(STM32_TIM2_HANDLER)
-#error "STM32_TIM2_HANDLER not defined"
-#endif
-/**
- * @brief TIM2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM2 */
-
-#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
-#if !defined(STM32_TIM3_HANDLER)
-#error "STM32_TIM3_HANDLER not defined"
-#endif
-/**
- * @brief TIM3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM3 */
-
-#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
-#if !defined(STM32_TIM4_HANDLER)
-#error "STM32_TIM4_HANDLER not defined"
-#endif
-/**
- * @brief TIM4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM4 */
-
-#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
-#if !defined(STM32_TIM5_HANDLER)
-#error "STM32_TIM5_HANDLER not defined"
-#endif
-/**
- * @brief TIM5 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM5 */
-
-#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM6_SUPPRESS_ISR)
-#if !defined(STM32_TIM6_HANDLER)
-#error "STM32_TIM6_HANDLER not defined"
-#endif
-/**
- * @brief TIM6 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM6_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM6 */
-
-#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM7_SUPPRESS_ISR)
-#if !defined(STM32_TIM7_HANDLER)
-#error "STM32_TIM7_HANDLER not defined"
-#endif
-/**
- * @brief TIM7 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM7_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM7 */
-
-#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
-#if !defined(STM32_TIM8_UP_HANDLER)
-#error "STM32_TIM8_UP_HANDLER not defined"
-#endif
-/**
- * @brief TIM8 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM8 */
-
-#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM9_SUPPRESS_ISR)
-#error "TIM9 ISR not defined by platform"
-#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM9 */
-
-#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM10_SUPPRESS_ISR)
-#error "TIM10 ISR not defined by platform"
-#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM10 */
-
-#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM11_SUPPRESS_ISR)
-#error "TIM11 ISR not defined by platform"
-#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM11 */
-
-#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM12_SUPPRESS_ISR)
-#error "TIM12 ISR not defined by platform"
-#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM12 */
-
-#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM13_SUPPRESS_ISR)
-#error "TIM13 ISR not defined by platform"
-#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM13 */
-
-#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM14_SUPPRESS_ISR)
-#error "TIM14 ISR not defined by platform"
-#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM14 */
-
-#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM15_SUPPRESS_ISR)
-#error "TIM15 ISR not defined by platform"
-#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM15 */
-
-#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM16_SUPPRESS_ISR)
-#error "TIM16 ISR not defined by platform"
-#endif /* !defined(STM32_TIM16_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM16 */
-
-#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM17_SUPPRESS_ISR)
-#error "TIM17 ISR not defined by platform"
-#endif /* !defined(STM32_TIM17_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM17 */
-
-#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM21_SUPPRESS_ISR)
-#if !defined(STM32_TIM21_HANDLER)
-#error "STM32_TIM21_HANDLER not defined"
-#endif
-/**
- * @brief TIM21 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM21_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD21);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM21 */
-
-#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM22_SUPPRESS_ISR)
-#if !defined(STM32_TIM22_HANDLER)
-#error "STM32_TIM22_HANDLER not defined"
-#endif
-/**
- * @brief TIM22 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM22_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- gpt_lld_serve_interrupt(&GPTD22);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */
-#endif /* STM32_GPT_USE_TIM22 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level GPT driver initialization.
- *
- * @notapi
- */
-void gpt_lld_init(void) {
-
-#if STM32_GPT_USE_TIM1
- /* Driver initialization.*/
- GPTD1.tim = STM32_TIM1;
- gptObjectInit(&GPTD1);
-#endif
-
-#if STM32_GPT_USE_TIM2
- /* Driver initialization.*/
- GPTD2.tim = STM32_TIM2;
- gptObjectInit(&GPTD2);
-#endif
-
-#if STM32_GPT_USE_TIM3
- /* Driver initialization.*/
- GPTD3.tim = STM32_TIM3;
- gptObjectInit(&GPTD3);
-#endif
-
-#if STM32_GPT_USE_TIM4
- /* Driver initialization.*/
- GPTD4.tim = STM32_TIM4;
- gptObjectInit(&GPTD4);
-#endif
-
-#if STM32_GPT_USE_TIM5
- /* Driver initialization.*/
- GPTD5.tim = STM32_TIM5;
- gptObjectInit(&GPTD5);
-#endif
-
-#if STM32_GPT_USE_TIM6
- /* Driver initialization.*/
- GPTD6.tim = STM32_TIM6;
- gptObjectInit(&GPTD6);
-#endif
-
-#if STM32_GPT_USE_TIM7
- /* Driver initialization.*/
- GPTD7.tim = STM32_TIM7;
- gptObjectInit(&GPTD7);
-#endif
-
-#if STM32_GPT_USE_TIM8
- /* Driver initialization.*/
- GPTD8.tim = STM32_TIM8;
- gptObjectInit(&GPTD8);
-#endif
-
-#if STM32_GPT_USE_TIM9
- /* Driver initialization.*/
- GPTD9.tim = STM32_TIM9;
- gptObjectInit(&GPTD9);
-#endif
-
-#if STM32_GPT_USE_TIM10
- /* Driver initialization.*/
- GPTD10.tim = STM32_TIM10;
- gptObjectInit(&GPTD10);
-#endif
-
-#if STM32_GPT_USE_TIM11
- /* Driver initialization.*/
- GPTD11.tim = STM32_TIM11;
- gptObjectInit(&GPTD11);
-#endif
-
-#if STM32_GPT_USE_TIM12
- /* Driver initialization.*/
- GPTD12.tim = STM32_TIM12;
- gptObjectInit(&GPTD12);
-#endif
-
-#if STM32_GPT_USE_TIM13
- /* Driver initialization.*/
- GPTD13.tim = STM32_TIM13;
- gptObjectInit(&GPTD13);
-#endif
-
-#if STM32_GPT_USE_TIM14
- /* Driver initialization.*/
- GPTD14.tim = STM32_TIM14;
- gptObjectInit(&GPTD14);
-#endif
-
-#if STM32_GPT_USE_TIM15
- /* Driver initialization.*/
- GPTD15.tim = STM32_TIM15;
- gptObjectInit(&GPTD15);
-#endif
-
-#if STM32_GPT_USE_TIM16
- /* Driver initialization.*/
- GPTD16.tim = STM32_TIM16;
- gptObjectInit(&GPTD16);
-#endif
-
-#if STM32_GPT_USE_TIM17
- /* Driver initialization.*/
- GPTD17.tim = STM32_TIM17;
- gptObjectInit(&GPTD17);
-#endif
-
-#if STM32_GPT_USE_TIM21
- /* Driver initialization.*/
- GPTD21.tim = STM32_TIM21;
- gptObjectInit(&GPTD21);
-#endif
-
-#if STM32_GPT_USE_TIM22
- /* Driver initialization.*/
- GPTD22.tim = STM32_TIM22;
- gptObjectInit(&GPTD22);
-#endif
-}
-
-/**
- * @brief Configures and activates the GPT peripheral.
- *
- * @param[in] gptp pointer to the @p GPTDriver object
- *
- * @notapi
- */
-void gpt_lld_start(GPTDriver *gptp) {
- uint16_t psc;
-
- if (gptp->state == GPT_STOP) {
- /* Clock activation.*/
-#if STM32_GPT_USE_TIM1
- if (&GPTD1 == gptp) {
- rccEnableTIM1(true);
- rccResetTIM1();
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_GPT_TIM1_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM1CLK)
- gptp->clock = STM32_TIM1CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM2
- if (&GPTD2 == gptp) {
- rccEnableTIM2(true);
- rccResetTIM2();
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM2_NUMBER, STM32_GPT_TIM2_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM2CLK)
- gptp->clock = STM32_TIM2CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM3
- if (&GPTD3 == gptp) {
- rccEnableTIM3(true);
- rccResetTIM3();
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM3_NUMBER, STM32_GPT_TIM3_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM3CLK)
- gptp->clock = STM32_TIM3CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM4
- if (&GPTD4 == gptp) {
- rccEnableTIM4(true);
- rccResetTIM4();
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM4_NUMBER, STM32_GPT_TIM4_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM4CLK)
- gptp->clock = STM32_TIM4CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM5
- if (&GPTD5 == gptp) {
- rccEnableTIM5(true);
- rccResetTIM5();
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM5_NUMBER, STM32_GPT_TIM5_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM5CLK)
- gptp->clock = STM32_TIM5CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM6
- if (&GPTD6 == gptp) {
- rccEnableTIM6(true);
- rccResetTIM6();
-#if !defined(STM32_TIM6_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM6_NUMBER, STM32_GPT_TIM6_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM6CLK)
- gptp->clock = STM32_TIM6CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM7
- if (&GPTD7 == gptp) {
- rccEnableTIM7(true);
- rccResetTIM7();
-#if !defined(STM32_TIM7_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM7_NUMBER, STM32_GPT_TIM7_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM7CLK)
- gptp->clock = STM32_TIM7CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM8
- if (&GPTD8 == gptp) {
- rccEnableTIM8(true);
- rccResetTIM8();
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_GPT_TIM8_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM8CLK)
- gptp->clock = STM32_TIM8CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM9
- if (&GPTD9 == gptp) {
- rccEnableTIM9(true);
- rccResetTIM9();
-#if !defined(STM32_TIM9_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM9_NUMBER, STM32_GPT_TIM9_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM9CLK)
- gptp->clock = STM32_TIM9CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM10
- if (&GPTD10 == gptp) {
- rccEnableTIM10(true);
- rccResetTIM10();
-#if !defined(STM32_TIM10_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM10_NUMBER, STM32_GPT_TIM10_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM10CLK)
- gptp->clock = STM32_TIM10CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM11
- if (&GPTD11 == gptp) {
- rccEnableTIM11(true);
- rccResetTIM11();
-#if !defined(STM32_TIM11_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM11_NUMBER, STM32_GPT_TIM11_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM11CLK)
- gptp->clock = STM32_TIM11CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM12
- if (&GPTD12 == gptp) {
- rccEnableTIM12(true);
- rccResetTIM12();
-#if !defined(STM32_TIM12_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM12_NUMBER, STM32_GPT_TIM12_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM12CLK)
- gptp->clock = STM32_TIM12CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM13
- if (&GPTD13 == gptp) {
- rccEnableTIM13(true);
- rccResetTIM13();
-#if !defined(STM32_TIM13_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM13_NUMBER, STM32_GPT_TIM13_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM13CLK)
- gptp->clock = STM32_TIM13CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM14
- if (&GPTD14 == gptp) {
- rccEnableTIM14(true);
- rccResetTIM14();
-#if !defined(STM32_TIM14_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM14_NUMBER, STM32_GPT_TIM14_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM14CLK)
- gptp->clock = STM32_TIM14CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM15
- if (&GPTD15 == gptp) {
- rccEnableTIM15(true);
- rccResetTIM15();
-#if defined(STM32_TIM15CLK)
- gptp->clock = STM32_TIM15CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM16
- if (&GPTD16 == gptp) {
- rccEnableTIM16(true);
- rccResetTIM16();
-#if defined(STM32_TIM16CLK)
- gptp->clock = STM32_TIM16CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM17
- if (&GPTD17 == gptp) {
- rccEnableTIM17(true);
- rccResetTIM17();
-#if defined(STM32_TIM17CLK)
- gptp->clock = STM32_TIM17CLK;
-#else
- gptp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM21
- if (&GPTD21 == gptp) {
- rccEnableTIM21(true);
- rccResetTIM21();
-#if !defined(STM32_TIM21_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM21_NUMBER, STM32_GPT_TIM21_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM21CLK)
- gptp->clock = STM32_TIM21CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_GPT_USE_TIM22
- if (&GPTD22 == gptp) {
- rccEnableTIM22(true);
- rccResetTIM22();
-#if !defined(STM32_TIM22_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM22_NUMBER, STM32_GPT_TIM22_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM22CLK)
- gptp->clock = STM32_TIM22CLK;
-#else
- gptp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
- }
-
- /* Prescaler value calculation.*/
- psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1);
- osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock,
- "invalid frequency");
-
- /* Timer configuration.*/
- gptp->tim->CR1 = 0; /* Initially stopped. */
- gptp->tim->CR2 = gptp->config->cr2;
- gptp->tim->PSC = psc; /* Prescaler value. */
- gptp->tim->SR = 0; /* Clear pending IRQs. */
- gptp->tim->DIER = gptp->config->dier & /* DMA-related DIER bits. */
- ~STM32_TIM_DIER_IRQ_MASK;
-}
-
-/**
- * @brief Deactivates the GPT peripheral.
- *
- * @param[in] gptp pointer to the @p GPTDriver object
- *
- * @notapi
- */
-void gpt_lld_stop(GPTDriver *gptp) {
-
- if (gptp->state == GPT_READY) {
- gptp->tim->CR1 = 0; /* Timer disabled. */
- gptp->tim->DIER = 0; /* All IRQs disabled. */
- gptp->tim->SR = 0; /* Clear pending IRQs. */
-
-#if STM32_GPT_USE_TIM1
- if (&GPTD1 == gptp) {
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM1_UP_NUMBER);
-#endif
- rccDisableTIM1();
- }
-#endif
-
-#if STM32_GPT_USE_TIM2
- if (&GPTD2 == gptp) {
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM2_NUMBER);
-#endif
- rccDisableTIM2();
- }
-#endif
-
-#if STM32_GPT_USE_TIM3
- if (&GPTD3 == gptp) {
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM3_NUMBER);
-#endif
- rccDisableTIM3();
- }
-#endif
-
-#if STM32_GPT_USE_TIM4
- if (&GPTD4 == gptp) {
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM4_NUMBER);
-#endif
- rccDisableTIM4();
- }
-#endif
-
-#if STM32_GPT_USE_TIM5
- if (&GPTD5 == gptp) {
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM5_NUMBER);
-#endif
- rccDisableTIM5();
- }
-#endif
-
-#if STM32_GPT_USE_TIM6
- if (&GPTD6 == gptp) {
-#if !defined(STM32_TIM6_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM6_NUMBER);
-#endif
- rccDisableTIM6();
- }
-#endif
-
-#if STM32_GPT_USE_TIM7
- if (&GPTD7 == gptp) {
-#if !defined(STM32_TIM7_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM7_NUMBER);
-#endif
- rccDisableTIM7();
- }
-#endif
-
-#if STM32_GPT_USE_TIM8
- if (&GPTD8 == gptp) {
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM8_UP_NUMBER);
-#endif
- rccDisableTIM8();
- }
-#endif
-
-#if STM32_GPT_USE_TIM9
- if (&GPTD9 == gptp) {
-#if !defined(STM32_TIM9_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM9_NUMBER);
-#endif
- rccDisableTIM9();
- }
-#endif
-
-#if STM32_GPT_USE_TIM10
- if (&GPTD10 == gptp) {
-#if !defined(STM32_TIM10_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM10_NUMBER);
-#endif
- rccDisableTIM10();
- }
-#endif
-
-#if STM32_GPT_USE_TIM11
- if (&GPTD11 == gptp) {
-#if !defined(STM32_TIM11_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM11_NUMBER);
-#endif
- rccDisableTIM11();
- }
-#endif
-
-#if STM32_GPT_USE_TIM12
- if (&GPTD12 == gptp) {
-#if !defined(STM32_TIM12_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM12_NUMBER);
-#endif
- rccDisableTIM12();
- }
-#endif
-
-#if STM32_GPT_USE_TIM13
- if (&GPTD13 == gptp) {
-#if !defined(STM32_TIM13_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM13_NUMBER);
-#endif
- rccDisableTIM13();
- }
-#endif
-
-#if STM32_GPT_USE_TIM14
- if (&GPTD14 == gptp) {
-#if !defined(STM32_TIM14_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM14_NUMBER);
-#endif
- rccDisableTIM14();
- }
-#endif
-
-#if STM32_GPT_USE_TIM15
- if (&GPTD15 == gptp) {
- rccDisableTIM15();
- }
-#endif
-
-#if STM32_GPT_USE_TIM16
- if (&GPTD16 == gptp) {
- rccDisableTIM16();
- }
-#endif
-
-#if STM32_GPT_USE_TIM17
- if (&GPTD17 == gptp) {
- rccDisableTIM17();
- }
-#endif
-
-#if STM32_GPT_USE_TIM21
- if (&GPTD21 == gptp) {
-#if !defined(STM32_TIM21_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM21_NUMBER);
-#endif
- rccDisableTIM21();
- }
-#endif
-
-#if STM32_GPT_USE_TIM22
- if (&GPTD22 == gptp) {
-#if !defined(STM32_TIM22_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM22_NUMBER);
-#endif
- rccDisableTIM22();
- }
-#endif
- }
-}
-
-/**
- * @brief Starts the timer in continuous mode.
- *
- * @param[in] gptp pointer to the @p GPTDriver object
- * @param[in] interval period in ticks
- *
- * @notapi
- */
-void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
-
- gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */
- gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
- gptp->tim->CNT = 0; /* Reset counter. */
-
- /* NOTE: After generating the UG event it takes several clock cycles before
- SR bit 0 goes to 1. This is why the clearing of CNT has been inserted
- before the clearing of SR, to give it some time.*/
- gptp->tim->SR = 0; /* Clear pending IRQs. */
- if (NULL != gptp->config->callback)
- gptp->tim->DIER |= STM32_TIM_DIER_UIE; /* Update Event IRQ enabled.*/
- gptp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
-}
-
-/**
- * @brief Stops the timer.
- *
- * @param[in] gptp pointer to the @p GPTDriver object
- *
- * @notapi
- */
-void gpt_lld_stop_timer(GPTDriver *gptp) {
-
- gptp->tim->CR1 = 0; /* Initially stopped. */
- gptp->tim->SR = 0; /* Clear pending IRQs. */
-
- /* All interrupts disabled.*/
- gptp->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
-}
-
-/**
- * @brief Starts the timer in one shot mode and waits for completion.
- * @details This function specifically polls the timer waiting for completion
- * in order to not have extra delays caused by interrupt servicing,
- * this function is only recommended for short delays.
- *
- * @param[in] gptp pointer to the @p GPTDriver object
- * @param[in] interval time interval in ticks
- *
- * @notapi
- */
-void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
-
- gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */
- gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
- gptp->tim->SR = 0; /* Clear pending IRQs. */
- gptp->tim->CR1 = STM32_TIM_CR1_OPM | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
- while (!(gptp->tim->SR & STM32_TIM_SR_UIF))
- ;
- gptp->tim->SR = 0; /* Clear pending IRQs. */
-}
-
-/**
- * @brief Shared IRQ handler.
- *
- * @param[in] gptp pointer to a @p GPTDriver object
- *
- * @notapi
- */
-void gpt_lld_serve_interrupt(GPTDriver *gptp) {
- uint32_t sr;
-
- sr = gptp->tim->SR;
- sr &= gptp->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
- gptp->tim->SR = ~sr;
- if ((sr & STM32_TIM_SR_UIF) != 0) {
- _gpt_isr_invoke_cb(gptp);
- }
-}
-
-#endif /* HAL_USE_GPT */
-
-/** @} */
+/*
+ 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 TIMv1/hal_gpt_lld.c
+ * @brief STM32 GPT subsystem low level driver source.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief GPTD1 driver identifier.
+ * @note The driver GPTD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
+GPTDriver GPTD1;
+#endif
+
+/**
+ * @brief GPTD2 driver identifier.
+ * @note The driver GPTD2 allocates the timer TIM2 when enabled.
+ */
+#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
+GPTDriver GPTD2;
+#endif
+
+/**
+ * @brief GPTD3 driver identifier.
+ * @note The driver GPTD3 allocates the timer TIM3 when enabled.
+ */
+#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
+GPTDriver GPTD3;
+#endif
+
+/**
+ * @brief GPTD4 driver identifier.
+ * @note The driver GPTD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
+GPTDriver GPTD4;
+#endif
+
+/**
+ * @brief GPTD5 driver identifier.
+ * @note The driver GPTD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
+GPTDriver GPTD5;
+#endif
+
+/**
+ * @brief GPTD6 driver identifier.
+ * @note The driver GPTD6 allocates the timer TIM6 when enabled.
+ */
+#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__)
+GPTDriver GPTD6;
+#endif
+
+/**
+ * @brief GPTD7 driver identifier.
+ * @note The driver GPTD7 allocates the timer TIM7 when enabled.
+ */
+#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__)
+GPTDriver GPTD7;
+#endif
+
+/**
+ * @brief GPTD8 driver identifier.
+ * @note The driver GPTD8 allocates the timer TIM8 when enabled.
+ */
+#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__)
+GPTDriver GPTD8;
+#endif
+
+/**
+ * @brief GPTD9 driver identifier.
+ * @note The driver GPTD9 allocates the timer TIM9 when enabled.
+ */
+#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__)
+GPTDriver GPTD9;
+#endif
+
+/**
+ * @brief GPTD10 driver identifier.
+ * @note The driver GPTD10 allocates the timer TIM10 when enabled.
+ */
+#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__)
+GPTDriver GPTD10;
+#endif
+
+/**
+ * @brief GPTD11 driver identifier.
+ * @note The driver GPTD11 allocates the timer TIM11 when enabled.
+ */
+#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__)
+GPTDriver GPTD11;
+#endif
+
+/**
+ * @brief GPTD12 driver identifier.
+ * @note The driver GPTD12 allocates the timer TIM12 when enabled.
+ */
+#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__)
+GPTDriver GPTD12;
+#endif
+
+/**
+ * @brief GPTD13 driver identifier.
+ * @note The driver GPTD13 allocates the timer TIM13 when enabled.
+ */
+#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__)
+GPTDriver GPTD13;
+#endif
+
+/**
+ * @brief GPTD14 driver identifier.
+ * @note The driver GPTD14 allocates the timer TIM14 when enabled.
+ */
+#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__)
+GPTDriver GPTD14;
+#endif
+
+/**
+ * @brief GPTD15 driver identifier.
+ * @note The driver GPTD14 allocates the timer TIM14 when enabled.
+ */
+#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__)
+GPTDriver GPTD15;
+#endif
+
+/**
+ * @brief GPTD16 driver identifier.
+ * @note The driver GPTD14 allocates the timer TIM14 when enabled.
+ */
+#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__)
+GPTDriver GPTD16;
+#endif
+
+/**
+ * @brief GPTD17 driver identifier.
+ * @note The driver GPTD14 allocates the timer TIM14 when enabled.
+ */
+#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__)
+GPTDriver GPTD17;
+#endif
+
+/**
+ * @brief GPTD21 driver identifier.
+ * @note The driver GPTD21 allocates the timer TIM21 when enabled.
+ */
+#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__)
+GPTDriver GPTD21;
+#endif
+
+/**
+ * @brief GPTD22 driver identifier.
+ * @note The driver GPTD22 allocates the timer TIM22 when enabled.
+ */
+#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__)
+GPTDriver GPTD22;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+#if !defined(STM32_TIM1_UP_HANDLER)
+#error "STM32_TIM1_UP_HANDLER not defined"
+#endif
+/**
+ * @brief TIM1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM1 */
+
+#if STM32_GPT_USE_TIM2 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+#if !defined(STM32_TIM2_HANDLER)
+#error "STM32_TIM2_HANDLER not defined"
+#endif
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM2 */
+
+#if STM32_GPT_USE_TIM3 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+#if !defined(STM32_TIM3_HANDLER)
+#error "STM32_TIM3_HANDLER not defined"
+#endif
+/**
+ * @brief TIM3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM3 */
+
+#if STM32_GPT_USE_TIM4 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+#if !defined(STM32_TIM4_HANDLER)
+#error "STM32_TIM4_HANDLER not defined"
+#endif
+/**
+ * @brief TIM4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM4 */
+
+#if STM32_GPT_USE_TIM5 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+#if !defined(STM32_TIM5_HANDLER)
+#error "STM32_TIM5_HANDLER not defined"
+#endif
+/**
+ * @brief TIM5 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM5 */
+
+#if STM32_GPT_USE_TIM6 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM6_SUPPRESS_ISR)
+#if !defined(STM32_TIM6_HANDLER)
+#error "STM32_TIM6_HANDLER not defined"
+#endif
+/**
+ * @brief TIM6 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM6_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM6 */
+
+#if STM32_GPT_USE_TIM7 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM7_SUPPRESS_ISR)
+#if !defined(STM32_TIM7_HANDLER)
+#error "STM32_TIM7_HANDLER not defined"
+#endif
+/**
+ * @brief TIM7 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM7_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM7 */
+
+#if STM32_GPT_USE_TIM8 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+#if !defined(STM32_TIM8_UP_HANDLER)
+#error "STM32_TIM8_UP_HANDLER not defined"
+#endif
+/**
+ * @brief TIM8 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM8 */
+
+#if STM32_GPT_USE_TIM9 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM9_SUPPRESS_ISR)
+#error "TIM9 ISR not defined by platform"
+#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM9 */
+
+#if STM32_GPT_USE_TIM10 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM10_SUPPRESS_ISR)
+#error "TIM10 ISR not defined by platform"
+#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM10 */
+
+#if STM32_GPT_USE_TIM11 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM11_SUPPRESS_ISR)
+#error "TIM11 ISR not defined by platform"
+#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM11 */
+
+#if STM32_GPT_USE_TIM12 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM12_SUPPRESS_ISR)
+#error "TIM12 ISR not defined by platform"
+#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM12 */
+
+#if STM32_GPT_USE_TIM13 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM13_SUPPRESS_ISR)
+#error "TIM13 ISR not defined by platform"
+#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM13 */
+
+#if STM32_GPT_USE_TIM14 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM14_SUPPRESS_ISR)
+#error "TIM14 ISR not defined by platform"
+#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM14 */
+
+#if STM32_GPT_USE_TIM15 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM15_SUPPRESS_ISR)
+#error "TIM15 ISR not defined by platform"
+#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM15 */
+
+#if STM32_GPT_USE_TIM16 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM16_SUPPRESS_ISR)
+#error "TIM16 ISR not defined by platform"
+#endif /* !defined(STM32_TIM16_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM16 */
+
+#if STM32_GPT_USE_TIM17 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM17_SUPPRESS_ISR)
+#error "TIM17 ISR not defined by platform"
+#endif /* !defined(STM32_TIM17_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM17 */
+
+#if STM32_GPT_USE_TIM21 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM21_SUPPRESS_ISR)
+#if !defined(STM32_TIM21_HANDLER)
+#error "STM32_TIM21_HANDLER not defined"
+#endif
+/**
+ * @brief TIM21 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM21_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD21);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM21 */
+
+#if STM32_GPT_USE_TIM22 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM22_SUPPRESS_ISR)
+#if !defined(STM32_TIM22_HANDLER)
+#error "STM32_TIM22_HANDLER not defined"
+#endif
+/**
+ * @brief TIM22 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM22_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ gpt_lld_serve_interrupt(&GPTD22);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */
+#endif /* STM32_GPT_USE_TIM22 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level GPT driver initialization.
+ *
+ * @notapi
+ */
+void gpt_lld_init(void) {
+
+#if STM32_GPT_USE_TIM1
+ /* Driver initialization.*/
+ GPTD1.tim = STM32_TIM1;
+ gptObjectInit(&GPTD1);
+#endif
+
+#if STM32_GPT_USE_TIM2
+ /* Driver initialization.*/
+ GPTD2.tim = STM32_TIM2;
+ gptObjectInit(&GPTD2);
+#endif
+
+#if STM32_GPT_USE_TIM3
+ /* Driver initialization.*/
+ GPTD3.tim = STM32_TIM3;
+ gptObjectInit(&GPTD3);
+#endif
+
+#if STM32_GPT_USE_TIM4
+ /* Driver initialization.*/
+ GPTD4.tim = STM32_TIM4;
+ gptObjectInit(&GPTD4);
+#endif
+
+#if STM32_GPT_USE_TIM5
+ /* Driver initialization.*/
+ GPTD5.tim = STM32_TIM5;
+ gptObjectInit(&GPTD5);
+#endif
+
+#if STM32_GPT_USE_TIM6
+ /* Driver initialization.*/
+ GPTD6.tim = STM32_TIM6;
+ gptObjectInit(&GPTD6);
+#endif
+
+#if STM32_GPT_USE_TIM7
+ /* Driver initialization.*/
+ GPTD7.tim = STM32_TIM7;
+ gptObjectInit(&GPTD7);
+#endif
+
+#if STM32_GPT_USE_TIM8
+ /* Driver initialization.*/
+ GPTD8.tim = STM32_TIM8;
+ gptObjectInit(&GPTD8);
+#endif
+
+#if STM32_GPT_USE_TIM9
+ /* Driver initialization.*/
+ GPTD9.tim = STM32_TIM9;
+ gptObjectInit(&GPTD9);
+#endif
+
+#if STM32_GPT_USE_TIM10
+ /* Driver initialization.*/
+ GPTD10.tim = STM32_TIM10;
+ gptObjectInit(&GPTD10);
+#endif
+
+#if STM32_GPT_USE_TIM11
+ /* Driver initialization.*/
+ GPTD11.tim = STM32_TIM11;
+ gptObjectInit(&GPTD11);
+#endif
+
+#if STM32_GPT_USE_TIM12
+ /* Driver initialization.*/
+ GPTD12.tim = STM32_TIM12;
+ gptObjectInit(&GPTD12);
+#endif
+
+#if STM32_GPT_USE_TIM13
+ /* Driver initialization.*/
+ GPTD13.tim = STM32_TIM13;
+ gptObjectInit(&GPTD13);
+#endif
+
+#if STM32_GPT_USE_TIM14
+ /* Driver initialization.*/
+ GPTD14.tim = STM32_TIM14;
+ gptObjectInit(&GPTD14);
+#endif
+
+#if STM32_GPT_USE_TIM15
+ /* Driver initialization.*/
+ GPTD15.tim = STM32_TIM15;
+ gptObjectInit(&GPTD15);
+#endif
+
+#if STM32_GPT_USE_TIM16
+ /* Driver initialization.*/
+ GPTD16.tim = STM32_TIM16;
+ gptObjectInit(&GPTD16);
+#endif
+
+#if STM32_GPT_USE_TIM17
+ /* Driver initialization.*/
+ GPTD17.tim = STM32_TIM17;
+ gptObjectInit(&GPTD17);
+#endif
+
+#if STM32_GPT_USE_TIM21
+ /* Driver initialization.*/
+ GPTD21.tim = STM32_TIM21;
+ gptObjectInit(&GPTD21);
+#endif
+
+#if STM32_GPT_USE_TIM22
+ /* Driver initialization.*/
+ GPTD22.tim = STM32_TIM22;
+ gptObjectInit(&GPTD22);
+#endif
+}
+
+/**
+ * @brief Configures and activates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_start(GPTDriver *gptp) {
+ uint16_t psc;
+
+ if (gptp->state == GPT_STOP) {
+ /* Clock activation.*/
+#if STM32_GPT_USE_TIM1
+ if (&GPTD1 == gptp) {
+ rccEnableTIM1(true);
+ rccResetTIM1();
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_GPT_TIM1_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM1CLK)
+ gptp->clock = STM32_TIM1CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM2
+ if (&GPTD2 == gptp) {
+ rccEnableTIM2(true);
+ rccResetTIM2();
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM2_NUMBER, STM32_GPT_TIM2_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM2CLK)
+ gptp->clock = STM32_TIM2CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM3
+ if (&GPTD3 == gptp) {
+ rccEnableTIM3(true);
+ rccResetTIM3();
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM3_NUMBER, STM32_GPT_TIM3_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM3CLK)
+ gptp->clock = STM32_TIM3CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM4
+ if (&GPTD4 == gptp) {
+ rccEnableTIM4(true);
+ rccResetTIM4();
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM4_NUMBER, STM32_GPT_TIM4_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM4CLK)
+ gptp->clock = STM32_TIM4CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM5
+ if (&GPTD5 == gptp) {
+ rccEnableTIM5(true);
+ rccResetTIM5();
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM5_NUMBER, STM32_GPT_TIM5_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM5CLK)
+ gptp->clock = STM32_TIM5CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM6
+ if (&GPTD6 == gptp) {
+ rccEnableTIM6(true);
+ rccResetTIM6();
+#if !defined(STM32_TIM6_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM6_NUMBER, STM32_GPT_TIM6_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM6CLK)
+ gptp->clock = STM32_TIM6CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM7
+ if (&GPTD7 == gptp) {
+ rccEnableTIM7(true);
+ rccResetTIM7();
+#if !defined(STM32_TIM7_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM7_NUMBER, STM32_GPT_TIM7_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM7CLK)
+ gptp->clock = STM32_TIM7CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM8
+ if (&GPTD8 == gptp) {
+ rccEnableTIM8(true);
+ rccResetTIM8();
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_GPT_TIM8_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM8CLK)
+ gptp->clock = STM32_TIM8CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM9
+ if (&GPTD9 == gptp) {
+ rccEnableTIM9(true);
+ rccResetTIM9();
+#if !defined(STM32_TIM9_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM9_NUMBER, STM32_GPT_TIM9_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM9CLK)
+ gptp->clock = STM32_TIM9CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM10
+ if (&GPTD10 == gptp) {
+ rccEnableTIM10(true);
+ rccResetTIM10();
+#if !defined(STM32_TIM10_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM10_NUMBER, STM32_GPT_TIM10_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM10CLK)
+ gptp->clock = STM32_TIM10CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM11
+ if (&GPTD11 == gptp) {
+ rccEnableTIM11(true);
+ rccResetTIM11();
+#if !defined(STM32_TIM11_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM11_NUMBER, STM32_GPT_TIM11_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM11CLK)
+ gptp->clock = STM32_TIM11CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM12
+ if (&GPTD12 == gptp) {
+ rccEnableTIM12(true);
+ rccResetTIM12();
+#if !defined(STM32_TIM12_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM12_NUMBER, STM32_GPT_TIM12_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM12CLK)
+ gptp->clock = STM32_TIM12CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM13
+ if (&GPTD13 == gptp) {
+ rccEnableTIM13(true);
+ rccResetTIM13();
+#if !defined(STM32_TIM13_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM13_NUMBER, STM32_GPT_TIM13_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM13CLK)
+ gptp->clock = STM32_TIM13CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM14
+ if (&GPTD14 == gptp) {
+ rccEnableTIM14(true);
+ rccResetTIM14();
+#if !defined(STM32_TIM14_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM14_NUMBER, STM32_GPT_TIM14_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM14CLK)
+ gptp->clock = STM32_TIM14CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM15
+ if (&GPTD15 == gptp) {
+ rccEnableTIM15(true);
+ rccResetTIM15();
+#if defined(STM32_TIM15CLK)
+ gptp->clock = STM32_TIM15CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM16
+ if (&GPTD16 == gptp) {
+ rccEnableTIM16(true);
+ rccResetTIM16();
+#if defined(STM32_TIM16CLK)
+ gptp->clock = STM32_TIM16CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM17
+ if (&GPTD17 == gptp) {
+ rccEnableTIM17(true);
+ rccResetTIM17();
+#if defined(STM32_TIM17CLK)
+ gptp->clock = STM32_TIM17CLK;
+#else
+ gptp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM21
+ if (&GPTD21 == gptp) {
+ rccEnableTIM21(true);
+ rccResetTIM21();
+#if !defined(STM32_TIM21_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM21_NUMBER, STM32_GPT_TIM21_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM21CLK)
+ gptp->clock = STM32_TIM21CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_GPT_USE_TIM22
+ if (&GPTD22 == gptp) {
+ rccEnableTIM22(true);
+ rccResetTIM22();
+#if !defined(STM32_TIM22_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM22_NUMBER, STM32_GPT_TIM22_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM22CLK)
+ gptp->clock = STM32_TIM22CLK;
+#else
+ gptp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+ }
+
+ /* Prescaler value calculation.*/
+ psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1);
+ osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock,
+ "invalid frequency");
+
+ /* Timer configuration.*/
+ gptp->tim->CR1 = 0; /* Initially stopped. */
+ gptp->tim->CR2 = gptp->config->cr2;
+ gptp->tim->PSC = psc; /* Prescaler value. */
+ gptp->tim->SR = 0; /* Clear pending IRQs. */
+ gptp->tim->DIER = gptp->config->dier & /* DMA-related DIER bits. */
+ ~STM32_TIM_DIER_IRQ_MASK;
+}
+
+/**
+ * @brief Deactivates the GPT peripheral.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop(GPTDriver *gptp) {
+
+ if (gptp->state == GPT_READY) {
+ gptp->tim->CR1 = 0; /* Timer disabled. */
+ gptp->tim->DIER = 0; /* All IRQs disabled. */
+ gptp->tim->SR = 0; /* Clear pending IRQs. */
+
+#if STM32_GPT_USE_TIM1
+ if (&GPTD1 == gptp) {
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM1_UP_NUMBER);
+#endif
+ rccDisableTIM1();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM2
+ if (&GPTD2 == gptp) {
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM2_NUMBER);
+#endif
+ rccDisableTIM2();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM3
+ if (&GPTD3 == gptp) {
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM3_NUMBER);
+#endif
+ rccDisableTIM3();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM4
+ if (&GPTD4 == gptp) {
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM4_NUMBER);
+#endif
+ rccDisableTIM4();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM5
+ if (&GPTD5 == gptp) {
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM5_NUMBER);
+#endif
+ rccDisableTIM5();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM6
+ if (&GPTD6 == gptp) {
+#if !defined(STM32_TIM6_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM6_NUMBER);
+#endif
+ rccDisableTIM6();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM7
+ if (&GPTD7 == gptp) {
+#if !defined(STM32_TIM7_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM7_NUMBER);
+#endif
+ rccDisableTIM7();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM8
+ if (&GPTD8 == gptp) {
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM8_UP_NUMBER);
+#endif
+ rccDisableTIM8();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM9
+ if (&GPTD9 == gptp) {
+#if !defined(STM32_TIM9_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM9_NUMBER);
+#endif
+ rccDisableTIM9();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM10
+ if (&GPTD10 == gptp) {
+#if !defined(STM32_TIM10_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM10_NUMBER);
+#endif
+ rccDisableTIM10();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM11
+ if (&GPTD11 == gptp) {
+#if !defined(STM32_TIM11_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM11_NUMBER);
+#endif
+ rccDisableTIM11();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM12
+ if (&GPTD12 == gptp) {
+#if !defined(STM32_TIM12_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM12_NUMBER);
+#endif
+ rccDisableTIM12();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM13
+ if (&GPTD13 == gptp) {
+#if !defined(STM32_TIM13_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM13_NUMBER);
+#endif
+ rccDisableTIM13();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM14
+ if (&GPTD14 == gptp) {
+#if !defined(STM32_TIM14_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM14_NUMBER);
+#endif
+ rccDisableTIM14();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM15
+ if (&GPTD15 == gptp) {
+ rccDisableTIM15();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM16
+ if (&GPTD16 == gptp) {
+ rccDisableTIM16();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM17
+ if (&GPTD17 == gptp) {
+ rccDisableTIM17();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM21
+ if (&GPTD21 == gptp) {
+#if !defined(STM32_TIM21_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM21_NUMBER);
+#endif
+ rccDisableTIM21();
+ }
+#endif
+
+#if STM32_GPT_USE_TIM22
+ if (&GPTD22 == gptp) {
+#if !defined(STM32_TIM22_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM22_NUMBER);
+#endif
+ rccDisableTIM22();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the timer in continuous mode.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval period in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */
+ gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
+ gptp->tim->CNT = 0; /* Reset counter. */
+
+ /* NOTE: After generating the UG event it takes several clock cycles before
+ SR bit 0 goes to 1. This is why the clearing of CNT has been inserted
+ before the clearing of SR, to give it some time.*/
+ gptp->tim->SR = 0; /* Clear pending IRQs. */
+ if (NULL != gptp->config->callback)
+ gptp->tim->DIER |= STM32_TIM_DIER_UIE; /* Update Event IRQ enabled.*/
+ gptp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
+}
+
+/**
+ * @brief Stops the timer.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_stop_timer(GPTDriver *gptp) {
+
+ gptp->tim->CR1 = 0; /* Initially stopped. */
+ gptp->tim->SR = 0; /* Clear pending IRQs. */
+
+ /* All interrupts disabled.*/
+ gptp->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
+}
+
+/**
+ * @brief Starts the timer in one shot mode and waits for completion.
+ * @details This function specifically polls the timer waiting for completion
+ * in order to not have extra delays caused by interrupt servicing,
+ * this function is only recommended for short delays.
+ *
+ * @param[in] gptp pointer to the @p GPTDriver object
+ * @param[in] interval time interval in ticks
+ *
+ * @notapi
+ */
+void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
+
+ gptp->tim->ARR = (uint32_t)(interval - 1U); /* Time constant. */
+ gptp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
+ gptp->tim->SR = 0; /* Clear pending IRQs. */
+ gptp->tim->CR1 = STM32_TIM_CR1_OPM | STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
+ while (!(gptp->tim->SR & STM32_TIM_SR_UIF))
+ ;
+ gptp->tim->SR = 0; /* Clear pending IRQs. */
+}
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ *
+ * @notapi
+ */
+void gpt_lld_serve_interrupt(GPTDriver *gptp) {
+ uint32_t sr;
+
+ sr = gptp->tim->SR;
+ sr &= gptp->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
+ gptp->tim->SR = ~sr;
+ if ((sr & STM32_TIM_SR_UIF) != 0) {
+ _gpt_isr_invoke_cb(gptp);
+ }
+}
+
+#endif /* HAL_USE_GPT */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.h
index 1fbdea3feb..631ca191bd 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_gpt_lld.h
@@ -1,980 +1,980 @@
-/*
- 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 TIMv1/hal_gpt_lld.h
- * @brief STM32 GPT subsystem low level driver header.
- *
- * @addtogroup GPT
- * @{
- */
-
-#ifndef HAL_GPT_LLD_H
-#define HAL_GPT_LLD_H
-
-#include "stm32_tim.h"
-
-#if HAL_USE_GPT || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief GPTD1 driver enable switch.
- * @details If set to @p TRUE the support for GPTD1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM1) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM1 FALSE
-#endif
-
-/**
- * @brief GPTD2 driver enable switch.
- * @details If set to @p TRUE the support for GPTD2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM2) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM2 FALSE
-#endif
-
-/**
- * @brief GPTD3 driver enable switch.
- * @details If set to @p TRUE the support for GPTD3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM3) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM3 FALSE
-#endif
-
-/**
- * @brief GPTD4 driver enable switch.
- * @details If set to @p TRUE the support for GPTD4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM4) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM4 FALSE
-#endif
-
-/**
- * @brief GPTD5 driver enable switch.
- * @details If set to @p TRUE the support for GPTD5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM5) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM5 FALSE
-#endif
-
-/**
- * @brief GPTD6 driver enable switch.
- * @details If set to @p TRUE the support for GPTD6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM6) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM6 FALSE
-#endif
-
-/**
- * @brief GPTD7 driver enable switch.
- * @details If set to @p TRUE the support for GPTD7 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM7) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM7 FALSE
-#endif
-
-/**
- * @brief GPTD8 driver enable switch.
- * @details If set to @p TRUE the support for GPTD8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM8) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM8 FALSE
-#endif
-
-/**
- * @brief GPTD9 driver enable switch.
- * @details If set to @p TRUE the support for GPTD9 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM9) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM9 FALSE
-#endif
-
-/**
- * @brief GPTD10 driver enable switch.
- * @details If set to @p TRUE the support for GPTD10 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM10) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM10 FALSE
-#endif
-
-/**
- * @brief GPTD11 driver enable switch.
- * @details If set to @p TRUE the support for GPTD11 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM11) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM11 FALSE
-#endif
-
-/**
- * @brief GPTD12 driver enable switch.
- * @details If set to @p TRUE the support for GPTD12 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM12) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM12 FALSE
-#endif
-
-/**
- * @brief GPTD13 driver enable switch.
- * @details If set to @p TRUE the support for GPTD13 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM13) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM13 FALSE
-#endif
-
-/**
- * @brief GPTD14 driver enable switch.
- * @details If set to @p TRUE the support for GPTD14 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM14) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM14 FALSE
-#endif
-
-/**
- * @brief GPTD14 driver enable switch.
- * @details If set to @p TRUE the support for GPTD15 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM15) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM15 FALSE
-#endif
-
-/**
- * @brief GPTD14 driver enable switch.
- * @details If set to @p TRUE the support for GPTD16 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM16) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM16 FALSE
-#endif
-
-/**
- * @brief GPTD14 driver enable switch.
- * @details If set to @p TRUE the support for GPTD17 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM17) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM17 FALSE
-#endif
-
-/**
- * @brief GPTD21 driver enable switch.
- * @details If set to @p TRUE the support for GPTD21 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM21) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM21 FALSE
-#endif
-
-/**
- * @brief GPTD22 driver enable switch.
- * @details If set to @p TRUE the support for GPTD22 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_GPT_USE_TIM22) || defined(__DOXYGEN__)
-#define STM32_GPT_USE_TIM22 FALSE
-#endif
-
-/**
- * @brief GPTD1 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM1_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD2 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM2_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD3 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM3_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD4 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM4_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD5 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM5_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD6 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM6_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD7 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM7_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM7_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD8 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM8_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD9 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM9_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD10 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM10_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM10_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD11 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM11_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD12 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM12_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD13 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM13_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM13_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD14 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM14_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD15 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM15_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM15_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD16 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM16_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM16_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD17 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM17_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM17_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD21 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM21_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM21_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief GPTD22 interrupt priority level setting.
- */
-#if !defined(STM32_GPT_TIM22_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_GPT_TIM22_IRQ_PRIORITY 7
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_TIM1)
-#define STM32_HAS_TIM1 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM2)
-#define STM32_HAS_TIM2 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM3)
-#define STM32_HAS_TIM3 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM4)
-#define STM32_HAS_TIM4 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM5)
-#define STM32_HAS_TIM5 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM6)
-#define STM32_HAS_TIM6 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM7)
-#define STM32_HAS_TIM7 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM8)
-#define STM32_HAS_TIM8 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM9)
-#define STM32_HAS_TIM9 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM10)
-#define STM32_HAS_TIM10 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM11)
-#define STM32_HAS_TIM11 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM12)
-#define STM32_HAS_TIM12 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM13)
-#define STM32_HAS_TIM13 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM14)
-#define STM32_HAS_TIM14 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM15)
-#define STM32_HAS_TIM15 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM16)
-#define STM32_HAS_TIM16 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM17)
-#define STM32_HAS_TIM17 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM21)
-#define STM32_HAS_TIM21 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM22)
-#define STM32_HAS_TIM22 FALSE
-#endif
-
-#if STM32_GPT_USE_TIM1 && !STM32_HAS_TIM1
-#error "TIM1 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM2 && !STM32_HAS_TIM2
-#error "TIM2 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM3 && !STM32_HAS_TIM3
-#error "TIM3 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM4 && !STM32_HAS_TIM4
-#error "TIM4 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM5 && !STM32_HAS_TIM5
-#error "TIM5 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM6 && !STM32_HAS_TIM6
-#error "TIM6 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM7 && !STM32_HAS_TIM7
-#error "TIM7 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM8 && !STM32_HAS_TIM8
-#error "TIM8 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM9 && !STM32_HAS_TIM9
-#error "TIM9 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM10 && !STM32_HAS_TIM10
-#error "TIM10 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM11 && !STM32_HAS_TIM11
-#error "TIM11 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM12 && !STM32_HAS_TIM12
-#error "TIM12 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM13 && !STM32_HAS_TIM13
-#error "TIM13 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM14 && !STM32_HAS_TIM14
-#error "TIM14 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM15 && !STM32_HAS_TIM15
-#error "TIM15 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM16 && !STM32_HAS_TIM16
-#error "TIM16 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM17 && !STM32_HAS_TIM17
-#error "TIM17 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM21 && !STM32_HAS_TIM21
-#error "TIM21 not present in the selected device"
-#endif
-
-#if STM32_GPT_USE_TIM22 && !STM32_HAS_TIM22
-#error "TIM22 not present in the selected device"
-#endif
-
-#if !STM32_GPT_USE_TIM1 && !STM32_GPT_USE_TIM2 && \
- !STM32_GPT_USE_TIM3 && !STM32_GPT_USE_TIM4 && \
- !STM32_GPT_USE_TIM5 && !STM32_GPT_USE_TIM6 && \
- !STM32_GPT_USE_TIM7 && !STM32_GPT_USE_TIM8 && \
- !STM32_GPT_USE_TIM9 && !STM32_GPT_USE_TIM10 && \
- !STM32_GPT_USE_TIM11 && !STM32_GPT_USE_TIM12 && \
- !STM32_GPT_USE_TIM13 && !STM32_GPT_USE_TIM14 && \
- !STM32_GPT_USE_TIM15 && !STM32_GPT_USE_TIM16 && \
- !STM32_GPT_USE_TIM17 && \
- !STM32_GPT_USE_TIM21 && !STM32_GPT_USE_TIM22
-#error "GPT driver activated but no TIM peripheral assigned"
-#endif
-
-/* Checks on allocation of TIMx units.*/
-#if STM32_GPT_USE_TIM1
-#if defined(STM32_TIM1_IS_USED)
-#error "GPTD1 requires TIM1 but the timer is already used"
-#else
-#define STM32_TIM1_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM2
-#if defined(STM32_TIM2_IS_USED)
-#error "GPTD2 requires TIM2 but the timer is already used"
-#else
-#define STM32_TIM2_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM3
-#if defined(STM32_TIM3_IS_USED)
-#error "GPTD3 requires TIM3 but the timer is already used"
-#else
-#define STM32_TIM3_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM4
-#if defined(STM32_TIM4_IS_USED)
-#error "GPTD4 requires TIM4 but the timer is already used"
-#else
-#define STM32_TIM4_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM5
-#if defined(STM32_TIM5_IS_USED)
-#error "GPTD5 requires TIM5 but the timer is already used"
-#else
-#define STM32_TIM5_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM6
-#if defined(STM32_TIM6_IS_USED)
-#error "GPTD6 requires TIM6 but the timer is already used"
-#else
-#define STM32_TIM6_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM7
-#if defined(STM32_TIM7_IS_USED)
-#error "GPTD7 requires TIM7 but the timer is already used"
-#else
-#define STM32_TIM7_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM8
-#if defined(STM32_TIM8_IS_USED)
-#error "GPTD8 requires TIM8 but the timer is already used"
-#else
-#define STM32_TIM8_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM9
-#if defined(STM32_TIM9_IS_USED)
-#error "GPTD9 requires TIM9 but the timer is already used"
-#else
-#define STM32_TIM9_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM10
-#if defined(STM32_TIM10_IS_USED)
-#error "GPTD10 requires TIM10 but the timer is already used"
-#else
-#define STM32_TIM10_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM11
-#if defined(STM32_TIM11_IS_USED)
-#error "GPTD11 requires TIM11 but the timer is already used"
-#else
-#define STM32_TIM11_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM12
-#if defined(STM32_TIM12_IS_USED)
-#error "GPTD12 requires TIM12 but the timer is already used"
-#else
-#define STM32_TIM12_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM13
-#if defined(STM32_TIM13_IS_USED)
-#error "GPTD13 requires TIM13 but the timer is already used"
-#else
-#define STM32_TIM13_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM14
-#if defined(STM32_TIM14_IS_USED)
-#error "GPTD14 requires TIM14 but the timer is already used"
-#else
-#define STM32_TIM14_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM15
-#if defined(STM32_TIM15_IS_USED)
-#error "GPTD14 requires TIM15 but the timer is already used"
-#else
-#define STM32_TIM15_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM16
-#if defined(STM32_TIM16_IS_USED)
-#error "GPTD14 requires TIM16 but the timer is already used"
-#else
-#define STM32_TIM16_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM17
-#if defined(STM32_TIM17_IS_USED)
-#error "GPTD14 requires TIM17 but the timer is already used"
-#else
-#define STM32_TIM17_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM21
-#if defined(STM32_TIM21_IS_USED)
-#error "GPTD21 requires TIM21 but the timer is already used"
-#else
-#define STM32_TIM21_IS_USED
-#endif
-#endif
-
-#if STM32_GPT_USE_TIM22
-#if defined(STM32_TIM22_IS_USED)
-#error "GPTD22 requires TIM22 but the timer is already used"
-#else
-#define STM32_TIM22_IS_USED
-#endif
-#endif
-
-/* IRQ priority checks.*/
-#if STM32_GPT_USE_TIM1 && !defined(STM32_TIM1_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM1"
-#endif
-
-#if STM32_GPT_USE_TIM2 && !defined(STM32_TIM2_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM2"
-#endif
-
-#if STM32_GPT_USE_TIM3 && !defined(STM32_TIM3_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM3"
-#endif
-
-#if STM32_GPT_USE_TIM4 && !defined(STM32_TIM_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM4"
-#endif
-
-#if STM32_GPT_USE_TIM5 && !defined(STM32_TIM5_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM5"
-#endif
-
-#if STM32_GPT_USE_TIM6 && !defined(STM32_TIM6_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM6_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM6"
-#endif
-
-#if STM32_GPT_USE_TIM7 && !defined(STM32_TIM7_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM7_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM7"
-#endif
-
-#if STM32_GPT_USE_TIM8 && !defined(STM32_TIM8_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM8_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM8"
-#endif
-
-#if STM32_GPT_USE_TIM9 && !defined(STM32_TIM9_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM9_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM9"
-#endif
-
-#if STM32_GPT_USE_TIM10 && !defined(STM32_TIM10_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM10_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM10"
-#endif
-
-#if STM32_GPT_USE_TIM11 && !defined(STM32_TIM11_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM11_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM11"
-#endif
-
-#if STM32_GPT_USE_TIM12 && !defined(STM32_TIM12_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM12_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM12"
-#endif
-
-#if STM32_GPT_USE_TIM13 && !defined(STM32_TIM13_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM13_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM13"
-#endif
-
-#if STM32_GPT_USE_TIM14 && !defined(STM32_TIM14_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM14_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM14"
-#endif
-
-#if STM32_GPT_USE_TIM15 && !defined(STM32_TIM15_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM15_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM15"
-#endif
-
-#if STM32_GPT_USE_TIM16 && !defined(STM32_TIM16_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM16_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM16"
-#endif
-
-#if STM32_GPT_USE_TIM17 && !defined(STM32_TIM17_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM17_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM17"
-#endif
-
-#if STM32_GPT_USE_TIM21 && !defined(STM32_TIM21_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM21_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM21"
-#endif
-
-#if STM32_GPT_USE_TIM22 && !defined(STM32_TIM22_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM22_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM22"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief GPT frequency type.
- */
-typedef uint32_t gptfreq_t;
-
-/**
- * @brief GPT counter type.
- */
-typedef uint32_t gptcnt_t;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Timer clock in Hz.
- * @note The low level can use assertions in order to catch invalid
- * frequency specifications.
- */
- gptfreq_t frequency;
- /**
- * @brief Timer callback pointer.
- * @note This callback is invoked on GPT counter events.
- * @note This callback can be set to @p NULL but in that case the
- * one-shot mode cannot be used.
- */
- gptcallback_t callback;
- /* End of the mandatory fields.*/
- /**
- * @brief TIM CR2 register initialization data.
- * @note The value of this field should normally be equal to zero.
- */
- uint32_t cr2;
- /**
- * @brief TIM DIER register initialization data.
- * @note The value of this field should normally be equal to zero.
- * @note Only the DMA-related bits can be specified in this field.
- */
- uint32_t dier;
-} GPTConfig;
-
-/**
- * @brief Structure representing a GPT driver.
- */
-struct GPTDriver {
- /**
- * @brief Driver state.
- */
- gptstate_t state;
- /**
- * @brief Current configuration data.
- */
- const GPTConfig *config;
-#if defined(GPT_DRIVER_EXT_FIELDS)
- GPT_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Timer base clock.
- */
- uint32_t clock;
- /**
- * @brief Pointer to the TIMx registers block.
- */
- stm32_tim_t *tim;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Changes the interval of GPT peripheral.
- * @details This function changes the interval of a running GPT unit.
- * @pre The GPT unit must be running in continuous mode.
- * @post The GPT unit interval is changed to the new value.
- * @note The function has effect at the next cycle start.
- *
- * @param[in] gptp pointer to a @p GPTDriver object
- * @param[in] interval new cycle time in timer ticks
- *
- * @notapi
- */
-#define gpt_lld_change_interval(gptp, interval) \
- ((gptp)->tim->ARR = (uint32_t)((interval) - 1U))
-
-/**
- * @brief Returns the interval of GPT peripheral.
- * @pre The GPT unit must be running in continuous mode.
- *
- * @param[in] gptp pointer to a @p GPTDriver object
- * @return The current interval.
- *
- * @notapi
- */
-#define gpt_lld_get_interval(gptp) ((gptcnt_t)((gptp)->tim->ARR + 1U))
-
-/**
- * @brief Returns the counter value of GPT peripheral.
- * @pre The GPT unit must be running in continuous mode.
- * @note The nature of the counter is not defined, it may count upward
- * or downward, it could be continuously running or not.
- *
- * @param[in] gptp pointer to a @p GPTDriver object
- * @return The current counter value.
- *
- * @notapi
- */
-#define gpt_lld_get_counter(gptp) ((gptcnt_t)(gptp)->tim->CNT)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_GPT_USE_TIM1 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD1;
-#endif
-
-#if STM32_GPT_USE_TIM2 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD2;
-#endif
-
-#if STM32_GPT_USE_TIM3 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD3;
-#endif
-
-#if STM32_GPT_USE_TIM4 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD4;
-#endif
-
-#if STM32_GPT_USE_TIM5 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD5;
-#endif
-
-#if STM32_GPT_USE_TIM6 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD6;
-#endif
-
-#if STM32_GPT_USE_TIM7 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD7;
-#endif
-
-#if STM32_GPT_USE_TIM8 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD8;
-#endif
-
-#if STM32_GPT_USE_TIM9 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD9;
-#endif
-
-#if STM32_GPT_USE_TIM10 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD10;
-#endif
-
-#if STM32_GPT_USE_TIM11 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD11;
-#endif
-
-#if STM32_GPT_USE_TIM12 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD12;
-#endif
-
-#if STM32_GPT_USE_TIM13 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD13;
-#endif
-
-#if STM32_GPT_USE_TIM14 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD14;
-#endif
-
-#if STM32_GPT_USE_TIM15 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD15;
-#endif
-
-#if STM32_GPT_USE_TIM16 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD16;
-#endif
-
-#if STM32_GPT_USE_TIM17 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD17;
-#endif
-
-#if STM32_GPT_USE_TIM21 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD21;
-#endif
-
-#if STM32_GPT_USE_TIM22 && !defined(__DOXYGEN__)
-extern GPTDriver GPTD22;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void gpt_lld_init(void);
- void gpt_lld_start(GPTDriver *gptp);
- void gpt_lld_stop(GPTDriver *gptp);
- void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
- void gpt_lld_stop_timer(GPTDriver *gptp);
- void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
- void gpt_lld_serve_interrupt(GPTDriver *gptp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_GPT */
-
-#endif /* HAL_GPT_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 TIMv1/hal_gpt_lld.h
+ * @brief STM32 GPT subsystem low level driver header.
+ *
+ * @addtogroup GPT
+ * @{
+ */
+
+#ifndef HAL_GPT_LLD_H
+#define HAL_GPT_LLD_H
+
+#include "stm32_tim.h"
+
+#if HAL_USE_GPT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief GPTD1 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM1 FALSE
+#endif
+
+/**
+ * @brief GPTD2 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM2 FALSE
+#endif
+
+/**
+ * @brief GPTD3 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM3 FALSE
+#endif
+
+/**
+ * @brief GPTD4 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM4 FALSE
+#endif
+
+/**
+ * @brief GPTD5 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM5 FALSE
+#endif
+
+/**
+ * @brief GPTD6 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM6) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM6 FALSE
+#endif
+
+/**
+ * @brief GPTD7 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD7 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM7) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM7 FALSE
+#endif
+
+/**
+ * @brief GPTD8 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM8) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM8 FALSE
+#endif
+
+/**
+ * @brief GPTD9 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD9 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM9) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM9 FALSE
+#endif
+
+/**
+ * @brief GPTD10 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD10 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM10) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM10 FALSE
+#endif
+
+/**
+ * @brief GPTD11 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD11 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM11) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM11 FALSE
+#endif
+
+/**
+ * @brief GPTD12 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD12 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM12) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM12 FALSE
+#endif
+
+/**
+ * @brief GPTD13 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD13 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM13) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM13 FALSE
+#endif
+
+/**
+ * @brief GPTD14 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD14 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM14) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM14 FALSE
+#endif
+
+/**
+ * @brief GPTD14 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD15 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM15) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM15 FALSE
+#endif
+
+/**
+ * @brief GPTD14 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD16 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM16) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM16 FALSE
+#endif
+
+/**
+ * @brief GPTD14 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD17 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM17) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM17 FALSE
+#endif
+
+/**
+ * @brief GPTD21 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD21 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM21) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM21 FALSE
+#endif
+
+/**
+ * @brief GPTD22 driver enable switch.
+ * @details If set to @p TRUE the support for GPTD22 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_GPT_USE_TIM22) || defined(__DOXYGEN__)
+#define STM32_GPT_USE_TIM22 FALSE
+#endif
+
+/**
+ * @brief GPTD1 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD2 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD3 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD4 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD5 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM5_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD6 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM6_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD7 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM7_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM7_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD8 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM8_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD9 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM9_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD10 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM10_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM10_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD11 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM11_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD12 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM12_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD13 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM13_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM13_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD14 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM14_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD15 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM15_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM15_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD16 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM16_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM16_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD17 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM17_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM17_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD21 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM21_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM21_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief GPTD22 interrupt priority level setting.
+ */
+#if !defined(STM32_GPT_TIM22_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_GPT_TIM22_IRQ_PRIORITY 7
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_TIM1)
+#define STM32_HAS_TIM1 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM2)
+#define STM32_HAS_TIM2 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM3)
+#define STM32_HAS_TIM3 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM4)
+#define STM32_HAS_TIM4 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM5)
+#define STM32_HAS_TIM5 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM6)
+#define STM32_HAS_TIM6 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM7)
+#define STM32_HAS_TIM7 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM8)
+#define STM32_HAS_TIM8 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM9)
+#define STM32_HAS_TIM9 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM10)
+#define STM32_HAS_TIM10 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM11)
+#define STM32_HAS_TIM11 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM12)
+#define STM32_HAS_TIM12 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM13)
+#define STM32_HAS_TIM13 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM14)
+#define STM32_HAS_TIM14 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM15)
+#define STM32_HAS_TIM15 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM16)
+#define STM32_HAS_TIM16 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM17)
+#define STM32_HAS_TIM17 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM21)
+#define STM32_HAS_TIM21 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM22)
+#define STM32_HAS_TIM22 FALSE
+#endif
+
+#if STM32_GPT_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM6 && !STM32_HAS_TIM6
+#error "TIM6 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM7 && !STM32_HAS_TIM7
+#error "TIM7 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM8 && !STM32_HAS_TIM8
+#error "TIM8 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM9 && !STM32_HAS_TIM9
+#error "TIM9 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM10 && !STM32_HAS_TIM10
+#error "TIM10 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM11 && !STM32_HAS_TIM11
+#error "TIM11 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM12 && !STM32_HAS_TIM12
+#error "TIM12 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM13 && !STM32_HAS_TIM13
+#error "TIM13 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM14 && !STM32_HAS_TIM14
+#error "TIM14 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM15 && !STM32_HAS_TIM15
+#error "TIM15 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM16 && !STM32_HAS_TIM16
+#error "TIM16 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM17 && !STM32_HAS_TIM17
+#error "TIM17 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM21 && !STM32_HAS_TIM21
+#error "TIM21 not present in the selected device"
+#endif
+
+#if STM32_GPT_USE_TIM22 && !STM32_HAS_TIM22
+#error "TIM22 not present in the selected device"
+#endif
+
+#if !STM32_GPT_USE_TIM1 && !STM32_GPT_USE_TIM2 && \
+ !STM32_GPT_USE_TIM3 && !STM32_GPT_USE_TIM4 && \
+ !STM32_GPT_USE_TIM5 && !STM32_GPT_USE_TIM6 && \
+ !STM32_GPT_USE_TIM7 && !STM32_GPT_USE_TIM8 && \
+ !STM32_GPT_USE_TIM9 && !STM32_GPT_USE_TIM10 && \
+ !STM32_GPT_USE_TIM11 && !STM32_GPT_USE_TIM12 && \
+ !STM32_GPT_USE_TIM13 && !STM32_GPT_USE_TIM14 && \
+ !STM32_GPT_USE_TIM15 && !STM32_GPT_USE_TIM16 && \
+ !STM32_GPT_USE_TIM17 && \
+ !STM32_GPT_USE_TIM21 && !STM32_GPT_USE_TIM22
+#error "GPT driver activated but no TIM peripheral assigned"
+#endif
+
+/* Checks on allocation of TIMx units.*/
+#if STM32_GPT_USE_TIM1
+#if defined(STM32_TIM1_IS_USED)
+#error "GPTD1 requires TIM1 but the timer is already used"
+#else
+#define STM32_TIM1_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM2
+#if defined(STM32_TIM2_IS_USED)
+#error "GPTD2 requires TIM2 but the timer is already used"
+#else
+#define STM32_TIM2_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM3
+#if defined(STM32_TIM3_IS_USED)
+#error "GPTD3 requires TIM3 but the timer is already used"
+#else
+#define STM32_TIM3_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM4
+#if defined(STM32_TIM4_IS_USED)
+#error "GPTD4 requires TIM4 but the timer is already used"
+#else
+#define STM32_TIM4_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM5
+#if defined(STM32_TIM5_IS_USED)
+#error "GPTD5 requires TIM5 but the timer is already used"
+#else
+#define STM32_TIM5_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM6
+#if defined(STM32_TIM6_IS_USED)
+#error "GPTD6 requires TIM6 but the timer is already used"
+#else
+#define STM32_TIM6_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM7
+#if defined(STM32_TIM7_IS_USED)
+#error "GPTD7 requires TIM7 but the timer is already used"
+#else
+#define STM32_TIM7_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM8
+#if defined(STM32_TIM8_IS_USED)
+#error "GPTD8 requires TIM8 but the timer is already used"
+#else
+#define STM32_TIM8_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM9
+#if defined(STM32_TIM9_IS_USED)
+#error "GPTD9 requires TIM9 but the timer is already used"
+#else
+#define STM32_TIM9_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM10
+#if defined(STM32_TIM10_IS_USED)
+#error "GPTD10 requires TIM10 but the timer is already used"
+#else
+#define STM32_TIM10_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM11
+#if defined(STM32_TIM11_IS_USED)
+#error "GPTD11 requires TIM11 but the timer is already used"
+#else
+#define STM32_TIM11_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM12
+#if defined(STM32_TIM12_IS_USED)
+#error "GPTD12 requires TIM12 but the timer is already used"
+#else
+#define STM32_TIM12_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM13
+#if defined(STM32_TIM13_IS_USED)
+#error "GPTD13 requires TIM13 but the timer is already used"
+#else
+#define STM32_TIM13_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM14
+#if defined(STM32_TIM14_IS_USED)
+#error "GPTD14 requires TIM14 but the timer is already used"
+#else
+#define STM32_TIM14_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM15
+#if defined(STM32_TIM15_IS_USED)
+#error "GPTD14 requires TIM15 but the timer is already used"
+#else
+#define STM32_TIM15_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM16
+#if defined(STM32_TIM16_IS_USED)
+#error "GPTD14 requires TIM16 but the timer is already used"
+#else
+#define STM32_TIM16_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM17
+#if defined(STM32_TIM17_IS_USED)
+#error "GPTD14 requires TIM17 but the timer is already used"
+#else
+#define STM32_TIM17_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM21
+#if defined(STM32_TIM21_IS_USED)
+#error "GPTD21 requires TIM21 but the timer is already used"
+#else
+#define STM32_TIM21_IS_USED
+#endif
+#endif
+
+#if STM32_GPT_USE_TIM22
+#if defined(STM32_TIM22_IS_USED)
+#error "GPTD22 requires TIM22 but the timer is already used"
+#else
+#define STM32_TIM22_IS_USED
+#endif
+#endif
+
+/* IRQ priority checks.*/
+#if STM32_GPT_USE_TIM1 && !defined(STM32_TIM1_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM1"
+#endif
+
+#if STM32_GPT_USE_TIM2 && !defined(STM32_TIM2_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM2"
+#endif
+
+#if STM32_GPT_USE_TIM3 && !defined(STM32_TIM3_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM3"
+#endif
+
+#if STM32_GPT_USE_TIM4 && !defined(STM32_TIM_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM4"
+#endif
+
+#if STM32_GPT_USE_TIM5 && !defined(STM32_TIM5_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM5"
+#endif
+
+#if STM32_GPT_USE_TIM6 && !defined(STM32_TIM6_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM6"
+#endif
+
+#if STM32_GPT_USE_TIM7 && !defined(STM32_TIM7_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM7_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM7"
+#endif
+
+#if STM32_GPT_USE_TIM8 && !defined(STM32_TIM8_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM8_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM8"
+#endif
+
+#if STM32_GPT_USE_TIM9 && !defined(STM32_TIM9_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM9_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM9"
+#endif
+
+#if STM32_GPT_USE_TIM10 && !defined(STM32_TIM10_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM10_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM10"
+#endif
+
+#if STM32_GPT_USE_TIM11 && !defined(STM32_TIM11_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM11_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM11"
+#endif
+
+#if STM32_GPT_USE_TIM12 && !defined(STM32_TIM12_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM12_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM12"
+#endif
+
+#if STM32_GPT_USE_TIM13 && !defined(STM32_TIM13_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM13_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM13"
+#endif
+
+#if STM32_GPT_USE_TIM14 && !defined(STM32_TIM14_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM14_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM14"
+#endif
+
+#if STM32_GPT_USE_TIM15 && !defined(STM32_TIM15_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM15_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM15"
+#endif
+
+#if STM32_GPT_USE_TIM16 && !defined(STM32_TIM16_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM16_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM16"
+#endif
+
+#if STM32_GPT_USE_TIM17 && !defined(STM32_TIM17_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM17_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM17"
+#endif
+
+#if STM32_GPT_USE_TIM21 && !defined(STM32_TIM21_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM21_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM21"
+#endif
+
+#if STM32_GPT_USE_TIM22 && !defined(STM32_TIM22_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_GPT_TIM22_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM22"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief GPT frequency type.
+ */
+typedef uint32_t gptfreq_t;
+
+/**
+ * @brief GPT counter type.
+ */
+typedef uint32_t gptcnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ gptfreq_t frequency;
+ /**
+ * @brief Timer callback pointer.
+ * @note This callback is invoked on GPT counter events.
+ * @note This callback can be set to @p NULL but in that case the
+ * one-shot mode cannot be used.
+ */
+ gptcallback_t callback;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief TIM CR2 register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */
+ uint32_t cr2;
+ /**
+ * @brief TIM DIER register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ * @note Only the DMA-related bits can be specified in this field.
+ */
+ uint32_t dier;
+} GPTConfig;
+
+/**
+ * @brief Structure representing a GPT driver.
+ */
+struct GPTDriver {
+ /**
+ * @brief Driver state.
+ */
+ gptstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const GPTConfig *config;
+#if defined(GPT_DRIVER_EXT_FIELDS)
+ GPT_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ stm32_tim_t *tim;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Changes the interval of GPT peripheral.
+ * @details This function changes the interval of a running GPT unit.
+ * @pre The GPT unit must be running in continuous mode.
+ * @post The GPT unit interval is changed to the new value.
+ * @note The function has effect at the next cycle start.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ * @param[in] interval new cycle time in timer ticks
+ *
+ * @notapi
+ */
+#define gpt_lld_change_interval(gptp, interval) \
+ ((gptp)->tim->ARR = (uint32_t)((interval) - 1U))
+
+/**
+ * @brief Returns the interval of GPT peripheral.
+ * @pre The GPT unit must be running in continuous mode.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ * @return The current interval.
+ *
+ * @notapi
+ */
+#define gpt_lld_get_interval(gptp) ((gptcnt_t)((gptp)->tim->ARR + 1U))
+
+/**
+ * @brief Returns the counter value of GPT peripheral.
+ * @pre The GPT unit must be running in continuous mode.
+ * @note The nature of the counter is not defined, it may count upward
+ * or downward, it could be continuously running or not.
+ *
+ * @param[in] gptp pointer to a @p GPTDriver object
+ * @return The current counter value.
+ *
+ * @notapi
+ */
+#define gpt_lld_get_counter(gptp) ((gptcnt_t)(gptp)->tim->CNT)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_GPT_USE_TIM1 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD1;
+#endif
+
+#if STM32_GPT_USE_TIM2 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD2;
+#endif
+
+#if STM32_GPT_USE_TIM3 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD3;
+#endif
+
+#if STM32_GPT_USE_TIM4 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD4;
+#endif
+
+#if STM32_GPT_USE_TIM5 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD5;
+#endif
+
+#if STM32_GPT_USE_TIM6 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD6;
+#endif
+
+#if STM32_GPT_USE_TIM7 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD7;
+#endif
+
+#if STM32_GPT_USE_TIM8 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD8;
+#endif
+
+#if STM32_GPT_USE_TIM9 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD9;
+#endif
+
+#if STM32_GPT_USE_TIM10 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD10;
+#endif
+
+#if STM32_GPT_USE_TIM11 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD11;
+#endif
+
+#if STM32_GPT_USE_TIM12 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD12;
+#endif
+
+#if STM32_GPT_USE_TIM13 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD13;
+#endif
+
+#if STM32_GPT_USE_TIM14 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD14;
+#endif
+
+#if STM32_GPT_USE_TIM15 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD15;
+#endif
+
+#if STM32_GPT_USE_TIM16 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD16;
+#endif
+
+#if STM32_GPT_USE_TIM17 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD17;
+#endif
+
+#if STM32_GPT_USE_TIM21 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD21;
+#endif
+
+#if STM32_GPT_USE_TIM22 && !defined(__DOXYGEN__)
+extern GPTDriver GPTD22;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void gpt_lld_init(void);
+ void gpt_lld_start(GPTDriver *gptp);
+ void gpt_lld_stop(GPTDriver *gptp);
+ void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
+ void gpt_lld_stop_timer(GPTDriver *gptp);
+ void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
+ void gpt_lld_serve_interrupt(GPTDriver *gptp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_GPT */
+
+#endif /* HAL_GPT_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
index e9a669dd66..cd3781a4f5 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.c
@@ -1,1135 +1,1135 @@
-/*
- 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 Fabio Utzig and
- Xo Wang.
- */
-
-/**
- * @file TIMv1/hal_icu_lld.c
- * @brief STM32 ICU subsystem low level driver header.
- *
- * @addtogroup ICU
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ICU || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief ICUD1 driver identifier.
- * @note The driver ICUD1 allocates the complex timer TIM1 when enabled.
- */
-#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
-ICUDriver ICUD1;
-#endif
-
-/**
- * @brief ICUD2 driver identifier.
- * @note The driver ICUD1 allocates the timer TIM2 when enabled.
- */
-#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
-ICUDriver ICUD2;
-#endif
-
-/**
- * @brief ICUD3 driver identifier.
- * @note The driver ICUD1 allocates the timer TIM3 when enabled.
- */
-#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
-ICUDriver ICUD3;
-#endif
-
-/**
- * @brief ICUD4 driver identifier.
- * @note The driver ICUD4 allocates the timer TIM4 when enabled.
- */
-#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
-ICUDriver ICUD4;
-#endif
-
-/**
- * @brief ICUD5 driver identifier.
- * @note The driver ICUD5 allocates the timer TIM5 when enabled.
- */
-#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
-ICUDriver ICUD5;
-#endif
-
-/**
- * @brief ICUD8 driver identifier.
- * @note The driver ICUD8 allocates the timer TIM8 when enabled.
- */
-#if STM32_ICU_USE_TIM8 || defined(__DOXYGEN__)
-ICUDriver ICUD8;
-#endif
-
-/**
- * @brief ICUD9 driver identifier.
- * @note The driver ICUD9 allocates the timer TIM9 when enabled.
- */
-#if STM32_ICU_USE_TIM9 || defined(__DOXYGEN__)
-ICUDriver ICUD9;
-#endif
-
-/**
- * @brief ICUD10 driver identifier.
- * @note The driver ICUD10 allocates the timer TIM10 when enabled.
- */
-#if STM32_ICU_USE_TIM10 || defined(__DOXYGEN__)
-ICUDriver ICUD10;
-#endif
-
-/**
- * @brief ICUD11 driver identifier.
- * @note The driver ICUD11 allocates the timer TIM11 when enabled.
- */
-#if STM32_ICU_USE_TIM11 || defined(__DOXYGEN__)
-ICUDriver ICUD11;
-#endif
-
-/**
- * @brief ICUD12 driver identifier.
- * @note The driver ICUD12 allocates the timer TIM12 when enabled.
- */
-#if STM32_ICU_USE_TIM12 || defined(__DOXYGEN__)
-ICUDriver ICUD12;
-#endif
-
-/**
- * @brief ICUD13 driver identifier.
- * @note The driver ICUD13 allocates the timer TIM13 when enabled.
- */
-#if STM32_ICU_USE_TIM13 || defined(__DOXYGEN__)
-ICUDriver ICUD13;
-#endif
-
-/**
- * @brief ICUD14 driver identifier.
- * @note The driver ICUD14 allocates the timer TIM14 when enabled.
- */
-#if STM32_ICU_USE_TIM14 || defined(__DOXYGEN__)
-ICUDriver ICUD14;
-#endif
-
-/**
- * @brief ICUD15 driver identifier.
- * @note The driver ICUD15 allocates the timer TIM15 when enabled.
- */
-#if STM32_ICU_USE_TIM15 || defined(__DOXYGEN__)
-ICUDriver ICUD15;
-#endif
-
-/**
- * @brief ICUD20 driver identifier.
- * @note The driver ICUD20 allocates the timer TIM20 when enabled.
- */
-#if STM32_ICU_USE_TIM20 || defined(__DOXYGEN__)
-ICUDriver ICUD20;
-#endif
-
-/**
- * @brief ICUD21 driver identifier.
- * @note The driver ICUD21 allocates the timer TIM21 when enabled.
- */
-#if STM32_ICU_USE_TIM21 || defined(__DOXYGEN__)
-ICUDriver ICUD21;
-#endif
-
-/**
- * @brief ICUD22 driver identifier.
- * @note The driver ICUD22 allocates the timer TIM22 when enabled.
- */
-#if STM32_ICU_USE_TIM22 || defined(__DOXYGEN__)
-ICUDriver ICUD22;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-static bool icu_lld_wait_edge(ICUDriver *icup) {
- uint32_t sr;
- bool result;
-
- /* Polled mode so re-enabling the interrupts while the operation is
- performed.*/
- osalSysUnlock();
-
- /* Polling the right bit depending on the input channel.*/
- if (icup->config->channel == ICU_CHANNEL_1) {
- /* Waiting for an edge.*/
- while (((sr = icup->tim->SR) &
- (STM32_TIM_SR_CC1IF | STM32_TIM_SR_UIF)) == 0)
- ;
- }
- else {
- /* Waiting for an edge.*/
- while (((sr = icup->tim->SR) &
- (STM32_TIM_SR_CC2IF | STM32_TIM_SR_UIF)) == 0)
- ;
- }
-
- /* Edge or overflow?*/
- result = (sr & STM32_TIM_SR_UIF) != 0 ? true : false;
-
- /* Done, disabling interrupts again.*/
- osalSysLock();
-
- /* Resetting all flags.*/
- icup->tim->SR &= ~(STM32_TIM_SR_CC1IF |
- STM32_TIM_SR_CC2IF |
- STM32_TIM_SR_UIF);
-
- return result;
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
-#if !defined(STM32_TIM1_UP_HANDLER)
-#error "STM32_TIM1_UP_HANDLER not defined"
-#endif
-/**
- * @brief TIM1 compare interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#if !defined(STM32_TIM1_CC_HANDLER)
-#error "STM32_TIM1_CC_HANDLER not defined"
-#endif
-/**
- * @brief TIM1 compare interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM1 */
-
-#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
-#if !defined(STM32_TIM2_HANDLER)
-#error "STM32_TIM2_HANDLER not defined"
-#endif
-/**
- * @brief TIM2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM2 */
-
-#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
-#if !defined(STM32_TIM3_HANDLER)
-#error "STM32_TIM3_HANDLER not defined"
-#endif
-/**
- * @brief TIM3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM3 */
-
-#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
-#if !defined(STM32_TIM4_HANDLER)
-#error "STM32_TIM4_HANDLER not defined"
-#endif
-/**
- * @brief TIM4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM4 */
-
-#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
-#if !defined(STM32_TIM5_HANDLER)
-#error "STM32_TIM5_HANDLER not defined"
-#endif
-/**
- * @brief TIM5 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM5 */
-
-#if STM32_ICU_USE_TIM8 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
-#if !defined(STM32_TIM8_UP_HANDLER)
-#error "STM32_TIM8_UP_HANDLER not defined"
-#endif
-/**
- * @brief TIM8 compare interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#if !defined(STM32_TIM8_CC_HANDLER)
-#error "STM32_TIM8_CC_HANDLER not defined"
-#endif
-/**
- * @brief TIM8 compare interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- icu_lld_serve_interrupt(&ICUD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM8 */
-
-#if STM32_ICU_USE_TIM9 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM9_SUPPRESS_ISR)
-#error "TIM9 ISR not defined by platform"
-#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM9 */
-
-#if STM32_ICU_USE_TIM10 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM10_SUPPRESS_ISR)
-#error "TIM10 ISR not defined by platform"
-#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM10 */
-
-#if STM32_ICU_USE_TIM11 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM11_SUPPRESS_ISR)
-#error "TIM11 ISR not defined by platform"
-#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM11 */
-
-#if STM32_ICU_USE_TIM12 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM12_SUPPRESS_ISR)
-#error "TIM12 ISR not defined by platform"
-#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM12 */
-
-#if STM32_ICU_USE_TIM13 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM13_SUPPRESS_ISR)
-#error "TIM13 ISR not defined by platform"
-#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM13 */
-
-#if STM32_ICU_USE_TIM14 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM14_SUPPRESS_ISR)
-#error "TIM14 ISR not defined by platform"
-#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM14 */
-
-#if STM32_ICU_USE_TIM15 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM15_SUPPRESS_ISR)
-#error "TIM15 ISR not defined by platform"
-#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM15 */
-
-#if STM32_ICU_USE_TIM20 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM20_SUPPRESS_ISR)
-#error "TIM20 ISR not defined by platform"
-#endif /* !defined(STM32_TIM20_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM20 */
-
-#if STM32_ICU_USE_TIM21 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM21_SUPPRESS_ISR)
-#error "TIM21 ISR not defined by platform"
-#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM21 */
-
-#if STM32_ICU_USE_TIM22 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM22_SUPPRESS_ISR)
-#error "TIM22 ISR not defined by platform"
-#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */
-#endif /* STM32_ICU_USE_TIM22 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ICU driver initialization.
- *
- * @notapi
- */
-void icu_lld_init(void) {
-
-#if STM32_ICU_USE_TIM1
- /* Driver initialization.*/
- icuObjectInit(&ICUD1);
- ICUD1.tim = STM32_TIM1;
-#endif
-
-#if STM32_ICU_USE_TIM2
- /* Driver initialization.*/
- icuObjectInit(&ICUD2);
- ICUD2.tim = STM32_TIM2;
-#endif
-
-#if STM32_ICU_USE_TIM3
- /* Driver initialization.*/
- icuObjectInit(&ICUD3);
- ICUD3.tim = STM32_TIM3;
-#endif
-
-#if STM32_ICU_USE_TIM4
- /* Driver initialization.*/
- icuObjectInit(&ICUD4);
- ICUD4.tim = STM32_TIM4;
-#endif
-
-#if STM32_ICU_USE_TIM5
- /* Driver initialization.*/
- icuObjectInit(&ICUD5);
- ICUD5.tim = STM32_TIM5;
-#endif
-
-#if STM32_ICU_USE_TIM8
- /* Driver initialization.*/
- icuObjectInit(&ICUD8);
- ICUD8.tim = STM32_TIM8;
-#endif
-
-#if STM32_ICU_USE_TIM9
- /* Driver initialization.*/
- icuObjectInit(&ICUD9);
- ICUD9.tim = STM32_TIM9;
-#endif
-
-#if STM32_ICU_USE_TIM10
- /* Driver initialization.*/
- icuObjectInit(&ICUD10);
- ICUD10.tim = STM32_TIM10;
-#endif
-
-#if STM32_ICU_USE_TIM11
- /* Driver initialization.*/
- icuObjectInit(&ICUD11);
- ICUD11.tim = STM32_TIM11;
-#endif
-
-#if STM32_ICU_USE_TIM12
- /* Driver initialization.*/
- icuObjectInit(&ICUD12);
- ICUD12.tim = STM32_TIM12;
-#endif
-
-#if STM32_ICU_USE_TIM13
- /* Driver initialization.*/
- icuObjectInit(&ICUD13);
- ICUD13.tim = STM32_TIM13;
-#endif
-
-#if STM32_ICU_USE_TIM14
- /* Driver initialization.*/
- icuObjectInit(&ICUD14);
- ICUD14.tim = STM32_TIM14;
-#endif
-
-#if STM32_ICU_USE_TIM15
- /* Driver initialization.*/
- icuObjectInit(&ICUD15);
- ICUD15.tim = STM32_TIM15;
-#endif
-
-#if STM32_ICU_USE_TIM20
- /* Driver initialization.*/
- icuObjectInit(&ICUD20);
- ICUD20.tim = STM32_TIM20;
-#endif
-
-#if STM32_ICU_USE_TIM21
- /* Driver initialization.*/
- icuObjectInit(&ICUD21);
- ICUD21.tim = STM32_TIM21;
-#endif
-
-#if STM32_ICU_USE_TIM22
- /* Driver initialization.*/
- icuObjectInit(&ICUD22);
- ICUD22.tim = STM32_TIM22;
-#endif
-}
-
-/**
- * @brief Configures and activates the ICU peripheral.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_start(ICUDriver *icup) {
- uint32_t psc;
-
- osalDbgAssert((icup->config->channel == ICU_CHANNEL_1) ||
- (icup->config->channel == ICU_CHANNEL_2),
- "invalid input");
-
- if (icup->state == ICU_STOP) {
- /* Clock activation and timer reset.*/
-#if STM32_ICU_USE_TIM1
- if (&ICUD1 == icup) {
- rccEnableTIM1(true);
- rccResetTIM1();
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
- nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM1CLK)
- icup->clock = STM32_TIM1CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM2
- if (&ICUD2 == icup) {
- rccEnableTIM2(true);
- rccResetTIM2();
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM2_NUMBER, STM32_ICU_TIM2_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM2CLK)
- icup->clock = STM32_TIM2CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM3
- if (&ICUD3 == icup) {
- rccEnableTIM3(true);
- rccResetTIM3();
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM3_NUMBER, STM32_ICU_TIM3_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM3CLK)
- icup->clock = STM32_TIM3CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM4
- if (&ICUD4 == icup) {
- rccEnableTIM4(true);
- rccResetTIM4();
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM4_NUMBER, STM32_ICU_TIM4_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM4CLK)
- icup->clock = STM32_TIM4CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM5
- if (&ICUD5 == icup) {
- rccEnableTIM5(true);
- rccResetTIM5();
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM5_NUMBER, STM32_ICU_TIM5_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM5CLK)
- icup->clock = STM32_TIM5CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM8
- if (&ICUD8 == icup) {
- rccEnableTIM8(true);
- rccResetTIM8();
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
- nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM8CLK)
- icup->clock = STM32_TIM8CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM9
- if (&ICUD9 == icup) {
- rccEnableTIM9(true);
- rccResetTIM9();
-#if defined(STM32_TIM9CLK)
- icup->clock = STM32_TIM9CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM10
- if (&ICUD10 == icup) {
- rccEnableTIM10(true);
- rccResetTIM10();
-#if defined(STM32_TIM10CLK)
- icup->clock = STM32_TIM10CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM11
- if (&ICUD11 == icup) {
- rccEnableTIM11(true);
- rccResetTIM11();
-#if defined(STM32_TIM11CLK)
- icup->clock = STM32_TIM11CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM12
- if (&ICUD12 == icup) {
- rccEnableTIM12(true);
- rccResetTIM12();
-#if defined(STM32_TIM12CLK)
- icup->clock = STM32_TIM12CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM13
- if (&ICUD13 == icup) {
- rccEnableTIM13(true);
- rccResetTIM13();
-#if defined(STM32_TIM13CLK)
- icup->clock = STM32_TIM13CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM14
- if (&ICUD14 == icup) {
- rccEnableTIM14(true);
- rccResetTIM14();
-#if defined(STM32_TIM14CLK)
- icup->clock = STM32_TIM14CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM15
- if (&ICUD15 == icup) {
- rccEnableTIM15(true);
- rccResetTIM15();
-#if defined(STM32_TIM15CLK)
- icup->clock = STM32_TIM15CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM20
- if (&ICUD20 == icup) {
- rccEnableTIM20(true);
- rccResetTIM20();
-#if defined(STM32_TIM20CLK)
- icup->clock = STM32_TIM20CLK;
-#else
- icup->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM21
- if (&ICUD21 == icup) {
- rccEnableTIM21(true);
- rccResetTIM21();
-#if defined(STM32_TIM21CLK)
- icup->clock = STM32_TIM21CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_ICU_USE_TIM22
- if (&ICUD22 == icup) {
- rccEnableTIM22(true);
- rccResetTIM22();
-#if defined(STM32_TIM22CLK)
- icup->clock = STM32_TIM22CLK;
-#else
- icup->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
- }
- else {
- /* Driver re-configuration scenario, it must be stopped first.*/
- icup->tim->CR1 = 0; /* Timer disabled. */
- icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */
- icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */
- icup->tim->CNT = 0; /* Counter reset to zero. */
- }
-
- /* Timer configuration.*/
- icup->tim->SR = 0; /* Clear eventual pending IRQs. */
- icup->tim->DIER = icup->config->dier & /* DMA-related DIER settings. */
- ~STM32_TIM_DIER_IRQ_MASK;
- psc = (icup->clock / icup->config->frequency) - 1;
- osalDbgAssert((psc <= 0xFFFF) &&
- ((psc + 1) * icup->config->frequency) == icup->clock,
- "invalid frequency");
- icup->tim->PSC = psc;
- if (icup->config->arr == 0U) {
- /* Zero is an invalid value and is turned in maximum value, also for
- legacy configurations compatibility.*/
- icup->tim->ARR = 0xFFFFFFFFU;
- }
- else {
- icup->tim->ARR = icup->config->arr;
- }
-
- if (icup->config->channel == ICU_CHANNEL_1) {
- /* Selected input 1.
- CCMR1_CC1S = 01 = CH1 Input on TI1.
- CCMR1_CC2S = 10 = CH2 Input on TI1.*/
- icup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(1) | STM32_TIM_CCMR1_CC2S(2);
-
- /* SMCR_TS = 101, input is TI1FP1.
- SMCR_SMS = 100, reset on rising edge.*/
- icup->tim->SMCR = STM32_TIM_SMCR_TS(5) | STM32_TIM_SMCR_SMS(4);
-
- /* The CCER settings depend on the selected trigger mode.
- ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
- ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
- if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
- icup->tim->CCER = STM32_TIM_CCER_CC1E |
- STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P;
- else
- icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P |
- STM32_TIM_CCER_CC2E;
-
- /* Direct pointers to the capture registers in order to make reading
- data faster from within callbacks.*/
- icup->wccrp = &icup->tim->CCR[1];
- icup->pccrp = &icup->tim->CCR[0];
- }
- else {
- /* Selected input 2.
- CCMR1_CC1S = 10 = CH1 Input on TI2.
- CCMR1_CC2S = 01 = CH2 Input on TI2.*/
- icup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(2) | STM32_TIM_CCMR1_CC2S(1);
-
- /* SMCR_TS = 110, input is TI2FP2.
- SMCR_SMS = 100, reset on rising edge.*/
- icup->tim->SMCR = STM32_TIM_SMCR_TS(6) | STM32_TIM_SMCR_SMS(4);
-
- /* The CCER settings depend on the selected trigger mode.
- ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
- ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
- if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
- icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P |
- STM32_TIM_CCER_CC2E;
- else
- icup->tim->CCER = STM32_TIM_CCER_CC1E |
- STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P;
-
- /* Direct pointers to the capture registers in order to make reading
- data faster from within callbacks.*/
- icup->wccrp = &icup->tim->CCR[0];
- icup->pccrp = &icup->tim->CCR[1];
- }
-}
-
-/**
- * @brief Deactivates the ICU peripheral.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_stop(ICUDriver *icup) {
-
- if (icup->state == ICU_READY) {
- /* Clock deactivation.*/
- icup->tim->CR1 = 0; /* Timer disabled. */
- icup->tim->DIER = 0; /* All IRQs disabled. */
- icup->tim->SR = 0; /* Clear eventual pending IRQs. */
-
-#if STM32_ICU_USE_TIM1
- if (&ICUD1 == icup) {
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM1_UP_NUMBER);
- nvicDisableVector(STM32_TIM1_CC_NUMBER);
-#endif
- rccDisableTIM1();
- }
-#endif
-
-#if STM32_ICU_USE_TIM2
- if (&ICUD2 == icup) {
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM2_NUMBER);
-#endif
- rccDisableTIM2();
- }
-#endif
-
-#if STM32_ICU_USE_TIM3
- if (&ICUD3 == icup) {
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM3_NUMBER);
-#endif
- rccDisableTIM3();
- }
-#endif
-
-#if STM32_ICU_USE_TIM4
- if (&ICUD4 == icup) {
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM4_NUMBER);
-#endif
- rccDisableTIM4();
- }
-#endif
-
-#if STM32_ICU_USE_TIM5
- if (&ICUD5 == icup) {
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM5_NUMBER);
-#endif
- rccDisableTIM5();
- }
-#endif
-
-#if STM32_ICU_USE_TIM8
- if (&ICUD8 == icup) {
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM8_UP_NUMBER);
- nvicDisableVector(STM32_TIM8_CC_NUMBER);
-#endif
- rccDisableTIM8();
- }
-#endif
-
-#if STM32_ICU_USE_TIM9
- if (&ICUD9 == icup) {
- rccDisableTIM9();
- }
-#endif
-
-#if STM32_ICU_USE_TIM10
- if (&ICUD10 == icup) {
- rccDisableTIM10();
- }
-#endif
-
-#if STM32_ICU_USE_TIM11
- if (&ICUD11 == icup) {
- rccDisableTIM11();
- }
-#endif
-
-#if STM32_ICU_USE_TIM12
- if (&ICUD12 == icup) {
- rccDisableTIM12();
- }
-#endif
-
-#if STM32_ICU_USE_TIM13
- if (&ICUD13 == icup) {
- rccDisableTIM13();
- }
-#endif
-
-#if STM32_ICU_USE_TIM14
- if (&ICUD14 == icup) {
- rccDisableTIM14();
- }
-#endif
-
-#if STM32_ICU_USE_TIM15
- if (&ICUD15 == icup) {
- rccDisableTIM15();
- }
-#endif
-
-#if STM32_ICU_USE_TIM20
- if (&ICUD20 == icup) {
- rccDisableTIM20();
- }
-#endif
-
-#if STM32_ICU_USE_TIM21
- if (&ICUD21 == icup) {
- rccDisableTIM21();
- }
-#endif
-
-#if STM32_ICU_USE_TIM22
- if (&ICUD22 == icup) {
- rccDisableTIM22();
- }
-#endif
- }
-}
-
-/**
- * @brief Starts the input capture.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_start_capture(ICUDriver *icup) {
-
- /* Triggering an UG and clearing the IRQ status.*/
- icup->tim->EGR |= STM32_TIM_EGR_UG;
- icup->tim->SR = 0;
-
- /* Timer is started.*/
- icup->tim->CR1 = STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
-}
-
-/**
- * @brief Waits for a completed capture.
- * @note The operation is performed in polled mode.
- * @note In order to use this function notifications must be disabled.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @return The capture status.
- * @retval false if the capture is successful.
- * @retval true if a timer overflow occurred.
- *
- * @notapi
- */
-bool icu_lld_wait_capture(ICUDriver *icup) {
-
- /* If the driver is still in the ICU_WAITING state then we need to wait
- for the first activation edge.*/
- if (icup->state == ICU_WAITING)
- if (icu_lld_wait_edge(icup))
- return true;
-
- /* This edge marks the availability of a capture result.*/
- return icu_lld_wait_edge(icup);
-}
-
-/**
- * @brief Stops the input capture.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_stop_capture(ICUDriver *icup) {
-
- /* Timer stopped.*/
- icup->tim->CR1 = 0;
-
- /* All interrupts disabled.*/
- icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
-}
-
-/**
- * @brief Enables notifications.
- * @pre The ICU unit must have been activated using @p icuStart() and the
- * capture started using @p icuStartCapture().
- * @note If the notification is already enabled then the call has no effect.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_enable_notifications(ICUDriver *icup) {
- uint32_t dier = icup->tim->DIER;
-
- /* If interrupts were already enabled then the operation is skipped.
- This is done in order to avoid clearing the SR and risk losing
- pending interrupts.*/
- if ((dier & STM32_TIM_DIER_IRQ_MASK) == 0) {
- /* Previously triggered IRQs are ignored, status cleared.*/
- icup->tim->SR = 0;
-
- if (icup->config->channel == ICU_CHANNEL_1) {
- /* Enabling periodic callback on CC1.*/
- dier |= STM32_TIM_DIER_CC1IE;
-
- /* Optionally enabling width callback on CC2.*/
- if (icup->config->width_cb != NULL)
- dier |= STM32_TIM_DIER_CC2IE;
- }
- else {
- /* Enabling periodic callback on CC2.*/
- dier |= STM32_TIM_DIER_CC2IE;
-
- /* Optionally enabling width callback on CC1.*/
- if (icup->config->width_cb != NULL)
- dier |= STM32_TIM_DIER_CC1IE;
- }
-
- /* If an overflow callback is defined then also the overflow callback
- is enabled.*/
- if (icup->config->overflow_cb != NULL)
- dier |= STM32_TIM_DIER_UIE;
-
- /* One single atomic write.*/
- icup->tim->DIER = dier;
- }
-}
-
-/**
- * @brief Disables notifications.
- * @pre The ICU unit must have been activated using @p icuStart() and the
- * capture started using @p icuStartCapture().
- * @note If the notification is already disabled then the call has no effect.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_disable_notifications(ICUDriver *icup) {
-
- /* All interrupts disabled.*/
- icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
-}
-
-/**
- * @brief Shared IRQ handler.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- *
- * @notapi
- */
-void icu_lld_serve_interrupt(ICUDriver *icup) {
- uint32_t sr;
-
- sr = icup->tim->SR;
- sr &= icup->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
- icup->tim->SR = ~sr;
- if (icup->config->channel == ICU_CHANNEL_1) {
- if ((sr & STM32_TIM_SR_CC2IF) != 0)
- _icu_isr_invoke_width_cb(icup);
- if ((sr & STM32_TIM_SR_CC1IF) != 0)
- _icu_isr_invoke_period_cb(icup);
- }
- else {
- if ((sr & STM32_TIM_SR_CC1IF) != 0)
- _icu_isr_invoke_width_cb(icup);
- if ((sr & STM32_TIM_SR_CC2IF) != 0)
- _icu_isr_invoke_period_cb(icup);
- }
- if ((sr & STM32_TIM_SR_UIF) != 0)
- _icu_isr_invoke_overflow_cb(icup);
-}
-
-#endif /* HAL_USE_ICU */
-
-/** @} */
+/*
+ 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 Fabio Utzig and
+ Xo Wang.
+ */
+
+/**
+ * @file TIMv1/hal_icu_lld.c
+ * @brief STM32 ICU subsystem low level driver header.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief ICUD1 driver identifier.
+ * @note The driver ICUD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
+ICUDriver ICUD1;
+#endif
+
+/**
+ * @brief ICUD2 driver identifier.
+ * @note The driver ICUD1 allocates the timer TIM2 when enabled.
+ */
+#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
+ICUDriver ICUD2;
+#endif
+
+/**
+ * @brief ICUD3 driver identifier.
+ * @note The driver ICUD1 allocates the timer TIM3 when enabled.
+ */
+#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
+ICUDriver ICUD3;
+#endif
+
+/**
+ * @brief ICUD4 driver identifier.
+ * @note The driver ICUD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
+ICUDriver ICUD4;
+#endif
+
+/**
+ * @brief ICUD5 driver identifier.
+ * @note The driver ICUD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
+ICUDriver ICUD5;
+#endif
+
+/**
+ * @brief ICUD8 driver identifier.
+ * @note The driver ICUD8 allocates the timer TIM8 when enabled.
+ */
+#if STM32_ICU_USE_TIM8 || defined(__DOXYGEN__)
+ICUDriver ICUD8;
+#endif
+
+/**
+ * @brief ICUD9 driver identifier.
+ * @note The driver ICUD9 allocates the timer TIM9 when enabled.
+ */
+#if STM32_ICU_USE_TIM9 || defined(__DOXYGEN__)
+ICUDriver ICUD9;
+#endif
+
+/**
+ * @brief ICUD10 driver identifier.
+ * @note The driver ICUD10 allocates the timer TIM10 when enabled.
+ */
+#if STM32_ICU_USE_TIM10 || defined(__DOXYGEN__)
+ICUDriver ICUD10;
+#endif
+
+/**
+ * @brief ICUD11 driver identifier.
+ * @note The driver ICUD11 allocates the timer TIM11 when enabled.
+ */
+#if STM32_ICU_USE_TIM11 || defined(__DOXYGEN__)
+ICUDriver ICUD11;
+#endif
+
+/**
+ * @brief ICUD12 driver identifier.
+ * @note The driver ICUD12 allocates the timer TIM12 when enabled.
+ */
+#if STM32_ICU_USE_TIM12 || defined(__DOXYGEN__)
+ICUDriver ICUD12;
+#endif
+
+/**
+ * @brief ICUD13 driver identifier.
+ * @note The driver ICUD13 allocates the timer TIM13 when enabled.
+ */
+#if STM32_ICU_USE_TIM13 || defined(__DOXYGEN__)
+ICUDriver ICUD13;
+#endif
+
+/**
+ * @brief ICUD14 driver identifier.
+ * @note The driver ICUD14 allocates the timer TIM14 when enabled.
+ */
+#if STM32_ICU_USE_TIM14 || defined(__DOXYGEN__)
+ICUDriver ICUD14;
+#endif
+
+/**
+ * @brief ICUD15 driver identifier.
+ * @note The driver ICUD15 allocates the timer TIM15 when enabled.
+ */
+#if STM32_ICU_USE_TIM15 || defined(__DOXYGEN__)
+ICUDriver ICUD15;
+#endif
+
+/**
+ * @brief ICUD20 driver identifier.
+ * @note The driver ICUD20 allocates the timer TIM20 when enabled.
+ */
+#if STM32_ICU_USE_TIM20 || defined(__DOXYGEN__)
+ICUDriver ICUD20;
+#endif
+
+/**
+ * @brief ICUD21 driver identifier.
+ * @note The driver ICUD21 allocates the timer TIM21 when enabled.
+ */
+#if STM32_ICU_USE_TIM21 || defined(__DOXYGEN__)
+ICUDriver ICUD21;
+#endif
+
+/**
+ * @brief ICUD22 driver identifier.
+ * @note The driver ICUD22 allocates the timer TIM22 when enabled.
+ */
+#if STM32_ICU_USE_TIM22 || defined(__DOXYGEN__)
+ICUDriver ICUD22;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+static bool icu_lld_wait_edge(ICUDriver *icup) {
+ uint32_t sr;
+ bool result;
+
+ /* Polled mode so re-enabling the interrupts while the operation is
+ performed.*/
+ osalSysUnlock();
+
+ /* Polling the right bit depending on the input channel.*/
+ if (icup->config->channel == ICU_CHANNEL_1) {
+ /* Waiting for an edge.*/
+ while (((sr = icup->tim->SR) &
+ (STM32_TIM_SR_CC1IF | STM32_TIM_SR_UIF)) == 0)
+ ;
+ }
+ else {
+ /* Waiting for an edge.*/
+ while (((sr = icup->tim->SR) &
+ (STM32_TIM_SR_CC2IF | STM32_TIM_SR_UIF)) == 0)
+ ;
+ }
+
+ /* Edge or overflow?*/
+ result = (sr & STM32_TIM_SR_UIF) != 0 ? true : false;
+
+ /* Done, disabling interrupts again.*/
+ osalSysLock();
+
+ /* Resetting all flags.*/
+ icup->tim->SR &= ~(STM32_TIM_SR_CC1IF |
+ STM32_TIM_SR_CC2IF |
+ STM32_TIM_SR_UIF);
+
+ return result;
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+#if !defined(STM32_TIM1_UP_HANDLER)
+#error "STM32_TIM1_UP_HANDLER not defined"
+#endif
+/**
+ * @brief TIM1 compare interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#if !defined(STM32_TIM1_CC_HANDLER)
+#error "STM32_TIM1_CC_HANDLER not defined"
+#endif
+/**
+ * @brief TIM1 compare interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM1 */
+
+#if STM32_ICU_USE_TIM2 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+#if !defined(STM32_TIM2_HANDLER)
+#error "STM32_TIM2_HANDLER not defined"
+#endif
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM2 */
+
+#if STM32_ICU_USE_TIM3 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+#if !defined(STM32_TIM3_HANDLER)
+#error "STM32_TIM3_HANDLER not defined"
+#endif
+/**
+ * @brief TIM3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM3 */
+
+#if STM32_ICU_USE_TIM4 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+#if !defined(STM32_TIM4_HANDLER)
+#error "STM32_TIM4_HANDLER not defined"
+#endif
+/**
+ * @brief TIM4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM4 */
+
+#if STM32_ICU_USE_TIM5 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+#if !defined(STM32_TIM5_HANDLER)
+#error "STM32_TIM5_HANDLER not defined"
+#endif
+/**
+ * @brief TIM5 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM5 */
+
+#if STM32_ICU_USE_TIM8 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+#if !defined(STM32_TIM8_UP_HANDLER)
+#error "STM32_TIM8_UP_HANDLER not defined"
+#endif
+/**
+ * @brief TIM8 compare interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#if !defined(STM32_TIM8_CC_HANDLER)
+#error "STM32_TIM8_CC_HANDLER not defined"
+#endif
+/**
+ * @brief TIM8 compare interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ icu_lld_serve_interrupt(&ICUD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM8 */
+
+#if STM32_ICU_USE_TIM9 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM9_SUPPRESS_ISR)
+#error "TIM9 ISR not defined by platform"
+#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM9 */
+
+#if STM32_ICU_USE_TIM10 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM10_SUPPRESS_ISR)
+#error "TIM10 ISR not defined by platform"
+#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM10 */
+
+#if STM32_ICU_USE_TIM11 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM11_SUPPRESS_ISR)
+#error "TIM11 ISR not defined by platform"
+#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM11 */
+
+#if STM32_ICU_USE_TIM12 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM12_SUPPRESS_ISR)
+#error "TIM12 ISR not defined by platform"
+#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM12 */
+
+#if STM32_ICU_USE_TIM13 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM13_SUPPRESS_ISR)
+#error "TIM13 ISR not defined by platform"
+#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM13 */
+
+#if STM32_ICU_USE_TIM14 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM14_SUPPRESS_ISR)
+#error "TIM14 ISR not defined by platform"
+#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM14 */
+
+#if STM32_ICU_USE_TIM15 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM15_SUPPRESS_ISR)
+#error "TIM15 ISR not defined by platform"
+#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM15 */
+
+#if STM32_ICU_USE_TIM20 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM20_SUPPRESS_ISR)
+#error "TIM20 ISR not defined by platform"
+#endif /* !defined(STM32_TIM20_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM20 */
+
+#if STM32_ICU_USE_TIM21 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM21_SUPPRESS_ISR)
+#error "TIM21 ISR not defined by platform"
+#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM21 */
+
+#if STM32_ICU_USE_TIM22 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM22_SUPPRESS_ISR)
+#error "TIM22 ISR not defined by platform"
+#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */
+#endif /* STM32_ICU_USE_TIM22 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ICU driver initialization.
+ *
+ * @notapi
+ */
+void icu_lld_init(void) {
+
+#if STM32_ICU_USE_TIM1
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD1);
+ ICUD1.tim = STM32_TIM1;
+#endif
+
+#if STM32_ICU_USE_TIM2
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD2);
+ ICUD2.tim = STM32_TIM2;
+#endif
+
+#if STM32_ICU_USE_TIM3
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD3);
+ ICUD3.tim = STM32_TIM3;
+#endif
+
+#if STM32_ICU_USE_TIM4
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD4);
+ ICUD4.tim = STM32_TIM4;
+#endif
+
+#if STM32_ICU_USE_TIM5
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD5);
+ ICUD5.tim = STM32_TIM5;
+#endif
+
+#if STM32_ICU_USE_TIM8
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD8);
+ ICUD8.tim = STM32_TIM8;
+#endif
+
+#if STM32_ICU_USE_TIM9
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD9);
+ ICUD9.tim = STM32_TIM9;
+#endif
+
+#if STM32_ICU_USE_TIM10
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD10);
+ ICUD10.tim = STM32_TIM10;
+#endif
+
+#if STM32_ICU_USE_TIM11
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD11);
+ ICUD11.tim = STM32_TIM11;
+#endif
+
+#if STM32_ICU_USE_TIM12
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD12);
+ ICUD12.tim = STM32_TIM12;
+#endif
+
+#if STM32_ICU_USE_TIM13
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD13);
+ ICUD13.tim = STM32_TIM13;
+#endif
+
+#if STM32_ICU_USE_TIM14
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD14);
+ ICUD14.tim = STM32_TIM14;
+#endif
+
+#if STM32_ICU_USE_TIM15
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD15);
+ ICUD15.tim = STM32_TIM15;
+#endif
+
+#if STM32_ICU_USE_TIM20
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD20);
+ ICUD20.tim = STM32_TIM20;
+#endif
+
+#if STM32_ICU_USE_TIM21
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD21);
+ ICUD21.tim = STM32_TIM21;
+#endif
+
+#if STM32_ICU_USE_TIM22
+ /* Driver initialization.*/
+ icuObjectInit(&ICUD22);
+ ICUD22.tim = STM32_TIM22;
+#endif
+}
+
+/**
+ * @brief Configures and activates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_start(ICUDriver *icup) {
+ uint32_t psc;
+
+ osalDbgAssert((icup->config->channel == ICU_CHANNEL_1) ||
+ (icup->config->channel == ICU_CHANNEL_2),
+ "invalid input");
+
+ if (icup->state == ICU_STOP) {
+ /* Clock activation and timer reset.*/
+#if STM32_ICU_USE_TIM1
+ if (&ICUD1 == icup) {
+ rccEnableTIM1(true);
+ rccResetTIM1();
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM1CLK)
+ icup->clock = STM32_TIM1CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM2
+ if (&ICUD2 == icup) {
+ rccEnableTIM2(true);
+ rccResetTIM2();
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM2_NUMBER, STM32_ICU_TIM2_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM2CLK)
+ icup->clock = STM32_TIM2CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM3
+ if (&ICUD3 == icup) {
+ rccEnableTIM3(true);
+ rccResetTIM3();
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM3_NUMBER, STM32_ICU_TIM3_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM3CLK)
+ icup->clock = STM32_TIM3CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM4
+ if (&ICUD4 == icup) {
+ rccEnableTIM4(true);
+ rccResetTIM4();
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM4_NUMBER, STM32_ICU_TIM4_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM4CLK)
+ icup->clock = STM32_TIM4CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM5
+ if (&ICUD5 == icup) {
+ rccEnableTIM5(true);
+ rccResetTIM5();
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM5_NUMBER, STM32_ICU_TIM5_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM5CLK)
+ icup->clock = STM32_TIM5CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM8
+ if (&ICUD8 == icup) {
+ rccEnableTIM8(true);
+ rccResetTIM8();
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
+ nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM8CLK)
+ icup->clock = STM32_TIM8CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM9
+ if (&ICUD9 == icup) {
+ rccEnableTIM9(true);
+ rccResetTIM9();
+#if defined(STM32_TIM9CLK)
+ icup->clock = STM32_TIM9CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM10
+ if (&ICUD10 == icup) {
+ rccEnableTIM10(true);
+ rccResetTIM10();
+#if defined(STM32_TIM10CLK)
+ icup->clock = STM32_TIM10CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM11
+ if (&ICUD11 == icup) {
+ rccEnableTIM11(true);
+ rccResetTIM11();
+#if defined(STM32_TIM11CLK)
+ icup->clock = STM32_TIM11CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM12
+ if (&ICUD12 == icup) {
+ rccEnableTIM12(true);
+ rccResetTIM12();
+#if defined(STM32_TIM12CLK)
+ icup->clock = STM32_TIM12CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM13
+ if (&ICUD13 == icup) {
+ rccEnableTIM13(true);
+ rccResetTIM13();
+#if defined(STM32_TIM13CLK)
+ icup->clock = STM32_TIM13CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM14
+ if (&ICUD14 == icup) {
+ rccEnableTIM14(true);
+ rccResetTIM14();
+#if defined(STM32_TIM14CLK)
+ icup->clock = STM32_TIM14CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM15
+ if (&ICUD15 == icup) {
+ rccEnableTIM15(true);
+ rccResetTIM15();
+#if defined(STM32_TIM15CLK)
+ icup->clock = STM32_TIM15CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM20
+ if (&ICUD20 == icup) {
+ rccEnableTIM20(true);
+ rccResetTIM20();
+#if defined(STM32_TIM20CLK)
+ icup->clock = STM32_TIM20CLK;
+#else
+ icup->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM21
+ if (&ICUD21 == icup) {
+ rccEnableTIM21(true);
+ rccResetTIM21();
+#if defined(STM32_TIM21CLK)
+ icup->clock = STM32_TIM21CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_ICU_USE_TIM22
+ if (&ICUD22 == icup) {
+ rccEnableTIM22(true);
+ rccResetTIM22();
+#if defined(STM32_TIM22CLK)
+ icup->clock = STM32_TIM22CLK;
+#else
+ icup->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+ }
+ else {
+ /* Driver re-configuration scenario, it must be stopped first.*/
+ icup->tim->CR1 = 0; /* Timer disabled. */
+ icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */
+ icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */
+ icup->tim->CNT = 0; /* Counter reset to zero. */
+ }
+
+ /* Timer configuration.*/
+ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
+ icup->tim->DIER = icup->config->dier & /* DMA-related DIER settings. */
+ ~STM32_TIM_DIER_IRQ_MASK;
+ psc = (icup->clock / icup->config->frequency) - 1;
+ osalDbgAssert((psc <= 0xFFFF) &&
+ ((psc + 1) * icup->config->frequency) == icup->clock,
+ "invalid frequency");
+ icup->tim->PSC = psc;
+ if (icup->config->arr == 0U) {
+ /* Zero is an invalid value and is turned in maximum value, also for
+ legacy configurations compatibility.*/
+ icup->tim->ARR = 0xFFFFFFFFU;
+ }
+ else {
+ icup->tim->ARR = icup->config->arr;
+ }
+
+ if (icup->config->channel == ICU_CHANNEL_1) {
+ /* Selected input 1.
+ CCMR1_CC1S = 01 = CH1 Input on TI1.
+ CCMR1_CC2S = 10 = CH2 Input on TI1.*/
+ icup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(1) | STM32_TIM_CCMR1_CC2S(2);
+
+ /* SMCR_TS = 101, input is TI1FP1.
+ SMCR_SMS = 100, reset on rising edge.*/
+ icup->tim->SMCR = STM32_TIM_SMCR_TS(5) | STM32_TIM_SMCR_SMS(4);
+
+ /* The CCER settings depend on the selected trigger mode.
+ ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
+ ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
+ if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
+ icup->tim->CCER = STM32_TIM_CCER_CC1E |
+ STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P;
+ else
+ icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P |
+ STM32_TIM_CCER_CC2E;
+
+ /* Direct pointers to the capture registers in order to make reading
+ data faster from within callbacks.*/
+ icup->wccrp = &icup->tim->CCR[1];
+ icup->pccrp = &icup->tim->CCR[0];
+ }
+ else {
+ /* Selected input 2.
+ CCMR1_CC1S = 10 = CH1 Input on TI2.
+ CCMR1_CC2S = 01 = CH2 Input on TI2.*/
+ icup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(2) | STM32_TIM_CCMR1_CC2S(1);
+
+ /* SMCR_TS = 110, input is TI2FP2.
+ SMCR_SMS = 100, reset on rising edge.*/
+ icup->tim->SMCR = STM32_TIM_SMCR_TS(6) | STM32_TIM_SMCR_SMS(4);
+
+ /* The CCER settings depend on the selected trigger mode.
+ ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge.
+ ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/
+ if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH)
+ icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P |
+ STM32_TIM_CCER_CC2E;
+ else
+ icup->tim->CCER = STM32_TIM_CCER_CC1E |
+ STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P;
+
+ /* Direct pointers to the capture registers in order to make reading
+ data faster from within callbacks.*/
+ icup->wccrp = &icup->tim->CCR[0];
+ icup->pccrp = &icup->tim->CCR[1];
+ }
+}
+
+/**
+ * @brief Deactivates the ICU peripheral.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop(ICUDriver *icup) {
+
+ if (icup->state == ICU_READY) {
+ /* Clock deactivation.*/
+ icup->tim->CR1 = 0; /* Timer disabled. */
+ icup->tim->DIER = 0; /* All IRQs disabled. */
+ icup->tim->SR = 0; /* Clear eventual pending IRQs. */
+
+#if STM32_ICU_USE_TIM1
+ if (&ICUD1 == icup) {
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM1_UP_NUMBER);
+ nvicDisableVector(STM32_TIM1_CC_NUMBER);
+#endif
+ rccDisableTIM1();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM2
+ if (&ICUD2 == icup) {
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM2_NUMBER);
+#endif
+ rccDisableTIM2();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM3
+ if (&ICUD3 == icup) {
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM3_NUMBER);
+#endif
+ rccDisableTIM3();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM4
+ if (&ICUD4 == icup) {
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM4_NUMBER);
+#endif
+ rccDisableTIM4();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM5
+ if (&ICUD5 == icup) {
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM5_NUMBER);
+#endif
+ rccDisableTIM5();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM8
+ if (&ICUD8 == icup) {
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM8_UP_NUMBER);
+ nvicDisableVector(STM32_TIM8_CC_NUMBER);
+#endif
+ rccDisableTIM8();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM9
+ if (&ICUD9 == icup) {
+ rccDisableTIM9();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM10
+ if (&ICUD10 == icup) {
+ rccDisableTIM10();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM11
+ if (&ICUD11 == icup) {
+ rccDisableTIM11();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM12
+ if (&ICUD12 == icup) {
+ rccDisableTIM12();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM13
+ if (&ICUD13 == icup) {
+ rccDisableTIM13();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM14
+ if (&ICUD14 == icup) {
+ rccDisableTIM14();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM15
+ if (&ICUD15 == icup) {
+ rccDisableTIM15();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM20
+ if (&ICUD20 == icup) {
+ rccDisableTIM20();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM21
+ if (&ICUD21 == icup) {
+ rccDisableTIM21();
+ }
+#endif
+
+#if STM32_ICU_USE_TIM22
+ if (&ICUD22 == icup) {
+ rccDisableTIM22();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_start_capture(ICUDriver *icup) {
+
+ /* Triggering an UG and clearing the IRQ status.*/
+ icup->tim->EGR |= STM32_TIM_EGR_UG;
+ icup->tim->SR = 0;
+
+ /* Timer is started.*/
+ icup->tim->CR1 = STM32_TIM_CR1_URS | STM32_TIM_CR1_CEN;
+}
+
+/**
+ * @brief Waits for a completed capture.
+ * @note The operation is performed in polled mode.
+ * @note In order to use this function notifications must be disabled.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The capture status.
+ * @retval false if the capture is successful.
+ * @retval true if a timer overflow occurred.
+ *
+ * @notapi
+ */
+bool icu_lld_wait_capture(ICUDriver *icup) {
+
+ /* If the driver is still in the ICU_WAITING state then we need to wait
+ for the first activation edge.*/
+ if (icup->state == ICU_WAITING)
+ if (icu_lld_wait_edge(icup))
+ return true;
+
+ /* This edge marks the availability of a capture result.*/
+ return icu_lld_wait_edge(icup);
+}
+
+/**
+ * @brief Stops the input capture.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_stop_capture(ICUDriver *icup) {
+
+ /* Timer stopped.*/
+ icup->tim->CR1 = 0;
+
+ /* All interrupts disabled.*/
+ icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
+}
+
+/**
+ * @brief Enables notifications.
+ * @pre The ICU unit must have been activated using @p icuStart() and the
+ * capture started using @p icuStartCapture().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_enable_notifications(ICUDriver *icup) {
+ uint32_t dier = icup->tim->DIER;
+
+ /* If interrupts were already enabled then the operation is skipped.
+ This is done in order to avoid clearing the SR and risk losing
+ pending interrupts.*/
+ if ((dier & STM32_TIM_DIER_IRQ_MASK) == 0) {
+ /* Previously triggered IRQs are ignored, status cleared.*/
+ icup->tim->SR = 0;
+
+ if (icup->config->channel == ICU_CHANNEL_1) {
+ /* Enabling periodic callback on CC1.*/
+ dier |= STM32_TIM_DIER_CC1IE;
+
+ /* Optionally enabling width callback on CC2.*/
+ if (icup->config->width_cb != NULL)
+ dier |= STM32_TIM_DIER_CC2IE;
+ }
+ else {
+ /* Enabling periodic callback on CC2.*/
+ dier |= STM32_TIM_DIER_CC2IE;
+
+ /* Optionally enabling width callback on CC1.*/
+ if (icup->config->width_cb != NULL)
+ dier |= STM32_TIM_DIER_CC1IE;
+ }
+
+ /* If an overflow callback is defined then also the overflow callback
+ is enabled.*/
+ if (icup->config->overflow_cb != NULL)
+ dier |= STM32_TIM_DIER_UIE;
+
+ /* One single atomic write.*/
+ icup->tim->DIER = dier;
+ }
+}
+
+/**
+ * @brief Disables notifications.
+ * @pre The ICU unit must have been activated using @p icuStart() and the
+ * capture started using @p icuStartCapture().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_disable_notifications(ICUDriver *icup) {
+
+ /* All interrupts disabled.*/
+ icup->tim->DIER &= ~STM32_TIM_DIER_IRQ_MASK;
+}
+
+/**
+ * @brief Shared IRQ handler.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ *
+ * @notapi
+ */
+void icu_lld_serve_interrupt(ICUDriver *icup) {
+ uint32_t sr;
+
+ sr = icup->tim->SR;
+ sr &= icup->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
+ icup->tim->SR = ~sr;
+ if (icup->config->channel == ICU_CHANNEL_1) {
+ if ((sr & STM32_TIM_SR_CC2IF) != 0)
+ _icu_isr_invoke_width_cb(icup);
+ if ((sr & STM32_TIM_SR_CC1IF) != 0)
+ _icu_isr_invoke_period_cb(icup);
+ }
+ else {
+ if ((sr & STM32_TIM_SR_CC1IF) != 0)
+ _icu_isr_invoke_width_cb(icup);
+ if ((sr & STM32_TIM_SR_CC2IF) != 0)
+ _icu_isr_invoke_period_cb(icup);
+ }
+ if ((sr & STM32_TIM_SR_UIF) != 0)
+ _icu_isr_invoke_overflow_cb(icup);
+}
+
+#endif /* HAL_USE_ICU */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.h
index 38c19078d3..f106a69bfa 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_icu_lld.h
@@ -1,893 +1,893 @@
-/*
- 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 TIMv1/hal_icu_lld.h
- * @brief STM32 ICU subsystem low level driver header.
- *
- * @addtogroup ICU
- * @{
- */
-
-#ifndef HAL_ICU_LLD_H
-#define HAL_ICU_LLD_H
-
-#if HAL_USE_ICU || defined(__DOXYGEN__)
-
-#include "stm32_tim.h"
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ICUD1 driver enable switch.
- * @details If set to @p TRUE the support for ICUD1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM1) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM1 FALSE
-#endif
-
-/**
- * @brief ICUD2 driver enable switch.
- * @details If set to @p TRUE the support for ICUD2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM2) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM2 FALSE
-#endif
-
-/**
- * @brief ICUD3 driver enable switch.
- * @details If set to @p TRUE the support for ICUD3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM3) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM3 FALSE
-#endif
-
-/**
- * @brief ICUD4 driver enable switch.
- * @details If set to @p TRUE the support for ICUD4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM4) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM4 FALSE
-#endif
-
-/**
- * @brief ICUD5 driver enable switch.
- * @details If set to @p TRUE the support for ICUD5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM5) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM5 FALSE
-#endif
-
-/**
- * @brief ICUD8 driver enable switch.
- * @details If set to @p TRUE the support for ICUD8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM8) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM8 FALSE
-#endif
-
-/**
- * @brief ICUD9 driver enable switch.
- * @details If set to @p TRUE the support for ICUD9 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM9) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM9 FALSE
-#endif
-
-/**
- * @brief ICUD10 driver enable switch.
- * @details If set to @p TRUE the support for ICUD10 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM10) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM10 FALSE
-#endif
-
-/**
- * @brief ICUD11 driver enable switch.
- * @details If set to @p TRUE the support for ICUD11 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM11) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM11 FALSE
-#endif
-
-/**
- * @brief ICUD12 driver enable switch.
- * @details If set to @p TRUE the support for ICUD12 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM12) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM12 FALSE
-#endif
-
-/**
- * @brief ICUD13 driver enable switch.
- * @details If set to @p TRUE the support for ICUD13 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM13) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM13 FALSE
-#endif
-
-/**
- * @brief ICUD14 driver enable switch.
- * @details If set to @p TRUE the support for ICUD14 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM14) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM14 FALSE
-#endif
-
-/**
- * @brief ICUD15 driver enable switch.
- * @details If set to @p TRUE the support for ICUD15 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM15) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM15 FALSE
-#endif
-
-/**
- * @brief ICUD20 driver enable switch.
- * @details If set to @p TRUE the support for ICUD20 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM20) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM20 FALSE
-#endif
-
-/**
- * @brief ICUD21 driver enable switch.
- * @details If set to @p TRUE the support for ICUD21 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM21) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM21 FALSE
-#endif
-
-/**
- * @brief ICUD22 driver enable switch.
- * @details If set to @p TRUE the support for ICUD22 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_ICU_USE_TIM22) || defined(__DOXYGEN__)
-#define STM32_ICU_USE_TIM22 FALSE
-#endif
-
-/**
- * @brief ICUD1 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM1_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD2 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM2_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD3 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM3_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD4 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM4_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD5 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM5_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD8 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM8_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD9 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM9_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD10 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM10_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM10_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD11 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM11_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD12 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM12_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD13 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM13_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM13_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD14 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM14_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD15 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM15_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM15_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD20 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM20_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM20_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD21 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM21_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM21_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief ICUD22 interrupt priority level setting.
- */
-#if !defined(STM32_ICU_TIM22_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ICU_TIM22_IRQ_PRIORITY 7
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_TIM1)
-#define STM32_HAS_TIM1 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM2)
-#define STM32_HAS_TIM2 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM3)
-#define STM32_HAS_TIM3 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM4)
-#define STM32_HAS_TIM4 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM5)
-#define STM32_HAS_TIM5 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM8)
-#define STM32_HAS_TIM8 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM9)
-#define STM32_HAS_TIM9 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM10)
-#define STM32_HAS_TIM10 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM11)
-#define STM32_HAS_TIM11 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM12)
-#define STM32_HAS_TIM12 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM13)
-#define STM32_HAS_TIM13 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM14)
-#define STM32_HAS_TIM14 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM15)
-#define STM32_HAS_TIM15 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM20)
-#define STM32_HAS_TIM20 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM21)
-#define STM32_HAS_TIM21 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM22)
-#define STM32_HAS_TIM22 FALSE
-#endif
-
-#if STM32_ICU_USE_TIM1 && !STM32_HAS_TIM1
-#error "TIM1 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM2 && !STM32_HAS_TIM2
-#error "TIM2 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM3 && !STM32_HAS_TIM3
-#error "TIM3 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM4 && !STM32_HAS_TIM4
-#error "TIM4 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM5 && !STM32_HAS_TIM5
-#error "TIM5 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM8 && !STM32_HAS_TIM8
-#error "TIM8 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM9 && !STM32_HAS_TIM9
-#error "TIM9 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM10 && !STM32_HAS_TIM10
-#error "TIM10 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM11 && !STM32_HAS_TIM11
-#error "TIM11 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM12 && !STM32_HAS_TIM12
-#error "TIM12 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM13 && !STM32_HAS_TIM13
-#error "TIM13 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM14 && !STM32_HAS_TIM14
-#error "TIM14 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM15 && !STM32_HAS_TIM15
-#error "TIM15 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM20 && !STM32_HAS_TIM20
-#error "TIM20 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM21 && !STM32_HAS_TIM21
-#error "TIM21 not present in the selected device"
-#endif
-
-#if STM32_ICU_USE_TIM22 && !STM32_HAS_TIM22
-#error "TIM22 not present in the selected device"
-#endif
-
-#if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \
- !STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \
- !STM32_ICU_USE_TIM5 && !STM32_ICU_USE_TIM8 && \
- !STM32_ICU_USE_TIM9 && !STM32_ICU_USE_TIM10 && \
- !STM32_ICU_USE_TIM11 && !STM32_ICU_USE_TIM12 && \
- !STM32_ICU_USE_TIM13 && !STM32_ICU_USE_TIM14 && \
- !STM32_ICU_USE_TIM15 && !STM32_ICU_USE_TIM20 && \
- !STM32_ICU_USE_TIM21 && !STM32_ICU_USE_TIM22
-#error "ICU driver activated but no TIM peripheral assigned"
-#endif
-
-/* Checks on allocation of TIMx units.*/
-#if STM32_ICU_USE_TIM1
-#if defined(STM32_TIM1_IS_USED)
-#error "ICUD1 requires TIM1 but the timer is already used"
-#else
-#define STM32_TIM1_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM2
-#if defined(STM32_TIM2_IS_USED)
-#error "ICUD2 requires TIM2 but the timer is already used"
-#else
-#define STM32_TIM2_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM3
-#if defined(STM32_TIM3_IS_USED)
-#error "ICUD3 requires TIM3 but the timer is already used"
-#else
-#define STM32_TIM3_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM4
-#if defined(STM32_TIM4_IS_USED)
-#error "ICUD4 requires TIM4 but the timer is already used"
-#else
-#define STM32_TIM4_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM5
-#if defined(STM32_TIM5_IS_USED)
-#error "ICUD5 requires TIM5 but the timer is already used"
-#else
-#define STM32_TIM5_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM8
-#if defined(STM32_TIM8_IS_USED)
-#error "ICUD8 requires TIM8 but the timer is already used"
-#else
-#define STM32_TIM8_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM9
-#if defined(STM32_TIM9_IS_USED)
-#error "ICUD9 requires TIM9 but the timer is already used"
-#else
-#define STM32_TIM9_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM10
-#if defined(STM32_TIM10_IS_USED)
-#error "ICUD10 requires TIM10 but the timer is already used"
-#else
-#define STM32_TIM10_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM11
-#if defined(STM32_TIM11_IS_USED)
-#error "ICUD11 requires TIM11 but the timer is already used"
-#else
-#define STM32_TIM11_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM12
-#if defined(STM32_TIM12_IS_USED)
-#error "ICUD12 requires TIM12 but the timer is already used"
-#else
-#define STM32_TIM12_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM13
-#if defined(STM32_TIM13_IS_USED)
-#error "ICUD13 requires TIM13 but the timer is already used"
-#else
-#define STM32_TIM13_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM14
-#if defined(STM32_TIM14_IS_USED)
-#error "ICUD14 requires TIM14 but the timer is already used"
-#else
-#define STM32_TIM14_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM15
-#if defined(STM32_TIM15_IS_USED)
-#error "ICUD15 requires TIM15 but the timer is already used"
-#else
-#define STM32_TIM15_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM20
-#if defined(STM32_TIM20_IS_USED)
-#error "ICUD20 requires TIM20 but the timer is already used"
-#else
-#define STM32_TIM20_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM21
-#if defined(STM32_TIM21_IS_USED)
-#error "ICUD21 requires TIM21 but the timer is already used"
-#else
-#define STM32_TIM21_IS_USED
-#endif
-#endif
-
-#if STM32_ICU_USE_TIM22
-#if defined(STM32_TIM22_IS_USED)
-#error "ICUD22 requires TIM22 but the timer is already used"
-#else
-#define STM32_TIM22_IS_USED
-#endif
-#endif
-
-/* IRQ priority checks.*/
-#if STM32_ICU_USE_TIM1 && !defined(STM32_TIM1_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM1"
-#endif
-
-#if STM32_ICU_USE_TIM2 && !defined(STM32_TIM2_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM2"
-#endif
-
-#if STM32_ICU_USE_TIM3 && !defined(STM32_TIM3_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM3"
-#endif
-
-#if STM32_ICU_USE_TIM4 && !defined(STM32_TIM4_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM4"
-#endif
-
-#if STM32_ICU_USE_TIM5 && !defined(STM32_TIM5_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM5"
-#endif
-
-#if STM32_ICU_USE_TIM8 && !defined(STM32_TIM8_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM8_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM8"
-#endif
-
-#if STM32_ICU_USE_TIM9 && !defined(STM32_TIM9_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM9_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM9"
-#endif
-
-#if STM32_ICU_USE_TIM10 && !defined(STM32_TIM10_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM10_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM10"
-#endif
-
-#if STM32_ICU_USE_TIM11 && !defined(STM32_TIM11_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM11_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM11"
-#endif
-
-#if STM32_ICU_USE_TIM12 && !defined(STM32_TIM12_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM12_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM12"
-#endif
-
-#if STM32_ICU_USE_TIM13 && !defined(STM32_TIM13_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM13_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM13"
-#endif
-
-#if STM32_ICU_USE_TIM14 && !defined(STM32_TIM14_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM14_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM14"
-#endif
-
-#if STM32_ICU_USE_TIM15 && !defined(STM32_TIM15_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM15_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM15"
-#endif
-
-#if STM32_ICU_USE_TIM20 && !defined(STM32_TIM20_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM20_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM20"
-#endif
-
-#if STM32_ICU_USE_TIM21 && !defined(STM32_TIM21_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM21_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM21"
-#endif
-
-#if STM32_ICU_USE_TIM22 && !defined(STM32_TIM22_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM22_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM22"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ICU driver mode.
- */
-typedef enum {
- ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
- ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
-} icumode_t;
-
-/**
- * @brief ICU frequency type.
- */
-typedef uint32_t icufreq_t;
-
-/**
- * @brief ICU channel type.
- */
-typedef enum {
- ICU_CHANNEL_1 = 0, /**< Use TIMxCH1. */
- ICU_CHANNEL_2 = 1, /**< Use TIMxCH2. */
-} icuchannel_t;
-
-/**
- * @brief ICU counter type.
- */
-typedef uint32_t icucnt_t;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Driver mode.
- */
- icumode_t mode;
- /**
- * @brief Timer clock in Hz.
- * @note The low level can use assertions in order to catch invalid
- * frequency specifications.
- */
- icufreq_t frequency;
- /**
- * @brief Callback for pulse width measurement.
- */
- icucallback_t width_cb;
- /**
- * @brief Callback for cycle period measurement.
- */
- icucallback_t period_cb;
- /**
- * @brief Callback for timer overflow.
- */
- icucallback_t overflow_cb;
- /* End of the mandatory fields.*/
- /**
- * @brief Timer input channel to be used.
- * @note Only inputs TIMx 1 and 2 are supported.
- */
- icuchannel_t channel;
- /**
- * @brief TIM DIER register initialization data.
- * @note The value of this field should normally be equal to zero.
- * @note Only the DMA-related bits can be specified in this field.
- */
- uint32_t dier;
- /**
- * @brief TIM ARR register initialization data.
- * @note The value of this field should normally be equal to 0xFFFFFFFFU.
- */
- uint32_t arr;
-} ICUConfig;
-
-/**
- * @brief Structure representing an ICU driver.
- */
-struct ICUDriver {
- /**
- * @brief Driver state.
- */
- icustate_t state;
- /**
- * @brief Current configuration data.
- */
- const ICUConfig *config;
-#if defined(ICU_DRIVER_EXT_FIELDS)
- ICU_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Timer base clock.
- */
- uint32_t clock;
- /**
- * @brief Pointer to the TIMx registers block.
- */
- stm32_tim_t *tim;
- /**
- * @brief CCR register used for width capture.
- */
- volatile uint32_t *wccrp;
- /**
- * @brief CCR register used for period capture.
- */
- volatile uint32_t *pccrp;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Returns the width of the latest pulse.
- * @details The pulse width is defined as number of ticks between the start
- * edge and the stop edge.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @return The number of ticks.
- *
- * @notapi
- */
-#define icu_lld_get_width(icup) (*((icup)->wccrp) + 1)
-
-/**
- * @brief Returns the width of the latest cycle.
- * @details The cycle width is defined as number of ticks between a start
- * edge and the next start edge.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @return The number of ticks.
- *
- * @notapi
- */
-#define icu_lld_get_period(icup) (*((icup)->pccrp) + 1)
-
-/**
- * @brief Check on notifications status.
- *
- * @param[in] icup pointer to the @p ICUDriver object
- * @return The notifications status.
- * @retval false if notifications are not enabled.
- * @retval true if notifications are enabled.
- *
- * @notapi
- */
-#define icu_lld_are_notifications_enabled(icup) \
- (bool)(((icup)->tim->DIER & STM32_TIM_DIER_IRQ_MASK) != 0)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ICU_USE_TIM1 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD1;
-#endif
-
-#if STM32_ICU_USE_TIM2 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD2;
-#endif
-
-#if STM32_ICU_USE_TIM3 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD3;
-#endif
-
-#if STM32_ICU_USE_TIM4 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD4;
-#endif
-
-#if STM32_ICU_USE_TIM5 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD5;
-#endif
-
-#if STM32_ICU_USE_TIM8 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD8;
-#endif
-
-#if STM32_ICU_USE_TIM9 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD9;
-#endif
-
-#if STM32_ICU_USE_TIM10 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD10;
-#endif
-
-#if STM32_ICU_USE_TIM11 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD11;
-#endif
-
-#if STM32_ICU_USE_TIM12 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD12;
-#endif
-
-#if STM32_ICU_USE_TIM13 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD13;
-#endif
-
-#if STM32_ICU_USE_TIM14 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD14;
-#endif
-
-#if STM32_ICU_USE_TIM15 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD15;
-#endif
-
-#if STM32_ICU_USE_TIM20 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD20;
-#endif
-
-#if STM32_ICU_USE_TIM21 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD21;
-#endif
-
-#if STM32_ICU_USE_TIM22 && !defined(__DOXYGEN__)
-extern ICUDriver ICUD22;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void icu_lld_init(void);
- void icu_lld_start(ICUDriver *icup);
- void icu_lld_stop(ICUDriver *icup);
- void icu_lld_start_capture(ICUDriver *icup);
- bool icu_lld_wait_capture(ICUDriver *icup);
- void icu_lld_stop_capture(ICUDriver *icup);
- void icu_lld_enable_notifications(ICUDriver *icup);
- void icu_lld_disable_notifications(ICUDriver *icup);
- void icu_lld_serve_interrupt(ICUDriver *icup);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ICU */
-
-#endif /* HAL_ICU_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 TIMv1/hal_icu_lld.h
+ * @brief STM32 ICU subsystem low level driver header.
+ *
+ * @addtogroup ICU
+ * @{
+ */
+
+#ifndef HAL_ICU_LLD_H
+#define HAL_ICU_LLD_H
+
+#if HAL_USE_ICU || defined(__DOXYGEN__)
+
+#include "stm32_tim.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ICUD1 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM1 FALSE
+#endif
+
+/**
+ * @brief ICUD2 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM2 FALSE
+#endif
+
+/**
+ * @brief ICUD3 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM3 FALSE
+#endif
+
+/**
+ * @brief ICUD4 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM4 FALSE
+#endif
+
+/**
+ * @brief ICUD5 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM5 FALSE
+#endif
+
+/**
+ * @brief ICUD8 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM8) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM8 FALSE
+#endif
+
+/**
+ * @brief ICUD9 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD9 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM9) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM9 FALSE
+#endif
+
+/**
+ * @brief ICUD10 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD10 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM10) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM10 FALSE
+#endif
+
+/**
+ * @brief ICUD11 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD11 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM11) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM11 FALSE
+#endif
+
+/**
+ * @brief ICUD12 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD12 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM12) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM12 FALSE
+#endif
+
+/**
+ * @brief ICUD13 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD13 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM13) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM13 FALSE
+#endif
+
+/**
+ * @brief ICUD14 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD14 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM14) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM14 FALSE
+#endif
+
+/**
+ * @brief ICUD15 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD15 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM15) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM15 FALSE
+#endif
+
+/**
+ * @brief ICUD20 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD20 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM20) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM20 FALSE
+#endif
+
+/**
+ * @brief ICUD21 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD21 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM21) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM21 FALSE
+#endif
+
+/**
+ * @brief ICUD22 driver enable switch.
+ * @details If set to @p TRUE the support for ICUD22 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_ICU_USE_TIM22) || defined(__DOXYGEN__)
+#define STM32_ICU_USE_TIM22 FALSE
+#endif
+
+/**
+ * @brief ICUD1 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD2 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD3 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD4 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD5 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM5_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD8 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM8_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD9 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM9_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD10 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM10_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM10_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD11 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM11_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD12 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM12_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD13 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM13_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM13_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD14 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM14_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD15 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM15_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM15_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD20 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM20_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM20_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD21 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM21_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM21_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief ICUD22 interrupt priority level setting.
+ */
+#if !defined(STM32_ICU_TIM22_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ICU_TIM22_IRQ_PRIORITY 7
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_TIM1)
+#define STM32_HAS_TIM1 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM2)
+#define STM32_HAS_TIM2 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM3)
+#define STM32_HAS_TIM3 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM4)
+#define STM32_HAS_TIM4 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM5)
+#define STM32_HAS_TIM5 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM8)
+#define STM32_HAS_TIM8 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM9)
+#define STM32_HAS_TIM9 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM10)
+#define STM32_HAS_TIM10 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM11)
+#define STM32_HAS_TIM11 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM12)
+#define STM32_HAS_TIM12 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM13)
+#define STM32_HAS_TIM13 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM14)
+#define STM32_HAS_TIM14 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM15)
+#define STM32_HAS_TIM15 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM20)
+#define STM32_HAS_TIM20 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM21)
+#define STM32_HAS_TIM21 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM22)
+#define STM32_HAS_TIM22 FALSE
+#endif
+
+#if STM32_ICU_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM8 && !STM32_HAS_TIM8
+#error "TIM8 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM9 && !STM32_HAS_TIM9
+#error "TIM9 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM10 && !STM32_HAS_TIM10
+#error "TIM10 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM11 && !STM32_HAS_TIM11
+#error "TIM11 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM12 && !STM32_HAS_TIM12
+#error "TIM12 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM13 && !STM32_HAS_TIM13
+#error "TIM13 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM14 && !STM32_HAS_TIM14
+#error "TIM14 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM15 && !STM32_HAS_TIM15
+#error "TIM15 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM20 && !STM32_HAS_TIM20
+#error "TIM20 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM21 && !STM32_HAS_TIM21
+#error "TIM21 not present in the selected device"
+#endif
+
+#if STM32_ICU_USE_TIM22 && !STM32_HAS_TIM22
+#error "TIM22 not present in the selected device"
+#endif
+
+#if !STM32_ICU_USE_TIM1 && !STM32_ICU_USE_TIM2 && \
+ !STM32_ICU_USE_TIM3 && !STM32_ICU_USE_TIM4 && \
+ !STM32_ICU_USE_TIM5 && !STM32_ICU_USE_TIM8 && \
+ !STM32_ICU_USE_TIM9 && !STM32_ICU_USE_TIM10 && \
+ !STM32_ICU_USE_TIM11 && !STM32_ICU_USE_TIM12 && \
+ !STM32_ICU_USE_TIM13 && !STM32_ICU_USE_TIM14 && \
+ !STM32_ICU_USE_TIM15 && !STM32_ICU_USE_TIM20 && \
+ !STM32_ICU_USE_TIM21 && !STM32_ICU_USE_TIM22
+#error "ICU driver activated but no TIM peripheral assigned"
+#endif
+
+/* Checks on allocation of TIMx units.*/
+#if STM32_ICU_USE_TIM1
+#if defined(STM32_TIM1_IS_USED)
+#error "ICUD1 requires TIM1 but the timer is already used"
+#else
+#define STM32_TIM1_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM2
+#if defined(STM32_TIM2_IS_USED)
+#error "ICUD2 requires TIM2 but the timer is already used"
+#else
+#define STM32_TIM2_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM3
+#if defined(STM32_TIM3_IS_USED)
+#error "ICUD3 requires TIM3 but the timer is already used"
+#else
+#define STM32_TIM3_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM4
+#if defined(STM32_TIM4_IS_USED)
+#error "ICUD4 requires TIM4 but the timer is already used"
+#else
+#define STM32_TIM4_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM5
+#if defined(STM32_TIM5_IS_USED)
+#error "ICUD5 requires TIM5 but the timer is already used"
+#else
+#define STM32_TIM5_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM8
+#if defined(STM32_TIM8_IS_USED)
+#error "ICUD8 requires TIM8 but the timer is already used"
+#else
+#define STM32_TIM8_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM9
+#if defined(STM32_TIM9_IS_USED)
+#error "ICUD9 requires TIM9 but the timer is already used"
+#else
+#define STM32_TIM9_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM10
+#if defined(STM32_TIM10_IS_USED)
+#error "ICUD10 requires TIM10 but the timer is already used"
+#else
+#define STM32_TIM10_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM11
+#if defined(STM32_TIM11_IS_USED)
+#error "ICUD11 requires TIM11 but the timer is already used"
+#else
+#define STM32_TIM11_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM12
+#if defined(STM32_TIM12_IS_USED)
+#error "ICUD12 requires TIM12 but the timer is already used"
+#else
+#define STM32_TIM12_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM13
+#if defined(STM32_TIM13_IS_USED)
+#error "ICUD13 requires TIM13 but the timer is already used"
+#else
+#define STM32_TIM13_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM14
+#if defined(STM32_TIM14_IS_USED)
+#error "ICUD14 requires TIM14 but the timer is already used"
+#else
+#define STM32_TIM14_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM15
+#if defined(STM32_TIM15_IS_USED)
+#error "ICUD15 requires TIM15 but the timer is already used"
+#else
+#define STM32_TIM15_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM20
+#if defined(STM32_TIM20_IS_USED)
+#error "ICUD20 requires TIM20 but the timer is already used"
+#else
+#define STM32_TIM20_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM21
+#if defined(STM32_TIM21_IS_USED)
+#error "ICUD21 requires TIM21 but the timer is already used"
+#else
+#define STM32_TIM21_IS_USED
+#endif
+#endif
+
+#if STM32_ICU_USE_TIM22
+#if defined(STM32_TIM22_IS_USED)
+#error "ICUD22 requires TIM22 but the timer is already used"
+#else
+#define STM32_TIM22_IS_USED
+#endif
+#endif
+
+/* IRQ priority checks.*/
+#if STM32_ICU_USE_TIM1 && !defined(STM32_TIM1_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM1"
+#endif
+
+#if STM32_ICU_USE_TIM2 && !defined(STM32_TIM2_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM2"
+#endif
+
+#if STM32_ICU_USE_TIM3 && !defined(STM32_TIM3_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM3"
+#endif
+
+#if STM32_ICU_USE_TIM4 && !defined(STM32_TIM4_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM4"
+#endif
+
+#if STM32_ICU_USE_TIM5 && !defined(STM32_TIM5_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM5"
+#endif
+
+#if STM32_ICU_USE_TIM8 && !defined(STM32_TIM8_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM8_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM8"
+#endif
+
+#if STM32_ICU_USE_TIM9 && !defined(STM32_TIM9_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM9_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM9"
+#endif
+
+#if STM32_ICU_USE_TIM10 && !defined(STM32_TIM10_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM10_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM10"
+#endif
+
+#if STM32_ICU_USE_TIM11 && !defined(STM32_TIM11_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM11_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM11"
+#endif
+
+#if STM32_ICU_USE_TIM12 && !defined(STM32_TIM12_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM12_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM12"
+#endif
+
+#if STM32_ICU_USE_TIM13 && !defined(STM32_TIM13_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM13_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM13"
+#endif
+
+#if STM32_ICU_USE_TIM14 && !defined(STM32_TIM14_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM14_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM14"
+#endif
+
+#if STM32_ICU_USE_TIM15 && !defined(STM32_TIM15_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM15_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM15"
+#endif
+
+#if STM32_ICU_USE_TIM20 && !defined(STM32_TIM20_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM20_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM20"
+#endif
+
+#if STM32_ICU_USE_TIM21 && !defined(STM32_TIM21_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM21_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM21"
+#endif
+
+#if STM32_ICU_USE_TIM22 && !defined(STM32_TIM22_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ICU_TIM22_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM22"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ICU driver mode.
+ */
+typedef enum {
+ ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
+ ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
+} icumode_t;
+
+/**
+ * @brief ICU frequency type.
+ */
+typedef uint32_t icufreq_t;
+
+/**
+ * @brief ICU channel type.
+ */
+typedef enum {
+ ICU_CHANNEL_1 = 0, /**< Use TIMxCH1. */
+ ICU_CHANNEL_2 = 1, /**< Use TIMxCH2. */
+} icuchannel_t;
+
+/**
+ * @brief ICU counter type.
+ */
+typedef uint32_t icucnt_t;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Driver mode.
+ */
+ icumode_t mode;
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ icufreq_t frequency;
+ /**
+ * @brief Callback for pulse width measurement.
+ */
+ icucallback_t width_cb;
+ /**
+ * @brief Callback for cycle period measurement.
+ */
+ icucallback_t period_cb;
+ /**
+ * @brief Callback for timer overflow.
+ */
+ icucallback_t overflow_cb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer input channel to be used.
+ * @note Only inputs TIMx 1 and 2 are supported.
+ */
+ icuchannel_t channel;
+ /**
+ * @brief TIM DIER register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ * @note Only the DMA-related bits can be specified in this field.
+ */
+ uint32_t dier;
+ /**
+ * @brief TIM ARR register initialization data.
+ * @note The value of this field should normally be equal to 0xFFFFFFFFU.
+ */
+ uint32_t arr;
+} ICUConfig;
+
+/**
+ * @brief Structure representing an ICU driver.
+ */
+struct ICUDriver {
+ /**
+ * @brief Driver state.
+ */
+ icustate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ICUConfig *config;
+#if defined(ICU_DRIVER_EXT_FIELDS)
+ ICU_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ stm32_tim_t *tim;
+ /**
+ * @brief CCR register used for width capture.
+ */
+ volatile uint32_t *wccrp;
+ /**
+ * @brief CCR register used for period capture.
+ */
+ volatile uint32_t *pccrp;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the width of the latest pulse.
+ * @details The pulse width is defined as number of ticks between the start
+ * edge and the stop edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_width(icup) (*((icup)->wccrp) + 1)
+
+/**
+ * @brief Returns the width of the latest cycle.
+ * @details The cycle width is defined as number of ticks between a start
+ * edge and the next start edge.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The number of ticks.
+ *
+ * @notapi
+ */
+#define icu_lld_get_period(icup) (*((icup)->pccrp) + 1)
+
+/**
+ * @brief Check on notifications status.
+ *
+ * @param[in] icup pointer to the @p ICUDriver object
+ * @return The notifications status.
+ * @retval false if notifications are not enabled.
+ * @retval true if notifications are enabled.
+ *
+ * @notapi
+ */
+#define icu_lld_are_notifications_enabled(icup) \
+ (bool)(((icup)->tim->DIER & STM32_TIM_DIER_IRQ_MASK) != 0)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ICU_USE_TIM1 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD1;
+#endif
+
+#if STM32_ICU_USE_TIM2 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD2;
+#endif
+
+#if STM32_ICU_USE_TIM3 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD3;
+#endif
+
+#if STM32_ICU_USE_TIM4 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD4;
+#endif
+
+#if STM32_ICU_USE_TIM5 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD5;
+#endif
+
+#if STM32_ICU_USE_TIM8 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD8;
+#endif
+
+#if STM32_ICU_USE_TIM9 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD9;
+#endif
+
+#if STM32_ICU_USE_TIM10 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD10;
+#endif
+
+#if STM32_ICU_USE_TIM11 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD11;
+#endif
+
+#if STM32_ICU_USE_TIM12 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD12;
+#endif
+
+#if STM32_ICU_USE_TIM13 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD13;
+#endif
+
+#if STM32_ICU_USE_TIM14 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD14;
+#endif
+
+#if STM32_ICU_USE_TIM15 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD15;
+#endif
+
+#if STM32_ICU_USE_TIM20 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD20;
+#endif
+
+#if STM32_ICU_USE_TIM21 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD21;
+#endif
+
+#if STM32_ICU_USE_TIM22 && !defined(__DOXYGEN__)
+extern ICUDriver ICUD22;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void icu_lld_init(void);
+ void icu_lld_start(ICUDriver *icup);
+ void icu_lld_stop(ICUDriver *icup);
+ void icu_lld_start_capture(ICUDriver *icup);
+ bool icu_lld_wait_capture(ICUDriver *icup);
+ void icu_lld_stop_capture(ICUDriver *icup);
+ void icu_lld_enable_notifications(ICUDriver *icup);
+ void icu_lld_disable_notifications(ICUDriver *icup);
+ void icu_lld_serve_interrupt(ICUDriver *icup);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ICU */
+
+#endif /* HAL_ICU_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
index eb6bebc7e4..ddc0f9b959 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.c
@@ -1,1302 +1,1302 @@
-/*
- 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 TIMv1/hal_pwm_lld.c
- * @brief STM32 PWM subsystem low level driver header.
- *
- * @addtogroup PWM
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_PWM || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief PWMD1 driver identifier.
- * @note The driver PWMD1 allocates the complex timer TIM1 when enabled.
- */
-#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
-PWMDriver PWMD1;
-#endif
-
-/**
- * @brief PWMD2 driver identifier.
- * @note The driver PWMD2 allocates the timer TIM2 when enabled.
- */
-#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
-PWMDriver PWMD2;
-#endif
-
-/**
- * @brief PWMD3 driver identifier.
- * @note The driver PWMD3 allocates the timer TIM3 when enabled.
- */
-#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
-PWMDriver PWMD3;
-#endif
-
-/**
- * @brief PWMD4 driver identifier.
- * @note The driver PWMD4 allocates the timer TIM4 when enabled.
- */
-#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
-PWMDriver PWMD4;
-#endif
-
-/**
- * @brief PWMD5 driver identifier.
- * @note The driver PWMD5 allocates the timer TIM5 when enabled.
- */
-#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
-PWMDriver PWMD5;
-#endif
-
-/**
- * @brief PWMD8 driver identifier.
- * @note The driver PWMD8 allocates the timer TIM8 when enabled.
- */
-#if STM32_PWM_USE_TIM8 || defined(__DOXYGEN__)
-PWMDriver PWMD8;
-#endif
-
-/**
- * @brief PWMD9 driver identifier.
- * @note The driver PWMD9 allocates the timer TIM9 when enabled.
- */
-#if STM32_PWM_USE_TIM9 || defined(__DOXYGEN__)
-PWMDriver PWMD9;
-#endif
-
-/**
- * @brief PWMD10 driver identifier.
- * @note The driver PWMD10 allocates the timer TIM10 when enabled.
- */
-#if STM32_PWM_USE_TIM10 || defined(__DOXYGEN__)
-PWMDriver PWMD10;
-#endif
-
-/**
- * @brief PWMD11 driver identifier.
- * @note The driver PWMD11 allocates the timer TIM11 when enabled.
- */
-#if STM32_PWM_USE_TIM11 || defined(__DOXYGEN__)
-PWMDriver PWMD11;
-#endif
-
-/**
- * @brief PWMD12 driver identifier.
- * @note The driver PWMD12 allocates the timer TIM12 when enabled.
- */
-#if STM32_PWM_USE_TIM12 || defined(__DOXYGEN__)
-PWMDriver PWMD12;
-#endif
-
-/**
- * @brief PWMD13 driver identifier.
- * @note The driver PWMD13 allocates the timer TIM13 when enabled.
- */
-#if STM32_PWM_USE_TIM13 || defined(__DOXYGEN__)
-PWMDriver PWMD13;
-#endif
-
-/**
- * @brief PWMD14 driver identifier.
- * @note The driver PWMD14 allocates the timer TIM14 when enabled.
- */
-#if STM32_PWM_USE_TIM14 || defined(__DOXYGEN__)
-PWMDriver PWMD14;
-#endif
-
-/**
- * @brief PWMD15 driver identifier.
- * @note The driver PWMD15 allocates the timer TIM15 when enabled.
- */
-#if STM32_PWM_USE_TIM15 || defined(__DOXYGEN__)
-PWMDriver PWMD15;
-#endif
-
-/**
- * @brief PWMD16 driver identifier.
- * @note The driver PWMD16 allocates the timer TIM16 when enabled.
- */
-#if STM32_PWM_USE_TIM16 || defined(__DOXYGEN__)
-PWMDriver PWMD16;
-#endif
-
-/**
- * @brief PWMD17 driver identifier.
- * @note The driver PWMD17 allocates the timer TIM17 when enabled.
- */
-#if STM32_PWM_USE_TIM17 || defined(__DOXYGEN__)
-PWMDriver PWMD17;
-#endif
-
-/**
- * @brief PWMD20 driver identifier.
- * @note The driver PWMD20 allocates the timer TIM20 when enabled.
- */
-#if STM32_PWM_USE_TIM20 || defined(__DOXYGEN__)
-PWMDriver PWMD20;
-#endif
-
-/**
- * @brief PWMD21 driver identifier.
- * @note The driver PWMD21 allocates the timer TIM21 when enabled.
- */
-#if STM32_PWM_USE_TIM21 || defined(__DOXYGEN__)
-PWMDriver PWMD21;
-#endif
-
-/**
- * @brief PWMD22 driver identifier.
- * @note The driver PWMD22 allocates the timer TIM22 when enabled.
- */
-#if STM32_PWM_USE_TIM22 || defined(__DOXYGEN__)
-PWMDriver PWMD22;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
-#if !defined(STM32_TIM1_UP_HANDLER)
-#error "STM32_TIM1_UP_HANDLER not defined"
-#endif
-/**
- * @brief TIM1 update interrupt handler.
- * @note It is assumed that this interrupt is only activated if the callback
- * pointer is not equal to @p NULL in order to not perform an extra
- * check in a potentially critical interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#if !defined(STM32_TIM1_CC_HANDLER)
-#error "STM32_TIM1_CC_HANDLER not defined"
-#endif
-/**
- * @brief TIM1 compare interrupt handler.
- * @note It is assumed that the various sources are only activated if the
- * associated callback pointer is not equal to @p NULL in order to not
- * perform an extra check in a potentially critical interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM1 */
-
-#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
-#if !defined(STM32_TIM2_HANDLER)
-#error "STM32_TIM2_HANDLER not defined"
-#endif
-/**
- * @brief TIM2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM2 */
-
-#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
-#if !defined(STM32_TIM3_HANDLER)
-#error "STM32_TIM3_HANDLER not defined"
-#endif
-/**
- * @brief TIM3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM3 */
-
-#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
-#if !defined(STM32_TIM4_HANDLER)
-#error "STM32_TIM4_HANDLER not defined"
-#endif
-/**
- * @brief TIM4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM4 */
-
-#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
-#if !defined(STM32_TIM5_HANDLER)
-#error "STM32_TIM5_HANDLER not defined"
-#endif
-/**
- * @brief TIM5 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM5 */
-
-#if STM32_PWM_USE_TIM8 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
-#if !defined(STM32_TIM8_UP_HANDLER)
-#error "STM32_TIM8_UP_HANDLER not defined"
-#endif
-/**
- * @brief TIM8 update interrupt handler.
- * @note It is assumed that this interrupt is only activated if the callback
- * pointer is not equal to @p NULL in order to not perform an extra
- * check in a potentially critical interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-
-#if !defined(STM32_TIM8_CC_HANDLER)
-#error "STM32_TIM8_CC_HANDLER not defined"
-#endif
-/**
- * @brief TIM8 compare interrupt handler.
- * @note It is assumed that the various sources are only activated if the
- * associated callback pointer is not equal to @p NULL in order to not
- * perform an extra check in a potentially critical interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- pwm_lld_serve_interrupt(&PWMD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM8 */
-
-#if STM32_PWM_USE_TIM9 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM9_SUPPRESS_ISR)
-#error "TIM9 ISR not defined by platform"
-#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM9 */
-
-#if STM32_PWM_USE_TIM10 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM10_SUPPRESS_ISR)
-#error "TIM10 ISR not defined by platform"
-#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM10 */
-
-#if STM32_PWM_USE_TIM11 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM11_SUPPRESS_ISR)
-#error "TIM11 ISR not defined by platform"
-#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM11 */
-
-#if STM32_PWM_USE_TIM12 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM12_SUPPRESS_ISR)
-#error "TIM12 ISR not defined by platform"
-#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM12 */
-
-#if STM32_PWM_USE_TIM13 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM13_SUPPRESS_ISR)
-#error "TIM13 ISR not defined by platform"
-#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM13 */
-
-#if STM32_PWM_USE_TIM14 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM14_SUPPRESS_ISR)
-#error "TIM14 ISR not defined by platform"
-#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM14 */
-
-#if STM32_PWM_USE_TIM15 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM15_SUPPRESS_ISR)
-#error "TIM15 ISR not defined by platform"
-#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM15 */
-
-#if STM32_PWM_USE_TIM16 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM16_SUPPRESS_ISR)
-#error "TIM16 ISR not defined by platform"
-#endif /* !defined(STM32_TIM16_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM16 */
-
-#if STM32_PWM_USE_TIM17 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM17_SUPPRESS_ISR)
-#error "TIM17 ISR not defined by platform"
-#endif /* !defined(STM32_TIM17_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM17 */
-
-#if STM32_PWM_USE_TIM20 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM20_SUPPRESS_ISR)
-#error "TIM20 ISR not defined by platform"
-#endif /* !defined(STM32_TIM20_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM20 */
-
-#if STM32_PWM_USE_TIM21 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM21_SUPPRESS_ISR)
-#error "TIM21 ISR not defined by platform"
-#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM21 */
-
-#if STM32_PWM_USE_TIM22 || defined(__DOXYGEN__)
-#if !defined(STM32_TIM22_SUPPRESS_ISR)
-#error "TIM22 ISR not defined by platform"
-#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */
-#endif /* STM32_PWM_USE_TIM22 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level PWM driver initialization.
- *
- * @notapi
- */
-void pwm_lld_init(void) {
-
-#if STM32_PWM_USE_TIM1
- /* Driver initialization.*/
- pwmObjectInit(&PWMD1);
- PWMD1.channels = STM32_TIM1_CHANNELS;
- PWMD1.tim = STM32_TIM1;
-#endif
-
-#if STM32_PWM_USE_TIM2
- /* Driver initialization.*/
- pwmObjectInit(&PWMD2);
- PWMD2.channels = STM32_TIM2_CHANNELS;
- PWMD2.tim = STM32_TIM2;
-#endif
-
-#if STM32_PWM_USE_TIM3
- /* Driver initialization.*/
- pwmObjectInit(&PWMD3);
- PWMD3.channels = STM32_TIM3_CHANNELS;
- PWMD3.tim = STM32_TIM3;
-#endif
-
-#if STM32_PWM_USE_TIM4
- /* Driver initialization.*/
- pwmObjectInit(&PWMD4);
- PWMD4.channels = STM32_TIM4_CHANNELS;
- PWMD4.tim = STM32_TIM4;
-#endif
-
-#if STM32_PWM_USE_TIM5
- /* Driver initialization.*/
- pwmObjectInit(&PWMD5);
- PWMD5.channels = STM32_TIM5_CHANNELS;
- PWMD5.tim = STM32_TIM5;
-#endif
-
-#if STM32_PWM_USE_TIM8
- /* Driver initialization.*/
- pwmObjectInit(&PWMD8);
- PWMD8.channels = STM32_TIM8_CHANNELS;
- PWMD8.tim = STM32_TIM8;
-#endif
-
-#if STM32_PWM_USE_TIM9
- /* Driver initialization.*/
- pwmObjectInit(&PWMD9);
- PWMD9.channels = STM32_TIM9_CHANNELS;
- PWMD9.tim = STM32_TIM9;
-#endif
-
-#if STM32_PWM_USE_TIM10
- /* Driver initialization.*/
- pwmObjectInit(&PWMD10);
- PWMD10.channels = STM32_TIM10_CHANNELS;
- PWMD10.tim = STM32_TIM10;
-#endif
-
-#if STM32_PWM_USE_TIM11
- /* Driver initialization.*/
- pwmObjectInit(&PWMD11);
- PWMD11.channels = STM32_TIM11_CHANNELS;
- PWMD11.tim = STM32_TIM11;
-#endif
-
-#if STM32_PWM_USE_TIM12
- /* Driver initialization.*/
- pwmObjectInit(&PWMD12);
- PWMD12.channels = STM32_TIM12_CHANNELS;
- PWMD12.tim = STM32_TIM12;
-#endif
-
-#if STM32_PWM_USE_TIM13
- /* Driver initialization.*/
- pwmObjectInit(&PWMD13);
- PWMD13.channels = STM32_TIM13_CHANNELS;
- PWMD13.tim = STM32_TIM13;
-#endif
-
-#if STM32_PWM_USE_TIM14
- /* Driver initialization.*/
- pwmObjectInit(&PWMD14);
- PWMD14.channels = STM32_TIM14_CHANNELS;
- PWMD14.tim = STM32_TIM14;
-#endif
-
-#if STM32_PWM_USE_TIM15
- /* Driver initialization.*/
- pwmObjectInit(&PWMD15);
- PWMD15.channels = STM32_TIM15_CHANNELS;
- PWMD15.tim = STM32_TIM15;
-#endif
-
-#if STM32_PWM_USE_TIM16
- /* Driver initialization.*/
- pwmObjectInit(&PWMD16);
- PWMD16.channels = STM32_TIM16_CHANNELS;
- PWMD16.tim = STM32_TIM16;
-#endif
-
-#if STM32_PWM_USE_TIM17
- /* Driver initialization.*/
- pwmObjectInit(&PWMD17);
- PWMD17.channels = STM32_TIM17_CHANNELS;
- PWMD17.tim = STM32_TIM17;
-#endif
-
-#if STM32_PWM_USE_TIM20
- /* Driver initialization.*/
- pwmObjectInit(&PWMD20);
- PWMD20.channels = STM32_TIM20_CHANNELS;
- PWMD20.tim = STM32_TIM20;
-#endif
-
-#if STM32_PWM_USE_TIM21
- /* Driver initialization.*/
- pwmObjectInit(&PWMD21);
- PWMD21.channels = STM32_TIM21_CHANNELS;
- PWMD21.tim = STM32_TIM21;
-#endif
-
-#if STM32_PWM_USE_TIM22
- /* Driver initialization.*/
- pwmObjectInit(&PWMD22);
- PWMD22.channels = STM32_TIM22_CHANNELS;
- PWMD22.tim = STM32_TIM22;
-#endif
-}
-
-/**
- * @brief Configures and activates the PWM peripheral.
- * @note Starting a driver that is already in the @p PWM_READY state
- * disables all the active channels.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_start(PWMDriver *pwmp) {
- uint32_t psc;
- uint32_t ccer;
-
- if (pwmp->state == PWM_STOP) {
- /* Clock activation and timer reset.*/
-#if STM32_PWM_USE_TIM1
- if (&PWMD1 == pwmp) {
- rccEnableTIM1(true);
- rccResetTIM1();
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
- nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM1CLK)
- pwmp->clock = STM32_TIM1CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM2
- if (&PWMD2 == pwmp) {
- rccEnableTIM2(true);
- rccResetTIM2();
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM2_NUMBER, STM32_PWM_TIM2_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM2CLK)
- pwmp->clock = STM32_TIM2CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM3
- if (&PWMD3 == pwmp) {
- rccEnableTIM3(true);
- rccResetTIM3();
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM3_NUMBER, STM32_PWM_TIM3_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM3CLK)
- pwmp->clock = STM32_TIM3CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM4
- if (&PWMD4 == pwmp) {
- rccEnableTIM4(true);
- rccResetTIM4();
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM4_NUMBER, STM32_PWM_TIM4_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM4CLK)
- pwmp->clock = STM32_TIM4CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM5
- if (&PWMD5 == pwmp) {
- rccEnableTIM5(true);
- rccResetTIM5();
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM5_NUMBER, STM32_PWM_TIM5_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM5CLK)
- pwmp->clock = STM32_TIM5CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM8
- if (&PWMD8 == pwmp) {
- rccEnableTIM8(true);
- rccResetTIM8();
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
- nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
- nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
-#endif
-#if defined(STM32_TIM8CLK)
- pwmp->clock = STM32_TIM8CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM9
- if (&PWMD9 == pwmp) {
- rccEnableTIM9(true);
- rccResetTIM9();
-#if defined(STM32_TIM9CLK)
- pwmp->clock = STM32_TIM9CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM10
- if (&PWMD10 == pwmp) {
- rccEnableTIM10(true);
- rccResetTIM10();
-#if defined(STM32_TIM10CLK)
- pwmp->clock = STM32_TIM10CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM11
- if (&PWMD11 == pwmp) {
- rccEnableTIM11(true);
- rccResetTIM11();
-#if defined(STM32_TIM11CLK)
- pwmp->clock = STM32_TIM11CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM12
- if (&PWMD12 == pwmp) {
- rccEnableTIM12(true);
- rccResetTIM12();
-#if defined(STM32_TIM12CLK)
- pwmp->clock = STM32_TIM12CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM13
- if (&PWMD13 == pwmp) {
- rccEnableTIM13(true);
- rccResetTIM13();
-#if defined(STM32_TIM13CLK)
- pwmp->clock = STM32_TIM13CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM14
- if (&PWMD14 == pwmp) {
- rccEnableTIM14(true);
- rccResetTIM14();
-#if defined(STM32_TIM14CLK)
- pwmp->clock = STM32_TIM14CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM15
- if (&PWMD15 == pwmp) {
- rccEnableTIM15(true);
- rccResetTIM15();
-#if defined(STM32_TIM15CLK)
- pwmp->clock = STM32_TIM15CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM16
- if (&PWMD16 == pwmp) {
- rccEnableTIM16(true);
- rccResetTIM16();
-#if defined(STM32_TIM16CLK)
- pwmp->clock = STM32_TIM16CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM17
- if (&PWMD17 == pwmp) {
- rccEnableTIM17(true);
- rccResetTIM17();
-#if defined(STM32_TIM17CLK)
- pwmp->clock = STM32_TIM17CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM20
- if (&PWMD20 == pwmp) {
- rccEnableTIM20(true);
- rccResetTIM20();
-#if defined(STM32_TIM20CLK)
- pwmp->clock = STM32_TIM20CLK;
-#else
- pwmp->clock = STM32_TIMCLK2;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM21
- if (&PWMD21 == pwmp) {
- rccEnableTIM21(true);
- rccResetTIM21();
-#if defined(STM32_TIM21CLK)
- pwmp->clock = STM32_TIM21CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
-#if STM32_PWM_USE_TIM22
- if (&PWMD22 == pwmp) {
- rccEnableTIM22(true);
- rccResetTIM22();
-#if defined(STM32_TIM22CLK)
- pwmp->clock = STM32_TIM22CLK;
-#else
- pwmp->clock = STM32_TIMCLK1;
-#endif
- }
-#endif
-
- /* All channels configured in PWM1 mode with preload enabled and will
- stay that way until the driver is stopped.*/
- pwmp->tim->CCMR1 = STM32_TIM_CCMR1_OC1M(6) | STM32_TIM_CCMR1_OC1PE |
- STM32_TIM_CCMR1_OC2M(6) | STM32_TIM_CCMR1_OC2PE;
- pwmp->tim->CCMR2 = STM32_TIM_CCMR2_OC3M(6) | STM32_TIM_CCMR2_OC3PE |
- STM32_TIM_CCMR2_OC4M(6) | STM32_TIM_CCMR2_OC4PE;
-#if STM32_TIM_MAX_CHANNELS > 4
- pwmp->tim->CCMR3 = STM32_TIM_CCMR3_OC5M(6) | STM32_TIM_CCMR3_OC5PE |
- STM32_TIM_CCMR3_OC6M(6) | STM32_TIM_CCMR3_OC6PE;
-#endif
- }
- else {
- /* Driver re-configuration scenario, it must be stopped first.*/
- pwmp->tim->CR1 = 0; /* Timer disabled. */
- pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */
- pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */
- pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */
- pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */
-#if STM32_TIM_MAX_CHANNELS > 4
- if (pwmp->channels > 4) {
- pwmp->tim->CCXR[0] = 0; /* Comparator 5 disabled. */
- pwmp->tim->CCXR[1] = 0; /* Comparator 6 disabled. */
- }
-#endif
- pwmp->tim->CNT = 0; /* Counter reset to zero. */
- }
-
- /* Timer configuration.*/
- psc = (pwmp->clock / pwmp->config->frequency) - 1;
- osalDbgAssert((psc <= 0xFFFF) &&
- ((psc + 1) * pwmp->config->frequency) == pwmp->clock,
- "invalid frequency");
- pwmp->tim->PSC = psc;
- pwmp->tim->ARR = pwmp->period - 1;
- pwmp->tim->CR2 = pwmp->config->cr2;
-
- /* Output enables and polarities setup.*/
- ccer = 0;
- switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) {
- case PWM_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC1P;
- /* Falls through.*/
- case PWM_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC1E;
- /* Falls through.*/
- default:
- ;
- }
- switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) {
- case PWM_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC2P;
- /* Falls through.*/
- case PWM_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC2E;
- /* Falls through.*/
- default:
- ;
- }
- switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) {
- case PWM_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC3P;
- /* Falls through.*/
- case PWM_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC3E;
- /* Falls through.*/
- default:
- ;
- }
- switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) {
- case PWM_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC4P;
- /* Falls through.*/
- case PWM_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC4E;
- /* Falls through.*/
- default:
- ;
- }
-#if STM32_PWM_USE_ADVANCED
-#if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && !STM32_PWM_USE_TIM20
- if (&PWMD1 == pwmp) {
-#endif
-#if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && !STM32_PWM_USE_TIM20
- if (&PWMD8 == pwmp) {
-#endif
-#if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && !STM32_PWM_USE_TIM20
- if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) {
-#endif
-#if !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
- if (&PWMD20 == pwmp) {
-#endif
-#if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
- if ((&PWMD1 == pwmp) || (&PWMD20 == pwmp)) {
-#endif
-#if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
- if ((&PWMD8 == pwmp) || (&PWMD20 == pwmp)) {
-#endif
-#if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
- if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp) || (&PWMD20 == pwmp)) {
-#endif
- switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC1NP;
- /* Falls through.*/
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC1NE;
- /* Falls through.*/
- default:
- ;
- }
- switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC2NP;
- /* Falls through.*/
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC2NE;
- /* Falls through.*/
- default:
- ;
- }
- switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC3NP;
- /* Falls through.*/
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC3NE;
- /* Falls through.*/
- default:
- ;
- }
- switch (pwmp->config->channels[3].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
- ccer |= STM32_TIM_CCER_CC4NP;
- /* Falls through.*/
- case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
- ccer |= STM32_TIM_CCER_CC4NE;
- /* Falls through.*/
- default:
- ;
- }
- }
-#endif /* STM32_PWM_USE_ADVANCED*/
-
- pwmp->tim->CCER = ccer;
- pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
- pwmp->tim->SR = 0; /* Clear pending IRQs. */
- pwmp->tim->DIER = pwmp->config->dier & /* DMA-related DIER settings. */
- ~STM32_TIM_DIER_IRQ_MASK;
-#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 || STM32_PWM_USE_TIM20
-#if STM32_PWM_USE_ADVANCED
- pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE;
-#else
- pwmp->tim->BDTR = STM32_TIM_BDTR_MOE;
-#endif
-#endif
- /* Timer configured and started.*/
- pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS |
- STM32_TIM_CR1_CEN;
-}
-
-/**
- * @brief Deactivates the PWM peripheral.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_stop(PWMDriver *pwmp) {
-
- /* If in ready state then disables the PWM clock.*/
- if (pwmp->state == PWM_READY) {
- pwmp->tim->CR1 = 0; /* Timer disabled. */
- pwmp->tim->DIER = 0; /* All IRQs disabled. */
- pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
-#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 || STM32_PWM_USE_TIM20
- pwmp->tim->BDTR = 0;
-#endif
-
-#if STM32_PWM_USE_TIM1
- if (&PWMD1 == pwmp) {
-#if !defined(STM32_TIM1_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM1_UP_NUMBER);
- nvicDisableVector(STM32_TIM1_CC_NUMBER);
-#endif
- rccDisableTIM1();
- }
-#endif
-
-#if STM32_PWM_USE_TIM2
- if (&PWMD2 == pwmp) {
-#if !defined(STM32_TIM2_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM2_NUMBER);
-#endif
- rccDisableTIM2();
- }
-#endif
-
-#if STM32_PWM_USE_TIM3
- if (&PWMD3 == pwmp) {
-#if !defined(STM32_TIM3_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM3_NUMBER);
-#endif
- rccDisableTIM3();
- }
-#endif
-
-#if STM32_PWM_USE_TIM4
- if (&PWMD4 == pwmp) {
-#if !defined(STM32_TIM4_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM4_NUMBER);
-#endif
- rccDisableTIM4();
- }
-#endif
-
-#if STM32_PWM_USE_TIM5
- if (&PWMD5 == pwmp) {
-#if !defined(STM32_TIM5_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM5_NUMBER);
-#endif
- rccDisableTIM5();
- }
-#endif
-
-#if STM32_PWM_USE_TIM8
- if (&PWMD8 == pwmp) {
-#if !defined(STM32_TIM8_SUPPRESS_ISR)
- nvicDisableVector(STM32_TIM8_UP_NUMBER);
- nvicDisableVector(STM32_TIM8_CC_NUMBER);
-#endif
- rccDisableTIM8();
- }
-#endif
-
-#if STM32_PWM_USE_TIM9
- if (&PWMD9 == pwmp) {
- rccDisableTIM9();
- }
-#endif
-
-#if STM32_PWM_USE_TIM10
- if (&PWMD10 == pwmp) {
- rccDisableTIM10();
- }
-#endif
-
-#if STM32_PWM_USE_TIM11
- if (&PWMD11 == pwmp) {
- rccDisableTIM11();
- }
-#endif
-
-#if STM32_PWM_USE_TIM12
- if (&PWMD12 == pwmp) {
- rccDisableTIM12();
- }
-#endif
-
-#if STM32_PWM_USE_TIM13
- if (&PWMD13 == pwmp) {
- rccDisableTIM13();
- }
-#endif
-
-#if STM32_PWM_USE_TIM14
- if (&PWMD14 == pwmp) {
- rccDisableTIM14();
- }
-#endif
-
-#if STM32_PWM_USE_TIM15
- if (&PWMD15 == pwmp) {
- rccDisableTIM15();
- }
-#endif
-
-#if STM32_PWM_USE_TIM16
- if (&PWMD16 == pwmp) {
- rccDisableTIM16();
- }
-#endif
-
-#if STM32_PWM_USE_TIM17
- if (&PWMD17 == pwmp) {
- rccDisableTIM17();
- }
-#endif
-
-#if STM32_PWM_USE_TIM20
- if (&PWMD20 == pwmp) {
- rccDisableTIM20();
- }
-#endif
-
-#if STM32_PWM_USE_TIM21
- if (&PWMD21 == pwmp) {
- rccDisableTIM21();
- }
-#endif
-
-#if STM32_PWM_USE_TIM22
- if (&PWMD22 == pwmp) {
- rccDisableTIM22();
- }
-#endif
- }
-}
-
-/**
- * @brief Enables a PWM channel.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @post The channel is active using the specified configuration.
- * @note The function has effect at the next cycle start.
- * @note Channel notification is not enabled.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- * @param[in] width PWM pulse width as clock pulses number
- *
- * @notapi
- */
-void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width) {
-
- /* Changing channel duty cycle on the fly.*/
-#if STM32_TIM_MAX_CHANNELS <= 4
- pwmp->tim->CCR[channel] = width;
-#else
- if (channel < 4)
- pwmp->tim->CCR[channel] = width;
- else
- pwmp->tim->CCXR[channel - 4] = width;
-#endif
-}
-
-/**
- * @brief Disables a PWM channel and its notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @post The channel is disabled and its output line returned to the
- * idle state.
- * @note The function has effect at the next cycle start.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- *
- * @notapi
- */
-void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
-
-#if STM32_TIM_MAX_CHANNELS <= 4
- pwmp->tim->CCR[channel] = 0;
- pwmp->tim->DIER &= ~(2 << channel);
-#else
- if (channel < 4) {
- pwmp->tim->CCR[channel] = 0;
- pwmp->tim->DIER &= ~(2 << channel);
- }
- else
- pwmp->tim->CCXR[channel - 4] = 0;
-#endif
-}
-
-/**
- * @brief Enables the periodic activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @note If the notification is already enabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
- uint32_t dier = pwmp->tim->DIER;
-
- /* If the IRQ is not already enabled care must be taken to clear it,
- it is probably already pending because the timer is running.*/
- if ((dier & STM32_TIM_DIER_UIE) == 0) {
- pwmp->tim->SR = ~STM32_TIM_SR_UIF;
- pwmp->tim->DIER = dier | STM32_TIM_DIER_UIE;
- }
-}
-
-/**
- * @brief Disables the periodic activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @note If the notification is already disabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
-
- pwmp->tim->DIER &= ~STM32_TIM_DIER_UIE;
-}
-
-/**
- * @brief Enables a channel de-activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @pre The channel must have been activated using @p pwmEnableChannel().
- * @note If the notification is already enabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- *
- * @notapi
- */
-void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel) {
- uint32_t dier = pwmp->tim->DIER;
-
-#if STM32_TIM_MAX_CHANNELS > 4
- /* Channels 4 and 5 do not support callbacks.*/
- osalDbgAssert(channel < 4, "callback not supported");
-#endif
-
- /* If the IRQ is not already enabled care must be taken to clear it,
- it is probably already pending because the timer is running.*/
- if ((dier & (2 << channel)) == 0) {
- pwmp->tim->SR = ~(2 << channel);
- pwmp->tim->DIER = dier | (2 << channel);
- }
-}
-
-/**
- * @brief Disables a channel de-activation edge notification.
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @pre The channel must have been activated using @p pwmEnableChannel().
- * @note If the notification is already disabled then the call has no effect.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] channel PWM channel identifier (0...channels-1)
- *
- * @notapi
- */
-void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel) {
-
- pwmp->tim->DIER &= ~(2 << channel);
-}
-
-/**
- * @brief Common TIM2...TIM5,TIM9 IRQ handler.
- * @note It is assumed that the various sources are only activated if the
- * associated callback pointer is not equal to @p NULL in order to not
- * perform an extra check in a potentially critical interrupt handler.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- *
- * @notapi
- */
-void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
- uint32_t sr;
-
- sr = pwmp->tim->SR;
- sr &= pwmp->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
- pwmp->tim->SR = ~sr;
- if (((sr & STM32_TIM_SR_CC1IF) != 0) &&
- (pwmp->config->channels[0].callback != NULL))
- pwmp->config->channels[0].callback(pwmp);
- if (((sr & STM32_TIM_SR_CC2IF) != 0) &&
- (pwmp->config->channels[1].callback != NULL))
- pwmp->config->channels[1].callback(pwmp);
- if (((sr & STM32_TIM_SR_CC3IF) != 0) &&
- (pwmp->config->channels[2].callback != NULL))
- pwmp->config->channels[2].callback(pwmp);
- if (((sr & STM32_TIM_SR_CC4IF) != 0) &&
- (pwmp->config->channels[3].callback != NULL))
- pwmp->config->channels[3].callback(pwmp);
- if (((sr & STM32_TIM_SR_UIF) != 0) && (pwmp->config->callback != NULL))
- pwmp->config->callback(pwmp);
-}
-
-#endif /* HAL_USE_PWM */
-
-/** @} */
+/*
+ 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 TIMv1/hal_pwm_lld.c
+ * @brief STM32 PWM subsystem low level driver header.
+ *
+ * @addtogroup PWM
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_PWM || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief PWMD1 driver identifier.
+ * @note The driver PWMD1 allocates the complex timer TIM1 when enabled.
+ */
+#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
+PWMDriver PWMD1;
+#endif
+
+/**
+ * @brief PWMD2 driver identifier.
+ * @note The driver PWMD2 allocates the timer TIM2 when enabled.
+ */
+#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
+PWMDriver PWMD2;
+#endif
+
+/**
+ * @brief PWMD3 driver identifier.
+ * @note The driver PWMD3 allocates the timer TIM3 when enabled.
+ */
+#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
+PWMDriver PWMD3;
+#endif
+
+/**
+ * @brief PWMD4 driver identifier.
+ * @note The driver PWMD4 allocates the timer TIM4 when enabled.
+ */
+#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
+PWMDriver PWMD4;
+#endif
+
+/**
+ * @brief PWMD5 driver identifier.
+ * @note The driver PWMD5 allocates the timer TIM5 when enabled.
+ */
+#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
+PWMDriver PWMD5;
+#endif
+
+/**
+ * @brief PWMD8 driver identifier.
+ * @note The driver PWMD8 allocates the timer TIM8 when enabled.
+ */
+#if STM32_PWM_USE_TIM8 || defined(__DOXYGEN__)
+PWMDriver PWMD8;
+#endif
+
+/**
+ * @brief PWMD9 driver identifier.
+ * @note The driver PWMD9 allocates the timer TIM9 when enabled.
+ */
+#if STM32_PWM_USE_TIM9 || defined(__DOXYGEN__)
+PWMDriver PWMD9;
+#endif
+
+/**
+ * @brief PWMD10 driver identifier.
+ * @note The driver PWMD10 allocates the timer TIM10 when enabled.
+ */
+#if STM32_PWM_USE_TIM10 || defined(__DOXYGEN__)
+PWMDriver PWMD10;
+#endif
+
+/**
+ * @brief PWMD11 driver identifier.
+ * @note The driver PWMD11 allocates the timer TIM11 when enabled.
+ */
+#if STM32_PWM_USE_TIM11 || defined(__DOXYGEN__)
+PWMDriver PWMD11;
+#endif
+
+/**
+ * @brief PWMD12 driver identifier.
+ * @note The driver PWMD12 allocates the timer TIM12 when enabled.
+ */
+#if STM32_PWM_USE_TIM12 || defined(__DOXYGEN__)
+PWMDriver PWMD12;
+#endif
+
+/**
+ * @brief PWMD13 driver identifier.
+ * @note The driver PWMD13 allocates the timer TIM13 when enabled.
+ */
+#if STM32_PWM_USE_TIM13 || defined(__DOXYGEN__)
+PWMDriver PWMD13;
+#endif
+
+/**
+ * @brief PWMD14 driver identifier.
+ * @note The driver PWMD14 allocates the timer TIM14 when enabled.
+ */
+#if STM32_PWM_USE_TIM14 || defined(__DOXYGEN__)
+PWMDriver PWMD14;
+#endif
+
+/**
+ * @brief PWMD15 driver identifier.
+ * @note The driver PWMD15 allocates the timer TIM15 when enabled.
+ */
+#if STM32_PWM_USE_TIM15 || defined(__DOXYGEN__)
+PWMDriver PWMD15;
+#endif
+
+/**
+ * @brief PWMD16 driver identifier.
+ * @note The driver PWMD16 allocates the timer TIM16 when enabled.
+ */
+#if STM32_PWM_USE_TIM16 || defined(__DOXYGEN__)
+PWMDriver PWMD16;
+#endif
+
+/**
+ * @brief PWMD17 driver identifier.
+ * @note The driver PWMD17 allocates the timer TIM17 when enabled.
+ */
+#if STM32_PWM_USE_TIM17 || defined(__DOXYGEN__)
+PWMDriver PWMD17;
+#endif
+
+/**
+ * @brief PWMD20 driver identifier.
+ * @note The driver PWMD20 allocates the timer TIM20 when enabled.
+ */
+#if STM32_PWM_USE_TIM20 || defined(__DOXYGEN__)
+PWMDriver PWMD20;
+#endif
+
+/**
+ * @brief PWMD21 driver identifier.
+ * @note The driver PWMD21 allocates the timer TIM21 when enabled.
+ */
+#if STM32_PWM_USE_TIM21 || defined(__DOXYGEN__)
+PWMDriver PWMD21;
+#endif
+
+/**
+ * @brief PWMD22 driver identifier.
+ * @note The driver PWMD22 allocates the timer TIM22 when enabled.
+ */
+#if STM32_PWM_USE_TIM22 || defined(__DOXYGEN__)
+PWMDriver PWMD22;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_PWM_USE_TIM1 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+#if !defined(STM32_TIM1_UP_HANDLER)
+#error "STM32_TIM1_UP_HANDLER not defined"
+#endif
+/**
+ * @brief TIM1 update interrupt handler.
+ * @note It is assumed that this interrupt is only activated if the callback
+ * pointer is not equal to @p NULL in order to not perform an extra
+ * check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM1_UP_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#if !defined(STM32_TIM1_CC_HANDLER)
+#error "STM32_TIM1_CC_HANDLER not defined"
+#endif
+/**
+ * @brief TIM1 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM1_CC_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM1_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM1 */
+
+#if STM32_PWM_USE_TIM2 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+#if !defined(STM32_TIM2_HANDLER)
+#error "STM32_TIM2_HANDLER not defined"
+#endif
+/**
+ * @brief TIM2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM2_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM2 */
+
+#if STM32_PWM_USE_TIM3 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+#if !defined(STM32_TIM3_HANDLER)
+#error "STM32_TIM3_HANDLER not defined"
+#endif
+/**
+ * @brief TIM3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM3_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM3 */
+
+#if STM32_PWM_USE_TIM4 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+#if !defined(STM32_TIM4_HANDLER)
+#error "STM32_TIM4_HANDLER not defined"
+#endif
+/**
+ * @brief TIM4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM4_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM4 */
+
+#if STM32_PWM_USE_TIM5 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+#if !defined(STM32_TIM5_HANDLER)
+#error "STM32_TIM5_HANDLER not defined"
+#endif
+/**
+ * @brief TIM5 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM5_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM5 */
+
+#if STM32_PWM_USE_TIM8 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+#if !defined(STM32_TIM8_UP_HANDLER)
+#error "STM32_TIM8_UP_HANDLER not defined"
+#endif
+/**
+ * @brief TIM8 update interrupt handler.
+ * @note It is assumed that this interrupt is only activated if the callback
+ * pointer is not equal to @p NULL in order to not perform an extra
+ * check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM8_UP_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+#if !defined(STM32_TIM8_CC_HANDLER)
+#error "STM32_TIM8_CC_HANDLER not defined"
+#endif
+/**
+ * @brief TIM8 compare interrupt handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_TIM8_CC_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ pwm_lld_serve_interrupt(&PWMD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* !defined(STM32_TIM8_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM8 */
+
+#if STM32_PWM_USE_TIM9 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM9_SUPPRESS_ISR)
+#error "TIM9 ISR not defined by platform"
+#endif /* !defined(STM32_TIM9_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM9 */
+
+#if STM32_PWM_USE_TIM10 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM10_SUPPRESS_ISR)
+#error "TIM10 ISR not defined by platform"
+#endif /* !defined(STM32_TIM10_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM10 */
+
+#if STM32_PWM_USE_TIM11 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM11_SUPPRESS_ISR)
+#error "TIM11 ISR not defined by platform"
+#endif /* !defined(STM32_TIM11_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM11 */
+
+#if STM32_PWM_USE_TIM12 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM12_SUPPRESS_ISR)
+#error "TIM12 ISR not defined by platform"
+#endif /* !defined(STM32_TIM12_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM12 */
+
+#if STM32_PWM_USE_TIM13 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM13_SUPPRESS_ISR)
+#error "TIM13 ISR not defined by platform"
+#endif /* !defined(STM32_TIM13_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM13 */
+
+#if STM32_PWM_USE_TIM14 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM14_SUPPRESS_ISR)
+#error "TIM14 ISR not defined by platform"
+#endif /* !defined(STM32_TIM14_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM14 */
+
+#if STM32_PWM_USE_TIM15 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM15_SUPPRESS_ISR)
+#error "TIM15 ISR not defined by platform"
+#endif /* !defined(STM32_TIM15_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM15 */
+
+#if STM32_PWM_USE_TIM16 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM16_SUPPRESS_ISR)
+#error "TIM16 ISR not defined by platform"
+#endif /* !defined(STM32_TIM16_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM16 */
+
+#if STM32_PWM_USE_TIM17 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM17_SUPPRESS_ISR)
+#error "TIM17 ISR not defined by platform"
+#endif /* !defined(STM32_TIM17_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM17 */
+
+#if STM32_PWM_USE_TIM20 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM20_SUPPRESS_ISR)
+#error "TIM20 ISR not defined by platform"
+#endif /* !defined(STM32_TIM20_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM20 */
+
+#if STM32_PWM_USE_TIM21 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM21_SUPPRESS_ISR)
+#error "TIM21 ISR not defined by platform"
+#endif /* !defined(STM32_TIM21_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM21 */
+
+#if STM32_PWM_USE_TIM22 || defined(__DOXYGEN__)
+#if !defined(STM32_TIM22_SUPPRESS_ISR)
+#error "TIM22 ISR not defined by platform"
+#endif /* !defined(STM32_TIM22_SUPPRESS_ISR) */
+#endif /* STM32_PWM_USE_TIM22 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level PWM driver initialization.
+ *
+ * @notapi
+ */
+void pwm_lld_init(void) {
+
+#if STM32_PWM_USE_TIM1
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD1);
+ PWMD1.channels = STM32_TIM1_CHANNELS;
+ PWMD1.tim = STM32_TIM1;
+#endif
+
+#if STM32_PWM_USE_TIM2
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD2);
+ PWMD2.channels = STM32_TIM2_CHANNELS;
+ PWMD2.tim = STM32_TIM2;
+#endif
+
+#if STM32_PWM_USE_TIM3
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD3);
+ PWMD3.channels = STM32_TIM3_CHANNELS;
+ PWMD3.tim = STM32_TIM3;
+#endif
+
+#if STM32_PWM_USE_TIM4
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD4);
+ PWMD4.channels = STM32_TIM4_CHANNELS;
+ PWMD4.tim = STM32_TIM4;
+#endif
+
+#if STM32_PWM_USE_TIM5
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD5);
+ PWMD5.channels = STM32_TIM5_CHANNELS;
+ PWMD5.tim = STM32_TIM5;
+#endif
+
+#if STM32_PWM_USE_TIM8
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD8);
+ PWMD8.channels = STM32_TIM8_CHANNELS;
+ PWMD8.tim = STM32_TIM8;
+#endif
+
+#if STM32_PWM_USE_TIM9
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD9);
+ PWMD9.channels = STM32_TIM9_CHANNELS;
+ PWMD9.tim = STM32_TIM9;
+#endif
+
+#if STM32_PWM_USE_TIM10
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD10);
+ PWMD10.channels = STM32_TIM10_CHANNELS;
+ PWMD10.tim = STM32_TIM10;
+#endif
+
+#if STM32_PWM_USE_TIM11
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD11);
+ PWMD11.channels = STM32_TIM11_CHANNELS;
+ PWMD11.tim = STM32_TIM11;
+#endif
+
+#if STM32_PWM_USE_TIM12
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD12);
+ PWMD12.channels = STM32_TIM12_CHANNELS;
+ PWMD12.tim = STM32_TIM12;
+#endif
+
+#if STM32_PWM_USE_TIM13
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD13);
+ PWMD13.channels = STM32_TIM13_CHANNELS;
+ PWMD13.tim = STM32_TIM13;
+#endif
+
+#if STM32_PWM_USE_TIM14
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD14);
+ PWMD14.channels = STM32_TIM14_CHANNELS;
+ PWMD14.tim = STM32_TIM14;
+#endif
+
+#if STM32_PWM_USE_TIM15
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD15);
+ PWMD15.channels = STM32_TIM15_CHANNELS;
+ PWMD15.tim = STM32_TIM15;
+#endif
+
+#if STM32_PWM_USE_TIM16
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD16);
+ PWMD16.channels = STM32_TIM16_CHANNELS;
+ PWMD16.tim = STM32_TIM16;
+#endif
+
+#if STM32_PWM_USE_TIM17
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD17);
+ PWMD17.channels = STM32_TIM17_CHANNELS;
+ PWMD17.tim = STM32_TIM17;
+#endif
+
+#if STM32_PWM_USE_TIM20
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD20);
+ PWMD20.channels = STM32_TIM20_CHANNELS;
+ PWMD20.tim = STM32_TIM20;
+#endif
+
+#if STM32_PWM_USE_TIM21
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD21);
+ PWMD21.channels = STM32_TIM21_CHANNELS;
+ PWMD21.tim = STM32_TIM21;
+#endif
+
+#if STM32_PWM_USE_TIM22
+ /* Driver initialization.*/
+ pwmObjectInit(&PWMD22);
+ PWMD22.channels = STM32_TIM22_CHANNELS;
+ PWMD22.tim = STM32_TIM22;
+#endif
+}
+
+/**
+ * @brief Configures and activates the PWM peripheral.
+ * @note Starting a driver that is already in the @p PWM_READY state
+ * disables all the active channels.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_start(PWMDriver *pwmp) {
+ uint32_t psc;
+ uint32_t ccer;
+
+ if (pwmp->state == PWM_STOP) {
+ /* Clock activation and timer reset.*/
+#if STM32_PWM_USE_TIM1
+ if (&PWMD1 == pwmp) {
+ rccEnableTIM1(true);
+ rccResetTIM1();
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_PWM_TIM1_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM1CLK)
+ pwmp->clock = STM32_TIM1CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM2
+ if (&PWMD2 == pwmp) {
+ rccEnableTIM2(true);
+ rccResetTIM2();
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM2_NUMBER, STM32_PWM_TIM2_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM2CLK)
+ pwmp->clock = STM32_TIM2CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM3
+ if (&PWMD3 == pwmp) {
+ rccEnableTIM3(true);
+ rccResetTIM3();
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM3_NUMBER, STM32_PWM_TIM3_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM3CLK)
+ pwmp->clock = STM32_TIM3CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM4
+ if (&PWMD4 == pwmp) {
+ rccEnableTIM4(true);
+ rccResetTIM4();
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM4_NUMBER, STM32_PWM_TIM4_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM4CLK)
+ pwmp->clock = STM32_TIM4CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM5
+ if (&PWMD5 == pwmp) {
+ rccEnableTIM5(true);
+ rccResetTIM5();
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM5_NUMBER, STM32_PWM_TIM5_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM5CLK)
+ pwmp->clock = STM32_TIM5CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM8
+ if (&PWMD8 == pwmp) {
+ rccEnableTIM8(true);
+ rccResetTIM8();
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+ nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
+ nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_PWM_TIM8_IRQ_PRIORITY);
+#endif
+#if defined(STM32_TIM8CLK)
+ pwmp->clock = STM32_TIM8CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM9
+ if (&PWMD9 == pwmp) {
+ rccEnableTIM9(true);
+ rccResetTIM9();
+#if defined(STM32_TIM9CLK)
+ pwmp->clock = STM32_TIM9CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM10
+ if (&PWMD10 == pwmp) {
+ rccEnableTIM10(true);
+ rccResetTIM10();
+#if defined(STM32_TIM10CLK)
+ pwmp->clock = STM32_TIM10CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM11
+ if (&PWMD11 == pwmp) {
+ rccEnableTIM11(true);
+ rccResetTIM11();
+#if defined(STM32_TIM11CLK)
+ pwmp->clock = STM32_TIM11CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM12
+ if (&PWMD12 == pwmp) {
+ rccEnableTIM12(true);
+ rccResetTIM12();
+#if defined(STM32_TIM12CLK)
+ pwmp->clock = STM32_TIM12CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM13
+ if (&PWMD13 == pwmp) {
+ rccEnableTIM13(true);
+ rccResetTIM13();
+#if defined(STM32_TIM13CLK)
+ pwmp->clock = STM32_TIM13CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM14
+ if (&PWMD14 == pwmp) {
+ rccEnableTIM14(true);
+ rccResetTIM14();
+#if defined(STM32_TIM14CLK)
+ pwmp->clock = STM32_TIM14CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM15
+ if (&PWMD15 == pwmp) {
+ rccEnableTIM15(true);
+ rccResetTIM15();
+#if defined(STM32_TIM15CLK)
+ pwmp->clock = STM32_TIM15CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM16
+ if (&PWMD16 == pwmp) {
+ rccEnableTIM16(true);
+ rccResetTIM16();
+#if defined(STM32_TIM16CLK)
+ pwmp->clock = STM32_TIM16CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM17
+ if (&PWMD17 == pwmp) {
+ rccEnableTIM17(true);
+ rccResetTIM17();
+#if defined(STM32_TIM17CLK)
+ pwmp->clock = STM32_TIM17CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM20
+ if (&PWMD20 == pwmp) {
+ rccEnableTIM20(true);
+ rccResetTIM20();
+#if defined(STM32_TIM20CLK)
+ pwmp->clock = STM32_TIM20CLK;
+#else
+ pwmp->clock = STM32_TIMCLK2;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM21
+ if (&PWMD21 == pwmp) {
+ rccEnableTIM21(true);
+ rccResetTIM21();
+#if defined(STM32_TIM21CLK)
+ pwmp->clock = STM32_TIM21CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+#if STM32_PWM_USE_TIM22
+ if (&PWMD22 == pwmp) {
+ rccEnableTIM22(true);
+ rccResetTIM22();
+#if defined(STM32_TIM22CLK)
+ pwmp->clock = STM32_TIM22CLK;
+#else
+ pwmp->clock = STM32_TIMCLK1;
+#endif
+ }
+#endif
+
+ /* All channels configured in PWM1 mode with preload enabled and will
+ stay that way until the driver is stopped.*/
+ pwmp->tim->CCMR1 = STM32_TIM_CCMR1_OC1M(6) | STM32_TIM_CCMR1_OC1PE |
+ STM32_TIM_CCMR1_OC2M(6) | STM32_TIM_CCMR1_OC2PE;
+ pwmp->tim->CCMR2 = STM32_TIM_CCMR2_OC3M(6) | STM32_TIM_CCMR2_OC3PE |
+ STM32_TIM_CCMR2_OC4M(6) | STM32_TIM_CCMR2_OC4PE;
+#if STM32_TIM_MAX_CHANNELS > 4
+ pwmp->tim->CCMR3 = STM32_TIM_CCMR3_OC5M(6) | STM32_TIM_CCMR3_OC5PE |
+ STM32_TIM_CCMR3_OC6M(6) | STM32_TIM_CCMR3_OC6PE;
+#endif
+ }
+ else {
+ /* Driver re-configuration scenario, it must be stopped first.*/
+ pwmp->tim->CR1 = 0; /* Timer disabled. */
+ pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */
+ pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */
+ pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */
+ pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */
+#if STM32_TIM_MAX_CHANNELS > 4
+ if (pwmp->channels > 4) {
+ pwmp->tim->CCXR[0] = 0; /* Comparator 5 disabled. */
+ pwmp->tim->CCXR[1] = 0; /* Comparator 6 disabled. */
+ }
+#endif
+ pwmp->tim->CNT = 0; /* Counter reset to zero. */
+ }
+
+ /* Timer configuration.*/
+ psc = (pwmp->clock / pwmp->config->frequency) - 1;
+ osalDbgAssert((psc <= 0xFFFF) &&
+ ((psc + 1) * pwmp->config->frequency) == pwmp->clock,
+ "invalid frequency");
+ pwmp->tim->PSC = psc;
+ pwmp->tim->ARR = pwmp->period - 1;
+ pwmp->tim->CR2 = pwmp->config->cr2;
+
+ /* Output enables and polarities setup.*/
+ ccer = 0;
+ switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) {
+ case PWM_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC1P;
+ /* Falls through.*/
+ case PWM_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC1E;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) {
+ case PWM_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC2P;
+ /* Falls through.*/
+ case PWM_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC2E;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) {
+ case PWM_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC3P;
+ /* Falls through.*/
+ case PWM_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC3E;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) {
+ case PWM_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC4P;
+ /* Falls through.*/
+ case PWM_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC4E;
+ /* Falls through.*/
+ default:
+ ;
+ }
+#if STM32_PWM_USE_ADVANCED
+#if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && !STM32_PWM_USE_TIM20
+ if (&PWMD1 == pwmp) {
+#endif
+#if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && !STM32_PWM_USE_TIM20
+ if (&PWMD8 == pwmp) {
+#endif
+#if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && !STM32_PWM_USE_TIM20
+ if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) {
+#endif
+#if !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
+ if (&PWMD20 == pwmp) {
+#endif
+#if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
+ if ((&PWMD1 == pwmp) || (&PWMD20 == pwmp)) {
+#endif
+#if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
+ if ((&PWMD8 == pwmp) || (&PWMD20 == pwmp)) {
+#endif
+#if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 && STM32_PWM_USE_TIM20
+ if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp) || (&PWMD20 == pwmp)) {
+#endif
+ switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC1NP;
+ /* Falls through.*/
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC1NE;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC2NP;
+ /* Falls through.*/
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC2NE;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC3NP;
+ /* Falls through.*/
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC3NE;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ switch (pwmp->config->channels[3].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) {
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW:
+ ccer |= STM32_TIM_CCER_CC4NP;
+ /* Falls through.*/
+ case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH:
+ ccer |= STM32_TIM_CCER_CC4NE;
+ /* Falls through.*/
+ default:
+ ;
+ }
+ }
+#endif /* STM32_PWM_USE_ADVANCED*/
+
+ pwmp->tim->CCER = ccer;
+ pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */
+ pwmp->tim->SR = 0; /* Clear pending IRQs. */
+ pwmp->tim->DIER = pwmp->config->dier & /* DMA-related DIER settings. */
+ ~STM32_TIM_DIER_IRQ_MASK;
+#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 || STM32_PWM_USE_TIM20
+#if STM32_PWM_USE_ADVANCED
+ pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE;
+#else
+ pwmp->tim->BDTR = STM32_TIM_BDTR_MOE;
+#endif
+#endif
+ /* Timer configured and started.*/
+ pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS |
+ STM32_TIM_CR1_CEN;
+}
+
+/**
+ * @brief Deactivates the PWM peripheral.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_stop(PWMDriver *pwmp) {
+
+ /* If in ready state then disables the PWM clock.*/
+ if (pwmp->state == PWM_READY) {
+ pwmp->tim->CR1 = 0; /* Timer disabled. */
+ pwmp->tim->DIER = 0; /* All IRQs disabled. */
+ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */
+#if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 || STM32_PWM_USE_TIM20
+ pwmp->tim->BDTR = 0;
+#endif
+
+#if STM32_PWM_USE_TIM1
+ if (&PWMD1 == pwmp) {
+#if !defined(STM32_TIM1_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM1_UP_NUMBER);
+ nvicDisableVector(STM32_TIM1_CC_NUMBER);
+#endif
+ rccDisableTIM1();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM2
+ if (&PWMD2 == pwmp) {
+#if !defined(STM32_TIM2_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM2_NUMBER);
+#endif
+ rccDisableTIM2();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM3
+ if (&PWMD3 == pwmp) {
+#if !defined(STM32_TIM3_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM3_NUMBER);
+#endif
+ rccDisableTIM3();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM4
+ if (&PWMD4 == pwmp) {
+#if !defined(STM32_TIM4_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM4_NUMBER);
+#endif
+ rccDisableTIM4();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM5
+ if (&PWMD5 == pwmp) {
+#if !defined(STM32_TIM5_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM5_NUMBER);
+#endif
+ rccDisableTIM5();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM8
+ if (&PWMD8 == pwmp) {
+#if !defined(STM32_TIM8_SUPPRESS_ISR)
+ nvicDisableVector(STM32_TIM8_UP_NUMBER);
+ nvicDisableVector(STM32_TIM8_CC_NUMBER);
+#endif
+ rccDisableTIM8();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM9
+ if (&PWMD9 == pwmp) {
+ rccDisableTIM9();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM10
+ if (&PWMD10 == pwmp) {
+ rccDisableTIM10();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM11
+ if (&PWMD11 == pwmp) {
+ rccDisableTIM11();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM12
+ if (&PWMD12 == pwmp) {
+ rccDisableTIM12();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM13
+ if (&PWMD13 == pwmp) {
+ rccDisableTIM13();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM14
+ if (&PWMD14 == pwmp) {
+ rccDisableTIM14();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM15
+ if (&PWMD15 == pwmp) {
+ rccDisableTIM15();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM16
+ if (&PWMD16 == pwmp) {
+ rccDisableTIM16();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM17
+ if (&PWMD17 == pwmp) {
+ rccDisableTIM17();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM20
+ if (&PWMD20 == pwmp) {
+ rccDisableTIM20();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM21
+ if (&PWMD21 == pwmp) {
+ rccDisableTIM21();
+ }
+#endif
+
+#if STM32_PWM_USE_TIM22
+ if (&PWMD22 == pwmp) {
+ rccDisableTIM22();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Enables a PWM channel.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is active using the specified configuration.
+ * @note The function has effect at the next cycle start.
+ * @note Channel notification is not enabled.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ * @param[in] width PWM pulse width as clock pulses number
+ *
+ * @notapi
+ */
+void pwm_lld_enable_channel(PWMDriver *pwmp,
+ pwmchannel_t channel,
+ pwmcnt_t width) {
+
+ /* Changing channel duty cycle on the fly.*/
+#if STM32_TIM_MAX_CHANNELS <= 4
+ pwmp->tim->CCR[channel] = width;
+#else
+ if (channel < 4)
+ pwmp->tim->CCR[channel] = width;
+ else
+ pwmp->tim->CCXR[channel - 4] = width;
+#endif
+}
+
+/**
+ * @brief Disables a PWM channel and its notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The channel is disabled and its output line returned to the
+ * idle state.
+ * @note The function has effect at the next cycle start.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @notapi
+ */
+void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) {
+
+#if STM32_TIM_MAX_CHANNELS <= 4
+ pwmp->tim->CCR[channel] = 0;
+ pwmp->tim->DIER &= ~(2 << channel);
+#else
+ if (channel < 4) {
+ pwmp->tim->CCR[channel] = 0;
+ pwmp->tim->DIER &= ~(2 << channel);
+ }
+ else
+ pwmp->tim->CCXR[channel - 4] = 0;
+#endif
+}
+
+/**
+ * @brief Enables the periodic activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) {
+ uint32_t dier = pwmp->tim->DIER;
+
+ /* If the IRQ is not already enabled care must be taken to clear it,
+ it is probably already pending because the timer is running.*/
+ if ((dier & STM32_TIM_DIER_UIE) == 0) {
+ pwmp->tim->SR = ~STM32_TIM_SR_UIF;
+ pwmp->tim->DIER = dier | STM32_TIM_DIER_UIE;
+ }
+}
+
+/**
+ * @brief Disables the periodic activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) {
+
+ pwmp->tim->DIER &= ~STM32_TIM_DIER_UIE;
+}
+
+/**
+ * @brief Enables a channel de-activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @pre The channel must have been activated using @p pwmEnableChannel().
+ * @note If the notification is already enabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @notapi
+ */
+void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel) {
+ uint32_t dier = pwmp->tim->DIER;
+
+#if STM32_TIM_MAX_CHANNELS > 4
+ /* Channels 4 and 5 do not support callbacks.*/
+ osalDbgAssert(channel < 4, "callback not supported");
+#endif
+
+ /* If the IRQ is not already enabled care must be taken to clear it,
+ it is probably already pending because the timer is running.*/
+ if ((dier & (2 << channel)) == 0) {
+ pwmp->tim->SR = ~(2 << channel);
+ pwmp->tim->DIER = dier | (2 << channel);
+ }
+}
+
+/**
+ * @brief Disables a channel de-activation edge notification.
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @pre The channel must have been activated using @p pwmEnableChannel().
+ * @note If the notification is already disabled then the call has no effect.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] channel PWM channel identifier (0...channels-1)
+ *
+ * @notapi
+ */
+void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel) {
+
+ pwmp->tim->DIER &= ~(2 << channel);
+}
+
+/**
+ * @brief Common TIM2...TIM5,TIM9 IRQ handler.
+ * @note It is assumed that the various sources are only activated if the
+ * associated callback pointer is not equal to @p NULL in order to not
+ * perform an extra check in a potentially critical interrupt handler.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ *
+ * @notapi
+ */
+void pwm_lld_serve_interrupt(PWMDriver *pwmp) {
+ uint32_t sr;
+
+ sr = pwmp->tim->SR;
+ sr &= pwmp->tim->DIER & STM32_TIM_DIER_IRQ_MASK;
+ pwmp->tim->SR = ~sr;
+ if (((sr & STM32_TIM_SR_CC1IF) != 0) &&
+ (pwmp->config->channels[0].callback != NULL))
+ pwmp->config->channels[0].callback(pwmp);
+ if (((sr & STM32_TIM_SR_CC2IF) != 0) &&
+ (pwmp->config->channels[1].callback != NULL))
+ pwmp->config->channels[1].callback(pwmp);
+ if (((sr & STM32_TIM_SR_CC3IF) != 0) &&
+ (pwmp->config->channels[2].callback != NULL))
+ pwmp->config->channels[2].callback(pwmp);
+ if (((sr & STM32_TIM_SR_CC4IF) != 0) &&
+ (pwmp->config->channels[3].callback != NULL))
+ pwmp->config->channels[3].callback(pwmp);
+ if (((sr & STM32_TIM_SR_UIF) != 0) && (pwmp->config->callback != NULL))
+ pwmp->config->callback(pwmp);
+}
+
+#endif /* HAL_USE_PWM */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.h
index b244e8b4ed..a1fce8ea60 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_pwm_lld.h
@@ -1,1034 +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 TIMv1/hal_pwm_lld.h
- * @brief STM32 PWM subsystem low level driver header.
- *
- * @addtogroup PWM
- * @{
- */
-
-#ifndef HAL_PWM_LLD_H
-#define HAL_PWM_LLD_H
-
-#if HAL_USE_PWM || defined(__DOXYGEN__)
-
-#include "stm32_tim.h"
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Number of PWM channels per PWM driver.
- */
-#define PWM_CHANNELS STM32_TIM_MAX_CHANNELS
-
-/**
- * @name STM32-specific PWM complementary output mode macros
- * @{
- */
-/**
- * @brief Complementary output modes mask.
- * @note This is an STM32-specific setting.
- */
-#define PWM_COMPLEMENTARY_OUTPUT_MASK 0xF0
-
-/**
- * @brief Complementary output not driven.
- * @note This is an STM32-specific setting.
- */
-#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00
-
-/**
- * @brief Complementary output, active is logic level one.
- * @note This is an STM32-specific setting.
- * @note This setting is only available if the configuration option
- * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
- * timers TIM1 and TIM8.
- */
-#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10
-
-/**
- * @brief Complementary output, active is logic level zero.
- * @note This is an STM32-specific setting.
- * @note This setting is only available if the configuration option
- * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
- * timers TIM1 and TIM8.
- */
-#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief If advanced timer features switch.
- * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are
- * enabled.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_ADVANCED) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_ADVANCED FALSE
-#endif
-
-/**
- * @brief PWMD1 driver enable switch.
- * @details If set to @p TRUE the support for PWMD1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM1) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM1 FALSE
-#endif
-
-/**
- * @brief PWMD2 driver enable switch.
- * @details If set to @p TRUE the support for PWMD2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM2) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM2 FALSE
-#endif
-
-/**
- * @brief PWMD3 driver enable switch.
- * @details If set to @p TRUE the support for PWMD3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM3) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM3 FALSE
-#endif
-
-/**
- * @brief PWMD4 driver enable switch.
- * @details If set to @p TRUE the support for PWMD4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM4) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM4 FALSE
-#endif
-
-/**
- * @brief PWMD5 driver enable switch.
- * @details If set to @p TRUE the support for PWMD5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM5) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM5 FALSE
-#endif
-
-/**
- * @brief PWMD8 driver enable switch.
- * @details If set to @p TRUE the support for PWMD8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM8) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM8 FALSE
-#endif
-
-/**
- * @brief PWMD9 driver enable switch.
- * @details If set to @p TRUE the support for PWMD9 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM9) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM9 FALSE
-#endif
-
-/**
- * @brief PWMD10 driver enable switch.
- * @details If set to @p TRUE the support for PWMD10 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM10) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM10 FALSE
-#endif
-
-/**
- * @brief PWMD11 driver enable switch.
- * @details If set to @p TRUE the support for PWMD11 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM11) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM11 FALSE
-#endif
-
-/**
- * @brief PWMD12 driver enable switch.
- * @details If set to @p TRUE the support for PWMD12 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM12) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM12 FALSE
-#endif
-
-/**
- * @brief PWMD13 driver enable switch.
- * @details If set to @p TRUE the support for PWMD13 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM13) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM13 FALSE
-#endif
-
-/**
- * @brief PWMD14 driver enable switch.
- * @details If set to @p TRUE the support for PWMD14 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM14) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM14 FALSE
-#endif
-
-/**
- * @brief PWMD15 driver enable switch.
- * @details If set to @p TRUE the support for PWMD15 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM15) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM15 FALSE
-#endif
-
-/**
- * @brief PWMD16 driver enable switch.
- * @details If set to @p TRUE the support for PWMD16 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM16) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM16 FALSE
-#endif
-
-/**
- * @brief PWMD17 driver enable switch.
- * @details If set to @p TRUE the support for PWMD17 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM17) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM17 FALSE
-#endif
-
-/**
- * @brief PWMD20 driver enable switch.
- * @details If set to @p TRUE the support for PWMD20 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM20) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM20 FALSE
-#endif
-
-/**
- * @brief PWMD21 driver enable switch.
- * @details If set to @p TRUE the support for PWMD21 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM21) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM21 FALSE
-#endif
-
-/**
- * @brief PWMD22 driver enable switch.
- * @details If set to @p TRUE the support for PWMD22 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_PWM_USE_TIM22) || defined(__DOXYGEN__)
-#define STM32_PWM_USE_TIM22 FALSE
-#endif
-
-/**
- * @brief PWMD1 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM1_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD2 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM2_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD3 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM3_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD4 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM4_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD5 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM5_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD8 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM8_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD9 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM9_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD10 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM10_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM10_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD11 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM11_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD12 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM12_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD13 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM13_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM13_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD14 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM14_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD15 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM15_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM15_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD16 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM16_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM16_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD17 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM17_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM17_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD20 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM20_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM20_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD21 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM21_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM21_IRQ_PRIORITY 7
-#endif
-
-/**
- * @brief PWMD22 interrupt priority level setting.
- */
-#if !defined(STM32_PWM_TIM22_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_PWM_TIM22_IRQ_PRIORITY 7
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Configuration checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_HAS_TIM1)
-#define STM32_HAS_TIM1 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM2)
-#define STM32_HAS_TIM2 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM3)
-#define STM32_HAS_TIM3 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM4)
-#define STM32_HAS_TIM4 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM5)
-#define STM32_HAS_TIM5 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM8)
-#define STM32_HAS_TIM8 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM9)
-#define STM32_HAS_TIM9 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM10)
-#define STM32_HAS_TIM10 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM11)
-#define STM32_HAS_TIM11 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM12)
-#define STM32_HAS_TIM12 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM13)
-#define STM32_HAS_TIM13 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM14)
-#define STM32_HAS_TIM14 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM15)
-#define STM32_HAS_TIM15 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM16)
-#define STM32_HAS_TIM16 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM17)
-#define STM32_HAS_TIM17 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM20)
-#define STM32_HAS_TIM20 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM21)
-#define STM32_HAS_TIM21 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM22)
-#define STM32_HAS_TIM22 FALSE
-#endif
-
-#if STM32_PWM_USE_TIM1 && !STM32_HAS_TIM1
-#error "TIM1 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM2 && !STM32_HAS_TIM2
-#error "TIM2 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM3 && !STM32_HAS_TIM3
-#error "TIM3 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM4 && !STM32_HAS_TIM4
-#error "TIM4 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM5 && !STM32_HAS_TIM5
-#error "TIM5 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM8 && !STM32_HAS_TIM8
-#error "TIM8 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM9 && !STM32_HAS_TIM9
-#error "TIM9 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM10 && !STM32_HAS_TIM10
-#error "TIM10 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM11 && !STM32_HAS_TIM11
-#error "TIM11 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM12 && !STM32_HAS_TIM12
-#error "TIM12 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM13 && !STM32_HAS_TIM13
-#error "TIM13 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM14 && !STM32_HAS_TIM14
-#error "TIM14 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM15 && !STM32_HAS_TIM15
-#error "TIM15 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM16 && !STM32_HAS_TIM16
-#error "TIM16 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM17 && !STM32_HAS_TIM17
-#error "TIM17 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM20 && !STM32_HAS_TIM20
-#error "TIM20 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM21 && !STM32_HAS_TIM21
-#error "TIM21 not present in the selected device"
-#endif
-
-#if STM32_PWM_USE_TIM22 && !STM32_HAS_TIM22
-#error "TIM22 not present in the selected device"
-#endif
-
-#if !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM2 && \
- !STM32_PWM_USE_TIM3 && !STM32_PWM_USE_TIM4 && \
- !STM32_PWM_USE_TIM5 && !STM32_PWM_USE_TIM8 && \
- !STM32_PWM_USE_TIM9 && !STM32_PWM_USE_TIM10 && \
- !STM32_PWM_USE_TIM11 && !STM32_PWM_USE_TIM12 && \
- !STM32_PWM_USE_TIM13 && !STM32_PWM_USE_TIM14 && \
- !STM32_PWM_USE_TIM15 && !STM32_PWM_USE_TIM16 && \
- !STM32_PWM_USE_TIM17 && !STM32_PWM_USE_TIM20 && \
- !STM32_PWM_USE_TIM21 && !STM32_PWM_USE_TIM22
-#error "PWM driver activated but no TIM peripheral assigned"
-#endif
-
-#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && \
- !STM32_PWM_USE_TIM20
-#error "advanced mode selected but no advanced timer assigned"
-#endif
-
-/* Checks on allocation of TIMx units.*/
-#if STM32_PWM_USE_TIM1
-#if defined(STM32_TIM1_IS_USED)
-#error "PWMD1 requires TIM1 but the timer is already used"
-#else
-#define STM32_TIM1_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM2
-#if defined(STM32_TIM2_IS_USED)
-#error "PWMD2 requires TIM2 but the timer is already used"
-#else
-#define STM32_TIM2_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM3
-#if defined(STM32_TIM3_IS_USED)
-#error "PWMD3 requires TIM3 but the timer is already used"
-#else
-#define STM32_TIM3_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM4
-#if defined(STM32_TIM4_IS_USED)
-#error "PWMD4 requires TIM4 but the timer is already used"
-#else
-#define STM32_TIM4_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM5
-#if defined(STM32_TIM5_IS_USED)
-#error "PWMD5 requires TIM5 but the timer is already used"
-#else
-#define STM32_TIM5_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM8
-#if defined(STM32_TIM8_IS_USED)
-#error "PWMD8 requires TIM8 but the timer is already used"
-#else
-#define STM32_TIM8_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM9
-#if defined(STM32_TIM9_IS_USED)
-#error "PWMD9 requires TIM9 but the timer is already used"
-#else
-#define STM32_TIM9_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM10
-#if defined(STM32_TIM10_IS_USED)
-#error "PWMD10 requires TIM10 but the timer is already used"
-#else
-#define STM32_TIM10_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM11
-#if defined(STM32_TIM11_IS_USED)
-#error "PWMD11 requires TIM11 but the timer is already used"
-#else
-#define STM32_TIM11_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM12
-#if defined(STM32_TIM12_IS_USED)
-#error "PWMD12 requires TIM12 but the timer is already used"
-#else
-#define STM32_TIM12_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM13
-#if defined(STM32_TIM13_IS_USED)
-#error "PWMD13 requires TIM13 but the timer is already used"
-#else
-#define STM32_TIM13_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM14
-#if defined(STM32_TIM14_IS_USED)
-#error "PWMD14 requires TIM14 but the timer is already used"
-#else
-#define STM32_TIM14_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM15
-#if defined(STM32_TIM15_IS_USED)
-#error "PWMD15 requires TIM15 but the timer is already used"
-#else
-#define STM32_TIM15_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM16
-#if defined(STM32_TIM16_IS_USED)
-#error "PWMD16 requires TIM16 but the timer is already used"
-#else
-#define STM32_TIM16_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM17
-#if defined(STM32_TIM17_IS_USED)
-#error "PWMD17 requires TIM17 but the timer is already used"
-#else
-#define STM32_TIM17_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM20
-#if defined(STM32_TIM20_IS_USED)
-#error "PWMD20 requires TIM20 but the timer is already used"
-#else
-#define STM32_TIM20_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM21
-#if defined(STM32_TIM21_IS_USED)
-#error "PWMD21 requires TIM21 but the timer is already used"
-#else
-#define STM32_TIM21_IS_USED
-#endif
-#endif
-
-#if STM32_PWM_USE_TIM22
-#if defined(STM32_TIM22_IS_USED)
-#error "PWMD22 requires TIM22 but the timer is already used"
-#else
-#define STM32_TIM22_IS_USED
-#endif
-#endif
-
-/* IRQ priority checks.*/
-#if STM32_PWM_USE_TIM1 && !defined(STM32_TIM1_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM1"
-#endif
-
-#if STM32_PWM_USE_TIM2 && !defined(STM32_TIM2_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM2"
-#endif
-
-#if STM32_PWM_USE_TIM3 && !defined(STM32_TIM3_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM3"
-#endif
-
-#if STM32_PWM_USE_TIM4 && !defined(STM32_TIM4_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM4"
-#endif
-
-#if STM32_PWM_USE_TIM5 && !defined(STM32_TIM5_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM5"
-#endif
-
-#if STM32_PWM_USE_TIM8 && !defined(STM32_TIM8_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM8_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM8"
-#endif
-
-#if STM32_PWM_USE_TIM9 && !defined(STM32_TIM9_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM9_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM9"
-#endif
-
-#if STM32_PWM_USE_TIM10 && !defined(STM32_TIM10_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM10_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM10"
-#endif
-
-#if STM32_PWM_USE_TIM11 && !defined(STM32_TIM11_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM11_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM11"
-#endif
-
-#if STM32_PWM_USE_TIM12 && !defined(STM32_TIM12_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM12_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM12"
-#endif
-
-#if STM32_PWM_USE_TIM13 && !defined(STM32_TIM13_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM13_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM13"
-#endif
-
-#if STM32_PWM_USE_TIM14 && !defined(STM32_TIM14_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM14_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM14"
-#endif
-
-#if STM32_PWM_USE_TIM15 && !defined(STM32_TIM15_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM15_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM15"
-#endif
-
-#if STM32_PWM_USE_TIM16 && !defined(STM32_TIM16_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM16_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM16"
-#endif
-
-#if STM32_PWM_USE_TIM17 && !defined(STM32_TIM17_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM17_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM17"
-#endif
-
-#if STM32_PWM_USE_TIM20 && !defined(STM32_TIM20_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM20_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM20"
-#endif
-
-#if STM32_PWM_USE_TIM21 && !defined(STM32_TIM21_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM21_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM21"
-#endif
-
-#if STM32_PWM_USE_TIM22 && !defined(STM32_TIM22_SUPPRESS_ISR) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM22_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to TIM22"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a PWM mode.
- */
-typedef uint32_t pwmmode_t;
-
-/**
- * @brief Type of a PWM channel.
- */
-typedef uint8_t pwmchannel_t;
-
-/**
- * @brief Type of a channels mask.
- */
-typedef uint32_t pwmchnmsk_t;
-
-/**
- * @brief Type of a PWM counter.
- */
-typedef uint32_t pwmcnt_t;
-
-/**
- * @brief Type of a PWM driver channel configuration structure.
- */
-typedef struct {
- /**
- * @brief Channel active logic level.
- */
- pwmmode_t mode;
- /**
- * @brief Channel callback pointer.
- * @note This callback is invoked on the channel compare event. If set to
- * @p NULL then the callback is disabled.
- */
- pwmcallback_t callback;
- /* End of the mandatory fields.*/
-} PWMChannelConfig;
-
-/**
- * @brief Type of a PWM driver configuration structure.
- */
-typedef struct {
- /**
- * @brief Timer clock in Hz.
- * @note The low level can use assertions in order to catch invalid
- * frequency specifications.
- */
- uint32_t frequency;
- /**
- * @brief PWM period in ticks.
- * @note The low level can use assertions in order to catch invalid
- * period specifications.
- */
- pwmcnt_t period;
- /**
- * @brief Periodic callback pointer.
- * @note This callback is invoked on PWM counter reset. If set to
- * @p NULL then the callback is disabled.
- */
- pwmcallback_t callback;
- /**
- * @brief Channels configurations.
- */
- PWMChannelConfig channels[PWM_CHANNELS];
- /* End of the mandatory fields.*/
- /**
- * @brief TIM CR2 register initialization data.
- * @note The value of this field should normally be equal to zero.
- */
- uint32_t cr2;
-#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__)
- /**
- * @brief TIM BDTR (break & dead-time) register initialization data.
- * @note The value of this field should normally be equal to zero.
- */ \
- uint32_t bdtr;
-#endif
- /**
- * @brief TIM DIER register initialization data.
- * @note The value of this field should normally be equal to zero.
- * @note Only the DMA-related bits can be specified in this field.
- */
- uint32_t dier;
-} PWMConfig;
-
-/**
- * @brief Structure representing a PWM driver.
- */
-struct PWMDriver {
- /**
- * @brief Driver state.
- */
- pwmstate_t state;
- /**
- * @brief Current driver configuration data.
- */
- const PWMConfig *config;
- /**
- * @brief Current PWM period in ticks.
- */
- pwmcnt_t period;
- /**
- * @brief Mask of the enabled channels.
- */
- pwmchnmsk_t enabled;
- /**
- * @brief Number of channels in this instance.
- */
- pwmchannel_t channels;
-#if defined(PWM_DRIVER_EXT_FIELDS)
- PWM_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Timer base clock.
- */
- uint32_t clock;
- /**
- * @brief Pointer to the TIMx registers block.
- */
- stm32_tim_t *tim;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Changes the period the PWM peripheral.
- * @details This function changes the period of a PWM unit that has already
- * been activated using @p pwmStart().
- * @pre The PWM unit must have been activated using @p pwmStart().
- * @post The PWM unit period is changed to the new value.
- * @note The function has effect at the next cycle start.
- * @note If a period is specified that is shorter than the pulse width
- * programmed in one of the channels then the behavior is not
- * guaranteed.
- *
- * @param[in] pwmp pointer to a @p PWMDriver object
- * @param[in] period new cycle time in ticks
- *
- * @notapi
- */
-#define pwm_lld_change_period(pwmp, period) \
- ((pwmp)->tim->ARR = ((period) - 1))
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_PWM_USE_TIM1 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD1;
-#endif
-
-#if STM32_PWM_USE_TIM2 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD2;
-#endif
-
-#if STM32_PWM_USE_TIM3 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD3;
-#endif
-
-#if STM32_PWM_USE_TIM4 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD4;
-#endif
-
-#if STM32_PWM_USE_TIM5 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD5;
-#endif
-
-#if STM32_PWM_USE_TIM8 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD8;
-#endif
-
-#if STM32_PWM_USE_TIM9 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD9;
-#endif
-
-#if STM32_PWM_USE_TIM10 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD10;
-#endif
-
-#if STM32_PWM_USE_TIM11 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD11;
-#endif
-
-#if STM32_PWM_USE_TIM12 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD12;
-#endif
-
-#if STM32_PWM_USE_TIM13 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD13;
-#endif
-
-#if STM32_PWM_USE_TIM14 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD14;
-#endif
-
-#if STM32_PWM_USE_TIM15 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD15;
-#endif
-
-#if STM32_PWM_USE_TIM16 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD16;
-#endif
-
-#if STM32_PWM_USE_TIM17 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD17;
-#endif
-
-#if STM32_PWM_USE_TIM20 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD20;
-#endif
-
-#if STM32_PWM_USE_TIM21 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD21;
-#endif
-
-#if STM32_PWM_USE_TIM22 && !defined(__DOXYGEN__)
-extern PWMDriver PWMD22;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void pwm_lld_init(void);
- void pwm_lld_start(PWMDriver *pwmp);
- void pwm_lld_stop(PWMDriver *pwmp);
- void pwm_lld_enable_channel(PWMDriver *pwmp,
- pwmchannel_t channel,
- pwmcnt_t width);
- void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
- void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
- void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
- void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel);
- void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
- pwmchannel_t channel);
- void pwm_lld_serve_interrupt(PWMDriver *pwmp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_PWM */
-
-#endif /* HAL_PWM_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 TIMv1/hal_pwm_lld.h
+ * @brief STM32 PWM subsystem low level driver header.
+ *
+ * @addtogroup PWM
+ * @{
+ */
+
+#ifndef HAL_PWM_LLD_H
+#define HAL_PWM_LLD_H
+
+#if HAL_USE_PWM || defined(__DOXYGEN__)
+
+#include "stm32_tim.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of PWM channels per PWM driver.
+ */
+#define PWM_CHANNELS STM32_TIM_MAX_CHANNELS
+
+/**
+ * @name STM32-specific PWM complementary output mode macros
+ * @{
+ */
+/**
+ * @brief Complementary output modes mask.
+ * @note This is an STM32-specific setting.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_MASK 0xF0
+
+/**
+ * @brief Complementary output not driven.
+ * @note This is an STM32-specific setting.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00
+
+/**
+ * @brief Complementary output, active is logic level one.
+ * @note This is an STM32-specific setting.
+ * @note This setting is only available if the configuration option
+ * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
+ * timers TIM1 and TIM8.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10
+
+/**
+ * @brief Complementary output, active is logic level zero.
+ * @note This is an STM32-specific setting.
+ * @note This setting is only available if the configuration option
+ * @p STM32_PWM_USE_ADVANCED is set to TRUE and only for advanced
+ * timers TIM1 and TIM8.
+ */
+#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief If advanced timer features switch.
+ * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are
+ * enabled.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_ADVANCED) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_ADVANCED FALSE
+#endif
+
+/**
+ * @brief PWMD1 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM1) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM1 FALSE
+#endif
+
+/**
+ * @brief PWMD2 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM2) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM2 FALSE
+#endif
+
+/**
+ * @brief PWMD3 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM3) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM3 FALSE
+#endif
+
+/**
+ * @brief PWMD4 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM4) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM4 FALSE
+#endif
+
+/**
+ * @brief PWMD5 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM5) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM5 FALSE
+#endif
+
+/**
+ * @brief PWMD8 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM8) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM8 FALSE
+#endif
+
+/**
+ * @brief PWMD9 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD9 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM9) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM9 FALSE
+#endif
+
+/**
+ * @brief PWMD10 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD10 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM10) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM10 FALSE
+#endif
+
+/**
+ * @brief PWMD11 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD11 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM11) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM11 FALSE
+#endif
+
+/**
+ * @brief PWMD12 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD12 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM12) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM12 FALSE
+#endif
+
+/**
+ * @brief PWMD13 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD13 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM13) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM13 FALSE
+#endif
+
+/**
+ * @brief PWMD14 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD14 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM14) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM14 FALSE
+#endif
+
+/**
+ * @brief PWMD15 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD15 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM15) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM15 FALSE
+#endif
+
+/**
+ * @brief PWMD16 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD16 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM16) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM16 FALSE
+#endif
+
+/**
+ * @brief PWMD17 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD17 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM17) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM17 FALSE
+#endif
+
+/**
+ * @brief PWMD20 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD20 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM20) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM20 FALSE
+#endif
+
+/**
+ * @brief PWMD21 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD21 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM21) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM21 FALSE
+#endif
+
+/**
+ * @brief PWMD22 driver enable switch.
+ * @details If set to @p TRUE the support for PWMD22 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_PWM_USE_TIM22) || defined(__DOXYGEN__)
+#define STM32_PWM_USE_TIM22 FALSE
+#endif
+
+/**
+ * @brief PWMD1 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM1_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD2 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM2_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD3 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM3_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD4 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM4_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD5 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM5_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD8 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM8_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM8_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD9 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM9_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM9_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD10 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM10_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM10_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD11 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM11_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM11_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD12 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM12_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM12_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD13 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM13_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM13_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD14 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM14_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM14_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD15 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM15_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM15_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD16 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM16_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM16_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD17 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM17_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM17_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD20 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM20_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM20_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD21 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM21_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM21_IRQ_PRIORITY 7
+#endif
+
+/**
+ * @brief PWMD22 interrupt priority level setting.
+ */
+#if !defined(STM32_PWM_TIM22_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_PWM_TIM22_IRQ_PRIORITY 7
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Configuration checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_HAS_TIM1)
+#define STM32_HAS_TIM1 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM2)
+#define STM32_HAS_TIM2 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM3)
+#define STM32_HAS_TIM3 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM4)
+#define STM32_HAS_TIM4 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM5)
+#define STM32_HAS_TIM5 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM8)
+#define STM32_HAS_TIM8 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM9)
+#define STM32_HAS_TIM9 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM10)
+#define STM32_HAS_TIM10 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM11)
+#define STM32_HAS_TIM11 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM12)
+#define STM32_HAS_TIM12 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM13)
+#define STM32_HAS_TIM13 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM14)
+#define STM32_HAS_TIM14 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM15)
+#define STM32_HAS_TIM15 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM16)
+#define STM32_HAS_TIM16 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM17)
+#define STM32_HAS_TIM17 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM20)
+#define STM32_HAS_TIM20 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM21)
+#define STM32_HAS_TIM21 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM22)
+#define STM32_HAS_TIM22 FALSE
+#endif
+
+#if STM32_PWM_USE_TIM1 && !STM32_HAS_TIM1
+#error "TIM1 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM2 && !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM3 && !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM4 && !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM5 && !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM8 && !STM32_HAS_TIM8
+#error "TIM8 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM9 && !STM32_HAS_TIM9
+#error "TIM9 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM10 && !STM32_HAS_TIM10
+#error "TIM10 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM11 && !STM32_HAS_TIM11
+#error "TIM11 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM12 && !STM32_HAS_TIM12
+#error "TIM12 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM13 && !STM32_HAS_TIM13
+#error "TIM13 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM14 && !STM32_HAS_TIM14
+#error "TIM14 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM15 && !STM32_HAS_TIM15
+#error "TIM15 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM16 && !STM32_HAS_TIM16
+#error "TIM16 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM17 && !STM32_HAS_TIM17
+#error "TIM17 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM20 && !STM32_HAS_TIM20
+#error "TIM20 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM21 && !STM32_HAS_TIM21
+#error "TIM21 not present in the selected device"
+#endif
+
+#if STM32_PWM_USE_TIM22 && !STM32_HAS_TIM22
+#error "TIM22 not present in the selected device"
+#endif
+
+#if !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM2 && \
+ !STM32_PWM_USE_TIM3 && !STM32_PWM_USE_TIM4 && \
+ !STM32_PWM_USE_TIM5 && !STM32_PWM_USE_TIM8 && \
+ !STM32_PWM_USE_TIM9 && !STM32_PWM_USE_TIM10 && \
+ !STM32_PWM_USE_TIM11 && !STM32_PWM_USE_TIM12 && \
+ !STM32_PWM_USE_TIM13 && !STM32_PWM_USE_TIM14 && \
+ !STM32_PWM_USE_TIM15 && !STM32_PWM_USE_TIM16 && \
+ !STM32_PWM_USE_TIM17 && !STM32_PWM_USE_TIM20 && \
+ !STM32_PWM_USE_TIM21 && !STM32_PWM_USE_TIM22
+#error "PWM driver activated but no TIM peripheral assigned"
+#endif
+
+#if STM32_PWM_USE_ADVANCED && !STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 && \
+ !STM32_PWM_USE_TIM20
+#error "advanced mode selected but no advanced timer assigned"
+#endif
+
+/* Checks on allocation of TIMx units.*/
+#if STM32_PWM_USE_TIM1
+#if defined(STM32_TIM1_IS_USED)
+#error "PWMD1 requires TIM1 but the timer is already used"
+#else
+#define STM32_TIM1_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM2
+#if defined(STM32_TIM2_IS_USED)
+#error "PWMD2 requires TIM2 but the timer is already used"
+#else
+#define STM32_TIM2_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM3
+#if defined(STM32_TIM3_IS_USED)
+#error "PWMD3 requires TIM3 but the timer is already used"
+#else
+#define STM32_TIM3_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM4
+#if defined(STM32_TIM4_IS_USED)
+#error "PWMD4 requires TIM4 but the timer is already used"
+#else
+#define STM32_TIM4_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM5
+#if defined(STM32_TIM5_IS_USED)
+#error "PWMD5 requires TIM5 but the timer is already used"
+#else
+#define STM32_TIM5_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM8
+#if defined(STM32_TIM8_IS_USED)
+#error "PWMD8 requires TIM8 but the timer is already used"
+#else
+#define STM32_TIM8_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM9
+#if defined(STM32_TIM9_IS_USED)
+#error "PWMD9 requires TIM9 but the timer is already used"
+#else
+#define STM32_TIM9_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM10
+#if defined(STM32_TIM10_IS_USED)
+#error "PWMD10 requires TIM10 but the timer is already used"
+#else
+#define STM32_TIM10_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM11
+#if defined(STM32_TIM11_IS_USED)
+#error "PWMD11 requires TIM11 but the timer is already used"
+#else
+#define STM32_TIM11_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM12
+#if defined(STM32_TIM12_IS_USED)
+#error "PWMD12 requires TIM12 but the timer is already used"
+#else
+#define STM32_TIM12_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM13
+#if defined(STM32_TIM13_IS_USED)
+#error "PWMD13 requires TIM13 but the timer is already used"
+#else
+#define STM32_TIM13_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM14
+#if defined(STM32_TIM14_IS_USED)
+#error "PWMD14 requires TIM14 but the timer is already used"
+#else
+#define STM32_TIM14_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM15
+#if defined(STM32_TIM15_IS_USED)
+#error "PWMD15 requires TIM15 but the timer is already used"
+#else
+#define STM32_TIM15_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM16
+#if defined(STM32_TIM16_IS_USED)
+#error "PWMD16 requires TIM16 but the timer is already used"
+#else
+#define STM32_TIM16_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM17
+#if defined(STM32_TIM17_IS_USED)
+#error "PWMD17 requires TIM17 but the timer is already used"
+#else
+#define STM32_TIM17_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM20
+#if defined(STM32_TIM20_IS_USED)
+#error "PWMD20 requires TIM20 but the timer is already used"
+#else
+#define STM32_TIM20_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM21
+#if defined(STM32_TIM21_IS_USED)
+#error "PWMD21 requires TIM21 but the timer is already used"
+#else
+#define STM32_TIM21_IS_USED
+#endif
+#endif
+
+#if STM32_PWM_USE_TIM22
+#if defined(STM32_TIM22_IS_USED)
+#error "PWMD22 requires TIM22 but the timer is already used"
+#else
+#define STM32_TIM22_IS_USED
+#endif
+#endif
+
+/* IRQ priority checks.*/
+#if STM32_PWM_USE_TIM1 && !defined(STM32_TIM1_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM1"
+#endif
+
+#if STM32_PWM_USE_TIM2 && !defined(STM32_TIM2_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM2"
+#endif
+
+#if STM32_PWM_USE_TIM3 && !defined(STM32_TIM3_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM3"
+#endif
+
+#if STM32_PWM_USE_TIM4 && !defined(STM32_TIM4_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM4"
+#endif
+
+#if STM32_PWM_USE_TIM5 && !defined(STM32_TIM5_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM5"
+#endif
+
+#if STM32_PWM_USE_TIM8 && !defined(STM32_TIM8_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM8_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM8"
+#endif
+
+#if STM32_PWM_USE_TIM9 && !defined(STM32_TIM9_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM9_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM9"
+#endif
+
+#if STM32_PWM_USE_TIM10 && !defined(STM32_TIM10_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM10_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM10"
+#endif
+
+#if STM32_PWM_USE_TIM11 && !defined(STM32_TIM11_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM11_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM11"
+#endif
+
+#if STM32_PWM_USE_TIM12 && !defined(STM32_TIM12_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM12_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM12"
+#endif
+
+#if STM32_PWM_USE_TIM13 && !defined(STM32_TIM13_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM13_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM13"
+#endif
+
+#if STM32_PWM_USE_TIM14 && !defined(STM32_TIM14_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM14_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM14"
+#endif
+
+#if STM32_PWM_USE_TIM15 && !defined(STM32_TIM15_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM15_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM15"
+#endif
+
+#if STM32_PWM_USE_TIM16 && !defined(STM32_TIM16_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM16_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM16"
+#endif
+
+#if STM32_PWM_USE_TIM17 && !defined(STM32_TIM17_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM17_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM17"
+#endif
+
+#if STM32_PWM_USE_TIM20 && !defined(STM32_TIM20_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM20_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM20"
+#endif
+
+#if STM32_PWM_USE_TIM21 && !defined(STM32_TIM21_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM21_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM21"
+#endif
+
+#if STM32_PWM_USE_TIM22 && !defined(STM32_TIM22_SUPPRESS_ISR) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_PWM_TIM22_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to TIM22"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a PWM mode.
+ */
+typedef uint32_t pwmmode_t;
+
+/**
+ * @brief Type of a PWM channel.
+ */
+typedef uint8_t pwmchannel_t;
+
+/**
+ * @brief Type of a channels mask.
+ */
+typedef uint32_t pwmchnmsk_t;
+
+/**
+ * @brief Type of a PWM counter.
+ */
+typedef uint32_t pwmcnt_t;
+
+/**
+ * @brief Type of a PWM driver channel configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Channel active logic level.
+ */
+ pwmmode_t mode;
+ /**
+ * @brief Channel callback pointer.
+ * @note This callback is invoked on the channel compare event. If set to
+ * @p NULL then the callback is disabled.
+ */
+ pwmcallback_t callback;
+ /* End of the mandatory fields.*/
+} PWMChannelConfig;
+
+/**
+ * @brief Type of a PWM driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Timer clock in Hz.
+ * @note The low level can use assertions in order to catch invalid
+ * frequency specifications.
+ */
+ uint32_t frequency;
+ /**
+ * @brief PWM period in ticks.
+ * @note The low level can use assertions in order to catch invalid
+ * period specifications.
+ */
+ pwmcnt_t period;
+ /**
+ * @brief Periodic callback pointer.
+ * @note This callback is invoked on PWM counter reset. If set to
+ * @p NULL then the callback is disabled.
+ */
+ pwmcallback_t callback;
+ /**
+ * @brief Channels configurations.
+ */
+ PWMChannelConfig channels[PWM_CHANNELS];
+ /* End of the mandatory fields.*/
+ /**
+ * @brief TIM CR2 register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */
+ uint32_t cr2;
+#if STM32_PWM_USE_ADVANCED || defined(__DOXYGEN__)
+ /**
+ * @brief TIM BDTR (break & dead-time) register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ */ \
+ uint32_t bdtr;
+#endif
+ /**
+ * @brief TIM DIER register initialization data.
+ * @note The value of this field should normally be equal to zero.
+ * @note Only the DMA-related bits can be specified in this field.
+ */
+ uint32_t dier;
+} PWMConfig;
+
+/**
+ * @brief Structure representing a PWM driver.
+ */
+struct PWMDriver {
+ /**
+ * @brief Driver state.
+ */
+ pwmstate_t state;
+ /**
+ * @brief Current driver configuration data.
+ */
+ const PWMConfig *config;
+ /**
+ * @brief Current PWM period in ticks.
+ */
+ pwmcnt_t period;
+ /**
+ * @brief Mask of the enabled channels.
+ */
+ pwmchnmsk_t enabled;
+ /**
+ * @brief Number of channels in this instance.
+ */
+ pwmchannel_t channels;
+#if defined(PWM_DRIVER_EXT_FIELDS)
+ PWM_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Timer base clock.
+ */
+ uint32_t clock;
+ /**
+ * @brief Pointer to the TIMx registers block.
+ */
+ stm32_tim_t *tim;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Changes the period the PWM peripheral.
+ * @details This function changes the period of a PWM unit that has already
+ * been activated using @p pwmStart().
+ * @pre The PWM unit must have been activated using @p pwmStart().
+ * @post The PWM unit period is changed to the new value.
+ * @note The function has effect at the next cycle start.
+ * @note If a period is specified that is shorter than the pulse width
+ * programmed in one of the channels then the behavior is not
+ * guaranteed.
+ *
+ * @param[in] pwmp pointer to a @p PWMDriver object
+ * @param[in] period new cycle time in ticks
+ *
+ * @notapi
+ */
+#define pwm_lld_change_period(pwmp, period) \
+ ((pwmp)->tim->ARR = ((period) - 1))
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_PWM_USE_TIM1 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD1;
+#endif
+
+#if STM32_PWM_USE_TIM2 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD2;
+#endif
+
+#if STM32_PWM_USE_TIM3 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD3;
+#endif
+
+#if STM32_PWM_USE_TIM4 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD4;
+#endif
+
+#if STM32_PWM_USE_TIM5 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD5;
+#endif
+
+#if STM32_PWM_USE_TIM8 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD8;
+#endif
+
+#if STM32_PWM_USE_TIM9 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD9;
+#endif
+
+#if STM32_PWM_USE_TIM10 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD10;
+#endif
+
+#if STM32_PWM_USE_TIM11 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD11;
+#endif
+
+#if STM32_PWM_USE_TIM12 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD12;
+#endif
+
+#if STM32_PWM_USE_TIM13 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD13;
+#endif
+
+#if STM32_PWM_USE_TIM14 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD14;
+#endif
+
+#if STM32_PWM_USE_TIM15 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD15;
+#endif
+
+#if STM32_PWM_USE_TIM16 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD16;
+#endif
+
+#if STM32_PWM_USE_TIM17 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD17;
+#endif
+
+#if STM32_PWM_USE_TIM20 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD20;
+#endif
+
+#if STM32_PWM_USE_TIM21 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD21;
+#endif
+
+#if STM32_PWM_USE_TIM22 && !defined(__DOXYGEN__)
+extern PWMDriver PWMD22;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void pwm_lld_init(void);
+ void pwm_lld_start(PWMDriver *pwmp);
+ void pwm_lld_stop(PWMDriver *pwmp);
+ void pwm_lld_enable_channel(PWMDriver *pwmp,
+ pwmchannel_t channel,
+ pwmcnt_t width);
+ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
+ void pwm_lld_enable_periodic_notification(PWMDriver *pwmp);
+ void pwm_lld_disable_periodic_notification(PWMDriver *pwmp);
+ void pwm_lld_enable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel);
+ void pwm_lld_disable_channel_notification(PWMDriver *pwmp,
+ pwmchannel_t channel);
+ void pwm_lld_serve_interrupt(PWMDriver *pwmp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_PWM */
+
+#endif /* HAL_PWM_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c
index 4ffcc7aeb1..741361bb5b 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c
@@ -1,492 +1,492 @@
-/*
- 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 TIMv1/hal_st_lld.c
- * @brief ST Driver subsystem low level driver code.
- *
- * @addtogroup ST
- * @{
- */
-
-#include "hal.h"
-
-#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
-
-#if (OSAL_ST_RESOLUTION == 32)
-#define ST_ARR_INIT 0xFFFFFFFFU
-#else
-#define ST_ARR_INIT 0x0000FFFFU
-#endif
-
-#if STM32_ST_USE_TIMER == 2
-
-#if !STM32_HAS_TIM2
-#error "TIM2 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM2_IS_32BITS
-#error "TIM2 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM2_HANDLER
-#define ST_NUMBER STM32_TIM2_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM2(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM2_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM2_STOP
-#elif defined(STM32G0XX)
-#define ST_ENABLE_STOP() DBG->APBFZ1 |= DBG_APB_FZ1_DBG_TIM2_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM2
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 3
-
-#if !STM32_HAS_TIM3
-#error "TIM3 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM3_IS_32BITS
-#error "TIM3 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM3_HANDLER
-#define ST_NUMBER STM32_TIM3_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM3(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM3_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM3_STOP
-#elif defined(STM32G0XX)
-#define ST_ENABLE_STOP() DBG->APBFZ1 |= DBG_APB_FZ1_DBG_TIM3_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM3
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM3_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 4
-
-#if !STM32_HAS_TIM4
-#error "TIM4 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM4_IS_32BITS
-#error "TIM4 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM4_HANDLER
-#define ST_NUMBER STM32_TIM4_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM4(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM4_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM4_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM4
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM4_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 5
-
-#if !STM32_HAS_TIM5
-#error "TIM5 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM5_IS_32BITS
-#error "TIM5 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM5_HANDLER
-#define ST_NUMBER STM32_TIM5_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM5(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM5_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM5_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM5
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 9
-
-#if !STM32_HAS_TIM9
-#error "TIM9 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM9_IS_32BITS
-#error "TIM9 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM9_HANDLER
-#define ST_NUMBER STM32_TIM9_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK2
-#define ST_ENABLE_CLOCK() rccEnableTIM9(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM9_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB2FZR1 |= DBGMCU_APB2FZR1_DBG_TIM9_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB2LFZ1 |= DBGMCU_APB2LFZ1_DBG_TIM9
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM9_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 10
-
-#if !STM32_HAS_TIM10
-#error "TIM10 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM10_IS_32BITS
-#error "TIM10 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM10_HANDLER
-#define ST_NUMBER STM32_TIM10_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK2
-#define ST_ENABLE_CLOCK() rccEnableTIM10(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM10_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB2FZR1 |= DBGMCU_APB2FZR1_DBG_TIM10_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB2LFZ1 |= DBGMCU_APB2LFZ1_DBG_TIM10
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM10_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 11
-
-#if !STM32_HAS_TIM11
-#error "TIM11 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM11_IS_32BITS
-#error "TIM11 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM11_HANDLER
-#define ST_NUMBER STM32_TIM11_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK2
-#define ST_ENABLE_CLOCK() rccEnableTIM11(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM11_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB2FZR1 |= DBGMCU_APB2FZR1_DBG_TIM11_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB2LFZ1 |= DBGMCU_APB2LFZ1_DBG_TIM11
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM11_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 12
-
-#if !STM32_HAS_TIM12
-#error "TIM12 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM12_IS_32BITS
-#error "TIM12 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM12_HANDLER
-#define ST_NUMBER STM32_TIM12_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM12(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM12_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM12_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM12
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM12_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 13
-
-#if !STM32_HAS_TIM13
-#error "TIM13 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM13_IS_32BITS
-#error "TIM13 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM13_HANDLER
-#define ST_NUMBER STM32_TIM13_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM13(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM13_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM13_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM13
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM13_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 14
-
-#if !STM32_HAS_TIM14
-#error "TIM14 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM14_IS_32BITS
-#error "TIM14 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM14_HANDLER
-#define ST_NUMBER STM32_TIM14_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK1
-#define ST_ENABLE_CLOCK() rccEnableTIM14(true)
-#if defined(STM32F1XX)
-#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM14_STOP
-#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM14_STOP
-#elif defined(STM32H7XX)
-#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM14
-#else
-#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM14_STOP
-#endif
-
-#elif STM32_ST_USE_TIMER == 21
-
-#if !STM32_HAS_TIM21
-#error "TIM21 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM21_IS_32BITS
-#error "TIM21 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM21_HANDLER
-#define ST_NUMBER STM32_TIM21_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK2
-#define ST_ENABLE_CLOCK() rccEnableTIM21(true)
-#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM21_STOP
-
-#elif STM32_ST_USE_TIMER == 22
-
-#if !STM32_HAS_TIM22
-#error "TIM22 not present in the selected device"
-#endif
-
-#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM22_IS_32BITS
-#error "TIM21 is not a 32bits timer"
-#endif
-
-#define ST_HANDLER STM32_TIM22_HANDLER
-#define ST_NUMBER STM32_TIM22_NUMBER
-#define ST_CLOCK_SRC STM32_TIMCLK2
-#define ST_ENABLE_CLOCK() rccEnableTIM22(true)
-#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM21_STOP
-
-#else
-#error "STM32_ST_USE_TIMER specifies an unsupported timer"
-#endif
-
-#if ST_CLOCK_SRC % OSAL_ST_FREQUENCY != 0
-#error "the selected ST frequency is not obtainable because integer rounding"
-#endif
-
-#if (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1 > 0xFFFF
-#error "the selected ST frequency is not obtainable because TIM timer prescaler limits"
-#endif
-
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
-
-#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
-
-#define ST_HANDLER SysTick_Handler
-
-#if defined(STM32_CORE_CK)
-#define SYSTICK_CK STM32_CORE_CK
-#else
-#define SYSTICK_CK STM32_HCLK
-#endif
-
-#if SYSTICK_CK % OSAL_ST_FREQUENCY != 0
-#error "the selected ST frequency is not obtainable because integer rounding"
-#endif
-
-#if (SYSTICK_CK / OSAL_ST_FREQUENCY) - 1 > 0xFFFFFF
-#error "the selected ST frequency is not obtainable because SysTick timer counter limits"
-#endif
-
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if !defined(STM32_SYSTICK_SUPPRESS_ISR)
-/**
- * @brief Interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(ST_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- st_lld_serve_interrupt();
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ST driver initialization.
- *
- * @notapi
- */
-void st_lld_init(void) {
-
-#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
- /* Free running counter mode.*/
-
- /* Enabling timer clock.*/
- ST_ENABLE_CLOCK();
-
- /* Enabling the stop mode during debug for this timer.*/
- ST_ENABLE_STOP();
-
- /* Initializing the counter in free running mode.*/
- STM32_ST_TIM->PSC = (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1;
- STM32_ST_TIM->ARR = ST_ARR_INIT;
- STM32_ST_TIM->CCMR1 = 0;
- STM32_ST_TIM->CCR[0] = 0;
-#if ST_LLD_NUM_ALARMS > 1
- STM32_ST_TIM->CCR[1] = 0;
-#endif
-#if ST_LLD_NUM_ALARMS > 2
- STM32_ST_TIM->CCR[2] = 0;
-#endif
-#if ST_LLD_NUM_ALARMS > 3
- STM32_ST_TIM->CCR[3] = 0;
-#endif
- STM32_ST_TIM->DIER = 0;
- STM32_ST_TIM->CR2 = 0;
- STM32_ST_TIM->EGR = TIM_EGR_UG;
- STM32_ST_TIM->CR1 = TIM_CR1_CEN;
-
-#if !defined(STM32_SYSTICK_SUPPRESS_ISR)
- /* IRQ enabled.*/
- nvicEnableVector(ST_NUMBER, STM32_ST_IRQ_PRIORITY);
-#endif
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
-
-#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
- /* Periodic systick mode, the Cortex-Mx internal systick timer is used
- in this mode.*/
- SysTick->LOAD = (SYSTICK_CK / OSAL_ST_FREQUENCY) - 1;
- SysTick->VAL = 0;
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_ENABLE_Msk |
- SysTick_CTRL_TICKINT_Msk;
-
- /* IRQ enabled.*/
- nvicSetSystemHandlerPriority(HANDLER_SYSTICK, STM32_ST_IRQ_PRIORITY);
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
-}
-
-/**
- * @brief IRQ handling code.
- */
-void st_lld_serve_interrupt(void) {
-#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
- uint32_t sr;
- stm32_tim_t *timp = STM32_ST_TIM;
-
- sr = timp->SR;
- sr &= timp->DIER & STM32_TIM_DIER_IRQ_MASK;
- timp->SR = ~sr;
-
- if ((sr & TIM_SR_CC1IF) != 0U)
-#endif
- {
- osalSysLockFromISR();
- osalOsTimerHandlerI();
- osalSysUnlockFromISR();
- }
-#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
-#if ST_LLD_NUM_ALARMS > 1
- if ((sr & TIM_SR_CC2IF) != 0U) {
- if (st_callbacks[1] != NULL) {
- st_callbacks[1](1U);
- }
- }
-#endif
-#if ST_LLD_NUM_ALARMS > 2
- if ((sr & TIM_SR_CC3IF) != 0U) {
- if (st_callbacks[2] != NULL) {
- st_callbacks[2](2U);
- }
- }
-#endif
-#if ST_LLD_NUM_ALARMS > 3
- if ((sr & TIM_SR_CC4IF) != 0U) {
- if (st_callbacks[3] != NULL) {
- st_callbacks[3](3U);
- }
- }
-#endif
-#endif
-}
-
-#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
-
-/** @} */
+/*
+ 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 TIMv1/hal_st_lld.c
+ * @brief ST Driver subsystem low level driver code.
+ *
+ * @addtogroup ST
+ * @{
+ */
+
+#include "hal.h"
+
+#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+
+#if (OSAL_ST_RESOLUTION == 32)
+#define ST_ARR_INIT 0xFFFFFFFFU
+#else
+#define ST_ARR_INIT 0x0000FFFFU
+#endif
+
+#if STM32_ST_USE_TIMER == 2
+
+#if !STM32_HAS_TIM2
+#error "TIM2 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM2_IS_32BITS
+#error "TIM2 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM2_HANDLER
+#define ST_NUMBER STM32_TIM2_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM2(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM2_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM2_STOP
+#elif defined(STM32G0XX)
+#define ST_ENABLE_STOP() DBG->APBFZ1 |= DBG_APB_FZ1_DBG_TIM2_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM2
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 3
+
+#if !STM32_HAS_TIM3
+#error "TIM3 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM3_IS_32BITS
+#error "TIM3 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM3_HANDLER
+#define ST_NUMBER STM32_TIM3_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM3(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM3_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM3_STOP
+#elif defined(STM32G0XX)
+#define ST_ENABLE_STOP() DBG->APBFZ1 |= DBG_APB_FZ1_DBG_TIM3_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM3
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM3_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 4
+
+#if !STM32_HAS_TIM4
+#error "TIM4 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM4_IS_32BITS
+#error "TIM4 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM4_HANDLER
+#define ST_NUMBER STM32_TIM4_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM4(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM4_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM4_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM4
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM4_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 5
+
+#if !STM32_HAS_TIM5
+#error "TIM5 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM5_IS_32BITS
+#error "TIM5 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM5_HANDLER
+#define ST_NUMBER STM32_TIM5_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM5(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM5_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM5_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM5
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 9
+
+#if !STM32_HAS_TIM9
+#error "TIM9 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM9_IS_32BITS
+#error "TIM9 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM9_HANDLER
+#define ST_NUMBER STM32_TIM9_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK2
+#define ST_ENABLE_CLOCK() rccEnableTIM9(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM9_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB2FZR1 |= DBGMCU_APB2FZR1_DBG_TIM9_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB2LFZ1 |= DBGMCU_APB2LFZ1_DBG_TIM9
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM9_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 10
+
+#if !STM32_HAS_TIM10
+#error "TIM10 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM10_IS_32BITS
+#error "TIM10 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM10_HANDLER
+#define ST_NUMBER STM32_TIM10_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK2
+#define ST_ENABLE_CLOCK() rccEnableTIM10(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM10_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB2FZR1 |= DBGMCU_APB2FZR1_DBG_TIM10_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB2LFZ1 |= DBGMCU_APB2LFZ1_DBG_TIM10
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM10_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 11
+
+#if !STM32_HAS_TIM11
+#error "TIM11 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM11_IS_32BITS
+#error "TIM11 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM11_HANDLER
+#define ST_NUMBER STM32_TIM11_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK2
+#define ST_ENABLE_CLOCK() rccEnableTIM11(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM11_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB2FZR1 |= DBGMCU_APB2FZR1_DBG_TIM11_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB2LFZ1 |= DBGMCU_APB2LFZ1_DBG_TIM11
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM11_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 12
+
+#if !STM32_HAS_TIM12
+#error "TIM12 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM12_IS_32BITS
+#error "TIM12 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM12_HANDLER
+#define ST_NUMBER STM32_TIM12_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM12(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM12_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM12_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM12
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM12_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 13
+
+#if !STM32_HAS_TIM13
+#error "TIM13 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM13_IS_32BITS
+#error "TIM13 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM13_HANDLER
+#define ST_NUMBER STM32_TIM13_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM13(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM13_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM13_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM13
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM13_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 14
+
+#if !STM32_HAS_TIM14
+#error "TIM14 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM14_IS_32BITS
+#error "TIM14 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM14_HANDLER
+#define ST_NUMBER STM32_TIM14_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK1
+#define ST_ENABLE_CLOCK() rccEnableTIM14(true)
+#if defined(STM32F1XX)
+#define ST_ENABLE_STOP() DBGMCU->CR |= DBGMCU_CR_DBG_TIM14_STOP
+#elif defined(STM32L4XX) || defined(STM32L4XXP) || defined(STM32G4XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZR1 |= DBGMCU_APB1FZR1_DBG_TIM14_STOP
+#elif defined(STM32H7XX)
+#define ST_ENABLE_STOP() DBGMCU->APB1LFZ1 |= DBGMCU_APB1LFZ1_DBG_TIM14
+#else
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM14_STOP
+#endif
+
+#elif STM32_ST_USE_TIMER == 21
+
+#if !STM32_HAS_TIM21
+#error "TIM21 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM21_IS_32BITS
+#error "TIM21 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM21_HANDLER
+#define ST_NUMBER STM32_TIM21_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK2
+#define ST_ENABLE_CLOCK() rccEnableTIM21(true)
+#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM21_STOP
+
+#elif STM32_ST_USE_TIMER == 22
+
+#if !STM32_HAS_TIM22
+#error "TIM22 not present in the selected device"
+#endif
+
+#if (OSAL_ST_RESOLUTION == 32) && !STM32_TIM22_IS_32BITS
+#error "TIM21 is not a 32bits timer"
+#endif
+
+#define ST_HANDLER STM32_TIM22_HANDLER
+#define ST_NUMBER STM32_TIM22_NUMBER
+#define ST_CLOCK_SRC STM32_TIMCLK2
+#define ST_ENABLE_CLOCK() rccEnableTIM22(true)
+#define ST_ENABLE_STOP() DBGMCU->APB2FZ |= DBGMCU_APB2_FZ_DBG_TIM21_STOP
+
+#else
+#error "STM32_ST_USE_TIMER specifies an unsupported timer"
+#endif
+
+#if ST_CLOCK_SRC % OSAL_ST_FREQUENCY != 0
+#error "the selected ST frequency is not obtainable because integer rounding"
+#endif
+
+#if (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1 > 0xFFFF
+#error "the selected ST frequency is not obtainable because TIM timer prescaler limits"
+#endif
+
+#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
+
+#define ST_HANDLER SysTick_Handler
+
+#if defined(STM32_CORE_CK)
+#define SYSTICK_CK STM32_CORE_CK
+#else
+#define SYSTICK_CK STM32_HCLK
+#endif
+
+#if SYSTICK_CK % OSAL_ST_FREQUENCY != 0
+#error "the selected ST frequency is not obtainable because integer rounding"
+#endif
+
+#if (SYSTICK_CK / OSAL_ST_FREQUENCY) - 1 > 0xFFFFFF
+#error "the selected ST frequency is not obtainable because SysTick timer counter limits"
+#endif
+
+#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if !defined(STM32_SYSTICK_SUPPRESS_ISR)
+/**
+ * @brief Interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(ST_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ st_lld_serve_interrupt();
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ST driver initialization.
+ *
+ * @notapi
+ */
+void st_lld_init(void) {
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+ /* Free running counter mode.*/
+
+ /* Enabling timer clock.*/
+ ST_ENABLE_CLOCK();
+
+ /* Enabling the stop mode during debug for this timer.*/
+ ST_ENABLE_STOP();
+
+ /* Initializing the counter in free running mode.*/
+ STM32_ST_TIM->PSC = (ST_CLOCK_SRC / OSAL_ST_FREQUENCY) - 1;
+ STM32_ST_TIM->ARR = ST_ARR_INIT;
+ STM32_ST_TIM->CCMR1 = 0;
+ STM32_ST_TIM->CCR[0] = 0;
+#if ST_LLD_NUM_ALARMS > 1
+ STM32_ST_TIM->CCR[1] = 0;
+#endif
+#if ST_LLD_NUM_ALARMS > 2
+ STM32_ST_TIM->CCR[2] = 0;
+#endif
+#if ST_LLD_NUM_ALARMS > 3
+ STM32_ST_TIM->CCR[3] = 0;
+#endif
+ STM32_ST_TIM->DIER = 0;
+ STM32_ST_TIM->CR2 = 0;
+ STM32_ST_TIM->EGR = TIM_EGR_UG;
+ STM32_ST_TIM->CR1 = TIM_CR1_CEN;
+
+#if !defined(STM32_SYSTICK_SUPPRESS_ISR)
+ /* IRQ enabled.*/
+ nvicEnableVector(ST_NUMBER, STM32_ST_IRQ_PRIORITY);
+#endif
+#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
+ /* Periodic systick mode, the Cortex-Mx internal systick timer is used
+ in this mode.*/
+ SysTick->LOAD = (SYSTICK_CK / OSAL_ST_FREQUENCY) - 1;
+ SysTick->VAL = 0;
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_ENABLE_Msk |
+ SysTick_CTRL_TICKINT_Msk;
+
+ /* IRQ enabled.*/
+ nvicSetSystemHandlerPriority(HANDLER_SYSTICK, STM32_ST_IRQ_PRIORITY);
+#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
+}
+
+/**
+ * @brief IRQ handling code.
+ */
+void st_lld_serve_interrupt(void) {
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+ uint32_t sr;
+ stm32_tim_t *timp = STM32_ST_TIM;
+
+ sr = timp->SR;
+ sr &= timp->DIER & STM32_TIM_DIER_IRQ_MASK;
+ timp->SR = ~sr;
+
+ if ((sr & TIM_SR_CC1IF) != 0U)
+#endif
+ {
+ osalSysLockFromISR();
+ osalOsTimerHandlerI();
+ osalSysUnlockFromISR();
+ }
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+#if ST_LLD_NUM_ALARMS > 1
+ if ((sr & TIM_SR_CC2IF) != 0U) {
+ if (st_callbacks[1] != NULL) {
+ st_callbacks[1](1U);
+ }
+ }
+#endif
+#if ST_LLD_NUM_ALARMS > 2
+ if ((sr & TIM_SR_CC3IF) != 0U) {
+ if (st_callbacks[2] != NULL) {
+ st_callbacks[2](2U);
+ }
+ }
+#endif
+#if ST_LLD_NUM_ALARMS > 3
+ if ((sr & TIM_SR_CC4IF) != 0U) {
+ if (st_callbacks[3] != NULL) {
+ st_callbacks[3](3U);
+ }
+ }
+#endif
+#endif
+}
+
+#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.h
index f98e5b82be..01de7b7074 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.h
@@ -1,701 +1,701 @@
-/*
- 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 TIMv1/hal_st_lld.h
- * @brief ST Driver subsystem low level driver header.
- * @details This header is designed to be include-able without having to
- * include other files from the HAL.
- *
- * @addtogroup ST
- * @{
- */
-
-#ifndef HAL_ST_LLD_H
-#define HAL_ST_LLD_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/* Feature currently disabled.*/
-#define STM32_ST_ENFORCE_ALARMS 1
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief SysTick timer IRQ priority.
- */
-#if !defined(STM32_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ST_IRQ_PRIORITY 8
-#endif
-
-/**
- * @brief TIMx unit (by number) to be used for free running operations.
- * @note You must select a 32 bits timer if a 32 bits @p systick_t type
- * is required.
- * @note Timers 2, 3, 4, 5, 21 and 22 are supported.
- */
-#if !defined(STM32_ST_USE_TIMER) || defined(__DOXYGEN__)
-#define STM32_ST_USE_TIMER 2
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* This has to go after transition to shared handlers is complete for all
- platforms.*/
-#if !defined(STM32_HAS_TIM2)
-#define STM32_HAS_TIM2 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM3)
-#define STM32_HAS_TIM3 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM4)
-#define STM32_HAS_TIM4 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM5)
-#define STM32_HAS_TIM5 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM9)
-#define STM32_HAS_TIM9 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM10)
-#define STM32_HAS_TIM10 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM11)
-#define STM32_HAS_TIM11 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM12)
-#define STM32_HAS_TIM12 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM13)
-#define STM32_HAS_TIM13 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM14)
-#define STM32_HAS_TIM14 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM21)
-#define STM32_HAS_TIM21 FALSE
-#endif
-
-#if !defined(STM32_HAS_TIM22)
-#define STM32_HAS_TIM22 FALSE
-#endif
-/**/
-
-#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
-
-#if STM32_ST_USE_TIMER == 2
-
-#if defined(STM32_TIM2_IS_USED)
-#error "ST requires TIM2 but the timer is already used"
-#else
-#define STM32_TIM2_IS_USED
-#endif
-
-#if defined(STM32_TIM2_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM2
-#define ST_LLD_NUM_ALARMS STM32_TIM2_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 TRUE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 3
-
-#if defined(STM32_TIM3_IS_USED)
-#error "ST requires TIM3 but the timer is already used"
-#else
-#define STM32_TIM3_IS_USED
-#endif
-
-#if defined(STM32_TIM3_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM3
-#define ST_LLD_NUM_ALARMS STM32_TIM3_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 TRUE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 4
-
-#if defined(STM32_TIM4_IS_USED)
-#error "ST requires TIM4 but the timer is already used"
-#else
-#define STM32_TIM4_IS_USED
-#endif
-
-#if defined(STM32_TIM4_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM4
-#define ST_LLD_NUM_ALARMS STM32_TIM4_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 TRUE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 5
-
-#if defined(STM32_TIM5_IS_USED)
-#error "ST requires TIM5 but the timer is already used"
-#else
-#define STM32_TIM5_IS_USED
-#endif
-
-#if defined(STM32_TIM5_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM5
-#define ST_LLD_NUM_ALARMS STM32_TIM5_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 TRUE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 9
-
-#if defined(STM32_TIM9_IS_USED)
-#error "ST requires TIM9 but the timer is already used"
-#else
-#define STM32_TIM9_IS_USED
-#endif
-
-#if defined(STM32_TIM9_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM9
-#define ST_LLD_NUM_ALARMS STM32_TIM9_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 TRUE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 10
-
-#if defined(STM32_TIM10_IS_USED)
-#error "ST requires TIM10 but the timer is already used"
-#else
-#define STM32_TIM10_IS_USED
-#endif
-
-#if defined(STM32_TIM10_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM10
-#define ST_LLD_NUM_ALARMS STM32_TIM10_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 TRUE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 11
-
-#if defined(STM32_TIM11_IS_USED)
-#error "ST requires TIM11 but the timer is already used"
-#else
-#define STM32_TIM11_IS_USED
-#endif
-
-#if defined(STM32_TIM11_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM11
-#define ST_LLD_NUM_ALARMS STM32_TIM11_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 TRUE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 12
-
-#if defined(STM32_TIM12_IS_USED)
-#error "ST requires TIM12 but the timer is already used"
-#else
-#define STM32_TIM12_IS_USED
-#endif
-
-#if defined(STM32_TIM12_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM12
-#define ST_LLD_NUM_ALARMS STM32_TIM12_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 TRUE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 13
-
-#if defined(STM32_TIM13_IS_USED)
-#error "ST requires TIM13 but the timer is already used"
-#else
-#define STM32_TIM13_IS_USED
-#endif
-
-#if defined(STM32_TIM13_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM13
-#define ST_LLD_NUM_ALARMS STM32_TIM13_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 TRUE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 14
-
-#if defined(STM32_TIM14_IS_USED)
-#error "ST requires TIM14 but the timer is already used"
-#else
-#define STM32_TIM14_IS_USED
-#endif
-
-#if defined(STM32_TIM14_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM14
-#define ST_LLD_NUM_ALARMS STM32_TIM14_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 TRUE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 21
-
-#if defined(STM32_TIM21_IS_USED)
-#error "ST requires TIM21 but the timer is already used"
-#else
-#define STM32_TIM21_IS_USED
-#endif
-
-#if defined(STM32_TIM21_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM21
-#define ST_LLD_NUM_ALARMS STM32_TIM21_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 TRUE
-#define STM32_ST_USE_TIM22 FALSE
-
-#elif STM32_ST_USE_TIMER == 22
-
-#if defined(STM32_TIM22_IS_USED)
-#error "ST requires TIM22 but the timer is already used"
-#else
-#define STM32_TIM22_IS_USED
-#endif
-
-#if defined(STM32_TIM22_SUPPRESS_ISR)
-#define STM32_SYSTICK_SUPPRESS_ISR
-#endif
-
-#define STM32_ST_TIM STM32_TIM22
-#define ST_LLD_NUM_ALARMS STM32_TIM22_CHANNELS
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 TRUE
-
-#else
-#error "STM32_ST_USE_TIMER specifies an unsupported timer"
-#endif
-
-#if defined(STM32_ST_ENFORCE_ALARMS)
-
-#if (STM32_ST_ENFORCE_ALARMS < 1) || (STM32_ST_ENFORCE_ALARMS > ST_LLD_NUM_ALARMS)
-#error "invalid STM32_ST_ENFORCE_ALARMS value"
-#endif
-
-#undef ST_LLD_NUM_ALARMS
-#define ST_LLD_NUM_ALARMS STM32_ST_ENFORCE_ALARMS
-#endif
-
-#elif OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
-
-#define STM32_ST_USE_SYSTICK TRUE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#else
-
-#define STM32_ST_USE_SYSTICK FALSE
-#define STM32_ST_USE_TIM2 FALSE
-#define STM32_ST_USE_TIM3 FALSE
-#define STM32_ST_USE_TIM4 FALSE
-#define STM32_ST_USE_TIM5 FALSE
-#define STM32_ST_USE_TIM9 FALSE
-#define STM32_ST_USE_TIM10 FALSE
-#define STM32_ST_USE_TIM11 FALSE
-#define STM32_ST_USE_TIM12 FALSE
-#define STM32_ST_USE_TIM13 FALSE
-#define STM32_ST_USE_TIM14 FALSE
-#define STM32_ST_USE_TIM21 FALSE
-#define STM32_ST_USE_TIM22 FALSE
-
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void st_lld_init(void);
- void st_lld_serve_interrupt(void);
-#ifdef __cplusplus
-}
-#endif
-
-/*===========================================================================*/
-/* Driver inline functions. */
-/*===========================================================================*/
-
-
-#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__)
-
-/**
- * @brief Returns the time counter value.
- *
- * @return The counter value.
- *
- * @notapi
- */
-static inline systime_t st_lld_get_counter(void) {
-
- return (systime_t)STM32_ST_TIM->CNT;
-}
-
-/**
- * @brief Starts the alarm.
- * @note Makes sure that no spurious alarms are triggered after
- * this call.
- *
- * @param[in] abstime the time to be set for the first alarm
- *
- * @notapi
- */
-static inline void st_lld_start_alarm(systime_t abstime) {
-
- STM32_ST_TIM->CCR[0] = (uint32_t)abstime;
- STM32_ST_TIM->SR = 0;
-#if ST_LLD_NUM_ALARMS == 1
- STM32_ST_TIM->DIER = STM32_TIM_DIER_CC1IE;
-#else
- STM32_ST_TIM->DIER |= STM32_TIM_DIER_CC1IE;
-#endif
-}
-
-/**
- * @brief Stops the alarm interrupt.
- *
- * @notapi
- */
-static inline void st_lld_stop_alarm(void) {
-
-#if ST_LLD_NUM_ALARMS == 1
- STM32_ST_TIM->DIER = 0U;
-#else
- STM32_ST_TIM->DIER &= ~STM32_TIM_DIER_CC1IE;
-#endif
-}
-
-/**
- * @brief Sets the alarm time.
- *
- * @param[in] abstime the time to be set for the next alarm
- *
- * @notapi
- */
-static inline void st_lld_set_alarm(systime_t abstime) {
-
- STM32_ST_TIM->CCR[0] = (uint32_t)abstime;
-}
-
-/**
- * @brief Returns the current alarm time.
- *
- * @return The currently set alarm time.
- *
- * @notapi
- */
-static inline systime_t st_lld_get_alarm(void) {
-
- return (systime_t)STM32_ST_TIM->CCR[0];
-}
-
-/**
- * @brief Determines if the alarm is active.
- *
- * @return The alarm status.
- * @retval false if the alarm is not active.
- * @retval true is the alarm is active
- *
- * @notapi
- */
-static inline bool st_lld_is_alarm_active(void) {
-
- return (bool)((STM32_ST_TIM->DIER & STM32_TIM_DIER_CC1IE) != 0);
-}
-
-#if (ST_LLD_NUM_ALARMS > 1) || defined(__DOXYGEN__)
-/**
- * @brief Starts an alarm.
- * @note Makes sure that no spurious alarms are triggered after
- * this call.
- * @note This functionality is only available in free running mode, the
- * behavior in periodic mode is undefined.
- *
- * @param[in] abstime the time to be set for the first alarm
- * @param[in] alarm alarm channel number
- *
- * @notapi
- */
-static inline void st_lld_start_alarm_n(unsigned alarm, systime_t abstime) {
-
-
- STM32_ST_TIM->CCR[alarm] = (uint32_t)abstime;
- STM32_ST_TIM->SR = 0;
- STM32_ST_TIM->DIER |= (STM32_TIM_DIER_CC1IE << alarm);
-}
-
-/**
- * @brief Stops an alarm interrupt.
- * @note This functionality is only available in free running mode, the
- * behavior in periodic mode is undefined.
- *
- * @param[in] alarm alarm channel number
- *
- * @notapi
- */
-static inline void st_lld_stop_alarm_n(unsigned alarm) {
-
- STM32_ST_TIM->DIER &= ~(STM32_TIM_DIER_CC1IE << alarm);
-}
-
-/**
- * @brief Sets an alarm time.
- * @note This functionality is only available in free running mode, the
- * behavior in periodic mode is undefined.
- *
- * @param[in] alarm alarm channel number
- * @param[in] abstime the time to be set for the next alarm
- *
- * @notapi
- */
-static inline void st_lld_set_alarm_n(unsigned alarm, systime_t abstime) {
-
- STM32_ST_TIM->CCR[alarm] = (uint32_t)abstime;
-}
-
-/**
- * @brief Returns an alarm current time.
- * @note This functionality is only available in free running mode, the
- * behavior in periodic mode is undefined.
- *
- * @param[in] alarm alarm channel number
- * @return The currently set alarm time.
- *
- * @notapi
- */
-static inline systime_t st_lld_get_alarm_n(unsigned alarm) {
-
- return (systime_t)STM32_ST_TIM->CCR[alarm];
-}
-
-/**
- * @brief Determines if an alarm is active.
- *
- * @param[in] alarm alarm channel number
- * @return The alarm status.
- * @retval false if the alarm is not active.
- * @retval true is the alarm is active
- *
- * @notapi
- */
-static inline bool st_lld_is_alarm_active_n(unsigned alarm) {
-
- return (bool)((STM32_ST_TIM->DIER & (STM32_TIM_DIER_CC1IE << alarm)) != 0);
-}
-#endif /* ST_LLD_NUM_ALARMS > 1 */
-
-#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
-
-#endif /* HAL_ST_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 TIMv1/hal_st_lld.h
+ * @brief ST Driver subsystem low level driver header.
+ * @details This header is designed to be include-able without having to
+ * include other files from the HAL.
+ *
+ * @addtogroup ST
+ * @{
+ */
+
+#ifndef HAL_ST_LLD_H
+#define HAL_ST_LLD_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/* Feature currently disabled.*/
+#define STM32_ST_ENFORCE_ALARMS 1
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief SysTick timer IRQ priority.
+ */
+#if !defined(STM32_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ST_IRQ_PRIORITY 8
+#endif
+
+/**
+ * @brief TIMx unit (by number) to be used for free running operations.
+ * @note You must select a 32 bits timer if a 32 bits @p systick_t type
+ * is required.
+ * @note Timers 2, 3, 4, 5, 21 and 22 are supported.
+ */
+#if !defined(STM32_ST_USE_TIMER) || defined(__DOXYGEN__)
+#define STM32_ST_USE_TIMER 2
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* This has to go after transition to shared handlers is complete for all
+ platforms.*/
+#if !defined(STM32_HAS_TIM2)
+#define STM32_HAS_TIM2 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM3)
+#define STM32_HAS_TIM3 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM4)
+#define STM32_HAS_TIM4 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM5)
+#define STM32_HAS_TIM5 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM9)
+#define STM32_HAS_TIM9 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM10)
+#define STM32_HAS_TIM10 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM11)
+#define STM32_HAS_TIM11 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM12)
+#define STM32_HAS_TIM12 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM13)
+#define STM32_HAS_TIM13 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM14)
+#define STM32_HAS_TIM14 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM21)
+#define STM32_HAS_TIM21 FALSE
+#endif
+
+#if !defined(STM32_HAS_TIM22)
+#define STM32_HAS_TIM22 FALSE
+#endif
+/**/
+
+#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
+
+#if STM32_ST_USE_TIMER == 2
+
+#if defined(STM32_TIM2_IS_USED)
+#error "ST requires TIM2 but the timer is already used"
+#else
+#define STM32_TIM2_IS_USED
+#endif
+
+#if defined(STM32_TIM2_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM2
+#define ST_LLD_NUM_ALARMS STM32_TIM2_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 TRUE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 3
+
+#if defined(STM32_TIM3_IS_USED)
+#error "ST requires TIM3 but the timer is already used"
+#else
+#define STM32_TIM3_IS_USED
+#endif
+
+#if defined(STM32_TIM3_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM3
+#define ST_LLD_NUM_ALARMS STM32_TIM3_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 TRUE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 4
+
+#if defined(STM32_TIM4_IS_USED)
+#error "ST requires TIM4 but the timer is already used"
+#else
+#define STM32_TIM4_IS_USED
+#endif
+
+#if defined(STM32_TIM4_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM4
+#define ST_LLD_NUM_ALARMS STM32_TIM4_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 TRUE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 5
+
+#if defined(STM32_TIM5_IS_USED)
+#error "ST requires TIM5 but the timer is already used"
+#else
+#define STM32_TIM5_IS_USED
+#endif
+
+#if defined(STM32_TIM5_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM5
+#define ST_LLD_NUM_ALARMS STM32_TIM5_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 TRUE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 9
+
+#if defined(STM32_TIM9_IS_USED)
+#error "ST requires TIM9 but the timer is already used"
+#else
+#define STM32_TIM9_IS_USED
+#endif
+
+#if defined(STM32_TIM9_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM9
+#define ST_LLD_NUM_ALARMS STM32_TIM9_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 TRUE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 10
+
+#if defined(STM32_TIM10_IS_USED)
+#error "ST requires TIM10 but the timer is already used"
+#else
+#define STM32_TIM10_IS_USED
+#endif
+
+#if defined(STM32_TIM10_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM10
+#define ST_LLD_NUM_ALARMS STM32_TIM10_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 TRUE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 11
+
+#if defined(STM32_TIM11_IS_USED)
+#error "ST requires TIM11 but the timer is already used"
+#else
+#define STM32_TIM11_IS_USED
+#endif
+
+#if defined(STM32_TIM11_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM11
+#define ST_LLD_NUM_ALARMS STM32_TIM11_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 TRUE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 12
+
+#if defined(STM32_TIM12_IS_USED)
+#error "ST requires TIM12 but the timer is already used"
+#else
+#define STM32_TIM12_IS_USED
+#endif
+
+#if defined(STM32_TIM12_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM12
+#define ST_LLD_NUM_ALARMS STM32_TIM12_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 TRUE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 13
+
+#if defined(STM32_TIM13_IS_USED)
+#error "ST requires TIM13 but the timer is already used"
+#else
+#define STM32_TIM13_IS_USED
+#endif
+
+#if defined(STM32_TIM13_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM13
+#define ST_LLD_NUM_ALARMS STM32_TIM13_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 TRUE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 14
+
+#if defined(STM32_TIM14_IS_USED)
+#error "ST requires TIM14 but the timer is already used"
+#else
+#define STM32_TIM14_IS_USED
+#endif
+
+#if defined(STM32_TIM14_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM14
+#define ST_LLD_NUM_ALARMS STM32_TIM14_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 TRUE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 21
+
+#if defined(STM32_TIM21_IS_USED)
+#error "ST requires TIM21 but the timer is already used"
+#else
+#define STM32_TIM21_IS_USED
+#endif
+
+#if defined(STM32_TIM21_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM21
+#define ST_LLD_NUM_ALARMS STM32_TIM21_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 TRUE
+#define STM32_ST_USE_TIM22 FALSE
+
+#elif STM32_ST_USE_TIMER == 22
+
+#if defined(STM32_TIM22_IS_USED)
+#error "ST requires TIM22 but the timer is already used"
+#else
+#define STM32_TIM22_IS_USED
+#endif
+
+#if defined(STM32_TIM22_SUPPRESS_ISR)
+#define STM32_SYSTICK_SUPPRESS_ISR
+#endif
+
+#define STM32_ST_TIM STM32_TIM22
+#define ST_LLD_NUM_ALARMS STM32_TIM22_CHANNELS
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 TRUE
+
+#else
+#error "STM32_ST_USE_TIMER specifies an unsupported timer"
+#endif
+
+#if defined(STM32_ST_ENFORCE_ALARMS)
+
+#if (STM32_ST_ENFORCE_ALARMS < 1) || (STM32_ST_ENFORCE_ALARMS > ST_LLD_NUM_ALARMS)
+#error "invalid STM32_ST_ENFORCE_ALARMS value"
+#endif
+
+#undef ST_LLD_NUM_ALARMS
+#define ST_LLD_NUM_ALARMS STM32_ST_ENFORCE_ALARMS
+#endif
+
+#elif OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
+
+#define STM32_ST_USE_SYSTICK TRUE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#else
+
+#define STM32_ST_USE_SYSTICK FALSE
+#define STM32_ST_USE_TIM2 FALSE
+#define STM32_ST_USE_TIM3 FALSE
+#define STM32_ST_USE_TIM4 FALSE
+#define STM32_ST_USE_TIM5 FALSE
+#define STM32_ST_USE_TIM9 FALSE
+#define STM32_ST_USE_TIM10 FALSE
+#define STM32_ST_USE_TIM11 FALSE
+#define STM32_ST_USE_TIM12 FALSE
+#define STM32_ST_USE_TIM13 FALSE
+#define STM32_ST_USE_TIM14 FALSE
+#define STM32_ST_USE_TIM21 FALSE
+#define STM32_ST_USE_TIM22 FALSE
+
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void st_lld_init(void);
+ void st_lld_serve_interrupt(void);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Driver inline functions. */
+/*===========================================================================*/
+
+
+#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__)
+
+/**
+ * @brief Returns the time counter value.
+ *
+ * @return The counter value.
+ *
+ * @notapi
+ */
+static inline systime_t st_lld_get_counter(void) {
+
+ return (systime_t)STM32_ST_TIM->CNT;
+}
+
+/**
+ * @brief Starts the alarm.
+ * @note Makes sure that no spurious alarms are triggered after
+ * this call.
+ *
+ * @param[in] abstime the time to be set for the first alarm
+ *
+ * @notapi
+ */
+static inline void st_lld_start_alarm(systime_t abstime) {
+
+ STM32_ST_TIM->CCR[0] = (uint32_t)abstime;
+ STM32_ST_TIM->SR = 0;
+#if ST_LLD_NUM_ALARMS == 1
+ STM32_ST_TIM->DIER = STM32_TIM_DIER_CC1IE;
+#else
+ STM32_ST_TIM->DIER |= STM32_TIM_DIER_CC1IE;
+#endif
+}
+
+/**
+ * @brief Stops the alarm interrupt.
+ *
+ * @notapi
+ */
+static inline void st_lld_stop_alarm(void) {
+
+#if ST_LLD_NUM_ALARMS == 1
+ STM32_ST_TIM->DIER = 0U;
+#else
+ STM32_ST_TIM->DIER &= ~STM32_TIM_DIER_CC1IE;
+#endif
+}
+
+/**
+ * @brief Sets the alarm time.
+ *
+ * @param[in] abstime the time to be set for the next alarm
+ *
+ * @notapi
+ */
+static inline void st_lld_set_alarm(systime_t abstime) {
+
+ STM32_ST_TIM->CCR[0] = (uint32_t)abstime;
+}
+
+/**
+ * @brief Returns the current alarm time.
+ *
+ * @return The currently set alarm time.
+ *
+ * @notapi
+ */
+static inline systime_t st_lld_get_alarm(void) {
+
+ return (systime_t)STM32_ST_TIM->CCR[0];
+}
+
+/**
+ * @brief Determines if the alarm is active.
+ *
+ * @return The alarm status.
+ * @retval false if the alarm is not active.
+ * @retval true is the alarm is active
+ *
+ * @notapi
+ */
+static inline bool st_lld_is_alarm_active(void) {
+
+ return (bool)((STM32_ST_TIM->DIER & STM32_TIM_DIER_CC1IE) != 0);
+}
+
+#if (ST_LLD_NUM_ALARMS > 1) || defined(__DOXYGEN__)
+/**
+ * @brief Starts an alarm.
+ * @note Makes sure that no spurious alarms are triggered after
+ * this call.
+ * @note This functionality is only available in free running mode, the
+ * behavior in periodic mode is undefined.
+ *
+ * @param[in] abstime the time to be set for the first alarm
+ * @param[in] alarm alarm channel number
+ *
+ * @notapi
+ */
+static inline void st_lld_start_alarm_n(unsigned alarm, systime_t abstime) {
+
+
+ STM32_ST_TIM->CCR[alarm] = (uint32_t)abstime;
+ STM32_ST_TIM->SR = 0;
+ STM32_ST_TIM->DIER |= (STM32_TIM_DIER_CC1IE << alarm);
+}
+
+/**
+ * @brief Stops an alarm interrupt.
+ * @note This functionality is only available in free running mode, the
+ * behavior in periodic mode is undefined.
+ *
+ * @param[in] alarm alarm channel number
+ *
+ * @notapi
+ */
+static inline void st_lld_stop_alarm_n(unsigned alarm) {
+
+ STM32_ST_TIM->DIER &= ~(STM32_TIM_DIER_CC1IE << alarm);
+}
+
+/**
+ * @brief Sets an alarm time.
+ * @note This functionality is only available in free running mode, the
+ * behavior in periodic mode is undefined.
+ *
+ * @param[in] alarm alarm channel number
+ * @param[in] abstime the time to be set for the next alarm
+ *
+ * @notapi
+ */
+static inline void st_lld_set_alarm_n(unsigned alarm, systime_t abstime) {
+
+ STM32_ST_TIM->CCR[alarm] = (uint32_t)abstime;
+}
+
+/**
+ * @brief Returns an alarm current time.
+ * @note This functionality is only available in free running mode, the
+ * behavior in periodic mode is undefined.
+ *
+ * @param[in] alarm alarm channel number
+ * @return The currently set alarm time.
+ *
+ * @notapi
+ */
+static inline systime_t st_lld_get_alarm_n(unsigned alarm) {
+
+ return (systime_t)STM32_ST_TIM->CCR[alarm];
+}
+
+/**
+ * @brief Determines if an alarm is active.
+ *
+ * @param[in] alarm alarm channel number
+ * @return The alarm status.
+ * @retval false if the alarm is not active.
+ * @retval true is the alarm is active
+ *
+ * @notapi
+ */
+static inline bool st_lld_is_alarm_active_n(unsigned alarm) {
+
+ return (bool)((STM32_ST_TIM->DIER & (STM32_TIM_DIER_CC1IE << alarm)) != 0);
+}
+#endif /* ST_LLD_NUM_ALARMS > 1 */
+
+#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
+
+#endif /* HAL_ST_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h b/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h
index 81d8c094e3..d15e600d28 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h
@@ -1,566 +1,566 @@
-/*
- 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 TIMv1/stm32_tim.h
- * @brief STM32 TIM units common header.
- * @note This file requires definitions from the ST STM32 header file.
- *
- * @addtogroup STM32_TIMv1
- * @{
- */
-
-#ifndef STM32_TIM_H
-#define STM32_TIM_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name TIM_CR1 register
- * @{
- */
-#define STM32_TIM_CR1_CEN (1U << 0)
-#define STM32_TIM_CR1_UDIS (1U << 1)
-#define STM32_TIM_CR1_URS (1U << 2)
-#define STM32_TIM_CR1_OPM (1U << 3)
-#define STM32_TIM_CR1_DIR (1U << 4)
-
-#define STM32_TIM_CR1_CMS_MASK (3U << 5)
-#define STM32_TIM_CR1_CMS(n) ((n) << 5)
-
-#define STM32_TIM_CR1_ARPE (1U << 7)
-
-#define STM32_TIM_CR1_CKD_MASK (3U << 8)
-#define STM32_TIM_CR1_CKD(n) ((n) << 8)
-
-#define STM32_TIM_CR1_UIFREMAP (1U << 11)
-/** @} */
-
-/**
- * @name TIM_CR2 register
- * @{
- */
-#define STM32_TIM_CR2_CCPC (1U << 0)
-#define STM32_TIM_CR2_CCUS (1U << 2)
-#define STM32_TIM_CR2_CCDS (1U << 3)
-
-#define STM32_TIM_CR2_MMS_MASK (7U << 4)
-#define STM32_TIM_CR2_MMS(n) ((n) << 4)
-
-#define STM32_TIM_CR2_TI1S (1U << 7)
-#define STM32_TIM_CR2_OIS1 (1U << 8)
-#define STM32_TIM_CR2_OIS1N (1U << 9)
-#define STM32_TIM_CR2_OIS2 (1U << 10)
-#define STM32_TIM_CR2_OIS2N (1U << 11)
-#define STM32_TIM_CR2_OIS3 (1U << 12)
-#define STM32_TIM_CR2_OIS3N (1U << 13)
-#define STM32_TIM_CR2_OIS4 (1U << 14)
-#define STM32_TIM_CR2_OIS5 (1U << 16)
-#define STM32_TIM_CR2_OIS6 (1U << 18)
-
-#define STM32_TIM_CR2_MMS2_MASK (15U << 20)
-#define STM32_TIM_CR2_MMS2(n) ((n) << 20)
-/** @} */
-
-/**
- * @name TIM_SMCR register
- * @{
- */
-#define STM32_TIM_SMCR_SMS_MASK ((7U << 0) | (1U << 16))
-#define STM32_TIM_SMCR_SMS(n) ((((n) & 7) << 0) | \
- (((n) >> 3) << 16))
-
-#define STM32_TIM_SMCR_OCCS (1U << 3)
-
-#define STM32_TIM_SMCR_TS_MASK (7U << 4)
-#define STM32_TIM_SMCR_TS(n) ((n) << 4)
-
-#define STM32_TIM_SMCR_MSM (1U << 7)
-
-#define STM32_TIM_SMCR_ETF_MASK (15U << 8)
-#define STM32_TIM_SMCR_ETF(n) ((n) << 8)
-
-#define STM32_TIM_SMCR_ETPS_MASK (3U << 12)
-#define STM32_TIM_SMCR_ETPS(n) ((n) << 12)
-
-#define STM32_TIM_SMCR_ECE (1U << 14)
-#define STM32_TIM_SMCR_ETP (1U << 15)
-/** @} */
-
-/**
- * @name TIM_DIER register
- * @{
- */
-#define STM32_TIM_DIER_UIE (1U << 0)
-#define STM32_TIM_DIER_CC1IE (1U << 1)
-#define STM32_TIM_DIER_CC2IE (1U << 2)
-#define STM32_TIM_DIER_CC3IE (1U << 3)
-#define STM32_TIM_DIER_CC4IE (1U << 4)
-#define STM32_TIM_DIER_COMIE (1U << 5)
-#define STM32_TIM_DIER_TIE (1U << 6)
-#define STM32_TIM_DIER_BIE (1U << 7)
-#define STM32_TIM_DIER_UDE (1U << 8)
-#define STM32_TIM_DIER_CC1DE (1U << 9)
-#define STM32_TIM_DIER_CC2DE (1U << 10)
-#define STM32_TIM_DIER_CC3DE (1U << 11)
-#define STM32_TIM_DIER_CC4DE (1U << 12)
-#define STM32_TIM_DIER_COMDE (1U << 13)
-#define STM32_TIM_DIER_TDE (1U << 14)
-
-#define STM32_TIM_DIER_IRQ_MASK (STM32_TIM_DIER_UIE | \
- STM32_TIM_DIER_CC1IE | \
- STM32_TIM_DIER_CC2IE | \
- STM32_TIM_DIER_CC3IE | \
- STM32_TIM_DIER_CC4IE | \
- STM32_TIM_DIER_COMIE | \
- STM32_TIM_DIER_TIE | \
- STM32_TIM_DIER_BIE)
-
-/** @} */
-
-/**
- * @name TIM_SR register
- * @{
- */
-#define STM32_TIM_SR_UIF (1U << 0)
-#define STM32_TIM_SR_CC1IF (1U << 1)
-#define STM32_TIM_SR_CC2IF (1U << 2)
-#define STM32_TIM_SR_CC3IF (1U << 3)
-#define STM32_TIM_SR_CC4IF (1U << 4)
-#define STM32_TIM_SR_COMIF (1U << 5)
-#define STM32_TIM_SR_TIF (1U << 6)
-#define STM32_TIM_SR_BIF (1U << 7)
-#define STM32_TIM_SR_B2IF (1U << 8)
-#define STM32_TIM_SR_CC1OF (1U << 9)
-#define STM32_TIM_SR_CC2OF (1U << 10)
-#define STM32_TIM_SR_CC3OF (1U << 11)
-#define STM32_TIM_SR_CC4OF (1U << 12)
-#define STM32_TIM_SR_CC5IF (1U << 16)
-#define STM32_TIM_SR_CC6IF (1U << 17)
-/** @} */
-
-/**
- * @name TIM_EGR register
- * @{
- */
-#define STM32_TIM_EGR_UG (1U << 0)
-#define STM32_TIM_EGR_CC1G (1U << 1)
-#define STM32_TIM_EGR_CC2G (1U << 2)
-#define STM32_TIM_EGR_CC3G (1U << 3)
-#define STM32_TIM_EGR_CC4G (1U << 4)
-#define STM32_TIM_EGR_COMG (1U << 5)
-#define STM32_TIM_EGR_TG (1U << 6)
-#define STM32_TIM_EGR_BG (1U << 7)
-#define STM32_TIM_EGR_B2G (1U << 8)
-/** @} */
-
-/**
- * @name TIM_CCMR1 register (output)
- * @{
- */
-#define STM32_TIM_CCMR1_CC1S_MASK (3U << 0)
-#define STM32_TIM_CCMR1_CC1S(n) ((n) << 0)
-
-#define STM32_TIM_CCMR1_OC1FE (1U << 2)
-#define STM32_TIM_CCMR1_OC1PE (1U << 3)
-
-#define STM32_TIM_CCMR1_OC1M_MASK ((7U << 4) | (1U << 16))
-#define STM32_TIM_CCMR1_OC1M(n) ((((n) & 7) << 4) | \
- (((n) >> 3) << 16))
-
-#define STM32_TIM_CCMR1_OC1CE (1U << 7)
-
-#define STM32_TIM_CCMR1_CC2S_MASK (3U << 8)
-#define STM32_TIM_CCMR1_CC2S(n) ((n) << 8)
-
-#define STM32_TIM_CCMR1_OC2FE (1U << 10)
-#define STM32_TIM_CCMR1_OC2PE (1U << 11)
-
-#define STM32_TIM_CCMR1_OC2M_MASK ((7U << 12) | (1U << 24))
-#define STM32_TIM_CCMR1_OC2M(n) ((((n) & 7) << 12) | \
- (((n) >> 3) << 24))
-
-#define STM32_TIM_CCMR1_OC2CE (1U << 15)
-/** @} */
-
-/**
- * @name CCMR1 register (input)
- * @{
- */
-#define STM32_TIM_CCMR1_IC1PSC_MASK (3U << 2)
-#define STM32_TIM_CCMR1_IC1PSC(n) ((n) << 2)
-
-#define STM32_TIM_CCMR1_IC1F_MASK (15U << 4)
-#define STM32_TIM_CCMR1_IC1F(n) ((n) << 4)
-
-#define STM32_TIM_CCMR1_IC2PSC_MASK (3U << 10)
-#define STM32_TIM_CCMR1_IC2PSC(n) ((n) << 10)
-
-#define STM32_TIM_CCMR1_IC2F_MASK (15U << 12)
-#define STM32_TIM_CCMR1_IC2F(n) ((n) << 12)
-/** @} */
-
-/**
- * @name TIM_CCMR2 register (output)
- * @{
- */
-#define STM32_TIM_CCMR2_CC3S_MASK (3U << 0)
-#define STM32_TIM_CCMR2_CC3S(n) ((n) << 0)
-
-#define STM32_TIM_CCMR2_OC3FE (1U << 2)
-#define STM32_TIM_CCMR2_OC3PE (1U << 3)
-
-#define STM32_TIM_CCMR2_OC3M_MASK ((7U << 4) | (1U << 16))
-#define STM32_TIM_CCMR2_OC3M(n) ((((n) & 7) << 4) | \
- (((n) >> 3) << 16))
-
-#define STM32_TIM_CCMR2_OC3CE (1U << 7)
-
-#define STM32_TIM_CCMR2_CC4S_MASK (3U << 8)
-#define STM32_TIM_CCMR2_CC4S(n) ((n) << 8)
-
-#define STM32_TIM_CCMR2_OC4FE (1U << 10)
-#define STM32_TIM_CCMR2_OC4PE (1U << 11)
-
-#define STM32_TIM_CCMR2_OC4M_MASK ((7U << 12) | (1U << 24))
-#define STM32_TIM_CCMR2_OC4M(n) ((((n) & 7) << 12) | \
- (((n) >> 3) << 24))
-
-#define STM32_TIM_CCMR2_OC4CE (1U << 15)
-/** @} */
-
-/**
- * @name TIM_CCMR2 register (input)
- * @{
- */
-#define STM32_TIM_CCMR2_IC3PSC_MASK (3U << 2)
-#define STM32_TIM_CCMR2_IC3PSC(n) ((n) << 2)
-
-#define STM32_TIM_CCMR2_IC3F_MASK (15U << 4)
-#define STM32_TIM_CCMR2_IC3F(n) ((n) << 4)
-
-#define STM32_TIM_CCMR2_IC4PSC_MASK (3U << 10)
-#define STM32_TIM_CCMR2_IC4PSC(n) ((n) << 10)
-
-#define STM32_TIM_CCMR2_IC4F_MASK (15U << 12)
-#define STM32_TIM_CCMR2_IC4F(n) ((n) << 12)
-/** @} */
-
-/**
- * @name TIM_CCER register
- * @{
- */
-#define STM32_TIM_CCER_CC1E (1U << 0)
-#define STM32_TIM_CCER_CC1P (1U << 1)
-#define STM32_TIM_CCER_CC1NE (1U << 2)
-#define STM32_TIM_CCER_CC1NP (1U << 3)
-#define STM32_TIM_CCER_CC2E (1U << 4)
-#define STM32_TIM_CCER_CC2P (1U << 5)
-#define STM32_TIM_CCER_CC2NE (1U << 6)
-#define STM32_TIM_CCER_CC2NP (1U << 7)
-#define STM32_TIM_CCER_CC3E (1U << 8)
-#define STM32_TIM_CCER_CC3P (1U << 9)
-#define STM32_TIM_CCER_CC3NE (1U << 10)
-#define STM32_TIM_CCER_CC3NP (1U << 11)
-#define STM32_TIM_CCER_CC4E (1U << 12)
-#define STM32_TIM_CCER_CC4P (1U << 13)
-#define STM32_TIM_CCER_CC4NE (1U << 14)
-#define STM32_TIM_CCER_CC4NP (1U << 15)
-#define STM32_TIM_CCER_CC5E (1U << 16)
-#define STM32_TIM_CCER_CC5P (1U << 17)
-#define STM32_TIM_CCER_CC6E (1U << 20)
-#define STM32_TIM_CCER_CC6P (1U << 21)
-/** @} */
-
-/**
- * @name TIM_CNT register
- * @{
- */
-#define STM32_TIM_CNT_UIFCPY (1U << 31)
-/** @} */
-
-/**
- * @name TIM_BDTR register
- * @{
- */
-#define STM32_TIM_BDTR_DTG_MASK (255U << 0)
-#define STM32_TIM_BDTR_DTG(n) ((n) << 0)
-
-#define STM32_TIM_BDTR_LOCK_MASK (3U << 8)
-#define STM32_TIM_BDTR_LOCK(n) ((n) << 8)
-
-#define STM32_TIM_BDTR_OSSI (1U << 10)
-#define STM32_TIM_BDTR_OSSR (1U << 11)
-#define STM32_TIM_BDTR_BKE (1U << 12)
-#define STM32_TIM_BDTR_BKP (1U << 13)
-#define STM32_TIM_BDTR_AOE (1U << 14)
-#define STM32_TIM_BDTR_MOE (1U << 15)
-
-#define STM32_TIM_BDTR_BKF_MASK (15U << 16)
-#define STM32_TIM_BDTR_BKF(n) ((n) << 16)
-#define STM32_TIM_BDTR_BK2F_MASK (15U << 20)
-#define STM32_TIM_BDTR_BK2F(n) ((n) << 20)
-
-#define STM32_TIM_BDTR_BK2E (1U << 24)
-#define STM32_TIM_BDTR_BK2P (1U << 25)
-/** @} */
-
-/**
- * @name TIM_DCR register
- * @{
- */
-#define STM32_TIM_DCR_DBA_MASK (31U << 0)
-#define STM32_TIM_DCR_DBA(n) ((n) << 0)
-
-#define STM32_TIM_DCR_DBL_MASK (31U << 8)
-#define STM32_TIM_DCR_DBL(n) ((n) << 8)
-/** @} */
-
-/**
- * @name TIM16_OR register
- * @{
- */
-#define STM32_TIM16_OR_TI1_RMP_MASK (3U << 6)
-#define STM32_TIM16_OR_TI1_RMP(n) ((n) << 6)
-/** @} */
-
-/**
- * @name TIM_OR register
- * @{
- */
-#define STM32_TIM_OR_ETR_RMP_MASK (15U << 0)
-#define STM32_TIM_OR_ETR_RMP(n) ((n) << 0)
-/** @} */
-
-/**
- * @name TIM_CCMR3 register
- * @{
- */
-#define STM32_TIM_CCMR3_OC5FE (1U << 2)
-#define STM32_TIM_CCMR3_OC5PE (1U << 3)
-
-#define STM32_TIM_CCMR3_OC5M_MASK ((7U << 4) | (1U << 16))
-#define STM32_TIM_CCMR3_OC5M(n) ((((n) & 7) << 4) | \
- (((n) >> 2) << 16))
-
-#define STM32_TIM_CCMR3_OC5CE (1U << 7)
-
-#define STM32_TIM_CCMR3_OC6FE (1U << 10)
-#define STM32_TIM_CCMR3_OC6PE (1U << 11)
-
-#define STM32_TIM_CCMR3_OC6M_MASK ((7U << 12) | (1U << 24))
-#define STM32_TIM_CCMR3_OC6M(n) ((((n) & 7) << 12) | \
- (((n) >> 2) << 24))
-
-#define STM32_TIM_CCMR3_OC6CE (1U << 15)
-/** @} */
-
-/**
- * @name LPTIM_ISR register
- * @{
- */
-#define STM32_LPTIM_ISR_CMPM (1U << 0)
-#define STM32_LPTIM_ISR_ARRM (1U << 1)
-#define STM32_LPTIM_ISR_EXTTRIG (1U << 2)
-#define STM32_LPTIM_ISR_CMPOK (1U << 3)
-#define STM32_LPTIM_ISR_ARROK (1U << 4)
-#define STM32_LPTIM_ISR_UP (1U << 5)
-#define STM32_LPTIM_ISR_DOWN (1U << 6)
-/** @} */
-
-/**
- * @name LPTIM_ICR register
- * @{
- */
-#define STM32_LPTIM_ICR_CMPMCF (1U << 0)
-#define STM32_LPTIM_ICR_ARRMCF (1U << 1)
-#define STM32_LPTIM_ICR_EXTTRIGCF (1U << 2)
-#define STM32_LPTIM_ICR_CMPOKCF (1U << 3)
-#define STM32_LPTIM_ICR_ARROKCF (1U << 4)
-#define STM32_LPTIM_ICR_UPCF (1U << 5)
-#define STM32_LPTIM_ICR_DOWNCF (1U << 6)
-/** @} */
-
-/**
- * @name LPTIM_IER register
- * @{
- */
-#define STM32_LPTIM_IER_CMPMIE (1U << 0)
-#define STM32_LPTIM_IER_ARRMIE (1U << 1)
-#define STM32_LPTIM_IER_EXTTRIGIE (1U << 2)
-#define STM32_LPTIM_IER_CMPOKIE (1U << 3)
-#define STM32_LPTIM_IER_ARROKIE (1U << 4)
-#define STM32_LPTIM_IER_UPIE (1U << 5)
-#define STM32_LPTIM_IER_DOWNIE (1U << 6)
-/** @} */
-
-/**
- * @name LPTIM_CFGR register
- * @{
- */
-#define STM32_LPTIM_CFGR_CKSEL (1U << 0)
-#define STM32_LPTIM_CFGR_CKPOL_MASK (3U << 1)
-#define STM32_LPTIM_CFGR_CKPOL(n) ((n) << 1)
-#define STM32_LPTIM_CFGR_CKFLT_MASK (3U << 3)
-#define STM32_LPTIM_CFGR_CKFLT(n) ((n) << 3)
-#define STM32_LPTIM_CFGR_TRGFLT_MASK (3U << 6)
-#define STM32_LPTIM_CFGR_TRGFLT(n) ((n) << 6)
-#define STM32_LPTIM_CFGR_PRESC_MASK (7U << 9)
-#define STM32_LPTIM_CFGR_PRESC(n) ((n) << 9)
-#define STM32_LPTIM_CFGR_TRIGSEL_MASK (7U << 13)
-#define STM32_LPTIM_CFGR_TRIGSEL(n) ((n) << 13)
-#define STM32_LPTIM_CFGR_TRIGEN_MASK (3U << 17)
-#define STM32_LPTIM_CFGR_TRIGEN(n) ((n) << 17)
-#define STM32_LPTIM_CFGR_TIMOUT (1U << 19)
-#define STM32_LPTIM_CFGR_WAVE (1U << 20)
-#define STM32_LPTIM_CFGR_WAVPOL (1U << 21)
-#define STM32_LPTIM_CFGR_PRELOAD (1U << 22)
-#define STM32_LPTIM_CFGR_COUNTMODE (1U << 23)
-#define STM32_LPTIM_CFGR_ENC (1U << 24)
-/** @} */
-
-/**
- * @name LPTIM_CR register
- * @{
- */
-#define STM32_LPTIM_CR_ENABLE (1U << 0)
-#define STM32_LPTIM_CR_SNGSTRT (1U << 1)
-#define STM32_LPTIM_CR_CNTSTRT (1U << 2)
-/** @} */
-
-/**
- * @name LPTIM_OR register
- * @{
- */
-#define STM32_LPTIM_OR_0 (1U << 0)
-#define STM32_LPTIM_OR_1 (1U << 1)
-/** @} */
-
-/**
- * @name TIM units references
- * @{
- */
-#define STM32_TIM1 ((stm32_tim_t *)TIM1_BASE)
-#define STM32_TIM2 ((stm32_tim_t *)TIM2_BASE)
-#define STM32_TIM3 ((stm32_tim_t *)TIM3_BASE)
-#define STM32_TIM4 ((stm32_tim_t *)TIM4_BASE)
-#define STM32_TIM5 ((stm32_tim_t *)TIM5_BASE)
-#define STM32_TIM6 ((stm32_tim_t *)TIM6_BASE)
-#define STM32_TIM7 ((stm32_tim_t *)TIM7_BASE)
-#define STM32_TIM8 ((stm32_tim_t *)TIM8_BASE)
-#define STM32_TIM9 ((stm32_tim_t *)TIM9_BASE)
-#define STM32_TIM10 ((stm32_tim_t *)TIM10_BASE)
-#define STM32_TIM11 ((stm32_tim_t *)TIM11_BASE)
-#define STM32_TIM12 ((stm32_tim_t *)TIM12_BASE)
-#define STM32_TIM13 ((stm32_tim_t *)TIM13_BASE)
-#define STM32_TIM14 ((stm32_tim_t *)TIM14_BASE)
-#define STM32_TIM15 ((stm32_tim_t *)TIM15_BASE)
-#define STM32_TIM16 ((stm32_tim_t *)TIM16_BASE)
-#define STM32_TIM17 ((stm32_tim_t *)TIM17_BASE)
-#define STM32_TIM18 ((stm32_tim_t *)TIM18_BASE)
-#define STM32_TIM19 ((stm32_tim_t *)TIM19_BASE)
-#define STM32_TIM20 ((stm32_tim_t *)TIM20_BASE)
-#define STM32_TIM21 ((stm32_tim_t *)TIM21_BASE)
-#define STM32_TIM22 ((stm32_tim_t *)TIM22_BASE)
-
-#define STM32_LPTIM1 ((stm32_lptim_t *)LPTIM1_BASE)
-#define STM32_LPTIM2 ((stm32_lptim_t *)LPTIM2_BASE)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 TIM registers block.
- * @note This is the most general known form, not all timers have
- * necessarily all registers and bits.
- */
-typedef struct {
- volatile uint32_t CR1;
- volatile uint32_t CR2;
- volatile uint32_t SMCR;
- volatile uint32_t DIER;
- volatile uint32_t SR;
- volatile uint32_t EGR;
- volatile uint32_t CCMR1;
- volatile uint32_t CCMR2;
- volatile uint32_t CCER;
- volatile uint32_t CNT;
- volatile uint32_t PSC;
- volatile uint32_t ARR;
- volatile uint32_t RCR;
- volatile uint32_t CCR[4];
- volatile uint32_t BDTR;
-#if defined(STM32G4)
- volatile uint32_t CCXR[2];
- volatile uint32_t CCMR3;
- volatile uint32_t DTR2;
- volatile uint32_t ECR;
- volatile uint32_t TISEL;
- volatile uint32_t AF1;
- volatile uint32_t AF2;
- volatile uint32_t OR;
- volatile uint32_t RESERVED0[220];
- volatile uint32_t DCR;
- volatile uint32_t DMAR;
-#else
- volatile uint32_t DCR;
- volatile uint32_t DMAR;
- volatile uint32_t OR;
- volatile uint32_t CCMR3;
- volatile uint32_t CCXR[2];
-#endif
-} stm32_tim_t;
-
-/**
- * @brief STM32 LPTIM registers block.
- * @note This is the most general known form, not all timers have
- * necessarily all registers and bits.
- */
-typedef struct {
- volatile uint32_t ISR;
- volatile uint32_t ICR;
- volatile uint32_t IER;
- volatile uint32_t CFGR;
- volatile uint32_t CR;
- volatile uint32_t CMP;
- volatile uint32_t ARR;
- volatile uint32_t CNT;
- volatile uint32_t OR;
-} stm32_lptim_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#endif /* STM32_TIM_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 TIMv1/stm32_tim.h
+ * @brief STM32 TIM units common header.
+ * @note This file requires definitions from the ST STM32 header file.
+ *
+ * @addtogroup STM32_TIMv1
+ * @{
+ */
+
+#ifndef STM32_TIM_H
+#define STM32_TIM_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name TIM_CR1 register
+ * @{
+ */
+#define STM32_TIM_CR1_CEN (1U << 0)
+#define STM32_TIM_CR1_UDIS (1U << 1)
+#define STM32_TIM_CR1_URS (1U << 2)
+#define STM32_TIM_CR1_OPM (1U << 3)
+#define STM32_TIM_CR1_DIR (1U << 4)
+
+#define STM32_TIM_CR1_CMS_MASK (3U << 5)
+#define STM32_TIM_CR1_CMS(n) ((n) << 5)
+
+#define STM32_TIM_CR1_ARPE (1U << 7)
+
+#define STM32_TIM_CR1_CKD_MASK (3U << 8)
+#define STM32_TIM_CR1_CKD(n) ((n) << 8)
+
+#define STM32_TIM_CR1_UIFREMAP (1U << 11)
+/** @} */
+
+/**
+ * @name TIM_CR2 register
+ * @{
+ */
+#define STM32_TIM_CR2_CCPC (1U << 0)
+#define STM32_TIM_CR2_CCUS (1U << 2)
+#define STM32_TIM_CR2_CCDS (1U << 3)
+
+#define STM32_TIM_CR2_MMS_MASK (7U << 4)
+#define STM32_TIM_CR2_MMS(n) ((n) << 4)
+
+#define STM32_TIM_CR2_TI1S (1U << 7)
+#define STM32_TIM_CR2_OIS1 (1U << 8)
+#define STM32_TIM_CR2_OIS1N (1U << 9)
+#define STM32_TIM_CR2_OIS2 (1U << 10)
+#define STM32_TIM_CR2_OIS2N (1U << 11)
+#define STM32_TIM_CR2_OIS3 (1U << 12)
+#define STM32_TIM_CR2_OIS3N (1U << 13)
+#define STM32_TIM_CR2_OIS4 (1U << 14)
+#define STM32_TIM_CR2_OIS5 (1U << 16)
+#define STM32_TIM_CR2_OIS6 (1U << 18)
+
+#define STM32_TIM_CR2_MMS2_MASK (15U << 20)
+#define STM32_TIM_CR2_MMS2(n) ((n) << 20)
+/** @} */
+
+/**
+ * @name TIM_SMCR register
+ * @{
+ */
+#define STM32_TIM_SMCR_SMS_MASK ((7U << 0) | (1U << 16))
+#define STM32_TIM_SMCR_SMS(n) ((((n) & 7) << 0) | \
+ (((n) >> 3) << 16))
+
+#define STM32_TIM_SMCR_OCCS (1U << 3)
+
+#define STM32_TIM_SMCR_TS_MASK (7U << 4)
+#define STM32_TIM_SMCR_TS(n) ((n) << 4)
+
+#define STM32_TIM_SMCR_MSM (1U << 7)
+
+#define STM32_TIM_SMCR_ETF_MASK (15U << 8)
+#define STM32_TIM_SMCR_ETF(n) ((n) << 8)
+
+#define STM32_TIM_SMCR_ETPS_MASK (3U << 12)
+#define STM32_TIM_SMCR_ETPS(n) ((n) << 12)
+
+#define STM32_TIM_SMCR_ECE (1U << 14)
+#define STM32_TIM_SMCR_ETP (1U << 15)
+/** @} */
+
+/**
+ * @name TIM_DIER register
+ * @{
+ */
+#define STM32_TIM_DIER_UIE (1U << 0)
+#define STM32_TIM_DIER_CC1IE (1U << 1)
+#define STM32_TIM_DIER_CC2IE (1U << 2)
+#define STM32_TIM_DIER_CC3IE (1U << 3)
+#define STM32_TIM_DIER_CC4IE (1U << 4)
+#define STM32_TIM_DIER_COMIE (1U << 5)
+#define STM32_TIM_DIER_TIE (1U << 6)
+#define STM32_TIM_DIER_BIE (1U << 7)
+#define STM32_TIM_DIER_UDE (1U << 8)
+#define STM32_TIM_DIER_CC1DE (1U << 9)
+#define STM32_TIM_DIER_CC2DE (1U << 10)
+#define STM32_TIM_DIER_CC3DE (1U << 11)
+#define STM32_TIM_DIER_CC4DE (1U << 12)
+#define STM32_TIM_DIER_COMDE (1U << 13)
+#define STM32_TIM_DIER_TDE (1U << 14)
+
+#define STM32_TIM_DIER_IRQ_MASK (STM32_TIM_DIER_UIE | \
+ STM32_TIM_DIER_CC1IE | \
+ STM32_TIM_DIER_CC2IE | \
+ STM32_TIM_DIER_CC3IE | \
+ STM32_TIM_DIER_CC4IE | \
+ STM32_TIM_DIER_COMIE | \
+ STM32_TIM_DIER_TIE | \
+ STM32_TIM_DIER_BIE)
+
+/** @} */
+
+/**
+ * @name TIM_SR register
+ * @{
+ */
+#define STM32_TIM_SR_UIF (1U << 0)
+#define STM32_TIM_SR_CC1IF (1U << 1)
+#define STM32_TIM_SR_CC2IF (1U << 2)
+#define STM32_TIM_SR_CC3IF (1U << 3)
+#define STM32_TIM_SR_CC4IF (1U << 4)
+#define STM32_TIM_SR_COMIF (1U << 5)
+#define STM32_TIM_SR_TIF (1U << 6)
+#define STM32_TIM_SR_BIF (1U << 7)
+#define STM32_TIM_SR_B2IF (1U << 8)
+#define STM32_TIM_SR_CC1OF (1U << 9)
+#define STM32_TIM_SR_CC2OF (1U << 10)
+#define STM32_TIM_SR_CC3OF (1U << 11)
+#define STM32_TIM_SR_CC4OF (1U << 12)
+#define STM32_TIM_SR_CC5IF (1U << 16)
+#define STM32_TIM_SR_CC6IF (1U << 17)
+/** @} */
+
+/**
+ * @name TIM_EGR register
+ * @{
+ */
+#define STM32_TIM_EGR_UG (1U << 0)
+#define STM32_TIM_EGR_CC1G (1U << 1)
+#define STM32_TIM_EGR_CC2G (1U << 2)
+#define STM32_TIM_EGR_CC3G (1U << 3)
+#define STM32_TIM_EGR_CC4G (1U << 4)
+#define STM32_TIM_EGR_COMG (1U << 5)
+#define STM32_TIM_EGR_TG (1U << 6)
+#define STM32_TIM_EGR_BG (1U << 7)
+#define STM32_TIM_EGR_B2G (1U << 8)
+/** @} */
+
+/**
+ * @name TIM_CCMR1 register (output)
+ * @{
+ */
+#define STM32_TIM_CCMR1_CC1S_MASK (3U << 0)
+#define STM32_TIM_CCMR1_CC1S(n) ((n) << 0)
+
+#define STM32_TIM_CCMR1_OC1FE (1U << 2)
+#define STM32_TIM_CCMR1_OC1PE (1U << 3)
+
+#define STM32_TIM_CCMR1_OC1M_MASK ((7U << 4) | (1U << 16))
+#define STM32_TIM_CCMR1_OC1M(n) ((((n) & 7) << 4) | \
+ (((n) >> 3) << 16))
+
+#define STM32_TIM_CCMR1_OC1CE (1U << 7)
+
+#define STM32_TIM_CCMR1_CC2S_MASK (3U << 8)
+#define STM32_TIM_CCMR1_CC2S(n) ((n) << 8)
+
+#define STM32_TIM_CCMR1_OC2FE (1U << 10)
+#define STM32_TIM_CCMR1_OC2PE (1U << 11)
+
+#define STM32_TIM_CCMR1_OC2M_MASK ((7U << 12) | (1U << 24))
+#define STM32_TIM_CCMR1_OC2M(n) ((((n) & 7) << 12) | \
+ (((n) >> 3) << 24))
+
+#define STM32_TIM_CCMR1_OC2CE (1U << 15)
+/** @} */
+
+/**
+ * @name CCMR1 register (input)
+ * @{
+ */
+#define STM32_TIM_CCMR1_IC1PSC_MASK (3U << 2)
+#define STM32_TIM_CCMR1_IC1PSC(n) ((n) << 2)
+
+#define STM32_TIM_CCMR1_IC1F_MASK (15U << 4)
+#define STM32_TIM_CCMR1_IC1F(n) ((n) << 4)
+
+#define STM32_TIM_CCMR1_IC2PSC_MASK (3U << 10)
+#define STM32_TIM_CCMR1_IC2PSC(n) ((n) << 10)
+
+#define STM32_TIM_CCMR1_IC2F_MASK (15U << 12)
+#define STM32_TIM_CCMR1_IC2F(n) ((n) << 12)
+/** @} */
+
+/**
+ * @name TIM_CCMR2 register (output)
+ * @{
+ */
+#define STM32_TIM_CCMR2_CC3S_MASK (3U << 0)
+#define STM32_TIM_CCMR2_CC3S(n) ((n) << 0)
+
+#define STM32_TIM_CCMR2_OC3FE (1U << 2)
+#define STM32_TIM_CCMR2_OC3PE (1U << 3)
+
+#define STM32_TIM_CCMR2_OC3M_MASK ((7U << 4) | (1U << 16))
+#define STM32_TIM_CCMR2_OC3M(n) ((((n) & 7) << 4) | \
+ (((n) >> 3) << 16))
+
+#define STM32_TIM_CCMR2_OC3CE (1U << 7)
+
+#define STM32_TIM_CCMR2_CC4S_MASK (3U << 8)
+#define STM32_TIM_CCMR2_CC4S(n) ((n) << 8)
+
+#define STM32_TIM_CCMR2_OC4FE (1U << 10)
+#define STM32_TIM_CCMR2_OC4PE (1U << 11)
+
+#define STM32_TIM_CCMR2_OC4M_MASK ((7U << 12) | (1U << 24))
+#define STM32_TIM_CCMR2_OC4M(n) ((((n) & 7) << 12) | \
+ (((n) >> 3) << 24))
+
+#define STM32_TIM_CCMR2_OC4CE (1U << 15)
+/** @} */
+
+/**
+ * @name TIM_CCMR2 register (input)
+ * @{
+ */
+#define STM32_TIM_CCMR2_IC3PSC_MASK (3U << 2)
+#define STM32_TIM_CCMR2_IC3PSC(n) ((n) << 2)
+
+#define STM32_TIM_CCMR2_IC3F_MASK (15U << 4)
+#define STM32_TIM_CCMR2_IC3F(n) ((n) << 4)
+
+#define STM32_TIM_CCMR2_IC4PSC_MASK (3U << 10)
+#define STM32_TIM_CCMR2_IC4PSC(n) ((n) << 10)
+
+#define STM32_TIM_CCMR2_IC4F_MASK (15U << 12)
+#define STM32_TIM_CCMR2_IC4F(n) ((n) << 12)
+/** @} */
+
+/**
+ * @name TIM_CCER register
+ * @{
+ */
+#define STM32_TIM_CCER_CC1E (1U << 0)
+#define STM32_TIM_CCER_CC1P (1U << 1)
+#define STM32_TIM_CCER_CC1NE (1U << 2)
+#define STM32_TIM_CCER_CC1NP (1U << 3)
+#define STM32_TIM_CCER_CC2E (1U << 4)
+#define STM32_TIM_CCER_CC2P (1U << 5)
+#define STM32_TIM_CCER_CC2NE (1U << 6)
+#define STM32_TIM_CCER_CC2NP (1U << 7)
+#define STM32_TIM_CCER_CC3E (1U << 8)
+#define STM32_TIM_CCER_CC3P (1U << 9)
+#define STM32_TIM_CCER_CC3NE (1U << 10)
+#define STM32_TIM_CCER_CC3NP (1U << 11)
+#define STM32_TIM_CCER_CC4E (1U << 12)
+#define STM32_TIM_CCER_CC4P (1U << 13)
+#define STM32_TIM_CCER_CC4NE (1U << 14)
+#define STM32_TIM_CCER_CC4NP (1U << 15)
+#define STM32_TIM_CCER_CC5E (1U << 16)
+#define STM32_TIM_CCER_CC5P (1U << 17)
+#define STM32_TIM_CCER_CC6E (1U << 20)
+#define STM32_TIM_CCER_CC6P (1U << 21)
+/** @} */
+
+/**
+ * @name TIM_CNT register
+ * @{
+ */
+#define STM32_TIM_CNT_UIFCPY (1U << 31)
+/** @} */
+
+/**
+ * @name TIM_BDTR register
+ * @{
+ */
+#define STM32_TIM_BDTR_DTG_MASK (255U << 0)
+#define STM32_TIM_BDTR_DTG(n) ((n) << 0)
+
+#define STM32_TIM_BDTR_LOCK_MASK (3U << 8)
+#define STM32_TIM_BDTR_LOCK(n) ((n) << 8)
+
+#define STM32_TIM_BDTR_OSSI (1U << 10)
+#define STM32_TIM_BDTR_OSSR (1U << 11)
+#define STM32_TIM_BDTR_BKE (1U << 12)
+#define STM32_TIM_BDTR_BKP (1U << 13)
+#define STM32_TIM_BDTR_AOE (1U << 14)
+#define STM32_TIM_BDTR_MOE (1U << 15)
+
+#define STM32_TIM_BDTR_BKF_MASK (15U << 16)
+#define STM32_TIM_BDTR_BKF(n) ((n) << 16)
+#define STM32_TIM_BDTR_BK2F_MASK (15U << 20)
+#define STM32_TIM_BDTR_BK2F(n) ((n) << 20)
+
+#define STM32_TIM_BDTR_BK2E (1U << 24)
+#define STM32_TIM_BDTR_BK2P (1U << 25)
+/** @} */
+
+/**
+ * @name TIM_DCR register
+ * @{
+ */
+#define STM32_TIM_DCR_DBA_MASK (31U << 0)
+#define STM32_TIM_DCR_DBA(n) ((n) << 0)
+
+#define STM32_TIM_DCR_DBL_MASK (31U << 8)
+#define STM32_TIM_DCR_DBL(n) ((n) << 8)
+/** @} */
+
+/**
+ * @name TIM16_OR register
+ * @{
+ */
+#define STM32_TIM16_OR_TI1_RMP_MASK (3U << 6)
+#define STM32_TIM16_OR_TI1_RMP(n) ((n) << 6)
+/** @} */
+
+/**
+ * @name TIM_OR register
+ * @{
+ */
+#define STM32_TIM_OR_ETR_RMP_MASK (15U << 0)
+#define STM32_TIM_OR_ETR_RMP(n) ((n) << 0)
+/** @} */
+
+/**
+ * @name TIM_CCMR3 register
+ * @{
+ */
+#define STM32_TIM_CCMR3_OC5FE (1U << 2)
+#define STM32_TIM_CCMR3_OC5PE (1U << 3)
+
+#define STM32_TIM_CCMR3_OC5M_MASK ((7U << 4) | (1U << 16))
+#define STM32_TIM_CCMR3_OC5M(n) ((((n) & 7) << 4) | \
+ (((n) >> 2) << 16))
+
+#define STM32_TIM_CCMR3_OC5CE (1U << 7)
+
+#define STM32_TIM_CCMR3_OC6FE (1U << 10)
+#define STM32_TIM_CCMR3_OC6PE (1U << 11)
+
+#define STM32_TIM_CCMR3_OC6M_MASK ((7U << 12) | (1U << 24))
+#define STM32_TIM_CCMR3_OC6M(n) ((((n) & 7) << 12) | \
+ (((n) >> 2) << 24))
+
+#define STM32_TIM_CCMR3_OC6CE (1U << 15)
+/** @} */
+
+/**
+ * @name LPTIM_ISR register
+ * @{
+ */
+#define STM32_LPTIM_ISR_CMPM (1U << 0)
+#define STM32_LPTIM_ISR_ARRM (1U << 1)
+#define STM32_LPTIM_ISR_EXTTRIG (1U << 2)
+#define STM32_LPTIM_ISR_CMPOK (1U << 3)
+#define STM32_LPTIM_ISR_ARROK (1U << 4)
+#define STM32_LPTIM_ISR_UP (1U << 5)
+#define STM32_LPTIM_ISR_DOWN (1U << 6)
+/** @} */
+
+/**
+ * @name LPTIM_ICR register
+ * @{
+ */
+#define STM32_LPTIM_ICR_CMPMCF (1U << 0)
+#define STM32_LPTIM_ICR_ARRMCF (1U << 1)
+#define STM32_LPTIM_ICR_EXTTRIGCF (1U << 2)
+#define STM32_LPTIM_ICR_CMPOKCF (1U << 3)
+#define STM32_LPTIM_ICR_ARROKCF (1U << 4)
+#define STM32_LPTIM_ICR_UPCF (1U << 5)
+#define STM32_LPTIM_ICR_DOWNCF (1U << 6)
+/** @} */
+
+/**
+ * @name LPTIM_IER register
+ * @{
+ */
+#define STM32_LPTIM_IER_CMPMIE (1U << 0)
+#define STM32_LPTIM_IER_ARRMIE (1U << 1)
+#define STM32_LPTIM_IER_EXTTRIGIE (1U << 2)
+#define STM32_LPTIM_IER_CMPOKIE (1U << 3)
+#define STM32_LPTIM_IER_ARROKIE (1U << 4)
+#define STM32_LPTIM_IER_UPIE (1U << 5)
+#define STM32_LPTIM_IER_DOWNIE (1U << 6)
+/** @} */
+
+/**
+ * @name LPTIM_CFGR register
+ * @{
+ */
+#define STM32_LPTIM_CFGR_CKSEL (1U << 0)
+#define STM32_LPTIM_CFGR_CKPOL_MASK (3U << 1)
+#define STM32_LPTIM_CFGR_CKPOL(n) ((n) << 1)
+#define STM32_LPTIM_CFGR_CKFLT_MASK (3U << 3)
+#define STM32_LPTIM_CFGR_CKFLT(n) ((n) << 3)
+#define STM32_LPTIM_CFGR_TRGFLT_MASK (3U << 6)
+#define STM32_LPTIM_CFGR_TRGFLT(n) ((n) << 6)
+#define STM32_LPTIM_CFGR_PRESC_MASK (7U << 9)
+#define STM32_LPTIM_CFGR_PRESC(n) ((n) << 9)
+#define STM32_LPTIM_CFGR_TRIGSEL_MASK (7U << 13)
+#define STM32_LPTIM_CFGR_TRIGSEL(n) ((n) << 13)
+#define STM32_LPTIM_CFGR_TRIGEN_MASK (3U << 17)
+#define STM32_LPTIM_CFGR_TRIGEN(n) ((n) << 17)
+#define STM32_LPTIM_CFGR_TIMOUT (1U << 19)
+#define STM32_LPTIM_CFGR_WAVE (1U << 20)
+#define STM32_LPTIM_CFGR_WAVPOL (1U << 21)
+#define STM32_LPTIM_CFGR_PRELOAD (1U << 22)
+#define STM32_LPTIM_CFGR_COUNTMODE (1U << 23)
+#define STM32_LPTIM_CFGR_ENC (1U << 24)
+/** @} */
+
+/**
+ * @name LPTIM_CR register
+ * @{
+ */
+#define STM32_LPTIM_CR_ENABLE (1U << 0)
+#define STM32_LPTIM_CR_SNGSTRT (1U << 1)
+#define STM32_LPTIM_CR_CNTSTRT (1U << 2)
+/** @} */
+
+/**
+ * @name LPTIM_OR register
+ * @{
+ */
+#define STM32_LPTIM_OR_0 (1U << 0)
+#define STM32_LPTIM_OR_1 (1U << 1)
+/** @} */
+
+/**
+ * @name TIM units references
+ * @{
+ */
+#define STM32_TIM1 ((stm32_tim_t *)TIM1_BASE)
+#define STM32_TIM2 ((stm32_tim_t *)TIM2_BASE)
+#define STM32_TIM3 ((stm32_tim_t *)TIM3_BASE)
+#define STM32_TIM4 ((stm32_tim_t *)TIM4_BASE)
+#define STM32_TIM5 ((stm32_tim_t *)TIM5_BASE)
+#define STM32_TIM6 ((stm32_tim_t *)TIM6_BASE)
+#define STM32_TIM7 ((stm32_tim_t *)TIM7_BASE)
+#define STM32_TIM8 ((stm32_tim_t *)TIM8_BASE)
+#define STM32_TIM9 ((stm32_tim_t *)TIM9_BASE)
+#define STM32_TIM10 ((stm32_tim_t *)TIM10_BASE)
+#define STM32_TIM11 ((stm32_tim_t *)TIM11_BASE)
+#define STM32_TIM12 ((stm32_tim_t *)TIM12_BASE)
+#define STM32_TIM13 ((stm32_tim_t *)TIM13_BASE)
+#define STM32_TIM14 ((stm32_tim_t *)TIM14_BASE)
+#define STM32_TIM15 ((stm32_tim_t *)TIM15_BASE)
+#define STM32_TIM16 ((stm32_tim_t *)TIM16_BASE)
+#define STM32_TIM17 ((stm32_tim_t *)TIM17_BASE)
+#define STM32_TIM18 ((stm32_tim_t *)TIM18_BASE)
+#define STM32_TIM19 ((stm32_tim_t *)TIM19_BASE)
+#define STM32_TIM20 ((stm32_tim_t *)TIM20_BASE)
+#define STM32_TIM21 ((stm32_tim_t *)TIM21_BASE)
+#define STM32_TIM22 ((stm32_tim_t *)TIM22_BASE)
+
+#define STM32_LPTIM1 ((stm32_lptim_t *)LPTIM1_BASE)
+#define STM32_LPTIM2 ((stm32_lptim_t *)LPTIM2_BASE)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 TIM registers block.
+ * @note This is the most general known form, not all timers have
+ * necessarily all registers and bits.
+ */
+typedef struct {
+ volatile uint32_t CR1;
+ volatile uint32_t CR2;
+ volatile uint32_t SMCR;
+ volatile uint32_t DIER;
+ volatile uint32_t SR;
+ volatile uint32_t EGR;
+ volatile uint32_t CCMR1;
+ volatile uint32_t CCMR2;
+ volatile uint32_t CCER;
+ volatile uint32_t CNT;
+ volatile uint32_t PSC;
+ volatile uint32_t ARR;
+ volatile uint32_t RCR;
+ volatile uint32_t CCR[4];
+ volatile uint32_t BDTR;
+#if defined(STM32G4)
+ volatile uint32_t CCXR[2];
+ volatile uint32_t CCMR3;
+ volatile uint32_t DTR2;
+ volatile uint32_t ECR;
+ volatile uint32_t TISEL;
+ volatile uint32_t AF1;
+ volatile uint32_t AF2;
+ volatile uint32_t OR;
+ volatile uint32_t RESERVED0[220];
+ volatile uint32_t DCR;
+ volatile uint32_t DMAR;
+#else
+ volatile uint32_t DCR;
+ volatile uint32_t DMAR;
+ volatile uint32_t OR;
+ volatile uint32_t CCMR3;
+ volatile uint32_t CCXR[2];
+#endif
+} stm32_tim_t;
+
+/**
+ * @brief STM32 LPTIM registers block.
+ * @note This is the most general known form, not all timers have
+ * necessarily all registers and bits.
+ */
+typedef struct {
+ volatile uint32_t ISR;
+ volatile uint32_t ICR;
+ volatile uint32_t IER;
+ volatile uint32_t CFGR;
+ volatile uint32_t CR;
+ volatile uint32_t CMP;
+ volatile uint32_t ARR;
+ volatile uint32_t CNT;
+ volatile uint32_t OR;
+} stm32_lptim_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#endif /* STM32_TIM_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/tim_irq_mapping.txt b/os/hal/ports/STM32/LLD/TIMv1/tim_irq_mapping.txt
index ed215722f8..802ad1f7a6 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/tim_irq_mapping.txt
+++ b/os/hal/ports/STM32/LLD/TIMv1/tim_irq_mapping.txt
@@ -1,14 +1,14 @@
-TIM units IRQ collisions mapping.
-
- 1B 1UP 1TC 1CC 2 3 4 5 6 7 8B 8UP 8TC 8CC 9 10 11 12 13 14 15 16 17 18 19 20 21 22 LP1 LP2
-F0xx 1---1 2---2 * * * * * * * *
-F030 1---1 2---2 * * * * *
-F1xx 1 2 3 * * * * * * * 1 2 3
-F100 1 2 3 * * * * * * * 1 2 3
-F3xx 1 2 3 * * * * * * * * * * 1 2 3
-F37x * * * * * * * * * * * * * *
-F4xx 1 2 3 * * * * * * * 4 5 6 * 1 2 3 4 5 6
-F7xx 1 2 3 * * * * * * * 4 5 6 * 1 2 3 4 5 6 *
-L0xx * * * * * * *
-L1xx * * * * * * * * *
-L4xx 1 2 3 * * * * * * * * * * * 1 2 3 * *
+TIM units IRQ collisions mapping.
+
+ 1B 1UP 1TC 1CC 2 3 4 5 6 7 8B 8UP 8TC 8CC 9 10 11 12 13 14 15 16 17 18 19 20 21 22 LP1 LP2
+F0xx 1---1 2---2 * * * * * * * *
+F030 1---1 2---2 * * * * *
+F1xx 1 2 3 * * * * * * * 1 2 3
+F100 1 2 3 * * * * * * * 1 2 3
+F3xx 1 2 3 * * * * * * * * * * 1 2 3
+F37x * * * * * * * * * * * * * *
+F4xx 1 2 3 * * * * * * * 4 5 6 * 1 2 3 4 5 6
+F7xx 1 2 3 * * * * * * * 4 5 6 * 1 2 3 4 5 6 *
+L0xx * * * * * * *
+L1xx * * * * * * * * *
+L4xx 1 2 3 * * * * * * * * * * * 1 2 3 * *
diff --git a/os/hal/ports/STM32/LLD/USARTv1/driver.mk b/os/hal/ports/STM32/LLD/USARTv1/driver.mk
index 2f65c1f1fb..4f46aebd5c 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/USARTv1/driver.mk
@@ -1,13 +1,13 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
-endif
-ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
+endif
+ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv1
diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
index 188740e5a3..8a8d856c64 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
@@ -1,650 +1,650 @@
-/*
- 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 USARTv1/hal_serial_lld.c
- * @brief STM32 low level serial driver code.
- *
- * @addtogroup SERIAL
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_SERIAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief USART1 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-SerialDriver SD1;
-#endif
-
-/** @brief USART2 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-SerialDriver SD2;
-#endif
-
-/** @brief USART3 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-SerialDriver SD3;
-#endif
-
-/** @brief UART4 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-SerialDriver SD4;
-#endif
-
-/** @brief UART5 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-SerialDriver SD5;
-#endif
-
-/** @brief USART6 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-SerialDriver SD6;
-#endif
-
-/** @brief UART7 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-SerialDriver SD7;
-#endif
-
-/** @brief UART8 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-SerialDriver SD8;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/** @brief Driver default configuration.*/
-static const SerialConfig default_config =
-{
- SERIAL_DEFAULT_BITRATE,
- 0,
- USART_CR2_STOP1_BITS,
- 0
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief USART initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- * @param[in] config the architecture-dependent serial driver configuration
- */
-static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
- uint32_t fck;
- USART_TypeDef *u = sdp->usart;
-
- /* Baud rate setting.*/
-#if STM32_HAS_USART6
- if ((sdp->usart == USART1) || (sdp->usart == USART6))
-#else
- if (sdp->usart == USART1)
-#endif
- fck = STM32_PCLK2 / config->speed;
- else
- fck = STM32_PCLK1 / config->speed;
-
- /* Correcting USARTDIV when oversampling by 8 instead of 16.
- Fraction is still 4 bits wide, but only lower 3 bits used.
- Mantissa is doubled, but Fraction is left the same.*/
-#if defined(USART_CR1_OVER8)
- if (config->cr1 & USART_CR1_OVER8)
- fck = ((fck & ~7) * 2) | (fck & 7);
-#endif
- u->BRR = fck;
-
- /* Note that some bits are enforced.*/
- u->CR2 = config->cr2 | USART_CR2_LBDIE;
- u->CR3 = config->cr3 | USART_CR3_EIE;
- u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE |
- USART_CR1_RXNEIE | USART_CR1_TE |
- USART_CR1_RE;
- u->SR = 0;
- (void)u->SR; /* SR reset step 1.*/
- (void)u->DR; /* SR reset step 2.*/
-
- /* Deciding mask to be applied on the data register on receive, this is
- required in order to mask out the parity bit.*/
- if ((config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_PCE) {
- sdp->rxmask = 0x7F;
- }
- else {
- sdp->rxmask = 0xFF;
- }
-}
-
-/**
- * @brief USART de-initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] u pointer to an USART I/O block
- */
-static void usart_deinit(USART_TypeDef *u) {
-
- u->CR1 = 0;
- u->CR2 = 0;
- u->CR3 = 0;
-}
-
-/**
- * @brief Error handling routine.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- * @param[in] sr USART SR register value
- */
-static void set_error(SerialDriver *sdp, uint16_t sr) {
- eventflags_t sts = 0;
-
- if (sr & USART_SR_ORE)
- sts |= SD_OVERRUN_ERROR;
- if (sr & USART_SR_PE)
- sts |= SD_PARITY_ERROR;
- if (sr & USART_SR_FE)
- sts |= SD_FRAMING_ERROR;
- if (sr & USART_SR_NE)
- sts |= SD_NOISE_ERROR;
- chnAddFlagsI(sdp, sts);
-}
-
-/**
- * @brief Common IRQ handler.
- *
- * @param[in] sdp communication channel associated to the USART
- */
-static void serve_interrupt(SerialDriver *sdp) {
- USART_TypeDef *u = sdp->usart;
- uint16_t cr1 = u->CR1;
- uint16_t sr = u->SR;
-
- /* Special case, LIN break detection.*/
- if (sr & USART_SR_LBD) {
- osalSysLockFromISR();
- chnAddFlagsI(sdp, SD_BREAK_DETECTED);
- u->SR = ~USART_SR_LBD;
- osalSysUnlockFromISR();
- }
-
- /* Data available.*/
- osalSysLockFromISR();
- while (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_NE | USART_SR_FE |
- USART_SR_PE)) {
- uint8_t b;
-
- /* Error condition detection.*/
- if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
- set_error(sdp, sr);
- b = (uint8_t)u->DR & sdp->rxmask;
- if (sr & USART_SR_RXNE)
- sdIncomingDataI(sdp, b);
- sr = u->SR;
- }
- osalSysUnlockFromISR();
-
- /* Transmission buffer empty.*/
- if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) {
- msg_t b;
- osalSysLockFromISR();
- b = oqGetI(&sdp->oqueue);
- if (b < MSG_OK) {
- chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
- u->CR1 = cr1 & ~USART_CR1_TXEIE;
- }
- else
- u->DR = b;
- osalSysUnlockFromISR();
- }
-
- /* Physical transmission end.*/
- if ((cr1 & USART_CR1_TCIE) && (sr & USART_SR_TC)) {
- osalSysLockFromISR();
- if (oqIsEmptyI(&sdp->oqueue)) {
- chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
- u->CR1 = cr1 & ~USART_CR1_TCIE;
- }
- osalSysUnlockFromISR();
- }
-}
-
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-static void notify1(io_queue_t *qp) {
-
- (void)qp;
- USART1->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-static void notify2(io_queue_t *qp) {
-
- (void)qp;
- USART2->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-static void notify3(io_queue_t *qp) {
-
- (void)qp;
- USART3->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-static void notify4(io_queue_t *qp) {
-
- (void)qp;
- UART4->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-static void notify5(io_queue_t *qp) {
-
- (void)qp;
- UART5->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-static void notify6(io_queue_t *qp) {
-
- (void)qp;
- USART6->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-static void notify7(io_queue_t *qp) {
-
- (void)qp;
- UART7->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-static void notify8(io_queue_t *qp) {
-
- (void)qp;
- UART8->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-#if !defined(STM32_USART1_HANDLER)
-#error "STM32_USART1_HANDLER not defined"
-#endif
-/**
- * @brief USART1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-#if !defined(STM32_USART2_HANDLER)
-#error "STM32_USART2_HANDLER not defined"
-#endif
-/**
- * @brief USART2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-#if !defined(STM32_USART3_HANDLER)
-#error "STM32_USART3_HANDLER not defined"
-#endif
-/**
- * @brief USART3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-#if !defined(STM32_UART4_HANDLER)
-#error "STM32_UART4_HANDLER not defined"
-#endif
-/**
- * @brief UART4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-#if !defined(STM32_UART5_HANDLER)
-#error "STM32_UART5_HANDLER not defined"
-#endif
-/**
- * @brief UART5 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-#if !defined(STM32_USART6_HANDLER)
-#error "STM32_USART6_HANDLER not defined"
-#endif
-/**
- * @brief USART6 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-#if !defined(STM32_UART7_HANDLER)
-#error "STM32_UART7_HANDLER not defined"
-#endif
-/**
- * @brief UART7 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-#if !defined(STM32_UART8_HANDLER)
-#error "STM32_UART8_HANDLER not defined"
-#endif
-/**
- * @brief UART8 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_interrupt(&SD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level serial driver initialization.
- *
- * @notapi
- */
-void sd_lld_init(void) {
-
-#if STM32_SERIAL_USE_USART1
- sdObjectInit(&SD1, NULL, notify1);
- SD1.usart = USART1;
-#endif
-
-#if STM32_SERIAL_USE_USART2
- sdObjectInit(&SD2, NULL, notify2);
- SD2.usart = USART2;
-#endif
-
-#if STM32_SERIAL_USE_USART3
- sdObjectInit(&SD3, NULL, notify3);
- SD3.usart = USART3;
-#endif
-
-#if STM32_SERIAL_USE_UART4
- sdObjectInit(&SD4, NULL, notify4);
- SD4.usart = UART4;
-#endif
-
-#if STM32_SERIAL_USE_UART5
- sdObjectInit(&SD5, NULL, notify5);
- SD5.usart = UART5;
-#endif
-
-#if STM32_SERIAL_USE_USART6
- sdObjectInit(&SD6, NULL, notify6);
- SD6.usart = USART6;
-#endif
-
-#if STM32_SERIAL_USE_UART7
- sdObjectInit(&SD7, NULL, notify7);
- SD7.usart = UART7;
-#endif
-
-#if STM32_SERIAL_USE_UART8
- sdObjectInit(&SD8, NULL, notify8);
- SD8.usart = UART8;
-#endif
-}
-
-/**
- * @brief Low level serial driver configuration and (re)start.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- * @param[in] config the architecture-dependent serial driver configuration.
- * If this parameter is set to @p NULL then a default
- * configuration is used.
- *
- * @notapi
- */
-void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
-
- if (config == NULL)
- config = &default_config;
-
- if (sdp->state == SD_STOP) {
-#if STM32_SERIAL_USE_USART1
- if (&SD1 == sdp) {
- rccEnableUSART1(true);
- nvicEnableVector(STM32_USART1_NUMBER, STM32_SERIAL_USART1_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_USART2
- if (&SD2 == sdp) {
- rccEnableUSART2(true);
- nvicEnableVector(STM32_USART2_NUMBER, STM32_SERIAL_USART2_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_USART3
- if (&SD3 == sdp) {
- rccEnableUSART3(true);
- nvicEnableVector(STM32_USART3_NUMBER, STM32_SERIAL_USART3_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_UART4
- if (&SD4 == sdp) {
- rccEnableUART4(true);
- nvicEnableVector(STM32_UART4_NUMBER, STM32_SERIAL_UART4_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_UART5
- if (&SD5 == sdp) {
- rccEnableUART5(true);
- nvicEnableVector(STM32_UART5_NUMBER, STM32_SERIAL_UART5_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_USART6
- if (&SD6 == sdp) {
- rccEnableUSART6(true);
- nvicEnableVector(STM32_USART6_NUMBER, STM32_SERIAL_USART6_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_UART7
- if (&SD7 == sdp) {
- rccEnableUART7(true);
- nvicEnableVector(STM32_UART7_NUMBER, STM32_SERIAL_UART7_PRIORITY);
- }
-#endif
-#if STM32_SERIAL_USE_UART8
- if (&SD8 == sdp) {
- rccEnableUART8(true);
- nvicEnableVector(STM32_UART8_NUMBER, STM32_SERIAL_UART8_PRIORITY);
- }
-#endif
- }
- usart_init(sdp, config);
-}
-
-/**
- * @brief Low level serial driver stop.
- * @details De-initializes the USART, stops the associated clock, resets the
- * interrupt vector.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- *
- * @notapi
- */
-void sd_lld_stop(SerialDriver *sdp) {
-
- if (sdp->state == SD_READY) {
- usart_deinit(sdp->usart);
-#if STM32_SERIAL_USE_USART1
- if (&SD1 == sdp) {
- rccDisableUSART1();
- nvicDisableVector(STM32_USART1_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_USART2
- if (&SD2 == sdp) {
- rccDisableUSART2();
- nvicDisableVector(STM32_USART2_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_USART3
- if (&SD3 == sdp) {
- rccDisableUSART3();
- nvicDisableVector(STM32_USART3_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART4
- if (&SD4 == sdp) {
- rccDisableUART4();
- nvicDisableVector(STM32_UART4_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART5
- if (&SD5 == sdp) {
- rccDisableUART5();
- nvicDisableVector(STM32_UART5_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_USART6
- if (&SD6 == sdp) {
- rccDisableUSART6();
- nvicDisableVector(STM32_USART6_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART7
- if (&SD7 == sdp) {
- rccDisableUART7();
- nvicDisableVector(STM32_UART7_NUMBER);
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART8
- if (&SD8 == sdp) {
- rccDisableUART8();
- nvicDisableVector(STM32_UART8_NUMBER);
- return;
- }
-#endif
- }
-}
-
-#endif /* HAL_USE_SERIAL */
-
-/** @} */
+/*
+ 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 USARTv1/hal_serial_lld.c
+ * @brief STM32 low level serial driver code.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief USART1 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+SerialDriver SD1;
+#endif
+
+/** @brief USART2 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+SerialDriver SD2;
+#endif
+
+/** @brief USART3 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+SerialDriver SD3;
+#endif
+
+/** @brief UART4 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+SerialDriver SD4;
+#endif
+
+/** @brief UART5 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+SerialDriver SD5;
+#endif
+
+/** @brief USART6 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+SerialDriver SD6;
+#endif
+
+/** @brief UART7 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+SerialDriver SD7;
+#endif
+
+/** @brief UART8 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+SerialDriver SD8;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/** @brief Driver default configuration.*/
+static const SerialConfig default_config =
+{
+ SERIAL_DEFAULT_BITRATE,
+ 0,
+ USART_CR2_STOP1_BITS,
+ 0
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief USART initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] config the architecture-dependent serial driver configuration
+ */
+static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
+ uint32_t fck;
+ USART_TypeDef *u = sdp->usart;
+
+ /* Baud rate setting.*/
+#if STM32_HAS_USART6
+ if ((sdp->usart == USART1) || (sdp->usart == USART6))
+#else
+ if (sdp->usart == USART1)
+#endif
+ fck = STM32_PCLK2 / config->speed;
+ else
+ fck = STM32_PCLK1 / config->speed;
+
+ /* Correcting USARTDIV when oversampling by 8 instead of 16.
+ Fraction is still 4 bits wide, but only lower 3 bits used.
+ Mantissa is doubled, but Fraction is left the same.*/
+#if defined(USART_CR1_OVER8)
+ if (config->cr1 & USART_CR1_OVER8)
+ fck = ((fck & ~7) * 2) | (fck & 7);
+#endif
+ u->BRR = fck;
+
+ /* Note that some bits are enforced.*/
+ u->CR2 = config->cr2 | USART_CR2_LBDIE;
+ u->CR3 = config->cr3 | USART_CR3_EIE;
+ u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE |
+ USART_CR1_RXNEIE | USART_CR1_TE |
+ USART_CR1_RE;
+ u->SR = 0;
+ (void)u->SR; /* SR reset step 1.*/
+ (void)u->DR; /* SR reset step 2.*/
+
+ /* Deciding mask to be applied on the data register on receive, this is
+ required in order to mask out the parity bit.*/
+ if ((config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_PCE) {
+ sdp->rxmask = 0x7F;
+ }
+ else {
+ sdp->rxmask = 0xFF;
+ }
+}
+
+/**
+ * @brief USART de-initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] u pointer to an USART I/O block
+ */
+static void usart_deinit(USART_TypeDef *u) {
+
+ u->CR1 = 0;
+ u->CR2 = 0;
+ u->CR3 = 0;
+}
+
+/**
+ * @brief Error handling routine.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] sr USART SR register value
+ */
+static void set_error(SerialDriver *sdp, uint16_t sr) {
+ eventflags_t sts = 0;
+
+ if (sr & USART_SR_ORE)
+ sts |= SD_OVERRUN_ERROR;
+ if (sr & USART_SR_PE)
+ sts |= SD_PARITY_ERROR;
+ if (sr & USART_SR_FE)
+ sts |= SD_FRAMING_ERROR;
+ if (sr & USART_SR_NE)
+ sts |= SD_NOISE_ERROR;
+ chnAddFlagsI(sdp, sts);
+}
+
+/**
+ * @brief Common IRQ handler.
+ *
+ * @param[in] sdp communication channel associated to the USART
+ */
+static void serve_interrupt(SerialDriver *sdp) {
+ USART_TypeDef *u = sdp->usart;
+ uint16_t cr1 = u->CR1;
+ uint16_t sr = u->SR;
+
+ /* Special case, LIN break detection.*/
+ if (sr & USART_SR_LBD) {
+ osalSysLockFromISR();
+ chnAddFlagsI(sdp, SD_BREAK_DETECTED);
+ u->SR = ~USART_SR_LBD;
+ osalSysUnlockFromISR();
+ }
+
+ /* Data available.*/
+ osalSysLockFromISR();
+ while (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_NE | USART_SR_FE |
+ USART_SR_PE)) {
+ uint8_t b;
+
+ /* Error condition detection.*/
+ if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE))
+ set_error(sdp, sr);
+ b = (uint8_t)u->DR & sdp->rxmask;
+ if (sr & USART_SR_RXNE)
+ sdIncomingDataI(sdp, b);
+ sr = u->SR;
+ }
+ osalSysUnlockFromISR();
+
+ /* Transmission buffer empty.*/
+ if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) {
+ msg_t b;
+ osalSysLockFromISR();
+ b = oqGetI(&sdp->oqueue);
+ if (b < MSG_OK) {
+ chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
+ u->CR1 = cr1 & ~USART_CR1_TXEIE;
+ }
+ else
+ u->DR = b;
+ osalSysUnlockFromISR();
+ }
+
+ /* Physical transmission end.*/
+ if ((cr1 & USART_CR1_TCIE) && (sr & USART_SR_TC)) {
+ osalSysLockFromISR();
+ if (oqIsEmptyI(&sdp->oqueue)) {
+ chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
+ u->CR1 = cr1 & ~USART_CR1_TCIE;
+ }
+ osalSysUnlockFromISR();
+ }
+}
+
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+static void notify1(io_queue_t *qp) {
+
+ (void)qp;
+ USART1->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+static void notify2(io_queue_t *qp) {
+
+ (void)qp;
+ USART2->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+static void notify3(io_queue_t *qp) {
+
+ (void)qp;
+ USART3->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+static void notify4(io_queue_t *qp) {
+
+ (void)qp;
+ UART4->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+static void notify5(io_queue_t *qp) {
+
+ (void)qp;
+ UART5->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+static void notify6(io_queue_t *qp) {
+
+ (void)qp;
+ USART6->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+static void notify7(io_queue_t *qp) {
+
+ (void)qp;
+ UART7->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+static void notify8(io_queue_t *qp) {
+
+ (void)qp;
+ UART8->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+#if !defined(STM32_USART1_HANDLER)
+#error "STM32_USART1_HANDLER not defined"
+#endif
+/**
+ * @brief USART1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+#if !defined(STM32_USART2_HANDLER)
+#error "STM32_USART2_HANDLER not defined"
+#endif
+/**
+ * @brief USART2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+#if !defined(STM32_USART3_HANDLER)
+#error "STM32_USART3_HANDLER not defined"
+#endif
+/**
+ * @brief USART3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+#if !defined(STM32_UART4_HANDLER)
+#error "STM32_UART4_HANDLER not defined"
+#endif
+/**
+ * @brief UART4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+#if !defined(STM32_UART5_HANDLER)
+#error "STM32_UART5_HANDLER not defined"
+#endif
+/**
+ * @brief UART5 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+#if !defined(STM32_USART6_HANDLER)
+#error "STM32_USART6_HANDLER not defined"
+#endif
+/**
+ * @brief USART6 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+#if !defined(STM32_UART7_HANDLER)
+#error "STM32_UART7_HANDLER not defined"
+#endif
+/**
+ * @brief UART7 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+#if !defined(STM32_UART8_HANDLER)
+#error "STM32_UART8_HANDLER not defined"
+#endif
+/**
+ * @brief UART8 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_interrupt(&SD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level serial driver initialization.
+ *
+ * @notapi
+ */
+void sd_lld_init(void) {
+
+#if STM32_SERIAL_USE_USART1
+ sdObjectInit(&SD1, NULL, notify1);
+ SD1.usart = USART1;
+#endif
+
+#if STM32_SERIAL_USE_USART2
+ sdObjectInit(&SD2, NULL, notify2);
+ SD2.usart = USART2;
+#endif
+
+#if STM32_SERIAL_USE_USART3
+ sdObjectInit(&SD3, NULL, notify3);
+ SD3.usart = USART3;
+#endif
+
+#if STM32_SERIAL_USE_UART4
+ sdObjectInit(&SD4, NULL, notify4);
+ SD4.usart = UART4;
+#endif
+
+#if STM32_SERIAL_USE_UART5
+ sdObjectInit(&SD5, NULL, notify5);
+ SD5.usart = UART5;
+#endif
+
+#if STM32_SERIAL_USE_USART6
+ sdObjectInit(&SD6, NULL, notify6);
+ SD6.usart = USART6;
+#endif
+
+#if STM32_SERIAL_USE_UART7
+ sdObjectInit(&SD7, NULL, notify7);
+ SD7.usart = UART7;
+#endif
+
+#if STM32_SERIAL_USE_UART8
+ sdObjectInit(&SD8, NULL, notify8);
+ SD8.usart = UART8;
+#endif
+}
+
+/**
+ * @brief Low level serial driver configuration and (re)start.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] config the architecture-dependent serial driver configuration.
+ * If this parameter is set to @p NULL then a default
+ * configuration is used.
+ *
+ * @notapi
+ */
+void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
+
+ if (config == NULL)
+ config = &default_config;
+
+ if (sdp->state == SD_STOP) {
+#if STM32_SERIAL_USE_USART1
+ if (&SD1 == sdp) {
+ rccEnableUSART1(true);
+ nvicEnableVector(STM32_USART1_NUMBER, STM32_SERIAL_USART1_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_USART2
+ if (&SD2 == sdp) {
+ rccEnableUSART2(true);
+ nvicEnableVector(STM32_USART2_NUMBER, STM32_SERIAL_USART2_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_USART3
+ if (&SD3 == sdp) {
+ rccEnableUSART3(true);
+ nvicEnableVector(STM32_USART3_NUMBER, STM32_SERIAL_USART3_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_UART4
+ if (&SD4 == sdp) {
+ rccEnableUART4(true);
+ nvicEnableVector(STM32_UART4_NUMBER, STM32_SERIAL_UART4_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_UART5
+ if (&SD5 == sdp) {
+ rccEnableUART5(true);
+ nvicEnableVector(STM32_UART5_NUMBER, STM32_SERIAL_UART5_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_USART6
+ if (&SD6 == sdp) {
+ rccEnableUSART6(true);
+ nvicEnableVector(STM32_USART6_NUMBER, STM32_SERIAL_USART6_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_UART7
+ if (&SD7 == sdp) {
+ rccEnableUART7(true);
+ nvicEnableVector(STM32_UART7_NUMBER, STM32_SERIAL_UART7_PRIORITY);
+ }
+#endif
+#if STM32_SERIAL_USE_UART8
+ if (&SD8 == sdp) {
+ rccEnableUART8(true);
+ nvicEnableVector(STM32_UART8_NUMBER, STM32_SERIAL_UART8_PRIORITY);
+ }
+#endif
+ }
+ usart_init(sdp, config);
+}
+
+/**
+ * @brief Low level serial driver stop.
+ * @details De-initializes the USART, stops the associated clock, resets the
+ * interrupt vector.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ *
+ * @notapi
+ */
+void sd_lld_stop(SerialDriver *sdp) {
+
+ if (sdp->state == SD_READY) {
+ usart_deinit(sdp->usart);
+#if STM32_SERIAL_USE_USART1
+ if (&SD1 == sdp) {
+ rccDisableUSART1();
+ nvicDisableVector(STM32_USART1_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_USART2
+ if (&SD2 == sdp) {
+ rccDisableUSART2();
+ nvicDisableVector(STM32_USART2_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_USART3
+ if (&SD3 == sdp) {
+ rccDisableUSART3();
+ nvicDisableVector(STM32_USART3_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART4
+ if (&SD4 == sdp) {
+ rccDisableUART4();
+ nvicDisableVector(STM32_UART4_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART5
+ if (&SD5 == sdp) {
+ rccDisableUART5();
+ nvicDisableVector(STM32_UART5_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_USART6
+ if (&SD6 == sdp) {
+ rccDisableUSART6();
+ nvicDisableVector(STM32_USART6_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART7
+ if (&SD7 == sdp) {
+ rccDisableUART7();
+ nvicDisableVector(STM32_UART7_NUMBER);
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART8
+ if (&SD8 == sdp) {
+ rccDisableUART8();
+ nvicDisableVector(STM32_UART8_NUMBER);
+ return;
+ }
+#endif
+ }
+}
+
+#endif /* HAL_USE_SERIAL */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h
index de259a70d3..4b40942266 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h
+++ b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h
@@ -1,362 +1,362 @@
-/*
- 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 USARTv1/hal_serial_lld.h
- * @brief STM32 low level serial driver header.
- *
- * @addtogroup SERIAL
- * @{
- */
-
-#ifndef HAL_SERIAL_LLD_H
-#define HAL_SERIAL_LLD_H
-
-#if HAL_USE_SERIAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief USART1 driver enable switch.
- * @details If set to @p TRUE the support for USART1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART1) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART1 FALSE
-#endif
-
-/**
- * @brief USART2 driver enable switch.
- * @details If set to @p TRUE the support for USART2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART2) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART2 FALSE
-#endif
-
-/**
- * @brief USART3 driver enable switch.
- * @details If set to @p TRUE the support for USART3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART3) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART3 FALSE
-#endif
-
-/**
- * @brief UART4 driver enable switch.
- * @details If set to @p TRUE the support for UART4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART4) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART4 FALSE
-#endif
-
-/**
- * @brief UART5 driver enable switch.
- * @details If set to @p TRUE the support for UART5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART5) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART5 FALSE
-#endif
-
-/**
- * @brief USART6 driver enable switch.
- * @details If set to @p TRUE the support for USART6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART6) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART6 FALSE
-#endif
-
-/**
- * @brief UART7 driver enable switch.
- * @details If set to @p TRUE the support for UART7 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART7) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART7 FALSE
-#endif
-
-/**
- * @brief UART8 driver enable switch.
- * @details If set to @p TRUE the support for UART8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART8) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART8 FALSE
-#endif
-
-/**
- * @brief USART1 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART1_PRIORITY 12
-#endif
-
-/**
- * @brief USART2 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART2_PRIORITY 12
-#endif
-
-/**
- * @brief USART3 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART3_PRIORITY 12
-#endif
-
-/**
- * @brief UART4 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART4_PRIORITY 12
-#endif
-
-/**
- * @brief UART5 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART5_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART5_PRIORITY 12
-#endif
-
-/**
- * @brief USART6 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART6_PRIORITY 12
-#endif
-
-/**
- * @brief UART7 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART7_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART7_PRIORITY 12
-#endif
-
-/**
- * @brief UART8 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART8_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART8_PRIORITY 12
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_SERIAL_USE_USART1 && !STM32_HAS_USART1
-#error "USART1 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_USART2 && !STM32_HAS_USART2
-#error "USART2 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_USART3 && !STM32_HAS_USART3
-#error "USART3 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART4 && !STM32_HAS_UART4
-#error "UART4 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART5 && !STM32_HAS_UART5
-#error "UART5 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_USART6 && !STM32_HAS_USART6
-#error "USART6 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART7 && !STM32_HAS_UART7
-#error "UART7 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART8 && !STM32_HAS_UART8
-#error "UART8 not present in the selected device"
-#endif
-
-#if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 && \
- !STM32_SERIAL_USE_USART3 && !STM32_SERIAL_USE_UART4 && \
- !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 && \
- !STM32_SERIAL_USE_UART7 && !STM32_SERIAL_USE_UART8
-#error "SERIAL driver activated but no USART/UART peripheral assigned"
-#endif
-
-#if STM32_SERIAL_USE_USART1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART1_PRIORITY)
-#error "Invalid IRQ priority assigned to USART1"
-#endif
-
-#if STM32_SERIAL_USE_USART2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART2_PRIORITY)
-#error "Invalid IRQ priority assigned to USART2"
-#endif
-
-#if STM32_SERIAL_USE_USART3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART3_PRIORITY)
-#error "Invalid IRQ priority assigned to USART3"
-#endif
-
-#if STM32_SERIAL_USE_UART4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART4_PRIORITY)
-#error "Invalid IRQ priority assigned to UART4"
-#endif
-
-#if STM32_SERIAL_USE_UART5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART5_PRIORITY)
-#error "Invalid IRQ priority assigned to UART5"
-#endif
-
-#if STM32_SERIAL_USE_USART6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART6_PRIORITY)
-#error "Invalid IRQ priority assigned to USART6"
-#endif
-
-#if STM32_SERIAL_USE_UART7 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART7_PRIORITY)
-#error "Invalid IRQ priority assigned to UART7"
-#endif
-
-#if STM32_SERIAL_USE_UART8 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART8_PRIORITY)
-#error "Invalid IRQ priority assigned to UART8"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 Serial Driver configuration structure.
- * @details An instance of this structure must be passed to @p sdStart()
- * in order to configure and start a serial driver operations.
- * @note This structure content is architecture dependent, each driver
- * implementation defines its own version and the custom static
- * initializers.
- */
-typedef struct {
- /**
- * @brief Bit rate.
- */
- uint32_t speed;
- /* End of the mandatory fields.*/
- /**
- * @brief Initialization value for the CR1 register.
- */
- uint16_t cr1;
- /**
- * @brief Initialization value for the CR2 register.
- */
- uint16_t cr2;
- /**
- * @brief Initialization value for the CR3 register.
- */
- uint16_t cr3;
-} SerialConfig;
-
-/**
- * @brief @p SerialDriver specific data.
- */
-#define _serial_driver_data \
- _base_asynchronous_channel_data \
- /* Driver state.*/ \
- sdstate_t state; \
- /* Input queue.*/ \
- input_queue_t iqueue; \
- /* Output queue.*/ \
- output_queue_t oqueue; \
- /* Input circular buffer.*/ \
- uint8_t ib[SERIAL_BUFFERS_SIZE]; \
- /* Output circular buffer.*/ \
- uint8_t ob[SERIAL_BUFFERS_SIZE]; \
- /* End of the mandatory fields.*/ \
- /* Pointer to the USART registers block.*/ \
- USART_TypeDef *usart; \
- /* Mask to be applied on received frames.*/ \
- uint8_t rxmask;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*
- * Extra USARTs definitions here (missing from the ST header file).
- */
-#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
-#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
-#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
-#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SERIAL_USE_USART1 && !defined(__DOXYGEN__)
-extern SerialDriver SD1;
-#endif
-#if STM32_SERIAL_USE_USART2 && !defined(__DOXYGEN__)
-extern SerialDriver SD2;
-#endif
-#if STM32_SERIAL_USE_USART3 && !defined(__DOXYGEN__)
-extern SerialDriver SD3;
-#endif
-#if STM32_SERIAL_USE_UART4 && !defined(__DOXYGEN__)
-extern SerialDriver SD4;
-#endif
-#if STM32_SERIAL_USE_UART5 && !defined(__DOXYGEN__)
-extern SerialDriver SD5;
-#endif
-#if STM32_SERIAL_USE_USART6 && !defined(__DOXYGEN__)
-extern SerialDriver SD6;
-#endif
-#if STM32_SERIAL_USE_UART7 && !defined(__DOXYGEN__)
-extern SerialDriver SD7;
-#endif
-#if STM32_SERIAL_USE_UART8 && !defined(__DOXYGEN__)
-extern SerialDriver SD8;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void sd_lld_init(void);
- void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
- void sd_lld_stop(SerialDriver *sdp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SERIAL */
-
-#endif /* HAL_SERIAL_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 USARTv1/hal_serial_lld.h
+ * @brief STM32 low level serial driver header.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#ifndef HAL_SERIAL_LLD_H
+#define HAL_SERIAL_LLD_H
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief USART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART1) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART1 FALSE
+#endif
+
+/**
+ * @brief USART2 driver enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART2) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART2 FALSE
+#endif
+
+/**
+ * @brief USART3 driver enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART3) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART3 FALSE
+#endif
+
+/**
+ * @brief UART4 driver enable switch.
+ * @details If set to @p TRUE the support for UART4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART4) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART4 FALSE
+#endif
+
+/**
+ * @brief UART5 driver enable switch.
+ * @details If set to @p TRUE the support for UART5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART5) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART5 FALSE
+#endif
+
+/**
+ * @brief USART6 driver enable switch.
+ * @details If set to @p TRUE the support for USART6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART6) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART6 FALSE
+#endif
+
+/**
+ * @brief UART7 driver enable switch.
+ * @details If set to @p TRUE the support for UART7 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART7) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART7 FALSE
+#endif
+
+/**
+ * @brief UART8 driver enable switch.
+ * @details If set to @p TRUE the support for UART8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART8) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART8 FALSE
+#endif
+
+/**
+ * @brief USART1 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART1_PRIORITY 12
+#endif
+
+/**
+ * @brief USART2 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART2_PRIORITY 12
+#endif
+
+/**
+ * @brief USART3 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART3_PRIORITY 12
+#endif
+
+/**
+ * @brief UART4 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART4_PRIORITY 12
+#endif
+
+/**
+ * @brief UART5 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART5_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART5_PRIORITY 12
+#endif
+
+/**
+ * @brief USART6 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART6_PRIORITY 12
+#endif
+
+/**
+ * @brief UART7 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART7_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART7_PRIORITY 12
+#endif
+
+/**
+ * @brief UART8 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART8_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART8_PRIORITY 12
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_SERIAL_USE_USART1 && !STM32_HAS_USART1
+#error "USART1 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_USART2 && !STM32_HAS_USART2
+#error "USART2 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_USART3 && !STM32_HAS_USART3
+#error "USART3 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART4 && !STM32_HAS_UART4
+#error "UART4 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART5 && !STM32_HAS_UART5
+#error "UART5 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_USART6 && !STM32_HAS_USART6
+#error "USART6 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART7 && !STM32_HAS_UART7
+#error "UART7 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART8 && !STM32_HAS_UART8
+#error "UART8 not present in the selected device"
+#endif
+
+#if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 && \
+ !STM32_SERIAL_USE_USART3 && !STM32_SERIAL_USE_UART4 && \
+ !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 && \
+ !STM32_SERIAL_USE_UART7 && !STM32_SERIAL_USE_UART8
+#error "SERIAL driver activated but no USART/UART peripheral assigned"
+#endif
+
+#if STM32_SERIAL_USE_USART1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART1_PRIORITY)
+#error "Invalid IRQ priority assigned to USART1"
+#endif
+
+#if STM32_SERIAL_USE_USART2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART2_PRIORITY)
+#error "Invalid IRQ priority assigned to USART2"
+#endif
+
+#if STM32_SERIAL_USE_USART3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART3_PRIORITY)
+#error "Invalid IRQ priority assigned to USART3"
+#endif
+
+#if STM32_SERIAL_USE_UART4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART4_PRIORITY)
+#error "Invalid IRQ priority assigned to UART4"
+#endif
+
+#if STM32_SERIAL_USE_UART5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART5_PRIORITY)
+#error "Invalid IRQ priority assigned to UART5"
+#endif
+
+#if STM32_SERIAL_USE_USART6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART6_PRIORITY)
+#error "Invalid IRQ priority assigned to USART6"
+#endif
+
+#if STM32_SERIAL_USE_UART7 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART7_PRIORITY)
+#error "Invalid IRQ priority assigned to UART7"
+#endif
+
+#if STM32_SERIAL_USE_UART8 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART8_PRIORITY)
+#error "Invalid IRQ priority assigned to UART8"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 Serial Driver configuration structure.
+ * @details An instance of this structure must be passed to @p sdStart()
+ * in order to configure and start a serial driver operations.
+ * @note This structure content is architecture dependent, each driver
+ * implementation defines its own version and the custom static
+ * initializers.
+ */
+typedef struct {
+ /**
+ * @brief Bit rate.
+ */
+ uint32_t speed;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Initialization value for the CR1 register.
+ */
+ uint16_t cr1;
+ /**
+ * @brief Initialization value for the CR2 register.
+ */
+ uint16_t cr2;
+ /**
+ * @brief Initialization value for the CR3 register.
+ */
+ uint16_t cr3;
+} SerialConfig;
+
+/**
+ * @brief @p SerialDriver specific data.
+ */
+#define _serial_driver_data \
+ _base_asynchronous_channel_data \
+ /* Driver state.*/ \
+ sdstate_t state; \
+ /* Input queue.*/ \
+ input_queue_t iqueue; \
+ /* Output queue.*/ \
+ output_queue_t oqueue; \
+ /* Input circular buffer.*/ \
+ uint8_t ib[SERIAL_BUFFERS_SIZE]; \
+ /* Output circular buffer.*/ \
+ uint8_t ob[SERIAL_BUFFERS_SIZE]; \
+ /* End of the mandatory fields.*/ \
+ /* Pointer to the USART registers block.*/ \
+ USART_TypeDef *usart; \
+ /* Mask to be applied on received frames.*/ \
+ uint8_t rxmask;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*
+ * Extra USARTs definitions here (missing from the ST header file).
+ */
+#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
+#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
+#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
+#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SERIAL_USE_USART1 && !defined(__DOXYGEN__)
+extern SerialDriver SD1;
+#endif
+#if STM32_SERIAL_USE_USART2 && !defined(__DOXYGEN__)
+extern SerialDriver SD2;
+#endif
+#if STM32_SERIAL_USE_USART3 && !defined(__DOXYGEN__)
+extern SerialDriver SD3;
+#endif
+#if STM32_SERIAL_USE_UART4 && !defined(__DOXYGEN__)
+extern SerialDriver SD4;
+#endif
+#if STM32_SERIAL_USE_UART5 && !defined(__DOXYGEN__)
+extern SerialDriver SD5;
+#endif
+#if STM32_SERIAL_USE_USART6 && !defined(__DOXYGEN__)
+extern SerialDriver SD6;
+#endif
+#if STM32_SERIAL_USE_UART7 && !defined(__DOXYGEN__)
+extern SerialDriver SD7;
+#endif
+#if STM32_SERIAL_USE_UART8 && !defined(__DOXYGEN__)
+extern SerialDriver SD8;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sd_lld_init(void);
+ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
+ void sd_lld_stop(SerialDriver *sdp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SERIAL */
+
+#endif /* HAL_SERIAL_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
index a41a557461..919bd978ec 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.c
@@ -1,1028 +1,1028 @@
-/*
- 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 USARTv1/hal_uart_lld.c
- * @brief STM32 low level UART driver code.
- *
- * @addtogroup UART
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_UART || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define USART1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART1_RX_DMA_STREAM, \
- STM32_USART1_RX_DMA_CHN)
-
-#define USART1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART1_TX_DMA_STREAM, \
- STM32_USART1_TX_DMA_CHN)
-
-#define USART2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART2_RX_DMA_STREAM, \
- STM32_USART2_RX_DMA_CHN)
-
-#define USART2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART2_TX_DMA_STREAM, \
- STM32_USART2_TX_DMA_CHN)
-
-#define USART3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART3_RX_DMA_STREAM, \
- STM32_USART3_RX_DMA_CHN)
-
-#define USART3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM, \
- STM32_USART3_TX_DMA_CHN)
-
-#define UART4_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART4_RX_DMA_STREAM, \
- STM32_UART4_RX_DMA_CHN)
-
-#define UART4_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART4_TX_DMA_STREAM, \
- STM32_UART4_TX_DMA_CHN)
-
-#define UART5_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART5_RX_DMA_STREAM, \
- STM32_UART5_RX_DMA_CHN)
-
-#define UART5_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART5_TX_DMA_STREAM, \
- STM32_UART5_TX_DMA_CHN)
-
-#define USART6_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART6_RX_DMA_STREAM, \
- STM32_USART6_RX_DMA_CHN)
-
-#define USART6_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART6_TX_DMA_STREAM, \
- STM32_USART6_TX_DMA_CHN)
-
-#define UART7_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART7_RX_DMA_STREAM, \
- STM32_UART7_RX_DMA_CHN)
-
-#define UART7_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART7_TX_DMA_STREAM, \
- STM32_UART7_TX_DMA_CHN)
-
-#define UART8_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART8_RX_DMA_STREAM, \
- STM32_UART8_RX_DMA_CHN)
-
-#define UART8_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART8_TX_DMA_STREAM, \
- STM32_UART8_TX_DMA_CHN)
-
-#define STM32_UART45_CR2_CHECK_MASK \
- (USART_CR2_STOP_0 | USART_CR2_CLKEN | USART_CR2_CPOL | USART_CR2_CPHA | \
- USART_CR2_LBCL)
-
-#define STM32_UART45_CR3_CHECK_MASK \
- (USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_SCEN | \
- USART_CR3_NACK)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief USART1 UART driver identifier.*/
-#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
-UARTDriver UARTD1;
-#endif
-
-/** @brief USART2 UART driver identifier.*/
-#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
-UARTDriver UARTD2;
-#endif
-
-/** @brief USART3 UART driver identifier.*/
-#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
-UARTDriver UARTD3;
-#endif
-
-/** @brief UART4 UART driver identifier.*/
-#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
-UARTDriver UARTD4;
-#endif
-
-/** @brief UART5 UART driver identifier.*/
-#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
-UARTDriver UARTD5;
-#endif
-
-/** @brief USART6 UART driver identifier.*/
-#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
-UARTDriver UARTD6;
-#endif
-
-/** @brief UART7 UART driver identifier.*/
-#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
-UARTDriver UARTD7;
-#endif
-
-/** @brief UART8 UART driver identifier.*/
-#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
-UARTDriver UARTD8;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Status bits translation.
- *
- * @param[in] sr USART SR register value
- *
- * @return The error flags.
- */
-static uartflags_t translate_errors(uint16_t sr) {
- uartflags_t sts = 0;
-
- if (sr & USART_SR_ORE)
- sts |= UART_OVERRUN_ERROR;
- if (sr & USART_SR_PE)
- sts |= UART_PARITY_ERROR;
- if (sr & USART_SR_FE)
- sts |= UART_FRAMING_ERROR;
- if (sr & USART_SR_NE)
- sts |= UART_NOISE_ERROR;
- if (sr & USART_SR_LBD)
- sts |= UART_BREAK_DETECTED;
- return sts;
-}
-
-/**
- * @brief Puts the receiver in the UART_RX_IDLE state.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void uart_enter_rx_idle_loop(UARTDriver *uartp) {
- uint32_t mode;
-
- /* RX DMA channel preparation, if the char callback is defined then the
- TCIE interrupt is enabled too.*/
- if (uartp->config->rxchar_cb == NULL)
- mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC;
- else
- mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TCIE;
- dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf);
- dmaStreamSetTransactionSize(uartp->dmarx, 1);
- dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
- dmaStreamEnable(uartp->dmarx);
-}
-
-/**
- * @brief USART de-initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void usart_stop(UARTDriver *uartp) {
-
- /* Stops RX and TX DMA channels.*/
- dmaStreamDisable(uartp->dmarx);
- dmaStreamDisable(uartp->dmatx);
-
- /* Stops USART operations.*/
- uartp->usart->CR1 = 0;
- uartp->usart->CR2 = 0;
- uartp->usart->CR3 = 0;
-}
-
-/**
- * @brief USART initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void usart_start(UARTDriver *uartp) {
- uint32_t fck;
- uint16_t cr1;
- USART_TypeDef *u = uartp->usart;
-
- /* Defensive programming, starting from a clean state.*/
- usart_stop(uartp);
-
- /* Baud rate setting.*/
-#if STM32_HAS_USART6
- if ((uartp->usart == USART1) || (uartp->usart == USART6))
-#else
- if (uartp->usart == USART1)
-#endif
- fck = STM32_PCLK2 / uartp->config->speed;
- else
- fck = STM32_PCLK1 / uartp->config->speed;
-
- /* Correcting USARTDIV when oversampling by 8 instead of 16.
- Fraction is still 4 bits wide, but only lower 3 bits used.
- Mantissa is doubled, but Fraction is left the same.*/
-#if defined(USART_CR1_OVER8)
- if (uartp->config->cr1 & USART_CR1_OVER8)
- fck = ((fck & ~7) * 2) | (fck & 7);
-#endif
- u->BRR = fck;
-
- /* Resetting eventual pending status flags.*/
- (void)u->SR; /* SR reset step 1.*/
- (void)u->DR; /* SR reset step 2.*/
- u->SR = 0;
-
- /* Note that some bits are enforced because required for correct driver
- operations.*/
- u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
- u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
- USART_CR3_EIE;
-
- /* Mustn't ever set TCIE here - if done, it causes an immediate
- interrupt.*/
- cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
-
- /* Add Idle interrupt if needed */
- if (uartp->config->timeout_cb != NULL)
- cr1 |= USART_CR1_IDLEIE;
-
- u->CR1 = uartp->config->cr1 | cr1;
-
- /* Starting the receiver idle loop.*/
- uart_enter_rx_idle_loop(uartp);
-}
-
-/**
- * @brief RX DMA common service routine.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_UART_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_UART_DMA_ERROR_HOOK(uartp);
- }
-#else
- (void)flags;
-#endif
-
- if (uartp->rxstate == UART_RX_IDLE) {
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- _uart_rx_idle_code(uartp);
- }
- /* DMA half-transter interrupt handling - for the 1st/2nd half transfers. */
- else if (uartp->config->rxhalf_cb != NULL) {
- if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- _uart_rx_half_isr_code(uartp, 0);
- }
- else if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- _uart_rx_half_isr_code(uartp, 1);
- }
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaStreamDisable(uartp->dmarx);
- _uart_rx_complete_isr_code(uartp);
- }
-}
-
-/**
- * @brief TX DMA common service routine.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_UART_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_UART_DMA_ERROR_HOOK(uartp);
- }
-#else
- (void)flags;
-#endif
-
- dmaStreamDisable(uartp->dmatx);
-
- /* A callback is generated, if enabled, after a completed transfer.*/
- _uart_tx1_isr_code(uartp);
-}
-
-/**
- * @brief USART common service routine.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void serve_usart_irq(UARTDriver *uartp) {
- uint16_t sr;
- USART_TypeDef *u = uartp->usart;
- uint32_t cr1 = u->CR1;
-
- sr = u->SR; /* SR reset step 1.*/
- (void)u->DR; /* SR reset step 2.*/
-
- if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE |
- USART_SR_FE | USART_SR_PE)) {
- u->SR = ~USART_SR_LBD;
- _uart_rx_error_isr_code(uartp, translate_errors(sr));
- }
-
- if ((sr & USART_SR_TC) && (cr1 & USART_CR1_TCIE)) {
- /* TC interrupt cleared and disabled.*/
- u->SR = ~USART_SR_TC;
- u->CR1 = cr1 & ~USART_CR1_TCIE;
-
- /* End of transmission, a callback is generated.*/
- _uart_tx2_isr_code(uartp);
- }
-
- /* Timeout interrupt sources are only checked if enabled in CR1.*/
- if ((cr1 & USART_CR1_IDLEIE) && (sr & USART_SR_IDLE)) {
- _uart_timeout_isr_code(uartp);
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
-#if !defined(STM32_USART1_HANDLER)
-#error "STM32_USART1_HANDLER not defined"
-#endif
-/**
- * @brief USART1 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_USART1 */
-
-#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
-#if !defined(STM32_USART2_HANDLER)
-#error "STM32_USART2_HANDLER not defined"
-#endif
-/**
- * @brief USART2 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_USART2 */
-
-#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
-#if !defined(STM32_USART3_HANDLER)
-#error "STM32_USART3_HANDLER not defined"
-#endif
-/**
- * @brief USART3 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_USART3 */
-
-#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
-#if !defined(STM32_UART4_HANDLER)
-#error "STM32_UART4_HANDLER not defined"
-#endif
-/**
- * @brief UART4 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_UART4 */
-
-#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
-#if !defined(STM32_UART5_HANDLER)
-#error "STM32_UART5_HANDLER not defined"
-#endif
-/**
- * @brief UART5 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_UART5 */
-
-#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
-#if !defined(STM32_USART6_HANDLER)
-#error "STM32_USART6_HANDLER not defined"
-#endif
-/**
- * @brief USART6 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_USART6 */
-
-#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
-#if !defined(STM32_UART7_HANDLER)
-#error "STM32_UART7_HANDLER not defined"
-#endif
-/**
- * @brief UART7 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_UART7 */
-
-#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
-#if !defined(STM32_UART8_HANDLER)
-#error "STM32_UART8_HANDLER not defined"
-#endif
-/**
- * @brief UART8 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- serve_usart_irq(&UARTD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_UART_USE_UART8 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level UART driver initialization.
- *
- * @notapi
- */
-void uart_lld_init(void) {
-
-#if STM32_UART_USE_USART1
- uartObjectInit(&UARTD1);
- UARTD1.usart = USART1;
- UARTD1.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD1.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD1.dmarx = NULL;
- UARTD1.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_USART2
- uartObjectInit(&UARTD2);
- UARTD2.usart = USART2;
- UARTD2.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD2.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD2.dmarx = NULL;
- UARTD2.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_USART3
- uartObjectInit(&UARTD3);
- UARTD3.usart = USART3;
- UARTD3.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD3.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD3.dmarx = NULL;
- UARTD3.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_UART4
- uartObjectInit(&UARTD4);
- UARTD4.usart = UART4;
- UARTD4.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD4.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD4.dmarx = NULL;
- UARTD4.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_UART5
- uartObjectInit(&UARTD5);
- UARTD5.usart = UART5;
- UARTD5.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD5.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD5.dmarx = NULL;
- UARTD5.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_USART6
- uartObjectInit(&UARTD6);
- UARTD6.usart = USART6;
- UARTD6.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD6.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD6.dmarx = NULL;
- UARTD6.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_UART7
- uartObjectInit(&UARTD7);
- UARTD7.usart = UART7;
- UARTD7.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD7.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD7.dmarx = NULL;
- UARTD7.dmatx = NULL;
-#endif
-
-#if STM32_UART_USE_UART8
- uartObjectInit(&UARTD8);
- UARTD8.usart = UART8;
- UARTD8.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD8.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD8.dmarx = NULL;
- UARTD8.dmatx = NULL;
-#endif
-}
-
-/**
- * @brief Configures and activates the UART peripheral.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @notapi
- */
-void uart_lld_start(UARTDriver *uartp) {
-
- if (uartp->state == UART_STOP) {
-#if STM32_UART_USE_USART1
- if (&UARTD1 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART1_RX_DMA_STREAM,
- STM32_UART_USART1_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART1_TX_DMA_STREAM,
- STM32_UART_USART1_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART1(true);
- nvicEnableVector(STM32_USART1_NUMBER, STM32_UART_USART1_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_USART2
- if (&UARTD2 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART2_RX_DMA_STREAM,
- STM32_UART_USART2_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART2_TX_DMA_STREAM,
- STM32_UART_USART2_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART2(true);
- nvicEnableVector(STM32_USART2_NUMBER, STM32_UART_USART2_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_USART3
- if (&UARTD3 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART3_RX_DMA_STREAM,
- STM32_UART_USART3_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART3_TX_DMA_STREAM,
- STM32_UART_USART3_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART3(true);
- nvicEnableVector(STM32_USART3_NUMBER, STM32_UART_USART3_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_UART4
- if (&UARTD4 == uartp) {
-
- osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
- "specified invalid bits in UART4 CR2 register settings");
- osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
- "specified invalid bits in UART4 CR3 register settings");
-
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART4_RX_DMA_STREAM,
- STM32_UART_UART4_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART4_TX_DMA_STREAM,
- STM32_UART_UART4_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART4(true);
- nvicEnableVector(STM32_UART4_NUMBER, STM32_UART_UART4_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART4_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_UART5
- if (&UARTD5 == uartp) {
-
- osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
- "specified invalid bits in UART5 CR2 register settings");
- osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
- "specified invalid bits in UART5 CR3 register settings");
-
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART5_RX_DMA_STREAM,
- STM32_UART_UART5_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART5_TX_DMA_STREAM,
- STM32_UART_UART5_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART5(true);
- nvicEnableVector(STM32_UART5_NUMBER, STM32_UART_UART5_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART5_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_USART6
- if (&UARTD6 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART6_RX_DMA_STREAM,
- STM32_UART_USART6_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART6_TX_DMA_STREAM,
- STM32_UART_USART6_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART6(true);
- nvicEnableVector(STM32_USART6_NUMBER, STM32_UART_USART6_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART6_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_UART7
- if (&UARTD7 == uartp) {
-
- osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
- "specified invalid bits in UART7 CR2 register settings");
- osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
- "specified invalid bits in UART7 CR3 register settings");
-
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART7_RX_DMA_STREAM,
- STM32_UART_UART7_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART7_TX_DMA_STREAM,
- STM32_UART_UART7_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART7(true);
- nvicEnableVector(STM32_UART7_NUMBER, STM32_UART_UART7_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART7_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART7_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
- }
-#endif
-
-#if STM32_UART_USE_UART8
- if (&UARTD8 == uartp) {
-
- osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
- "specified invalid bits in UART8 CR2 register settings");
- osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
- "specified invalid bits in UART8 CR3 register settings");
-
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART8_RX_DMA_STREAM,
- STM32_UART_UART8_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART8_TX_DMA_STREAM,
- STM32_UART_UART8_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART8(true);
- nvicEnableVector(STM32_UART8_NUMBER, STM32_UART_UART8_IRQ_PRIORITY);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART8_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART8_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
- }
-#endif
-
- /* Static DMA setup, the transfer size depends on the USART settings,
- it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
- if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) {
- uartp->dmarxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- uartp->dmatxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- }
- dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR);
- dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR);
- uartp->rxbuf = 0;
- }
-
- uartp->rxstate = UART_RX_IDLE;
- uartp->txstate = UART_TX_IDLE;
- usart_start(uartp);
-}
-
-/**
- * @brief Deactivates the UART peripheral.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @notapi
- */
-void uart_lld_stop(UARTDriver *uartp) {
-
- if (uartp->state == UART_READY) {
- usart_stop(uartp);
- dmaStreamFreeI(uartp->dmarx);
- dmaStreamFreeI(uartp->dmatx);
- uartp->dmarx = NULL;
- uartp->dmatx = NULL;
-
-#if STM32_UART_USE_USART1
- if (&UARTD1 == uartp) {
- nvicDisableVector(STM32_USART1_NUMBER);
- rccDisableUSART1();
- return;
- }
-#endif
-
-#if STM32_UART_USE_USART2
- if (&UARTD2 == uartp) {
- nvicDisableVector(STM32_USART2_NUMBER);
- rccDisableUSART2();
- return;
- }
-#endif
-
-#if STM32_UART_USE_USART3
- if (&UARTD3 == uartp) {
- nvicDisableVector(STM32_USART3_NUMBER);
- rccDisableUSART3();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART4
- if (&UARTD4 == uartp) {
- nvicDisableVector(STM32_UART4_NUMBER);
- rccDisableUART4();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART5
- if (&UARTD5 == uartp) {
- nvicDisableVector(STM32_UART5_NUMBER);
- rccDisableUART5();
- return;
- }
-#endif
-
-#if STM32_UART_USE_USART6
- if (&UARTD6 == uartp) {
- nvicDisableVector(STM32_USART6_NUMBER);
- rccDisableUSART6();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART7
- if (&UARTD7 == uartp) {
- nvicDisableVector(STM32_UART7_NUMBER);
- rccDisableUART7();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART8
- if (&UARTD8 == uartp) {
- nvicDisableVector(STM32_UART8_NUMBER);
- rccDisableUART8();
- return;
- }
-#endif
- }
-}
-
-/**
- * @brief Starts a transmission on the UART peripheral.
- * @note The buffers are organized as uint8_t arrays for data sizes below
- * or equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] n number of data frames to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
-
- /* TX DMA channel preparation.*/
- dmaStreamSetMemory0(uartp->dmatx, txbuf);
- dmaStreamSetTransactionSize(uartp->dmatx, n);
- dmaStreamSetMode(uartp->dmatx, uartp->dmatxmode | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
-
- /* Only enable TC interrupt if there's a callback attached to it or
- if called from uartSendFullTimeout(). Also we need to clear TC flag
- which could be set before.*/
-#if UART_USE_WAIT == TRUE
- if ((uartp->config->txend2_cb != NULL) || (uartp->early == false)) {
-#else
- if (uartp->config->txend2_cb != NULL) {
-#endif
- uartp->usart->SR = ~USART_SR_TC;
- uartp->usart->CR1 |= USART_CR1_TCIE;
- }
-
- /* Starting transfer.*/
- dmaStreamEnable(uartp->dmatx);
-}
-
-/**
- * @brief Stops any ongoing transmission.
- * @note Stopping a transmission also suppresses the transmission callbacks.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @return The number of data frames not transmitted by the
- * stopped transmit operation.
- *
- * @notapi
- */
-size_t uart_lld_stop_send(UARTDriver *uartp) {
-
- dmaStreamDisable(uartp->dmatx);
-
- return dmaStreamGetTransactionSize(uartp->dmatx);
-}
-
-/**
- * @brief Starts a receive operation on the UART peripheral.
- * @note The buffers are organized as uint8_t arrays for data sizes below
- * or equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] n number of data frames to send
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
-
- /* Stopping previous activity (idle state).*/
- dmaStreamDisable(uartp->dmarx);
-
- /* RX DMA channel preparation.*/
- dmaStreamSetMemory0(uartp->dmarx, rxbuf);
- dmaStreamSetTransactionSize(uartp->dmarx, n);
-
- uint32_t mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE;
-
- /* DMA half-transfer interrupt & circular mode, if needed */
- if (uartp->config->rxhalf_cb != NULL)
- mode |= STM32_DMA_CR_HTIE | STM32_DMA_CR_CIRC;
-
- dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
-
- /* Starting transfer.*/
- dmaStreamEnable(uartp->dmarx);
-}
-
-/**
- * @brief Stops any ongoing receive operation.
- * @note Stopping a receive operation also suppresses the receive callbacks.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @return The number of data frames not received by the
- * stopped receive operation.
- *
- * @notapi
- */
-size_t uart_lld_stop_receive(UARTDriver *uartp) {
- size_t n;
-
- dmaStreamDisable(uartp->dmarx);
- n = dmaStreamGetTransactionSize(uartp->dmarx);
- uart_enter_rx_idle_loop(uartp);
-
- return n;
-}
-
-#endif /* HAL_USE_UART */
-
-/** @} */
+/*
+ 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 USARTv1/hal_uart_lld.c
+ * @brief STM32 low level UART driver code.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define USART1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART1_RX_DMA_STREAM, \
+ STM32_USART1_RX_DMA_CHN)
+
+#define USART1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART1_TX_DMA_STREAM, \
+ STM32_USART1_TX_DMA_CHN)
+
+#define USART2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART2_RX_DMA_STREAM, \
+ STM32_USART2_RX_DMA_CHN)
+
+#define USART2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART2_TX_DMA_STREAM, \
+ STM32_USART2_TX_DMA_CHN)
+
+#define USART3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART3_RX_DMA_STREAM, \
+ STM32_USART3_RX_DMA_CHN)
+
+#define USART3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM, \
+ STM32_USART3_TX_DMA_CHN)
+
+#define UART4_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART4_RX_DMA_STREAM, \
+ STM32_UART4_RX_DMA_CHN)
+
+#define UART4_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART4_TX_DMA_STREAM, \
+ STM32_UART4_TX_DMA_CHN)
+
+#define UART5_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART5_RX_DMA_STREAM, \
+ STM32_UART5_RX_DMA_CHN)
+
+#define UART5_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART5_TX_DMA_STREAM, \
+ STM32_UART5_TX_DMA_CHN)
+
+#define USART6_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART6_RX_DMA_STREAM, \
+ STM32_USART6_RX_DMA_CHN)
+
+#define USART6_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART6_TX_DMA_STREAM, \
+ STM32_USART6_TX_DMA_CHN)
+
+#define UART7_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART7_RX_DMA_STREAM, \
+ STM32_UART7_RX_DMA_CHN)
+
+#define UART7_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART7_TX_DMA_STREAM, \
+ STM32_UART7_TX_DMA_CHN)
+
+#define UART8_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART8_RX_DMA_STREAM, \
+ STM32_UART8_RX_DMA_CHN)
+
+#define UART8_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART8_TX_DMA_STREAM, \
+ STM32_UART8_TX_DMA_CHN)
+
+#define STM32_UART45_CR2_CHECK_MASK \
+ (USART_CR2_STOP_0 | USART_CR2_CLKEN | USART_CR2_CPOL | USART_CR2_CPHA | \
+ USART_CR2_LBCL)
+
+#define STM32_UART45_CR3_CHECK_MASK \
+ (USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | USART_CR3_SCEN | \
+ USART_CR3_NACK)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief USART1 UART driver identifier.*/
+#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
+UARTDriver UARTD1;
+#endif
+
+/** @brief USART2 UART driver identifier.*/
+#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
+UARTDriver UARTD2;
+#endif
+
+/** @brief USART3 UART driver identifier.*/
+#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
+UARTDriver UARTD3;
+#endif
+
+/** @brief UART4 UART driver identifier.*/
+#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
+UARTDriver UARTD4;
+#endif
+
+/** @brief UART5 UART driver identifier.*/
+#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
+UARTDriver UARTD5;
+#endif
+
+/** @brief USART6 UART driver identifier.*/
+#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
+UARTDriver UARTD6;
+#endif
+
+/** @brief UART7 UART driver identifier.*/
+#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
+UARTDriver UARTD7;
+#endif
+
+/** @brief UART8 UART driver identifier.*/
+#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
+UARTDriver UARTD8;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Status bits translation.
+ *
+ * @param[in] sr USART SR register value
+ *
+ * @return The error flags.
+ */
+static uartflags_t translate_errors(uint16_t sr) {
+ uartflags_t sts = 0;
+
+ if (sr & USART_SR_ORE)
+ sts |= UART_OVERRUN_ERROR;
+ if (sr & USART_SR_PE)
+ sts |= UART_PARITY_ERROR;
+ if (sr & USART_SR_FE)
+ sts |= UART_FRAMING_ERROR;
+ if (sr & USART_SR_NE)
+ sts |= UART_NOISE_ERROR;
+ if (sr & USART_SR_LBD)
+ sts |= UART_BREAK_DETECTED;
+ return sts;
+}
+
+/**
+ * @brief Puts the receiver in the UART_RX_IDLE state.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void uart_enter_rx_idle_loop(UARTDriver *uartp) {
+ uint32_t mode;
+
+ /* RX DMA channel preparation, if the char callback is defined then the
+ TCIE interrupt is enabled too.*/
+ if (uartp->config->rxchar_cb == NULL)
+ mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC;
+ else
+ mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TCIE;
+ dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf);
+ dmaStreamSetTransactionSize(uartp->dmarx, 1);
+ dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
+ dmaStreamEnable(uartp->dmarx);
+}
+
+/**
+ * @brief USART de-initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_stop(UARTDriver *uartp) {
+
+ /* Stops RX and TX DMA channels.*/
+ dmaStreamDisable(uartp->dmarx);
+ dmaStreamDisable(uartp->dmatx);
+
+ /* Stops USART operations.*/
+ uartp->usart->CR1 = 0;
+ uartp->usart->CR2 = 0;
+ uartp->usart->CR3 = 0;
+}
+
+/**
+ * @brief USART initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_start(UARTDriver *uartp) {
+ uint32_t fck;
+ uint16_t cr1;
+ USART_TypeDef *u = uartp->usart;
+
+ /* Defensive programming, starting from a clean state.*/
+ usart_stop(uartp);
+
+ /* Baud rate setting.*/
+#if STM32_HAS_USART6
+ if ((uartp->usart == USART1) || (uartp->usart == USART6))
+#else
+ if (uartp->usart == USART1)
+#endif
+ fck = STM32_PCLK2 / uartp->config->speed;
+ else
+ fck = STM32_PCLK1 / uartp->config->speed;
+
+ /* Correcting USARTDIV when oversampling by 8 instead of 16.
+ Fraction is still 4 bits wide, but only lower 3 bits used.
+ Mantissa is doubled, but Fraction is left the same.*/
+#if defined(USART_CR1_OVER8)
+ if (uartp->config->cr1 & USART_CR1_OVER8)
+ fck = ((fck & ~7) * 2) | (fck & 7);
+#endif
+ u->BRR = fck;
+
+ /* Resetting eventual pending status flags.*/
+ (void)u->SR; /* SR reset step 1.*/
+ (void)u->DR; /* SR reset step 2.*/
+ u->SR = 0;
+
+ /* Note that some bits are enforced because required for correct driver
+ operations.*/
+ u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
+ u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
+ USART_CR3_EIE;
+
+ /* Mustn't ever set TCIE here - if done, it causes an immediate
+ interrupt.*/
+ cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
+
+ /* Add Idle interrupt if needed */
+ if (uartp->config->timeout_cb != NULL)
+ cr1 |= USART_CR1_IDLEIE;
+
+ u->CR1 = uartp->config->cr1 | cr1;
+
+ /* Starting the receiver idle loop.*/
+ uart_enter_rx_idle_loop(uartp);
+}
+
+/**
+ * @brief RX DMA common service routine.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (uartp->rxstate == UART_RX_IDLE) {
+ /* Receiver in idle state, a callback is generated, if enabled, for each
+ received character and then the driver stays in the same state.*/
+ _uart_rx_idle_code(uartp);
+ }
+ /* DMA half-transter interrupt handling - for the 1st/2nd half transfers. */
+ else if (uartp->config->rxhalf_cb != NULL) {
+ if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ _uart_rx_half_isr_code(uartp, 0);
+ }
+ else if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ _uart_rx_half_isr_code(uartp, 1);
+ }
+ }
+ else {
+ /* Receiver in active state, a callback is generated, if enabled, after
+ a completed transfer.*/
+ dmaStreamDisable(uartp->dmarx);
+ _uart_rx_complete_isr_code(uartp);
+ }
+}
+
+/**
+ * @brief TX DMA common service routine.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ dmaStreamDisable(uartp->dmatx);
+
+ /* A callback is generated, if enabled, after a completed transfer.*/
+ _uart_tx1_isr_code(uartp);
+}
+
+/**
+ * @brief USART common service routine.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void serve_usart_irq(UARTDriver *uartp) {
+ uint16_t sr;
+ USART_TypeDef *u = uartp->usart;
+ uint32_t cr1 = u->CR1;
+
+ sr = u->SR; /* SR reset step 1.*/
+ (void)u->DR; /* SR reset step 2.*/
+
+ if (sr & (USART_SR_LBD | USART_SR_ORE | USART_SR_NE |
+ USART_SR_FE | USART_SR_PE)) {
+ u->SR = ~USART_SR_LBD;
+ _uart_rx_error_isr_code(uartp, translate_errors(sr));
+ }
+
+ if ((sr & USART_SR_TC) && (cr1 & USART_CR1_TCIE)) {
+ /* TC interrupt cleared and disabled.*/
+ u->SR = ~USART_SR_TC;
+ u->CR1 = cr1 & ~USART_CR1_TCIE;
+
+ /* End of transmission, a callback is generated.*/
+ _uart_tx2_isr_code(uartp);
+ }
+
+ /* Timeout interrupt sources are only checked if enabled in CR1.*/
+ if ((cr1 & USART_CR1_IDLEIE) && (sr & USART_SR_IDLE)) {
+ _uart_timeout_isr_code(uartp);
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
+#if !defined(STM32_USART1_HANDLER)
+#error "STM32_USART1_HANDLER not defined"
+#endif
+/**
+ * @brief USART1 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_USART1 */
+
+#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
+#if !defined(STM32_USART2_HANDLER)
+#error "STM32_USART2_HANDLER not defined"
+#endif
+/**
+ * @brief USART2 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_USART2 */
+
+#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
+#if !defined(STM32_USART3_HANDLER)
+#error "STM32_USART3_HANDLER not defined"
+#endif
+/**
+ * @brief USART3 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_USART3 */
+
+#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
+#if !defined(STM32_UART4_HANDLER)
+#error "STM32_UART4_HANDLER not defined"
+#endif
+/**
+ * @brief UART4 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_UART4 */
+
+#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
+#if !defined(STM32_UART5_HANDLER)
+#error "STM32_UART5_HANDLER not defined"
+#endif
+/**
+ * @brief UART5 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_UART5 */
+
+#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
+#if !defined(STM32_USART6_HANDLER)
+#error "STM32_USART6_HANDLER not defined"
+#endif
+/**
+ * @brief USART6 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_USART6 */
+
+#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
+#if !defined(STM32_UART7_HANDLER)
+#error "STM32_UART7_HANDLER not defined"
+#endif
+/**
+ * @brief UART7 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_UART7 */
+
+#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
+#if !defined(STM32_UART8_HANDLER)
+#error "STM32_UART8_HANDLER not defined"
+#endif
+/**
+ * @brief UART8 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_UART8 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level UART driver initialization.
+ *
+ * @notapi
+ */
+void uart_lld_init(void) {
+
+#if STM32_UART_USE_USART1
+ uartObjectInit(&UARTD1);
+ UARTD1.usart = USART1;
+ UARTD1.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD1.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD1.dmarx = NULL;
+ UARTD1.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_USART2
+ uartObjectInit(&UARTD2);
+ UARTD2.usart = USART2;
+ UARTD2.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD2.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD2.dmarx = NULL;
+ UARTD2.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_USART3
+ uartObjectInit(&UARTD3);
+ UARTD3.usart = USART3;
+ UARTD3.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD3.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD3.dmarx = NULL;
+ UARTD3.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_UART4
+ uartObjectInit(&UARTD4);
+ UARTD4.usart = UART4;
+ UARTD4.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD4.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD4.dmarx = NULL;
+ UARTD4.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_UART5
+ uartObjectInit(&UARTD5);
+ UARTD5.usart = UART5;
+ UARTD5.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD5.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD5.dmarx = NULL;
+ UARTD5.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_USART6
+ uartObjectInit(&UARTD6);
+ UARTD6.usart = USART6;
+ UARTD6.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD6.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD6.dmarx = NULL;
+ UARTD6.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_UART7
+ uartObjectInit(&UARTD7);
+ UARTD7.usart = UART7;
+ UARTD7.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD7.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD7.dmarx = NULL;
+ UARTD7.dmatx = NULL;
+#endif
+
+#if STM32_UART_USE_UART8
+ uartObjectInit(&UARTD8);
+ UARTD8.usart = UART8;
+ UARTD8.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD8.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD8.dmarx = NULL;
+ UARTD8.dmatx = NULL;
+#endif
+}
+
+/**
+ * @brief Configures and activates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+void uart_lld_start(UARTDriver *uartp) {
+
+ if (uartp->state == UART_STOP) {
+#if STM32_UART_USE_USART1
+ if (&UARTD1 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART1_RX_DMA_STREAM,
+ STM32_UART_USART1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART1_TX_DMA_STREAM,
+ STM32_UART_USART1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART1(true);
+ nvicEnableVector(STM32_USART1_NUMBER, STM32_UART_USART1_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_USART2
+ if (&UARTD2 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART2_RX_DMA_STREAM,
+ STM32_UART_USART2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART2_TX_DMA_STREAM,
+ STM32_UART_USART2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART2(true);
+ nvicEnableVector(STM32_USART2_NUMBER, STM32_UART_USART2_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_USART3
+ if (&UARTD3 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART3_RX_DMA_STREAM,
+ STM32_UART_USART3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART3_TX_DMA_STREAM,
+ STM32_UART_USART3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART3(true);
+ nvicEnableVector(STM32_USART3_NUMBER, STM32_UART_USART3_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_UART4
+ if (&UARTD4 == uartp) {
+
+ osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
+ "specified invalid bits in UART4 CR2 register settings");
+ osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
+ "specified invalid bits in UART4 CR3 register settings");
+
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART4_RX_DMA_STREAM,
+ STM32_UART_UART4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART4_TX_DMA_STREAM,
+ STM32_UART_UART4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART4(true);
+ nvicEnableVector(STM32_UART4_NUMBER, STM32_UART_UART4_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART4_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_UART5
+ if (&UARTD5 == uartp) {
+
+ osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
+ "specified invalid bits in UART5 CR2 register settings");
+ osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
+ "specified invalid bits in UART5 CR3 register settings");
+
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART5_RX_DMA_STREAM,
+ STM32_UART_UART5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART5_TX_DMA_STREAM,
+ STM32_UART_UART5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART5(true);
+ nvicEnableVector(STM32_UART5_NUMBER, STM32_UART_UART5_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART5_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_USART6
+ if (&UARTD6 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART6_RX_DMA_STREAM,
+ STM32_UART_USART6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART6_TX_DMA_STREAM,
+ STM32_UART_USART6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART6(true);
+ nvicEnableVector(STM32_USART6_NUMBER, STM32_UART_USART6_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART6_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_UART7
+ if (&UARTD7 == uartp) {
+
+ osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
+ "specified invalid bits in UART7 CR2 register settings");
+ osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
+ "specified invalid bits in UART7 CR3 register settings");
+
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART7_RX_DMA_STREAM,
+ STM32_UART_UART7_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART7_TX_DMA_STREAM,
+ STM32_UART_UART7_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART7(true);
+ nvicEnableVector(STM32_UART7_NUMBER, STM32_UART_UART7_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART7_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART7_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
+ }
+#endif
+
+#if STM32_UART_USE_UART8
+ if (&UARTD8 == uartp) {
+
+ osalDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0,
+ "specified invalid bits in UART8 CR2 register settings");
+ osalDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0,
+ "specified invalid bits in UART8 CR3 register settings");
+
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART8_RX_DMA_STREAM,
+ STM32_UART_UART8_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART8_TX_DMA_STREAM,
+ STM32_UART_UART8_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART8(true);
+ nvicEnableVector(STM32_UART8_NUMBER, STM32_UART_UART8_IRQ_PRIORITY);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART8_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART8_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
+ }
+#endif
+
+ /* Static DMA setup, the transfer size depends on the USART settings,
+ it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
+ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) {
+ uartp->dmarxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ uartp->dmatxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ }
+ dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR);
+ dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR);
+ uartp->rxbuf = 0;
+ }
+
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
+ usart_start(uartp);
+}
+
+/**
+ * @brief Deactivates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+void uart_lld_stop(UARTDriver *uartp) {
+
+ if (uartp->state == UART_READY) {
+ usart_stop(uartp);
+ dmaStreamFreeI(uartp->dmarx);
+ dmaStreamFreeI(uartp->dmatx);
+ uartp->dmarx = NULL;
+ uartp->dmatx = NULL;
+
+#if STM32_UART_USE_USART1
+ if (&UARTD1 == uartp) {
+ nvicDisableVector(STM32_USART1_NUMBER);
+ rccDisableUSART1();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_USART2
+ if (&UARTD2 == uartp) {
+ nvicDisableVector(STM32_USART2_NUMBER);
+ rccDisableUSART2();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_USART3
+ if (&UARTD3 == uartp) {
+ nvicDisableVector(STM32_USART3_NUMBER);
+ rccDisableUSART3();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART4
+ if (&UARTD4 == uartp) {
+ nvicDisableVector(STM32_UART4_NUMBER);
+ rccDisableUART4();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART5
+ if (&UARTD5 == uartp) {
+ nvicDisableVector(STM32_UART5_NUMBER);
+ rccDisableUART5();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_USART6
+ if (&UARTD6 == uartp) {
+ nvicDisableVector(STM32_USART6_NUMBER);
+ rccDisableUSART6();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART7
+ if (&UARTD7 == uartp) {
+ nvicDisableVector(STM32_UART7_NUMBER);
+ rccDisableUART7();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART8
+ if (&UARTD8 == uartp) {
+ nvicDisableVector(STM32_UART8_NUMBER);
+ rccDisableUART8();
+ return;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts a transmission on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
+
+ /* TX DMA channel preparation.*/
+ dmaStreamSetMemory0(uartp->dmatx, txbuf);
+ dmaStreamSetTransactionSize(uartp->dmatx, n);
+ dmaStreamSetMode(uartp->dmatx, uartp->dmatxmode | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
+
+ /* Only enable TC interrupt if there's a callback attached to it or
+ if called from uartSendFullTimeout(). Also we need to clear TC flag
+ which could be set before.*/
+#if UART_USE_WAIT == TRUE
+ if ((uartp->config->txend2_cb != NULL) || (uartp->early == false)) {
+#else
+ if (uartp->config->txend2_cb != NULL) {
+#endif
+ uartp->usart->SR = ~USART_SR_TC;
+ uartp->usart->CR1 |= USART_CR1_TCIE;
+ }
+
+ /* Starting transfer.*/
+ dmaStreamEnable(uartp->dmatx);
+}
+
+/**
+ * @brief Stops any ongoing transmission.
+ * @note Stopping a transmission also suppresses the transmission callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not transmitted by the
+ * stopped transmit operation.
+ *
+ * @notapi
+ */
+size_t uart_lld_stop_send(UARTDriver *uartp) {
+
+ dmaStreamDisable(uartp->dmatx);
+
+ return dmaStreamGetTransactionSize(uartp->dmatx);
+}
+
+/**
+ * @brief Starts a receive operation on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
+
+ /* Stopping previous activity (idle state).*/
+ dmaStreamDisable(uartp->dmarx);
+
+ /* RX DMA channel preparation.*/
+ dmaStreamSetMemory0(uartp->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(uartp->dmarx, n);
+
+ uint32_t mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE;
+
+ /* DMA half-transfer interrupt & circular mode, if needed */
+ if (uartp->config->rxhalf_cb != NULL)
+ mode |= STM32_DMA_CR_HTIE | STM32_DMA_CR_CIRC;
+
+ dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
+
+ /* Starting transfer.*/
+ dmaStreamEnable(uartp->dmarx);
+}
+
+/**
+ * @brief Stops any ongoing receive operation.
+ * @note Stopping a receive operation also suppresses the receive callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not received by the
+ * stopped receive operation.
+ *
+ * @notapi
+ */
+size_t uart_lld_stop_receive(UARTDriver *uartp) {
+ size_t n;
+
+ dmaStreamDisable(uartp->dmarx);
+ n = dmaStreamGetTransactionSize(uartp->dmarx);
+ uart_enter_rx_idle_loop(uartp);
+
+ return n;
+}
+
+#endif /* HAL_USE_UART */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h
index 72e492c1fd..c1e17440e8 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h
+++ b/os/hal/ports/STM32/LLD/USARTv1/hal_uart_lld.h
@@ -1,771 +1,771 @@
-/*
- 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 USARTv1/hal_uart_lld.h
- * @brief STM32 low level UART driver header.
- *
- * @addtogroup UART
- * @{
- */
-
-#ifndef HAL_UART_LLD_H
-#define HAL_UART_LLD_H
-
-#if HAL_USE_UART || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief UART driver on USART1 enable switch.
- * @details If set to @p TRUE the support for USART1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART1 FALSE
-#endif
-
-/**
- * @brief UART driver on USART2 enable switch.
- * @details If set to @p TRUE the support for USART2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART2 FALSE
-#endif
-
-/**
- * @brief UART driver on USART3 enable switch.
- * @details If set to @p TRUE the support for USART3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART3 FALSE
-#endif
-
-/**
- * @brief UART driver on UART4 enable switch.
- * @details If set to @p TRUE the support for UART4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART4 FALSE
-#endif
-
-/**
- * @brief UART driver on UART5 enable switch.
- * @details If set to @p TRUE the support for UART5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART5) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART5 FALSE
-#endif
-
-/**
- * @brief UART driver on USART6 enable switch.
- * @details If set to @p TRUE the support for USART6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART6) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART6 FALSE
-#endif
-
-/**
- * @brief UART driver on UART7 enable switch.
- * @details If set to @p TRUE the support for UART7 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART7) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART7 FALSE
-#endif
-
-/**
- * @brief UART driver on UART8 enable switch.
- * @details If set to @p TRUE the support for UART8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART8) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART8 FALSE
-#endif
-
-/**
- * @brief USART1 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART2 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART3 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART4 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART4_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART5 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART5_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART6 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART6_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART7 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART7_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART7_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART8 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART8_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART8_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART4_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART5 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART5_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART5_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART6 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART6_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART6_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART7 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART7_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART7_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART8 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART8_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART8_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_UART_USE_USART1 && !STM32_HAS_USART1
-#error "USART1 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_USART2 && !STM32_HAS_USART2
-#error "USART2 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_USART3 && !STM32_HAS_USART3
-#error "USART3 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART4
-#if !STM32_HAS_UART4
-#error "UART4 not present in the selected device"
-#endif
-
-#if !defined(STM32F2XX) && !defined(STM32F4XX) && !defined(STM32L151xE) && \
- !defined(STM32L152xE) && !defined(STM32L162xE)
-#error "UART4 DMA access not supported in this platform"
-#endif
-#endif /* STM32_UART_USE_UART4 */
-
-#if STM32_UART_USE_UART5
-#if !STM32_HAS_UART5
-#error "UART5 not present in the selected device"
-#endif
-
-#if !defined(STM32F2XX) && !defined(STM32F4XX) && !defined(STM32L151xE) && \
- !defined(STM32L152xE) && !defined(STM32L162xE)
-#error "UART5 DMA access not supported in this platform"
-#endif
-#endif /* STM32_UART_USE_UART5 */
-
-#if STM32_UART_USE_USART6 && !STM32_HAS_USART6
-#error "USART6 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART7 && !STM32_HAS_UART7
-#error "UART7 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART8 && !STM32_HAS_UART8
-#error "UART8 not present in the selected device"
-#endif
-
-#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \
- !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4 && \
- !STM32_UART_USE_UART5 && !STM32_UART_USE_USART6 && \
- !STM32_UART_USE_UART7 && !STM32_UART_USE_UART8
-#error "UART driver activated but no USART/UART peripheral assigned"
-#endif
-
-#if STM32_UART_USE_USART1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART1"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART2"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART3"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART4"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART5"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART6_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART6"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART7_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART7"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART8_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART8"
-#endif
-
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART1"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART2"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART3"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART4"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART5_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART5"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART6_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART6"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART7_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART7"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART8_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART8"
-#endif
-
-/* The following checks are only required when there is a DMA able to
- reassign streams to different channels.*/
-#if STM32_ADVANCED_DMA
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_UART_USE_USART1 && (!defined(STM32_UART_USART1_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART1_TX_DMA_STREAM))
-#error "USART1 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_USART2 && (!defined(STM32_UART_USART2_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART2_TX_DMA_STREAM))
-#error "USART2 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_USART3 && (!defined(STM32_UART_USART3_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART3_TX_DMA_STREAM))
-#error "USART3 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART4 && (!defined(STM32_UART_UART4_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART4_TX_DMA_STREAM))
-#error "UART4 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART5 && (!defined(STM32_UART_UART5_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART5_TX_DMA_STREAM))
-#error "UART5 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_USART6 && (!defined(STM32_UART_USART6_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART6_TX_DMA_STREAM))
-#error "USART6 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART7 && (!defined(STM32_UART_UART7_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART7_TX_DMA_STREAM))
-#error "UART7 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART8 && (!defined(STM32_UART_UART8_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART8_TX_DMA_STREAM))
-#error "UART8 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \
- STM32_USART1_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART1 RX"
-#endif
-
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_TX_DMA_STREAM, \
- STM32_USART1_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART1 TX"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_RX_DMA_STREAM, \
- STM32_USART2_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART2 RX"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_TX_DMA_STREAM, \
- STM32_USART2_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART2 TX"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_RX_DMA_STREAM, \
- STM32_USART3_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART3 RX"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_TX_DMA_STREAM, \
- STM32_USART3_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART3 TX"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_RX_DMA_STREAM, \
- STM32_UART4_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART4 RX"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_TX_DMA_STREAM, \
- STM32_UART4_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART4 TX"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_RX_DMA_STREAM, \
- STM32_UART5_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART5 RX"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_TX_DMA_STREAM, \
- STM32_UART5_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART5 TX"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_RX_DMA_STREAM, \
- STM32_USART6_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART6 RX"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_TX_DMA_STREAM, \
- STM32_USART6_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART6 TX"
-#endif
-#endif /* STM32_ADVANCED_DMA */
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_RX_DMA_STREAM, \
- STM32_UART7_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART7 RX"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_TX_DMA_STREAM, \
- STM32_UART7_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART7 TX"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_RX_DMA_STREAM, \
- STM32_UART8_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART8 RX"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_TX_DMA_STREAM, \
- STM32_UART8_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART8 TX"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief UART driver condition flags type.
- */
-typedef uint32_t uartflags_t;
-
-/**
- * @brief Structure representing an UART driver.
- */
-typedef struct UARTDriver UARTDriver;
-
-/**
- * @brief Generic UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-typedef void (*uartcb_t)(UARTDriver *uartp);
-
-/**
- * @brief Character received UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] c received character
- */
-typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
-
-/**
- * @brief Receive error UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] e receive error mask
- */
-typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
-
-/**
- * @brief Receive Half-transfer UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] full flag set to 1 for the second half, and 0 for the first half
- */
-typedef void (*uarthcb_t)(UARTDriver *uartp, uartflags_t full);
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief End of transmission buffer callback.
- */
- uartcb_t txend1_cb;
- /**
- * @brief Physical end of transmission callback.
- */
- uartcb_t txend2_cb;
- /**
- * @brief Receive buffer filled callback.
- */
- uartcb_t rxend_cb;
- /**
- * @brief Character received while out if the @p UART_RECEIVE state.
- */
- uartccb_t rxchar_cb;
- /**
- * @brief Receive error callback.
- */
- uartecb_t rxerr_cb;
- /* End of the mandatory fields.*/
- /**
- * @brief Receiver timeout callback.
- * @details Handles idle interrupts depending on configured
- * flags in CR registers and supported hardware features.
- */
- uartcb_t timeout_cb;
- /**
- * @brief Bit rate.
- */
- uint32_t speed;
- /**
- * @brief Initialization value for the CR1 register.
- */
- uint16_t cr1;
- /**
- * @brief Initialization value for the CR2 register.
- */
- uint16_t cr2;
- /**
- * @brief Initialization value for the CR3 register.
- */
- uint16_t cr3;
- /* Additional (optional) handlers. Placed here for the struct compatibility.*/
- /**
- * @brief Half-transfer receive buffer callback.
- */
- uarthcb_t rxhalf_cb;
-} UARTConfig;
-
-/**
- * @brief Structure representing an UART driver.
- */
-struct UARTDriver {
- /**
- * @brief Driver state.
- */
- uartstate_t state;
- /**
- * @brief Transmitter state.
- */
- uarttxstate_t txstate;
- /**
- * @brief Receiver state.
- */
- uartrxstate_t rxstate;
- /**
- * @brief Current configuration data.
- */
- const UARTConfig *config;
-#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Synchronization flag for transmit operations.
- */
- bool early;
- /**
- * @brief Waiting thread on RX.
- */
- thread_reference_t threadrx;
- /**
- * @brief Waiting thread on TX.
- */
- thread_reference_t threadtx;
-#endif /* UART_USE_WAIT */
-#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Mutex protecting the peripheral.
- */
- mutex_t mutex;
-#endif /* UART_USE_MUTUAL_EXCLUSION */
-#if defined(UART_DRIVER_EXT_FIELDS)
- UART_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the USART registers block.
- */
- USART_TypeDef *usart;
- /**
- * @brief Receive DMA mode bit mask.
- */
- uint32_t dmarxmode;
- /**
- * @brief Send DMA mode bit mask.
- */
- uint32_t dmatxmode;
- /**
- * @brief Receive DMA channel.
- */
- const stm32_dma_stream_t *dmarx;
- /**
- * @brief Transmit DMA channel.
- */
- const stm32_dma_stream_t *dmatx;
- /**
- * @brief Default receive buffer while into @p UART_RX_IDLE state.
- */
- volatile uint16_t rxbuf;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD1;
-#endif
-
-#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD2;
-#endif
-
-#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD3;
-#endif
-
-#if STM32_UART_USE_UART4 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD4;
-#endif
-
-#if STM32_UART_USE_UART5 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD5;
-#endif
-
-#if STM32_UART_USE_USART6 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD6;
-#endif
-
-#if STM32_UART_USE_UART7 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD7;
-#endif
-
-#if STM32_UART_USE_UART8 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD8;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void uart_lld_init(void);
- void uart_lld_start(UARTDriver *uartp);
- void uart_lld_stop(UARTDriver *uartp);
- void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
- size_t uart_lld_stop_send(UARTDriver *uartp);
- void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
- size_t uart_lld_stop_receive(UARTDriver *uartp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_UART */
-
-#endif /* HAL_UART_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 USARTv1/hal_uart_lld.h
+ * @brief STM32 low level UART driver header.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#ifndef HAL_UART_LLD_H
+#define HAL_UART_LLD_H
+
+#if HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief UART driver on USART1 enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART1 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART2 enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART2 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART3 enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART3 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART4 enable switch.
+ * @details If set to @p TRUE the support for UART4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART4 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART5 enable switch.
+ * @details If set to @p TRUE the support for UART5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART5) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART5 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART6 enable switch.
+ * @details If set to @p TRUE the support for USART6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART6) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART6 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART7 enable switch.
+ * @details If set to @p TRUE the support for UART7 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART7) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART7 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART8 enable switch.
+ * @details If set to @p TRUE the support for UART8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART8) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART8 FALSE
+#endif
+
+/**
+ * @brief USART1 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART1_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART2 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART2_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART3 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART3_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART4 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART4_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART5 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART5_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART6 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART6_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART7 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART7_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART7_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART8 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART8_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART8_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART3_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART4_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART5 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART5_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART6 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART6_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART6_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART7 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART7_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART7_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART8 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART8_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART8_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_UART_USE_USART1 && !STM32_HAS_USART1
+#error "USART1 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_USART2 && !STM32_HAS_USART2
+#error "USART2 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_USART3 && !STM32_HAS_USART3
+#error "USART3 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART4
+#if !STM32_HAS_UART4
+#error "UART4 not present in the selected device"
+#endif
+
+#if !defined(STM32F2XX) && !defined(STM32F4XX) && !defined(STM32L151xE) && \
+ !defined(STM32L152xE) && !defined(STM32L162xE)
+#error "UART4 DMA access not supported in this platform"
+#endif
+#endif /* STM32_UART_USE_UART4 */
+
+#if STM32_UART_USE_UART5
+#if !STM32_HAS_UART5
+#error "UART5 not present in the selected device"
+#endif
+
+#if !defined(STM32F2XX) && !defined(STM32F4XX) && !defined(STM32L151xE) && \
+ !defined(STM32L152xE) && !defined(STM32L162xE)
+#error "UART5 DMA access not supported in this platform"
+#endif
+#endif /* STM32_UART_USE_UART5 */
+
+#if STM32_UART_USE_USART6 && !STM32_HAS_USART6
+#error "USART6 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART7 && !STM32_HAS_UART7
+#error "UART7 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART8 && !STM32_HAS_UART8
+#error "UART8 not present in the selected device"
+#endif
+
+#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \
+ !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4 && \
+ !STM32_UART_USE_UART5 && !STM32_UART_USE_USART6 && \
+ !STM32_UART_USE_UART7 && !STM32_UART_USE_UART8
+#error "UART driver activated but no USART/UART peripheral assigned"
+#endif
+
+#if STM32_UART_USE_USART1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART1"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART2"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART3"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART4"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART5"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART6"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART7_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART7"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART8_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART8"
+#endif
+
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART1"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART2"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART3"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART4"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART5_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART5"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART6_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART6"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART7_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART7"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART8_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART8"
+#endif
+
+/* The following checks are only required when there is a DMA able to
+ reassign streams to different channels.*/
+#if STM32_ADVANCED_DMA
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_UART_USE_USART1 && (!defined(STM32_UART_USART1_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART1_TX_DMA_STREAM))
+#error "USART1 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_USART2 && (!defined(STM32_UART_USART2_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART2_TX_DMA_STREAM))
+#error "USART2 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_USART3 && (!defined(STM32_UART_USART3_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART3_TX_DMA_STREAM))
+#error "USART3 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART4 && (!defined(STM32_UART_UART4_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART4_TX_DMA_STREAM))
+#error "UART4 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART5 && (!defined(STM32_UART_UART5_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART5_TX_DMA_STREAM))
+#error "UART5 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_USART6 && (!defined(STM32_UART_USART6_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART6_TX_DMA_STREAM))
+#error "USART6 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART7 && (!defined(STM32_UART_UART7_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART7_TX_DMA_STREAM))
+#error "UART7 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART8 && (!defined(STM32_UART_UART8_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART8_TX_DMA_STREAM))
+#error "UART8 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \
+ STM32_USART1_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART1 RX"
+#endif
+
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_TX_DMA_STREAM, \
+ STM32_USART1_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART1 TX"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_RX_DMA_STREAM, \
+ STM32_USART2_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART2 RX"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_TX_DMA_STREAM, \
+ STM32_USART2_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART2 TX"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_RX_DMA_STREAM, \
+ STM32_USART3_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART3 RX"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_TX_DMA_STREAM, \
+ STM32_USART3_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART3 TX"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_RX_DMA_STREAM, \
+ STM32_UART4_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART4 RX"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_TX_DMA_STREAM, \
+ STM32_UART4_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART4 TX"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_RX_DMA_STREAM, \
+ STM32_UART5_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART5 RX"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_TX_DMA_STREAM, \
+ STM32_UART5_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART5 TX"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_RX_DMA_STREAM, \
+ STM32_USART6_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART6 RX"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_TX_DMA_STREAM, \
+ STM32_USART6_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART6 TX"
+#endif
+#endif /* STM32_ADVANCED_DMA */
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_RX_DMA_STREAM, \
+ STM32_UART7_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART7 RX"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_TX_DMA_STREAM, \
+ STM32_UART7_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART7 TX"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_RX_DMA_STREAM, \
+ STM32_UART8_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART8 RX"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_TX_DMA_STREAM, \
+ STM32_UART8_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART8 TX"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief UART driver condition flags type.
+ */
+typedef uint32_t uartflags_t;
+
+/**
+ * @brief Structure representing an UART driver.
+ */
+typedef struct UARTDriver UARTDriver;
+
+/**
+ * @brief Generic UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+typedef void (*uartcb_t)(UARTDriver *uartp);
+
+/**
+ * @brief Character received UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] c received character
+ */
+typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
+
+/**
+ * @brief Receive error UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] e receive error mask
+ */
+typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
+
+/**
+ * @brief Receive Half-transfer UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] full flag set to 1 for the second half, and 0 for the first half
+ */
+typedef void (*uarthcb_t)(UARTDriver *uartp, uartflags_t full);
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief End of transmission buffer callback.
+ */
+ uartcb_t txend1_cb;
+ /**
+ * @brief Physical end of transmission callback.
+ */
+ uartcb_t txend2_cb;
+ /**
+ * @brief Receive buffer filled callback.
+ */
+ uartcb_t rxend_cb;
+ /**
+ * @brief Character received while out if the @p UART_RECEIVE state.
+ */
+ uartccb_t rxchar_cb;
+ /**
+ * @brief Receive error callback.
+ */
+ uartecb_t rxerr_cb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Receiver timeout callback.
+ * @details Handles idle interrupts depending on configured
+ * flags in CR registers and supported hardware features.
+ */
+ uartcb_t timeout_cb;
+ /**
+ * @brief Bit rate.
+ */
+ uint32_t speed;
+ /**
+ * @brief Initialization value for the CR1 register.
+ */
+ uint16_t cr1;
+ /**
+ * @brief Initialization value for the CR2 register.
+ */
+ uint16_t cr2;
+ /**
+ * @brief Initialization value for the CR3 register.
+ */
+ uint16_t cr3;
+ /* Additional (optional) handlers. Placed here for the struct compatibility.*/
+ /**
+ * @brief Half-transfer receive buffer callback.
+ */
+ uarthcb_t rxhalf_cb;
+} UARTConfig;
+
+/**
+ * @brief Structure representing an UART driver.
+ */
+struct UARTDriver {
+ /**
+ * @brief Driver state.
+ */
+ uartstate_t state;
+ /**
+ * @brief Transmitter state.
+ */
+ uarttxstate_t txstate;
+ /**
+ * @brief Receiver state.
+ */
+ uartrxstate_t rxstate;
+ /**
+ * @brief Current configuration data.
+ */
+ const UARTConfig *config;
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Synchronization flag for transmit operations.
+ */
+ bool early;
+ /**
+ * @brief Waiting thread on RX.
+ */
+ thread_reference_t threadrx;
+ /**
+ * @brief Waiting thread on TX.
+ */
+ thread_reference_t threadtx;
+#endif /* UART_USE_WAIT */
+#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the peripheral.
+ */
+ mutex_t mutex;
+#endif /* UART_USE_MUTUAL_EXCLUSION */
+#if defined(UART_DRIVER_EXT_FIELDS)
+ UART_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the USART registers block.
+ */
+ USART_TypeDef *usart;
+ /**
+ * @brief Receive DMA mode bit mask.
+ */
+ uint32_t dmarxmode;
+ /**
+ * @brief Send DMA mode bit mask.
+ */
+ uint32_t dmatxmode;
+ /**
+ * @brief Receive DMA channel.
+ */
+ const stm32_dma_stream_t *dmarx;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const stm32_dma_stream_t *dmatx;
+ /**
+ * @brief Default receive buffer while into @p UART_RX_IDLE state.
+ */
+ volatile uint16_t rxbuf;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD1;
+#endif
+
+#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD2;
+#endif
+
+#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD3;
+#endif
+
+#if STM32_UART_USE_UART4 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD4;
+#endif
+
+#if STM32_UART_USE_UART5 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD5;
+#endif
+
+#if STM32_UART_USE_USART6 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD6;
+#endif
+
+#if STM32_UART_USE_UART7 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD7;
+#endif
+
+#if STM32_UART_USE_UART8 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD8;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void uart_lld_init(void);
+ void uart_lld_start(UARTDriver *uartp);
+ void uart_lld_stop(UARTDriver *uartp);
+ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
+ size_t uart_lld_stop_send(UARTDriver *uartp);
+ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
+ size_t uart_lld_stop_receive(UARTDriver *uartp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_UART */
+
+#endif /* HAL_UART_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv2/driver.mk b/os/hal/ports/STM32/LLD/USARTv2/driver.mk
index 2de63f8e64..6b614601d3 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+++ b/os/hal/ports/STM32/LLD/USARTv2/driver.mk
@@ -1,13 +1,13 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
-endif
-ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_SERIAL TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
+endif
+ifneq ($(findstring HAL_USE_UART TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2
diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
index 7c89ecf872..27b6a64046 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
@@ -1,913 +1,913 @@
-/*
- 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 USARTv2/hal_serial_lld.c
- * @brief STM32 low level serial driver code.
- *
- * @addtogroup SERIAL
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_SERIAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* For compatibility for those devices without LIN support in the USARTs.*/
-#if !defined(USART_ISR_LBDF)
-#define USART_ISR_LBDF 0
-#endif
-
-#if !defined(USART_CR2_LBDIE)
-#define USART_CR2_LBDIE 0
-#endif
-
-/* Differences in L4+ headers.*/
-#if !defined(USART_CR1_TXEIE)
-#define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE
-#endif
-
-#if !defined(USART_CR1_RXNEIE)
-#define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE
-#endif
-
-#if !defined(USART_ISR_TXE)
-#define USART_ISR_TXE USART_ISR_TXE_TXFNF
-#endif
-
-#if !defined(USART_ISR_RXNE)
-#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
-#endif
-
-/* STM32L0xx/STM32F7xx ST headers difference.*/
-#if !defined(USART_ISR_LBDF)
-#define USART_ISR_LBDF USART_ISR_LBD
-#endif
-
-/* Handling differences in frame size bits.*/
-#if !defined(USART_CR1_M_0)
-#define USART_CR1_M_0 (1 << 12)
-#endif
-
-#if !defined(USART_CR1_M_1)
-#define USART_CR1_M_1 (1 << 28)
-#endif
-
-/* Workarounds for those devices where UARTs are USARTs.*/
-#if defined(USART4)
-#define UART4 USART4
-#endif
-#if defined(USART5)
-#define UART5 USART5
-#endif
-#if defined(USART7)
-#define UART7 USART7
-#endif
-#if defined(USART8)
-#define UART8 USART8
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief USART1 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-SerialDriver SD1;
-#endif
-
-/** @brief USART2 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-SerialDriver SD2;
-#endif
-
-/** @brief USART3 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-SerialDriver SD3;
-#endif
-
-/** @brief UART4 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-SerialDriver SD4;
-#endif
-
-/** @brief UART5 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-SerialDriver SD5;
-#endif
-
-/** @brief USART6 serial driver identifier.*/
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-SerialDriver SD6;
-#endif
-
-/** @brief UART7 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-SerialDriver SD7;
-#endif
-
-/** @brief UART8 serial driver identifier.*/
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-SerialDriver SD8;
-#endif
-
-/** @brief LPUART1 serial driver identifier.*/
-#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
-SerialDriver LPSD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/** @brief Driver default configuration.*/
-static const SerialConfig default_config =
-{
- SERIAL_DEFAULT_BITRATE,
- 0,
- USART_CR2_STOP1_BITS,
- 0
-};
-
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD1.*/
-static uint8_t sd_in_buf1[STM32_SERIAL_USART1_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD1.*/
-static uint8_t sd_out_buf1[STM32_SERIAL_USART1_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD2.*/
-static uint8_t sd_in_buf2[STM32_SERIAL_USART2_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD2.*/
-static uint8_t sd_out_buf2[STM32_SERIAL_USART2_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD3.*/
-static uint8_t sd_in_buf3[STM32_SERIAL_USART3_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD3.*/
-static uint8_t sd_out_buf3[STM32_SERIAL_USART3_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD4.*/
-static uint8_t sd_in_buf4[STM32_SERIAL_UART4_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD4.*/
-static uint8_t sd_out_buf4[STM32_SERIAL_UART4_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD5.*/
-static uint8_t sd_in_buf5[STM32_SERIAL_UART5_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD5.*/
-static uint8_t sd_out_buf5[STM32_SERIAL_UART5_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD6.*/
-static uint8_t sd_in_buf6[STM32_SERIAL_USART6_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD6.*/
-static uint8_t sd_out_buf6[STM32_SERIAL_USART6_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD7.*/
-static uint8_t sd_in_buf7[STM32_SERIAL_UART7_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD7.*/
-static uint8_t sd_out_buf7[STM32_SERIAL_UART7_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-/** @brief Input buffer for SD8.*/
-static uint8_t sd_in_buf8[STM32_SERIAL_UART8_IN_BUF_SIZE];
-
-/** @brief Output buffer for SD8.*/
-static uint8_t sd_out_buf8[STM32_SERIAL_UART8_OUT_BUF_SIZE];
-#endif
-
-#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
-/** @brief Input buffer for LPSD1.*/
-static uint8_t sd_in_buflp1[STM32_SERIAL_LPUART1_IN_BUF_SIZE];
-
-/** @brief Output buffer for LPSD1.*/
-static uint8_t sd_out_buflp1[STM32_SERIAL_LPUART1_OUT_BUF_SIZE];
-#endif
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief USART initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- * @param[in] config the architecture-dependent serial driver configuration
- */
-static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
- uint32_t brr;
- USART_TypeDef *u = sdp->usart;
-
- /* Baud rate setting.*/
-#if STM32_SERIAL_USE_LPUART1
- if (sdp == &LPSD1) {
- osalDbgAssert((sdp->clock >= config->speed * 3U) &&
- (sdp->clock <= config->speed * 4096U),
- "invalid baud rate vs input clock");
-
- brr = (uint32_t)(((uint64_t)sdp->clock * 256) / config->speed);
-
- osalDbgAssert((brr >= 0x300) && (brr < 0x100000), "invalid BRR value");
- }
- else
-#endif
- {
- brr = (uint32_t)(sdp->clock / config->speed);
-
- /* Correcting BRR value when oversampling by 8 instead of 16.
- Fraction is still 4 bits wide, but only lower 3 bits used.
- Mantissa is doubled, but Fraction is left the same.*/
- if (config->cr1 & USART_CR1_OVER8)
- brr = ((brr & ~7) * 2) | (brr & 7);
-
- osalDbgAssert(brr < 0x10000, "invalid BRR value");
- }
- u->BRR = brr;
-
- /* Note that some bits are enforced.*/
- u->CR2 = config->cr2 | USART_CR2_LBDIE;
- u->CR3 = config->cr3 | USART_CR3_EIE;
- u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE |
- USART_CR1_RXNEIE | USART_CR1_TE |
- USART_CR1_RE;
- u->ICR = 0xFFFFFFFFU;
-
- /* Deciding mask to be applied on the data register on receive, this is
- required in order to mask out the parity bit.*/
- if ((config->cr1 & USART_CR1_PCE) != 0U) {
- switch (config->cr1 & (USART_CR1_M_1 | USART_CR1_M_0)) {
- case 0:
- sdp->rxmask = 0x7F;
- break;
- case USART_CR1_M_1:
- sdp->rxmask = 0x3F;
- break;
- default:
- sdp->rxmask = 0xFF;
- }
- }
- else {
- sdp->rxmask = 0xFF;
- }
-}
-
-/**
- * @brief USART de-initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] u pointer to an USART I/O block
- */
-static void usart_deinit(USART_TypeDef *u) {
-
- u->CR1 = 0;
- u->CR2 = 0;
- u->CR3 = 0;
-}
-
-/**
- * @brief Error handling routine.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- * @param[in] isr USART ISR register value
- */
-static void set_error(SerialDriver *sdp, uint32_t isr) {
- eventflags_t sts = 0;
-
- if (isr & USART_ISR_ORE)
- sts |= SD_OVERRUN_ERROR;
- if (isr & USART_ISR_PE)
- sts |= SD_PARITY_ERROR;
- if (isr & USART_ISR_FE)
- sts |= SD_FRAMING_ERROR;
- if (isr & USART_ISR_NE)
- sts |= SD_NOISE_ERROR;
- osalSysLockFromISR();
- chnAddFlagsI(sdp, sts);
- osalSysUnlockFromISR();
-}
-
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-static void notify1(io_queue_t *qp) {
-
- (void)qp;
- USART1->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-static void notify2(io_queue_t *qp) {
-
- (void)qp;
- USART2->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-static void notify3(io_queue_t *qp) {
-
- (void)qp;
- USART3->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-static void notify4(io_queue_t *qp) {
-
- (void)qp;
- UART4->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-static void notify5(io_queue_t *qp) {
-
- (void)qp;
- UART5->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-static void notify6(io_queue_t *qp) {
-
- (void)qp;
- USART6->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-static void notify7(io_queue_t *qp) {
-
- (void)qp;
- UART7->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-static void notify8(io_queue_t *qp) {
-
- (void)qp;
- UART8->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
-static void notifylp1(io_queue_t *qp) {
-
- (void)qp;
- LPUART1->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
-}
-#endif
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
-#if !defined(STM32_USART1_SUPPRESS_ISR)
-#if !defined(STM32_USART1_HANDLER)
-#error "STM32_USART1_HANDLER not defined"
-#endif
-/**
- * @brief USART1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
-#if !defined(STM32_USART2_SUPPRESS_ISR)
-#if !defined(STM32_USART2_HANDLER)
-#error "STM32_USART2_HANDLER not defined"
-#endif
-/**
- * @brief USART2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
-#if !defined(STM32_USART3_SUPPRESS_ISR)
-#if !defined(STM32_USART3_HANDLER)
-#error "STM32_USART3_HANDLER not defined"
-#endif
-/**
- * @brief USART3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
-#if !defined(STM32_UART4_SUPPRESS_ISR)
-#if !defined(STM32_UART4_HANDLER)
-#error "STM32_UART4_HANDLER not defined"
-#endif
-/**
- * @brief UART4 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
-#if !defined(STM32_UART5_SUPPRESS_ISR)
-#if !defined(STM32_UART5_HANDLER)
-#error "STM32_UART5_HANDLER not defined"
-#endif
-/**
- * @brief UART5 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
-#if !defined(STM32_USART6_SUPPRESS_ISR)
-#if !defined(STM32_USART6_HANDLER)
-#error "STM32_USART6_HANDLER not defined"
-#endif
-/**
- * @brief USART6 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
-#if !defined(STM32_UART7_SUPPRESS_ISR)
-#if !defined(STM32_UART7_HANDLER)
-#error "STM32_UART7_HANDLER not defined"
-#endif
-/**
- * @brief UART7 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
-#if !defined(STM32_UART8_SUPPRESS_ISR)
-#if !defined(STM32_UART8_HANDLER)
-#error "STM32_UART8_HANDLER not defined"
-#endif
-/**
- * @brief UART8 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&SD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
-#if !defined(STM32_LPUART1_SUPPRESS_ISR)
-#if !defined(STM32_LPUART1_HANDLER)
-#error "STM32_LPUART1_HANDLER not defined"
-#endif
-/**
- * @brief LPUART1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_LPUART1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- sd_lld_serve_interrupt(&LPSD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level serial driver initialization.
- *
- * @notapi
- */
-void sd_lld_init(void) {
-
-#if STM32_SERIAL_USE_USART1
- sdObjectInit(&SD1);
- iqObjectInit(&SD1.iqueue, sd_in_buf1, sizeof sd_in_buf1, NULL, &SD1);
- oqObjectInit(&SD1.oqueue, sd_out_buf1, sizeof sd_out_buf1, notify1, &SD1);
- SD1.usart = USART1;
- SD1.clock = STM32_USART1CLK;
-#if !defined(STM32_USART1_SUPPRESS_ISR) && defined(STM32_USART1_NUMBER)
- nvicEnableVector(STM32_USART1_NUMBER, STM32_SERIAL_USART1_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_USART2
- sdObjectInit(&SD2);
- iqObjectInit(&SD2.iqueue, sd_in_buf2, sizeof sd_in_buf2, NULL, &SD2);
- oqObjectInit(&SD2.oqueue, sd_out_buf2, sizeof sd_out_buf2, notify2, &SD2);
- SD2.usart = USART2;
- SD2.clock = STM32_USART2CLK;
-#if !defined(STM32_USART2_SUPPRESS_ISR) && defined(STM32_USART2_NUMBER)
- nvicEnableVector(STM32_USART2_NUMBER, STM32_SERIAL_USART2_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_USART3
- sdObjectInit(&SD3);
- iqObjectInit(&SD3.iqueue, sd_in_buf3, sizeof sd_in_buf3, NULL, &SD3);
- oqObjectInit(&SD3.oqueue, sd_out_buf3, sizeof sd_out_buf3, notify3, &SD3);
- SD3.usart = USART3;
- SD3.clock = STM32_USART3CLK;
-#if !defined(STM32_USART3_SUPPRESS_ISR) && defined(STM32_USART3_NUMBER)
- nvicEnableVector(STM32_USART3_NUMBER, STM32_SERIAL_USART3_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART4
- sdObjectInit(&SD4);
- iqObjectInit(&SD4.iqueue, sd_in_buf4, sizeof sd_in_buf4, NULL, &SD4);
- oqObjectInit(&SD4.oqueue, sd_out_buf4, sizeof sd_out_buf4, notify4, &SD4);
- SD4.usart = UART4;
- SD4.clock = STM32_UART4CLK;
-#if !defined(STM32_UART4_SUPPRESS_ISR) && defined(STM32_UART4_NUMBER)
- nvicEnableVector(STM32_UART4_NUMBER, STM32_SERIAL_UART4_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART5
- sdObjectInit(&SD5);
- iqObjectInit(&SD5.iqueue, sd_in_buf5, sizeof sd_in_buf5, NULL, &SD5);
- oqObjectInit(&SD5.oqueue, sd_out_buf5, sizeof sd_out_buf5, notify5, &SD5);
- SD5.usart = UART5;
- SD5.clock = STM32_UART5CLK;
-#if !defined(STM32_UART5_SUPPRESS_ISR) && defined(STM32_UART5_NUMBER)
- nvicEnableVector(STM32_UART5_NUMBER, STM32_SERIAL_UART5_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_USART6
- sdObjectInit(&SD6);
- iqObjectInit(&SD6.iqueue, sd_in_buf6, sizeof sd_in_buf6, NULL, &SD6);
- oqObjectInit(&SD6.oqueue, sd_out_buf6, sizeof sd_out_buf6, notify6, &SD6);
- SD6.usart = USART6;
- SD6.clock = STM32_USART6CLK;
-#if !defined(STM32_USART6_SUPPRESS_ISR) && defined(STM32_USART6_NUMBER)
- nvicEnableVector(STM32_USART6_NUMBER, STM32_SERIAL_USART6_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART7
- sdObjectInit(&SD7);
- iqObjectInit(&SD7.iqueue, sd_in_buf7, sizeof sd_in_buf7, NULL, &SD7);
- oqObjectInit(&SD7.oqueue, sd_out_buf7, sizeof sd_out_buf7, notify7, &SD7);
- SD7.usart = UART7;
- SD7.clock = STM32_UART7CLK;
-#if !defined(STM32_UART7_SUPPRESS_ISR) && defined(STM32_UART7_NUMBER)
- nvicEnableVector(STM32_UART7_NUMBER, STM32_SERIAL_UART7_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_UART8
- sdObjectInit(&SD8);
- iqObjectInit(&SD8.iqueue, sd_in_buf8, sizeof sd_in_buf8, NULL, &SD8);
- oqObjectInit(&SD8.oqueue, sd_out_buf8, sizeof sd_out_buf8, notify8, &SD8);
- SD8.usart = UART8;
- SD8.clock = STM32_UART8CLK;
-#if !defined(STM32_UART8_SUPPRESS_ISR) && defined(STM32_UART8_NUMBER)
- nvicEnableVector(STM32_UART8_NUMBER, STM32_SERIAL_UART8_PRIORITY);
-#endif
-#endif
-
-#if STM32_SERIAL_USE_LPUART1
- sdObjectInit(&LPSD1);
- iqObjectInit(&LPSD1.iqueue, sd_in_buflp1, sizeof sd_in_buflp1, NULL, &LPSD1);
- oqObjectInit(&LPSD1.oqueue, sd_out_buflp1, sizeof sd_out_buflp1, notifylp1, &LPSD1);
- LPSD1.usart = LPUART1;
- LPSD1.clock = STM32_LPUART1CLK;
-#if !defined(STM32_LPUART1_SUPPRESS_ISR) && defined(STM32_LPUART1_NUMBER)
- nvicEnableVector(STM32_LPUART1_NUMBER, STM32_SERIAL_LPUART1_PRIORITY);
-#endif
-#endif
-}
-
-/**
- * @brief Low level serial driver configuration and (re)start.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- * @param[in] config the architecture-dependent serial driver configuration.
- * If this parameter is set to @p NULL then a default
- * configuration is used.
- *
- * @notapi
- */
-void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
-
- if (config == NULL)
- config = &default_config;
-
- if (sdp->state == SD_STOP) {
-#if STM32_SERIAL_USE_USART1
- if (&SD1 == sdp) {
- rccEnableUSART1(true);
- }
-#endif
-#if STM32_SERIAL_USE_USART2
- if (&SD2 == sdp) {
- rccEnableUSART2(true);
- }
-#endif
-#if STM32_SERIAL_USE_USART3
- if (&SD3 == sdp) {
- rccEnableUSART3(true);
- }
-#endif
-#if STM32_SERIAL_USE_UART4
- if (&SD4 == sdp) {
- rccEnableUART4(true);
- }
-#endif
-#if STM32_SERIAL_USE_UART5
- if (&SD5 == sdp) {
- rccEnableUART5(true);
- }
-#endif
-#if STM32_SERIAL_USE_USART6
- if (&SD6 == sdp) {
- rccEnableUSART6(true);
- }
-#endif
-#if STM32_SERIAL_USE_UART7
- if (&SD7 == sdp) {
- rccEnableUART7(true);
- }
-#endif
-#if STM32_SERIAL_USE_UART8
- if (&SD8 == sdp) {
- rccEnableUART8(true);
- }
-#endif
-#if STM32_SERIAL_USE_LPUART1
- if (&LPSD1 == sdp) {
- rccEnableLPUART1(true);
- }
-#endif
- }
- usart_init(sdp, config);
-}
-
-/**
- * @brief Low level serial driver stop.
- * @details De-initializes the USART, stops the associated clock, resets the
- * interrupt vector.
- *
- * @param[in] sdp pointer to a @p SerialDriver object
- *
- * @notapi
- */
-void sd_lld_stop(SerialDriver *sdp) {
-
- if (sdp->state == SD_READY) {
- /* UART is de-initialized then clocks are disabled.*/
- usart_deinit(sdp->usart);
-
-#if STM32_SERIAL_USE_USART1
- if (&SD1 == sdp) {
- rccDisableUSART1();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_USART2
- if (&SD2 == sdp) {
- rccDisableUSART2();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_USART3
- if (&SD3 == sdp) {
- rccDisableUSART3();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART4
- if (&SD4 == sdp) {
- rccDisableUART4();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART5
- if (&SD5 == sdp) {
- rccDisableUART5();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_USART6
- if (&SD6 == sdp) {
- rccDisableUSART6();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART7
- if (&SD7 == sdp) {
- rccDisableUART7();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_UART8
- if (&SD8 == sdp) {
- rccDisableUART8();
- return;
- }
-#endif
-#if STM32_SERIAL_USE_LPUART1
- if (&LPSD1 == sdp) {
- rccDisableLPUART1();
- return;
- }
-#endif
- }
-}
-
-/**
- * @brief Common IRQ handler.
- *
- * @param[in] sdp communication channel associated to the USART
- */
-void sd_lld_serve_interrupt(SerialDriver *sdp) {
- USART_TypeDef *u = sdp->usart;
- uint32_t cr1 = u->CR1;
- uint32_t isr;
-
- /* Reading and clearing status.*/
- isr = u->ISR;
- u->ICR = isr;
-
- /* Error condition detection.*/
- if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE))
- set_error(sdp, isr);
-
- /* Special case, LIN break detection.*/
- if (isr & USART_ISR_LBDF) {
- osalSysLockFromISR();
- chnAddFlagsI(sdp, SD_BREAK_DETECTED);
- osalSysUnlockFromISR();
- }
-
- /* Data available, note it is a while in order to handle two situations:
- 1) Another byte arrived after removing the previous one, this would cause
- an extra interrupt to serve.
- 2) FIFO mode is enabled on devices that support it, we need to empty
- the FIFO.*/
- while (isr & USART_ISR_RXNE) {
- osalSysLockFromISR();
- sdIncomingDataI(sdp, (uint8_t)u->RDR & sdp->rxmask);
- osalSysUnlockFromISR();
-
- isr = u->ISR;
- }
-
- /* Transmission buffer empty, note it is a while in order to handle two
- situations:
- 1) The data registers has been emptied immediately after writing it, this
- would cause an extra interrupt to serve.
- 2) FIFO mode is enabled on devices that support it, we need to fill
- the FIFO.*/
- if (cr1 & USART_CR1_TXEIE) {
- while (isr & USART_ISR_TXE) {
- msg_t b;
-
- osalSysLockFromISR();
- b = oqGetI(&sdp->oqueue);
- if (b < MSG_OK) {
- chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
- u->CR1 = cr1 & ~USART_CR1_TXEIE;
- osalSysUnlockFromISR();
- break;
- }
- u->TDR = b;
- osalSysUnlockFromISR();
-
- isr = u->ISR;
- }
- }
-
- /* Physical transmission end.*/
- if ((cr1 & USART_CR1_TCIE) && (isr & USART_ISR_TC)) {
- osalSysLockFromISR();
- if (oqIsEmptyI(&sdp->oqueue)) {
- chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
- u->CR1 = cr1 & ~USART_CR1_TCIE;
- }
- osalSysUnlockFromISR();
- }
-}
-
-#endif /* HAL_USE_SERIAL */
-
-/** @} */
+/*
+ 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 USARTv2/hal_serial_lld.c
+ * @brief STM32 low level serial driver code.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* For compatibility for those devices without LIN support in the USARTs.*/
+#if !defined(USART_ISR_LBDF)
+#define USART_ISR_LBDF 0
+#endif
+
+#if !defined(USART_CR2_LBDIE)
+#define USART_CR2_LBDIE 0
+#endif
+
+/* Differences in L4+ headers.*/
+#if !defined(USART_CR1_TXEIE)
+#define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE
+#endif
+
+#if !defined(USART_CR1_RXNEIE)
+#define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE
+#endif
+
+#if !defined(USART_ISR_TXE)
+#define USART_ISR_TXE USART_ISR_TXE_TXFNF
+#endif
+
+#if !defined(USART_ISR_RXNE)
+#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
+#endif
+
+/* STM32L0xx/STM32F7xx ST headers difference.*/
+#if !defined(USART_ISR_LBDF)
+#define USART_ISR_LBDF USART_ISR_LBD
+#endif
+
+/* Handling differences in frame size bits.*/
+#if !defined(USART_CR1_M_0)
+#define USART_CR1_M_0 (1 << 12)
+#endif
+
+#if !defined(USART_CR1_M_1)
+#define USART_CR1_M_1 (1 << 28)
+#endif
+
+/* Workarounds for those devices where UARTs are USARTs.*/
+#if defined(USART4)
+#define UART4 USART4
+#endif
+#if defined(USART5)
+#define UART5 USART5
+#endif
+#if defined(USART7)
+#define UART7 USART7
+#endif
+#if defined(USART8)
+#define UART8 USART8
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief USART1 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+SerialDriver SD1;
+#endif
+
+/** @brief USART2 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+SerialDriver SD2;
+#endif
+
+/** @brief USART3 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+SerialDriver SD3;
+#endif
+
+/** @brief UART4 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+SerialDriver SD4;
+#endif
+
+/** @brief UART5 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+SerialDriver SD5;
+#endif
+
+/** @brief USART6 serial driver identifier.*/
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+SerialDriver SD6;
+#endif
+
+/** @brief UART7 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+SerialDriver SD7;
+#endif
+
+/** @brief UART8 serial driver identifier.*/
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+SerialDriver SD8;
+#endif
+
+/** @brief LPUART1 serial driver identifier.*/
+#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
+SerialDriver LPSD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/** @brief Driver default configuration.*/
+static const SerialConfig default_config =
+{
+ SERIAL_DEFAULT_BITRATE,
+ 0,
+ USART_CR2_STOP1_BITS,
+ 0
+};
+
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD1.*/
+static uint8_t sd_in_buf1[STM32_SERIAL_USART1_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD1.*/
+static uint8_t sd_out_buf1[STM32_SERIAL_USART1_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD2.*/
+static uint8_t sd_in_buf2[STM32_SERIAL_USART2_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD2.*/
+static uint8_t sd_out_buf2[STM32_SERIAL_USART2_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD3.*/
+static uint8_t sd_in_buf3[STM32_SERIAL_USART3_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD3.*/
+static uint8_t sd_out_buf3[STM32_SERIAL_USART3_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD4.*/
+static uint8_t sd_in_buf4[STM32_SERIAL_UART4_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD4.*/
+static uint8_t sd_out_buf4[STM32_SERIAL_UART4_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD5.*/
+static uint8_t sd_in_buf5[STM32_SERIAL_UART5_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD5.*/
+static uint8_t sd_out_buf5[STM32_SERIAL_UART5_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD6.*/
+static uint8_t sd_in_buf6[STM32_SERIAL_USART6_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD6.*/
+static uint8_t sd_out_buf6[STM32_SERIAL_USART6_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD7.*/
+static uint8_t sd_in_buf7[STM32_SERIAL_UART7_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD7.*/
+static uint8_t sd_out_buf7[STM32_SERIAL_UART7_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+/** @brief Input buffer for SD8.*/
+static uint8_t sd_in_buf8[STM32_SERIAL_UART8_IN_BUF_SIZE];
+
+/** @brief Output buffer for SD8.*/
+static uint8_t sd_out_buf8[STM32_SERIAL_UART8_OUT_BUF_SIZE];
+#endif
+
+#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
+/** @brief Input buffer for LPSD1.*/
+static uint8_t sd_in_buflp1[STM32_SERIAL_LPUART1_IN_BUF_SIZE];
+
+/** @brief Output buffer for LPSD1.*/
+static uint8_t sd_out_buflp1[STM32_SERIAL_LPUART1_OUT_BUF_SIZE];
+#endif
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief USART initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] config the architecture-dependent serial driver configuration
+ */
+static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
+ uint32_t brr;
+ USART_TypeDef *u = sdp->usart;
+
+ /* Baud rate setting.*/
+#if STM32_SERIAL_USE_LPUART1
+ if (sdp == &LPSD1) {
+ osalDbgAssert((sdp->clock >= config->speed * 3U) &&
+ (sdp->clock <= config->speed * 4096U),
+ "invalid baud rate vs input clock");
+
+ brr = (uint32_t)(((uint64_t)sdp->clock * 256) / config->speed);
+
+ osalDbgAssert((brr >= 0x300) && (brr < 0x100000), "invalid BRR value");
+ }
+ else
+#endif
+ {
+ brr = (uint32_t)(sdp->clock / config->speed);
+
+ /* Correcting BRR value when oversampling by 8 instead of 16.
+ Fraction is still 4 bits wide, but only lower 3 bits used.
+ Mantissa is doubled, but Fraction is left the same.*/
+ if (config->cr1 & USART_CR1_OVER8)
+ brr = ((brr & ~7) * 2) | (brr & 7);
+
+ osalDbgAssert(brr < 0x10000, "invalid BRR value");
+ }
+ u->BRR = brr;
+
+ /* Note that some bits are enforced.*/
+ u->CR2 = config->cr2 | USART_CR2_LBDIE;
+ u->CR3 = config->cr3 | USART_CR3_EIE;
+ u->CR1 = config->cr1 | USART_CR1_UE | USART_CR1_PEIE |
+ USART_CR1_RXNEIE | USART_CR1_TE |
+ USART_CR1_RE;
+ u->ICR = 0xFFFFFFFFU;
+
+ /* Deciding mask to be applied on the data register on receive, this is
+ required in order to mask out the parity bit.*/
+ if ((config->cr1 & USART_CR1_PCE) != 0U) {
+ switch (config->cr1 & (USART_CR1_M_1 | USART_CR1_M_0)) {
+ case 0:
+ sdp->rxmask = 0x7F;
+ break;
+ case USART_CR1_M_1:
+ sdp->rxmask = 0x3F;
+ break;
+ default:
+ sdp->rxmask = 0xFF;
+ }
+ }
+ else {
+ sdp->rxmask = 0xFF;
+ }
+}
+
+/**
+ * @brief USART de-initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] u pointer to an USART I/O block
+ */
+static void usart_deinit(USART_TypeDef *u) {
+
+ u->CR1 = 0;
+ u->CR2 = 0;
+ u->CR3 = 0;
+}
+
+/**
+ * @brief Error handling routine.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] isr USART ISR register value
+ */
+static void set_error(SerialDriver *sdp, uint32_t isr) {
+ eventflags_t sts = 0;
+
+ if (isr & USART_ISR_ORE)
+ sts |= SD_OVERRUN_ERROR;
+ if (isr & USART_ISR_PE)
+ sts |= SD_PARITY_ERROR;
+ if (isr & USART_ISR_FE)
+ sts |= SD_FRAMING_ERROR;
+ if (isr & USART_ISR_NE)
+ sts |= SD_NOISE_ERROR;
+ osalSysLockFromISR();
+ chnAddFlagsI(sdp, sts);
+ osalSysUnlockFromISR();
+}
+
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+static void notify1(io_queue_t *qp) {
+
+ (void)qp;
+ USART1->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+static void notify2(io_queue_t *qp) {
+
+ (void)qp;
+ USART2->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+static void notify3(io_queue_t *qp) {
+
+ (void)qp;
+ USART3->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+static void notify4(io_queue_t *qp) {
+
+ (void)qp;
+ UART4->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+static void notify5(io_queue_t *qp) {
+
+ (void)qp;
+ UART5->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+static void notify6(io_queue_t *qp) {
+
+ (void)qp;
+ USART6->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+static void notify7(io_queue_t *qp) {
+
+ (void)qp;
+ UART7->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+static void notify8(io_queue_t *qp) {
+
+ (void)qp;
+ UART8->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
+static void notifylp1(io_queue_t *qp) {
+
+ (void)qp;
+ LPUART1->CR1 |= USART_CR1_TXEIE | USART_CR1_TCIE;
+}
+#endif
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__)
+#if !defined(STM32_USART1_SUPPRESS_ISR)
+#if !defined(STM32_USART1_HANDLER)
+#error "STM32_USART1_HANDLER not defined"
+#endif
+/**
+ * @brief USART1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__)
+#if !defined(STM32_USART2_SUPPRESS_ISR)
+#if !defined(STM32_USART2_HANDLER)
+#error "STM32_USART2_HANDLER not defined"
+#endif
+/**
+ * @brief USART2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_USART3 || defined(__DOXYGEN__)
+#if !defined(STM32_USART3_SUPPRESS_ISR)
+#if !defined(STM32_USART3_HANDLER)
+#error "STM32_USART3_HANDLER not defined"
+#endif
+/**
+ * @brief USART3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART4 || defined(__DOXYGEN__)
+#if !defined(STM32_UART4_SUPPRESS_ISR)
+#if !defined(STM32_UART4_HANDLER)
+#error "STM32_UART4_HANDLER not defined"
+#endif
+/**
+ * @brief UART4 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART5 || defined(__DOXYGEN__)
+#if !defined(STM32_UART5_SUPPRESS_ISR)
+#if !defined(STM32_UART5_HANDLER)
+#error "STM32_UART5_HANDLER not defined"
+#endif
+/**
+ * @brief UART5 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_USART6 || defined(__DOXYGEN__)
+#if !defined(STM32_USART6_SUPPRESS_ISR)
+#if !defined(STM32_USART6_HANDLER)
+#error "STM32_USART6_HANDLER not defined"
+#endif
+/**
+ * @brief USART6 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART7 || defined(__DOXYGEN__)
+#if !defined(STM32_UART7_SUPPRESS_ISR)
+#if !defined(STM32_UART7_HANDLER)
+#error "STM32_UART7_HANDLER not defined"
+#endif
+/**
+ * @brief UART7 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART8 || defined(__DOXYGEN__)
+#if !defined(STM32_UART8_SUPPRESS_ISR)
+#if !defined(STM32_UART8_HANDLER)
+#error "STM32_UART8_HANDLER not defined"
+#endif
+/**
+ * @brief UART8 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&SD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_SERIAL_USE_LPUART1 || defined(__DOXYGEN__)
+#if !defined(STM32_LPUART1_SUPPRESS_ISR)
+#if !defined(STM32_LPUART1_HANDLER)
+#error "STM32_LPUART1_HANDLER not defined"
+#endif
+/**
+ * @brief LPUART1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_LPUART1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ sd_lld_serve_interrupt(&LPSD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level serial driver initialization.
+ *
+ * @notapi
+ */
+void sd_lld_init(void) {
+
+#if STM32_SERIAL_USE_USART1
+ sdObjectInit(&SD1);
+ iqObjectInit(&SD1.iqueue, sd_in_buf1, sizeof sd_in_buf1, NULL, &SD1);
+ oqObjectInit(&SD1.oqueue, sd_out_buf1, sizeof sd_out_buf1, notify1, &SD1);
+ SD1.usart = USART1;
+ SD1.clock = STM32_USART1CLK;
+#if !defined(STM32_USART1_SUPPRESS_ISR) && defined(STM32_USART1_NUMBER)
+ nvicEnableVector(STM32_USART1_NUMBER, STM32_SERIAL_USART1_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_USART2
+ sdObjectInit(&SD2);
+ iqObjectInit(&SD2.iqueue, sd_in_buf2, sizeof sd_in_buf2, NULL, &SD2);
+ oqObjectInit(&SD2.oqueue, sd_out_buf2, sizeof sd_out_buf2, notify2, &SD2);
+ SD2.usart = USART2;
+ SD2.clock = STM32_USART2CLK;
+#if !defined(STM32_USART2_SUPPRESS_ISR) && defined(STM32_USART2_NUMBER)
+ nvicEnableVector(STM32_USART2_NUMBER, STM32_SERIAL_USART2_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_USART3
+ sdObjectInit(&SD3);
+ iqObjectInit(&SD3.iqueue, sd_in_buf3, sizeof sd_in_buf3, NULL, &SD3);
+ oqObjectInit(&SD3.oqueue, sd_out_buf3, sizeof sd_out_buf3, notify3, &SD3);
+ SD3.usart = USART3;
+ SD3.clock = STM32_USART3CLK;
+#if !defined(STM32_USART3_SUPPRESS_ISR) && defined(STM32_USART3_NUMBER)
+ nvicEnableVector(STM32_USART3_NUMBER, STM32_SERIAL_USART3_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART4
+ sdObjectInit(&SD4);
+ iqObjectInit(&SD4.iqueue, sd_in_buf4, sizeof sd_in_buf4, NULL, &SD4);
+ oqObjectInit(&SD4.oqueue, sd_out_buf4, sizeof sd_out_buf4, notify4, &SD4);
+ SD4.usart = UART4;
+ SD4.clock = STM32_UART4CLK;
+#if !defined(STM32_UART4_SUPPRESS_ISR) && defined(STM32_UART4_NUMBER)
+ nvicEnableVector(STM32_UART4_NUMBER, STM32_SERIAL_UART4_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART5
+ sdObjectInit(&SD5);
+ iqObjectInit(&SD5.iqueue, sd_in_buf5, sizeof sd_in_buf5, NULL, &SD5);
+ oqObjectInit(&SD5.oqueue, sd_out_buf5, sizeof sd_out_buf5, notify5, &SD5);
+ SD5.usart = UART5;
+ SD5.clock = STM32_UART5CLK;
+#if !defined(STM32_UART5_SUPPRESS_ISR) && defined(STM32_UART5_NUMBER)
+ nvicEnableVector(STM32_UART5_NUMBER, STM32_SERIAL_UART5_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_USART6
+ sdObjectInit(&SD6);
+ iqObjectInit(&SD6.iqueue, sd_in_buf6, sizeof sd_in_buf6, NULL, &SD6);
+ oqObjectInit(&SD6.oqueue, sd_out_buf6, sizeof sd_out_buf6, notify6, &SD6);
+ SD6.usart = USART6;
+ SD6.clock = STM32_USART6CLK;
+#if !defined(STM32_USART6_SUPPRESS_ISR) && defined(STM32_USART6_NUMBER)
+ nvicEnableVector(STM32_USART6_NUMBER, STM32_SERIAL_USART6_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART7
+ sdObjectInit(&SD7);
+ iqObjectInit(&SD7.iqueue, sd_in_buf7, sizeof sd_in_buf7, NULL, &SD7);
+ oqObjectInit(&SD7.oqueue, sd_out_buf7, sizeof sd_out_buf7, notify7, &SD7);
+ SD7.usart = UART7;
+ SD7.clock = STM32_UART7CLK;
+#if !defined(STM32_UART7_SUPPRESS_ISR) && defined(STM32_UART7_NUMBER)
+ nvicEnableVector(STM32_UART7_NUMBER, STM32_SERIAL_UART7_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_UART8
+ sdObjectInit(&SD8);
+ iqObjectInit(&SD8.iqueue, sd_in_buf8, sizeof sd_in_buf8, NULL, &SD8);
+ oqObjectInit(&SD8.oqueue, sd_out_buf8, sizeof sd_out_buf8, notify8, &SD8);
+ SD8.usart = UART8;
+ SD8.clock = STM32_UART8CLK;
+#if !defined(STM32_UART8_SUPPRESS_ISR) && defined(STM32_UART8_NUMBER)
+ nvicEnableVector(STM32_UART8_NUMBER, STM32_SERIAL_UART8_PRIORITY);
+#endif
+#endif
+
+#if STM32_SERIAL_USE_LPUART1
+ sdObjectInit(&LPSD1);
+ iqObjectInit(&LPSD1.iqueue, sd_in_buflp1, sizeof sd_in_buflp1, NULL, &LPSD1);
+ oqObjectInit(&LPSD1.oqueue, sd_out_buflp1, sizeof sd_out_buflp1, notifylp1, &LPSD1);
+ LPSD1.usart = LPUART1;
+ LPSD1.clock = STM32_LPUART1CLK;
+#if !defined(STM32_LPUART1_SUPPRESS_ISR) && defined(STM32_LPUART1_NUMBER)
+ nvicEnableVector(STM32_LPUART1_NUMBER, STM32_SERIAL_LPUART1_PRIORITY);
+#endif
+#endif
+}
+
+/**
+ * @brief Low level serial driver configuration and (re)start.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ * @param[in] config the architecture-dependent serial driver configuration.
+ * If this parameter is set to @p NULL then a default
+ * configuration is used.
+ *
+ * @notapi
+ */
+void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
+
+ if (config == NULL)
+ config = &default_config;
+
+ if (sdp->state == SD_STOP) {
+#if STM32_SERIAL_USE_USART1
+ if (&SD1 == sdp) {
+ rccEnableUSART1(true);
+ }
+#endif
+#if STM32_SERIAL_USE_USART2
+ if (&SD2 == sdp) {
+ rccEnableUSART2(true);
+ }
+#endif
+#if STM32_SERIAL_USE_USART3
+ if (&SD3 == sdp) {
+ rccEnableUSART3(true);
+ }
+#endif
+#if STM32_SERIAL_USE_UART4
+ if (&SD4 == sdp) {
+ rccEnableUART4(true);
+ }
+#endif
+#if STM32_SERIAL_USE_UART5
+ if (&SD5 == sdp) {
+ rccEnableUART5(true);
+ }
+#endif
+#if STM32_SERIAL_USE_USART6
+ if (&SD6 == sdp) {
+ rccEnableUSART6(true);
+ }
+#endif
+#if STM32_SERIAL_USE_UART7
+ if (&SD7 == sdp) {
+ rccEnableUART7(true);
+ }
+#endif
+#if STM32_SERIAL_USE_UART8
+ if (&SD8 == sdp) {
+ rccEnableUART8(true);
+ }
+#endif
+#if STM32_SERIAL_USE_LPUART1
+ if (&LPSD1 == sdp) {
+ rccEnableLPUART1(true);
+ }
+#endif
+ }
+ usart_init(sdp, config);
+}
+
+/**
+ * @brief Low level serial driver stop.
+ * @details De-initializes the USART, stops the associated clock, resets the
+ * interrupt vector.
+ *
+ * @param[in] sdp pointer to a @p SerialDriver object
+ *
+ * @notapi
+ */
+void sd_lld_stop(SerialDriver *sdp) {
+
+ if (sdp->state == SD_READY) {
+ /* UART is de-initialized then clocks are disabled.*/
+ usart_deinit(sdp->usart);
+
+#if STM32_SERIAL_USE_USART1
+ if (&SD1 == sdp) {
+ rccDisableUSART1();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_USART2
+ if (&SD2 == sdp) {
+ rccDisableUSART2();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_USART3
+ if (&SD3 == sdp) {
+ rccDisableUSART3();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART4
+ if (&SD4 == sdp) {
+ rccDisableUART4();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART5
+ if (&SD5 == sdp) {
+ rccDisableUART5();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_USART6
+ if (&SD6 == sdp) {
+ rccDisableUSART6();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART7
+ if (&SD7 == sdp) {
+ rccDisableUART7();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_UART8
+ if (&SD8 == sdp) {
+ rccDisableUART8();
+ return;
+ }
+#endif
+#if STM32_SERIAL_USE_LPUART1
+ if (&LPSD1 == sdp) {
+ rccDisableLPUART1();
+ return;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Common IRQ handler.
+ *
+ * @param[in] sdp communication channel associated to the USART
+ */
+void sd_lld_serve_interrupt(SerialDriver *sdp) {
+ USART_TypeDef *u = sdp->usart;
+ uint32_t cr1 = u->CR1;
+ uint32_t isr;
+
+ /* Reading and clearing status.*/
+ isr = u->ISR;
+ u->ICR = isr;
+
+ /* Error condition detection.*/
+ if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE))
+ set_error(sdp, isr);
+
+ /* Special case, LIN break detection.*/
+ if (isr & USART_ISR_LBDF) {
+ osalSysLockFromISR();
+ chnAddFlagsI(sdp, SD_BREAK_DETECTED);
+ osalSysUnlockFromISR();
+ }
+
+ /* Data available, note it is a while in order to handle two situations:
+ 1) Another byte arrived after removing the previous one, this would cause
+ an extra interrupt to serve.
+ 2) FIFO mode is enabled on devices that support it, we need to empty
+ the FIFO.*/
+ while (isr & USART_ISR_RXNE) {
+ osalSysLockFromISR();
+ sdIncomingDataI(sdp, (uint8_t)u->RDR & sdp->rxmask);
+ osalSysUnlockFromISR();
+
+ isr = u->ISR;
+ }
+
+ /* Transmission buffer empty, note it is a while in order to handle two
+ situations:
+ 1) The data registers has been emptied immediately after writing it, this
+ would cause an extra interrupt to serve.
+ 2) FIFO mode is enabled on devices that support it, we need to fill
+ the FIFO.*/
+ if (cr1 & USART_CR1_TXEIE) {
+ while (isr & USART_ISR_TXE) {
+ msg_t b;
+
+ osalSysLockFromISR();
+ b = oqGetI(&sdp->oqueue);
+ if (b < MSG_OK) {
+ chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
+ u->CR1 = cr1 & ~USART_CR1_TXEIE;
+ osalSysUnlockFromISR();
+ break;
+ }
+ u->TDR = b;
+ osalSysUnlockFromISR();
+
+ isr = u->ISR;
+ }
+ }
+
+ /* Physical transmission end.*/
+ if ((cr1 & USART_CR1_TCIE) && (isr & USART_ISR_TC)) {
+ osalSysLockFromISR();
+ if (oqIsEmptyI(&sdp->oqueue)) {
+ chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
+ u->CR1 = cr1 & ~USART_CR1_TCIE;
+ }
+ osalSysUnlockFromISR();
+ }
+}
+
+#endif /* HAL_USE_SERIAL */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h
index 19ee3291c0..2655d7ca26 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h
+++ b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h
@@ -1,534 +1,534 @@
-/*
- 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 USARTv2/hal_serial_lld.h
- * @brief STM32 low level serial driver header.
- *
- * @addtogroup SERIAL
- * @{
- */
-
-#ifndef HAL_SERIAL_LLD_H
-#define HAL_SERIAL_LLD_H
-
-#if HAL_USE_SERIAL || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Advanced buffering support switch.
- * @details This constants enables the advanced buffering support in the
- * low level driver, the queue buffer is no more part of the
- * @p SerialDriver structure, each driver can have a different
- * queue size.
- */
-#define SERIAL_ADVANCED_BUFFERING_SUPPORT TRUE
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief USART1 driver enable switch.
- * @details If set to @p TRUE the support for USART1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART1) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART1 FALSE
-#endif
-
-/**
- * @brief USART2 driver enable switch.
- * @details If set to @p TRUE the support for USART2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART2) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART2 FALSE
-#endif
-
-/**
- * @brief USART3 driver enable switch.
- * @details If set to @p TRUE the support for USART3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART3) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART3 FALSE
-#endif
-
-/**
- * @brief UART4 driver enable switch.
- * @details If set to @p TRUE the support for UART4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART4) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART4 FALSE
-#endif
-
-/**
- * @brief UART5 driver enable switch.
- * @details If set to @p TRUE the support for UART5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART5) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART5 FALSE
-#endif
-
-/**
- * @brief USART6 driver enable switch.
- * @details If set to @p TRUE the support for USART6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_USART6) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_USART6 FALSE
-#endif
-
-/**
- * @brief UART7 driver enable switch.
- * @details If set to @p TRUE the support for UART7 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART7) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART7 FALSE
-#endif
-
-/**
- * @brief UART8 driver enable switch.
- * @details If set to @p TRUE the support for UART8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_UART8) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_UART8 FALSE
-#endif
-
-/**
- * @brief LPUART1 driver enable switch.
- * @details If set to @p TRUE the support for LPUART is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_SERIAL_USE_LPUART1) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USE_LPUART1 FALSE
-#endif
-
-/**
- * @brief USART1 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART1_PRIORITY 12
-#endif
-
-/**
- * @brief USART2 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART2_PRIORITY 12
-#endif
-
-/**
- * @brief USART3 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART3_PRIORITY 12
-#endif
-
-/**
- * @brief UART4 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART4_PRIORITY 12
-#endif
-
-/**
- * @brief UART5 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART5_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART5_PRIORITY 12
-#endif
-
-/**
- * @brief USART6 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART6_PRIORITY 12
-#endif
-
-/**
- * @brief UART7 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART7_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART7_PRIORITY 12
-#endif
-
-/**
- * @brief UART8 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_UART8_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART8_PRIORITY 12
-#endif
-
-/**
- * @brief LPUART1 interrupt priority level setting.
- */
-#if !defined(STM32_SERIAL_LPUART1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_SERIAL_LPUART1_PRIORITY 12
-#endif
-
-/**
- * @brief Input buffer size for USART1.
- */
-#if !defined(STM32_SERIAL_USART1_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART1_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for USART1.
- */
-#if !defined(STM32_SERIAL_USART1_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART1_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for USART2.
- */
-#if !defined(STM32_SERIAL_USART2_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART2_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for USART2.
- */
-#if !defined(STM32_SERIAL_USART2_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART2_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for USART3.
- */
-#if !defined(STM32_SERIAL_USART3_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART3_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for USART3.
- */
-#if !defined(STM32_SERIAL_USART3_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART3_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for UART4.
- */
-#if !defined(STM32_SERIAL_UART4_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART4_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for UART4.
- */
-#if !defined(STM32_SERIAL_UART4_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART4_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for UART5.
- */
-#if !defined(STM32_SERIAL_UART5_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART5_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for UART5.
- */
-#if !defined(STM32_SERIAL_UART5_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART5_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for USART6.
- */
-#if !defined(STM32_SERIAL_USART6_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART6_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for USART6.
- */
-#if !defined(STM32_SERIAL_USART6_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_USART6_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for UART7.
- */
-#if !defined(STM32_SERIAL_UART7_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART7_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for UART7.
- */
-#if !defined(STM32_SERIAL_UART7_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART7_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for UART8.
- */
-#if !defined(STM32_SERIAL_UART8_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART8_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for UART8.
- */
-#if !defined(STM32_SERIAL_UART8_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_UART8_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Input buffer size for LPUART1.
- */
-#if !defined(STM32_SERIAL_LPUART1_IN_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_LPUART1_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-
-/**
- * @brief Output buffer size for LPUART1.
- */
-#if !defined(STM32_SERIAL_LPUART1_OUT_BUF_SIZE) || defined(__DOXYGEN__)
-#define STM32_SERIAL_LPUART1_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_SERIAL_USE_USART1 && !STM32_HAS_USART1
-#error "USART1 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_USART2 && !STM32_HAS_USART2
-#error "USART2 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_USART3 && !STM32_HAS_USART3
-#error "USART3 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART4 && !STM32_HAS_UART4
-#error "UART4 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART5 && !STM32_HAS_UART5
-#error "UART5 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_USART6 && !STM32_HAS_USART6
-#error "USART6 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART7 && !STM32_HAS_UART7
-#error "UART7 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_UART8 && !STM32_HAS_UART8
-#error "UART8 not present in the selected device"
-#endif
-
-#if STM32_SERIAL_USE_LPUART1 && !STM32_HAS_LPUART1
-#error "LPUART1 not present in the selected device"
-#endif
-
-#if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 && \
- !STM32_SERIAL_USE_USART3 && !STM32_SERIAL_USE_UART4 && \
- !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 && \
- !STM32_SERIAL_USE_UART7 && !STM32_SERIAL_USE_UART8 && \
- !STM32_SERIAL_USE_LPUART1
-#error "SERIAL driver activated but no USART/UART peripheral assigned"
-#endif
-
-#if !defined(STM32_USART1_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_USART1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART1_PRIORITY)
-#error "Invalid IRQ priority assigned to USART1"
-#endif
-
-#if !defined(STM32_USART2_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_USART2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART2_PRIORITY)
-#error "Invalid IRQ priority assigned to USART2"
-#endif
-
-#if !defined(STM32_USART3_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_USART3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART3_PRIORITY)
-#error "Invalid IRQ priority assigned to USART3"
-#endif
-
-#if !defined(STM32_UART4_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_UART4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART4_PRIORITY)
-#error "Invalid IRQ priority assigned to UART4"
-#endif
-
-#if !defined(STM32_UART5_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_UART5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART5_PRIORITY)
-#error "Invalid IRQ priority assigned to UART5"
-#endif
-
-#if !defined(STM32_USART6_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_USART6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART6_PRIORITY)
-#error "Invalid IRQ priority assigned to USART6"
-#endif
-
-#if !defined(STM32_UART7_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_UART7 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART7_PRIORITY)
-#error "Invalid IRQ priority assigned to UART7"
-#endif
-
-#if !defined(STM32_UART8_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_UART8 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART8_PRIORITY)
-#error "Invalid IRQ priority assigned to UART8"
-#endif
-
-#if !defined(STM32_LPUART1_SUPPRESS_ISR) && \
- STM32_SERIAL_USE_LPUART1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_LPUART1_PRIORITY)
-#error "Invalid IRQ priority assigned to LPUART1"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief STM32 Serial Driver configuration structure.
- * @details An instance of this structure must be passed to @p sdStart()
- * in order to configure and start a serial driver operations.
- * @note This structure content is architecture dependent, each driver
- * implementation defines its own version and the custom static
- * initializers.
- */
-typedef struct {
- /**
- * @brief Bit rate.
- */
- uint32_t speed;
- /* End of the mandatory fields.*/
- /**
- * @brief Initialization value for the CR1 register.
- */
- uint32_t cr1;
- /**
- * @brief Initialization value for the CR2 register.
- */
- uint32_t cr2;
- /**
- * @brief Initialization value for the CR3 register.
- */
- uint32_t cr3;
-} SerialConfig;
-
-/**
- * @brief @p SerialDriver specific data.
- */
-#define _serial_driver_data \
- _base_asynchronous_channel_data \
- /* Driver state.*/ \
- sdstate_t state; \
- /* Input queue.*/ \
- input_queue_t iqueue; \
- /* Output queue.*/ \
- output_queue_t oqueue; \
- /* End of the mandatory fields.*/ \
- /* Pointer to the USART registers block.*/ \
- USART_TypeDef *usart; \
- /* Clock frequency for the associated USART/UART.*/ \
- uint32_t clock; \
- /* Mask to be applied on received frames.*/ \
- uint8_t rxmask;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*
- * Extra USARTs definitions here (missing from the ST header file).
- */
-#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
-#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
-#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
-#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_SERIAL_USE_USART1 && !defined(__DOXYGEN__)
-extern SerialDriver SD1;
-#endif
-#if STM32_SERIAL_USE_USART2 && !defined(__DOXYGEN__)
-extern SerialDriver SD2;
-#endif
-#if STM32_SERIAL_USE_USART3 && !defined(__DOXYGEN__)
-extern SerialDriver SD3;
-#endif
-#if STM32_SERIAL_USE_UART4 && !defined(__DOXYGEN__)
-extern SerialDriver SD4;
-#endif
-#if STM32_SERIAL_USE_UART5 && !defined(__DOXYGEN__)
-extern SerialDriver SD5;
-#endif
-#if STM32_SERIAL_USE_USART6 && !defined(__DOXYGEN__)
-extern SerialDriver SD6;
-#endif
-#if STM32_SERIAL_USE_UART7 && !defined(__DOXYGEN__)
-extern SerialDriver SD7;
-#endif
-#if STM32_SERIAL_USE_UART8 && !defined(__DOXYGEN__)
-extern SerialDriver SD8;
-#endif
-#if STM32_SERIAL_USE_LPUART1 && !defined(__DOXYGEN__)
-extern SerialDriver LPSD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void sd_lld_init(void);
- void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
- void sd_lld_stop(SerialDriver *sdp);
- void sd_lld_serve_interrupt(SerialDriver *sdp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_SERIAL */
-
-#endif /* HAL_SERIAL_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 USARTv2/hal_serial_lld.h
+ * @brief STM32 low level serial driver header.
+ *
+ * @addtogroup SERIAL
+ * @{
+ */
+
+#ifndef HAL_SERIAL_LLD_H
+#define HAL_SERIAL_LLD_H
+
+#if HAL_USE_SERIAL || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Advanced buffering support switch.
+ * @details This constants enables the advanced buffering support in the
+ * low level driver, the queue buffer is no more part of the
+ * @p SerialDriver structure, each driver can have a different
+ * queue size.
+ */
+#define SERIAL_ADVANCED_BUFFERING_SUPPORT TRUE
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief USART1 driver enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART1) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART1 FALSE
+#endif
+
+/**
+ * @brief USART2 driver enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART2) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART2 FALSE
+#endif
+
+/**
+ * @brief USART3 driver enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART3) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART3 FALSE
+#endif
+
+/**
+ * @brief UART4 driver enable switch.
+ * @details If set to @p TRUE the support for UART4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART4) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART4 FALSE
+#endif
+
+/**
+ * @brief UART5 driver enable switch.
+ * @details If set to @p TRUE the support for UART5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART5) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART5 FALSE
+#endif
+
+/**
+ * @brief USART6 driver enable switch.
+ * @details If set to @p TRUE the support for USART6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_USART6) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_USART6 FALSE
+#endif
+
+/**
+ * @brief UART7 driver enable switch.
+ * @details If set to @p TRUE the support for UART7 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART7) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART7 FALSE
+#endif
+
+/**
+ * @brief UART8 driver enable switch.
+ * @details If set to @p TRUE the support for UART8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_UART8) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_UART8 FALSE
+#endif
+
+/**
+ * @brief LPUART1 driver enable switch.
+ * @details If set to @p TRUE the support for LPUART is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_SERIAL_USE_LPUART1) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USE_LPUART1 FALSE
+#endif
+
+/**
+ * @brief USART1 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART1_PRIORITY 12
+#endif
+
+/**
+ * @brief USART2 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART2_PRIORITY 12
+#endif
+
+/**
+ * @brief USART3 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART3_PRIORITY 12
+#endif
+
+/**
+ * @brief UART4 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART4_PRIORITY 12
+#endif
+
+/**
+ * @brief UART5 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART5_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART5_PRIORITY 12
+#endif
+
+/**
+ * @brief USART6 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_USART6_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART6_PRIORITY 12
+#endif
+
+/**
+ * @brief UART7 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART7_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART7_PRIORITY 12
+#endif
+
+/**
+ * @brief UART8 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_UART8_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART8_PRIORITY 12
+#endif
+
+/**
+ * @brief LPUART1 interrupt priority level setting.
+ */
+#if !defined(STM32_SERIAL_LPUART1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_SERIAL_LPUART1_PRIORITY 12
+#endif
+
+/**
+ * @brief Input buffer size for USART1.
+ */
+#if !defined(STM32_SERIAL_USART1_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART1_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for USART1.
+ */
+#if !defined(STM32_SERIAL_USART1_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART1_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for USART2.
+ */
+#if !defined(STM32_SERIAL_USART2_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART2_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for USART2.
+ */
+#if !defined(STM32_SERIAL_USART2_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART2_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for USART3.
+ */
+#if !defined(STM32_SERIAL_USART3_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART3_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for USART3.
+ */
+#if !defined(STM32_SERIAL_USART3_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART3_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for UART4.
+ */
+#if !defined(STM32_SERIAL_UART4_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART4_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for UART4.
+ */
+#if !defined(STM32_SERIAL_UART4_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART4_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for UART5.
+ */
+#if !defined(STM32_SERIAL_UART5_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART5_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for UART5.
+ */
+#if !defined(STM32_SERIAL_UART5_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART5_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for USART6.
+ */
+#if !defined(STM32_SERIAL_USART6_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART6_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for USART6.
+ */
+#if !defined(STM32_SERIAL_USART6_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_USART6_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for UART7.
+ */
+#if !defined(STM32_SERIAL_UART7_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART7_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for UART7.
+ */
+#if !defined(STM32_SERIAL_UART7_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART7_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for UART8.
+ */
+#if !defined(STM32_SERIAL_UART8_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART8_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for UART8.
+ */
+#if !defined(STM32_SERIAL_UART8_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_UART8_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Input buffer size for LPUART1.
+ */
+#if !defined(STM32_SERIAL_LPUART1_IN_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_LPUART1_IN_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+
+/**
+ * @brief Output buffer size for LPUART1.
+ */
+#if !defined(STM32_SERIAL_LPUART1_OUT_BUF_SIZE) || defined(__DOXYGEN__)
+#define STM32_SERIAL_LPUART1_OUT_BUF_SIZE SERIAL_BUFFERS_SIZE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_SERIAL_USE_USART1 && !STM32_HAS_USART1
+#error "USART1 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_USART2 && !STM32_HAS_USART2
+#error "USART2 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_USART3 && !STM32_HAS_USART3
+#error "USART3 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART4 && !STM32_HAS_UART4
+#error "UART4 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART5 && !STM32_HAS_UART5
+#error "UART5 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_USART6 && !STM32_HAS_USART6
+#error "USART6 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART7 && !STM32_HAS_UART7
+#error "UART7 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_UART8 && !STM32_HAS_UART8
+#error "UART8 not present in the selected device"
+#endif
+
+#if STM32_SERIAL_USE_LPUART1 && !STM32_HAS_LPUART1
+#error "LPUART1 not present in the selected device"
+#endif
+
+#if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 && \
+ !STM32_SERIAL_USE_USART3 && !STM32_SERIAL_USE_UART4 && \
+ !STM32_SERIAL_USE_UART5 && !STM32_SERIAL_USE_USART6 && \
+ !STM32_SERIAL_USE_UART7 && !STM32_SERIAL_USE_UART8 && \
+ !STM32_SERIAL_USE_LPUART1
+#error "SERIAL driver activated but no USART/UART peripheral assigned"
+#endif
+
+#if !defined(STM32_USART1_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_USART1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART1_PRIORITY)
+#error "Invalid IRQ priority assigned to USART1"
+#endif
+
+#if !defined(STM32_USART2_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_USART2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART2_PRIORITY)
+#error "Invalid IRQ priority assigned to USART2"
+#endif
+
+#if !defined(STM32_USART3_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_USART3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART3_PRIORITY)
+#error "Invalid IRQ priority assigned to USART3"
+#endif
+
+#if !defined(STM32_UART4_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_UART4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART4_PRIORITY)
+#error "Invalid IRQ priority assigned to UART4"
+#endif
+
+#if !defined(STM32_UART5_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_UART5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART5_PRIORITY)
+#error "Invalid IRQ priority assigned to UART5"
+#endif
+
+#if !defined(STM32_USART6_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_USART6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_USART6_PRIORITY)
+#error "Invalid IRQ priority assigned to USART6"
+#endif
+
+#if !defined(STM32_UART7_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_UART7 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART7_PRIORITY)
+#error "Invalid IRQ priority assigned to UART7"
+#endif
+
+#if !defined(STM32_UART8_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_UART8 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_UART8_PRIORITY)
+#error "Invalid IRQ priority assigned to UART8"
+#endif
+
+#if !defined(STM32_LPUART1_SUPPRESS_ISR) && \
+ STM32_SERIAL_USE_LPUART1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_SERIAL_LPUART1_PRIORITY)
+#error "Invalid IRQ priority assigned to LPUART1"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief STM32 Serial Driver configuration structure.
+ * @details An instance of this structure must be passed to @p sdStart()
+ * in order to configure and start a serial driver operations.
+ * @note This structure content is architecture dependent, each driver
+ * implementation defines its own version and the custom static
+ * initializers.
+ */
+typedef struct {
+ /**
+ * @brief Bit rate.
+ */
+ uint32_t speed;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Initialization value for the CR1 register.
+ */
+ uint32_t cr1;
+ /**
+ * @brief Initialization value for the CR2 register.
+ */
+ uint32_t cr2;
+ /**
+ * @brief Initialization value for the CR3 register.
+ */
+ uint32_t cr3;
+} SerialConfig;
+
+/**
+ * @brief @p SerialDriver specific data.
+ */
+#define _serial_driver_data \
+ _base_asynchronous_channel_data \
+ /* Driver state.*/ \
+ sdstate_t state; \
+ /* Input queue.*/ \
+ input_queue_t iqueue; \
+ /* Output queue.*/ \
+ output_queue_t oqueue; \
+ /* End of the mandatory fields.*/ \
+ /* Pointer to the USART registers block.*/ \
+ USART_TypeDef *usart; \
+ /* Clock frequency for the associated USART/UART.*/ \
+ uint32_t clock; \
+ /* Mask to be applied on received frames.*/ \
+ uint8_t rxmask;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*
+ * Extra USARTs definitions here (missing from the ST header file).
+ */
+#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
+#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
+#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
+#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_SERIAL_USE_USART1 && !defined(__DOXYGEN__)
+extern SerialDriver SD1;
+#endif
+#if STM32_SERIAL_USE_USART2 && !defined(__DOXYGEN__)
+extern SerialDriver SD2;
+#endif
+#if STM32_SERIAL_USE_USART3 && !defined(__DOXYGEN__)
+extern SerialDriver SD3;
+#endif
+#if STM32_SERIAL_USE_UART4 && !defined(__DOXYGEN__)
+extern SerialDriver SD4;
+#endif
+#if STM32_SERIAL_USE_UART5 && !defined(__DOXYGEN__)
+extern SerialDriver SD5;
+#endif
+#if STM32_SERIAL_USE_USART6 && !defined(__DOXYGEN__)
+extern SerialDriver SD6;
+#endif
+#if STM32_SERIAL_USE_UART7 && !defined(__DOXYGEN__)
+extern SerialDriver SD7;
+#endif
+#if STM32_SERIAL_USE_UART8 && !defined(__DOXYGEN__)
+extern SerialDriver SD8;
+#endif
+#if STM32_SERIAL_USE_LPUART1 && !defined(__DOXYGEN__)
+extern SerialDriver LPSD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void sd_lld_init(void);
+ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
+ void sd_lld_stop(SerialDriver *sdp);
+ void sd_lld_serve_interrupt(SerialDriver *sdp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_SERIAL */
+
+#endif /* HAL_SERIAL_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
index 37877168aa..d28bc0e129 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.c
@@ -1,1075 +1,1075 @@
-/*
- 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 USARTv2/hal_uart_lld.c
- * @brief STM32 low level UART driver code.
- *
- * @addtogroup UART
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_UART || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/* For compatibility for those devices without LIN support in the USARTs.*/
-#if !defined(USART_ISR_LBDF)
-#define USART_ISR_LBDF 0
-#endif
-
-#if !defined(USART_CR2_LBDIE)
-#define USART_CR2_LBDIE 0
-#endif
-
-/* STM32L0xx/STM32F7xx ST headers difference.*/
-#if !defined(USART_ISR_LBDF)
-#define USART_ISR_LBDF USART_ISR_LBD
-#endif
-
-/* STM32L0xx/STM32F7xx ST headers difference.*/
-#if !defined(USART_ISR_LBDF)
-#define USART_ISR_LBDF USART_ISR_LBD
-#endif
-
-#define USART1_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART1_RX_DMA_STREAM, \
- STM32_USART1_RX_DMA_CHN)
-
-#define USART1_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART1_TX_DMA_STREAM, \
- STM32_USART1_TX_DMA_CHN)
-
-#define USART2_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART2_RX_DMA_STREAM, \
- STM32_USART2_RX_DMA_CHN)
-
-#define USART2_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART2_TX_DMA_STREAM, \
- STM32_USART2_TX_DMA_CHN)
-
-#define USART3_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART3_RX_DMA_STREAM, \
- STM32_USART3_RX_DMA_CHN)
-
-#define USART3_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM, \
- STM32_USART3_TX_DMA_CHN)
-
-#define UART4_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART4_RX_DMA_STREAM, \
- STM32_UART4_RX_DMA_CHN)
-
-#define UART4_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART4_TX_DMA_STREAM, \
- STM32_UART4_TX_DMA_CHN)
-
-#define UART5_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART5_RX_DMA_STREAM, \
- STM32_UART5_RX_DMA_CHN)
-
-#define UART5_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART5_TX_DMA_STREAM, \
- STM32_UART5_TX_DMA_CHN)
-
-#define USART6_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART6_RX_DMA_STREAM, \
- STM32_USART6_RX_DMA_CHN)
-
-#define USART6_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_USART6_TX_DMA_STREAM, \
- STM32_USART6_TX_DMA_CHN)
-
-#define UART7_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART7_RX_DMA_STREAM, \
- STM32_UART7_RX_DMA_CHN)
-
-#define UART7_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART7_TX_DMA_STREAM, \
- STM32_UART7_TX_DMA_CHN)
-
-#define UART8_RX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART8_RX_DMA_STREAM, \
- STM32_UART8_RX_DMA_CHN)
-
-#define UART8_TX_DMA_CHANNEL \
- STM32_DMA_GETCHANNEL(STM32_UART_UART8_TX_DMA_STREAM, \
- STM32_UART8_TX_DMA_CHN)
-
-/* Workarounds for those devices where UARTs are USARTs.*/
-#if defined(USART4)
-#define UART4 USART4
-#endif
-#if defined(USART5)
-#define UART5 USART5
-#endif
-#if defined(USART7)
-#define UART7 USART7
-#endif
-#if defined(USART8)
-#define UART8 USART8
-#endif
-
-/* Workaround for more differences in headers.*/
-#if !defined(USART_CR1_M0)
-#define USART_CR1_M0 USART_CR1_M
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief USART1 UART driver identifier.*/
-#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
-UARTDriver UARTD1;
-#endif
-
-/** @brief USART2 UART driver identifier.*/
-#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
-UARTDriver UARTD2;
-#endif
-
-/** @brief USART3 UART driver identifier.*/
-#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
-UARTDriver UARTD3;
-#endif
-
-/** @brief UART4 UART driver identifier.*/
-#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
-UARTDriver UARTD4;
-#endif
-
-/** @brief UART5 UART driver identifier.*/
-#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
-UARTDriver UARTD5;
-#endif
-
-/** @brief USART6 UART driver identifier.*/
-#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
-UARTDriver UARTD6;
-#endif
-
-/** @brief UART7 UART driver identifier.*/
-#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
-UARTDriver UARTD7;
-#endif
-
-/** @brief UART8 UART driver identifier.*/
-#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
-UARTDriver UARTD8;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Status bits translation.
- *
- * @param[in] isr USART SR register value
- *
- * @return The error flags.
- */
-static uartflags_t translate_errors(uint32_t isr) {
- uartflags_t sts = 0;
-
- if (isr & USART_ISR_ORE)
- sts |= UART_OVERRUN_ERROR;
- if (isr & USART_ISR_PE)
- sts |= UART_PARITY_ERROR;
- if (isr & USART_ISR_FE)
- sts |= UART_FRAMING_ERROR;
- if (isr & USART_ISR_NE)
- sts |= UART_NOISE_ERROR;
- if (isr & USART_ISR_LBDF)
- sts |= UART_BREAK_DETECTED;
- return sts;
-}
-
-/**
- * @brief Puts the receiver in the UART_RX_IDLE state.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void uart_enter_rx_idle_loop(UARTDriver *uartp) {
- uint32_t mode;
-
- /* RX DMA channel preparation, if the char callback is defined then the
- TCIE interrupt is enabled too.*/
- if (uartp->config->rxchar_cb == NULL)
- mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC;
- else
- mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TCIE;
- dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf);
- dmaStreamSetTransactionSize(uartp->dmarx, 1);
- dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
- dmaStreamEnable(uartp->dmarx);
-}
-
-/**
- * @brief USART de-initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void usart_stop(UARTDriver *uartp) {
-
- /* Stops RX and TX DMA channels.*/
- dmaStreamDisable(uartp->dmarx);
- dmaStreamDisable(uartp->dmatx);
-
- /* Stops USART operations.*/
- uartp->usart->CR1 = 0;
- uartp->usart->CR2 = 0;
- uartp->usart->CR3 = 0;
-}
-
-/**
- * @brief USART initialization.
- * @details This function must be invoked with interrupts disabled.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-static void usart_start(UARTDriver *uartp) {
- uint32_t fck;
- uint32_t cr1;
- const uint32_t tmo = uartp->config->timeout;
- USART_TypeDef *u = uartp->usart;
-
- /* Defensive programming, starting from a clean state.*/
- usart_stop(uartp);
-
- /* Baud rate setting.*/
- fck = (uint32_t)(uartp->clock / uartp->config->speed);
-
- /* Correcting USARTDIV when oversampling by 8 instead of 16.
- Fraction is still 4 bits wide, but only lower 3 bits used.
- Mantissa is doubled, but Fraction is left the same.*/
- if (uartp->config->cr1 & USART_CR1_OVER8)
- fck = ((fck & ~7) * 2) | (fck & 7);
- u->BRR = fck;
-
- /* Resetting eventual pending status flags.*/
- u->ICR = 0xFFFFFFFFU;
-
- /* Note that some bits are enforced because required for correct driver
- operations.*/
- u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
- u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
- USART_CR3_EIE;
-
- /* Mustn't ever set TCIE here - if done, it causes an immediate
- interrupt.*/
- cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
- u->CR1 = uartp->config->cr1 | cr1;
-
- /* Set receive timeout and checks if it is really applied.*/
- if (tmo > 0) {
- osalDbgAssert(tmo <= USART_RTOR_RTO, "Timeout overflow");
- u->RTOR = tmo;
- osalDbgAssert(tmo == u->RTOR, "Timeout feature unsupported in this UART");
- }
-
- /* Starting the receiver idle loop.*/
- uart_enter_rx_idle_loop(uartp);
-}
-
-/**
- * @brief RX DMA common service routine.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_UART_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_UART_DMA_ERROR_HOOK(uartp);
- }
-#else
- (void)flags;
-#endif
-
- if (uartp->rxstate == UART_RX_IDLE) {
- /* Receiver in idle state, a callback is generated, if enabled, for each
- received character and then the driver stays in the same state.*/
- _uart_rx_idle_code(uartp);
- }
- else {
- /* Receiver in active state, a callback is generated, if enabled, after
- a completed transfer.*/
- dmaStreamDisable(uartp->dmarx);
- _uart_rx_complete_isr_code(uartp);
- }
-}
-
-/**
- * @brief TX DMA common service routine.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
-
- /* DMA errors handling.*/
-#if defined(STM32_UART_DMA_ERROR_HOOK)
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- STM32_UART_DMA_ERROR_HOOK(uartp);
- }
-#else
- (void)flags;
-#endif
-
- dmaStreamDisable(uartp->dmatx);
-
- /* A callback is generated, if enabled, after a completed transfer.*/
- _uart_tx1_isr_code(uartp);
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
-#if !defined(STM32_USART1_SUPPRESS_ISR)
-#if !defined(STM32_USART1_HANDLER)
-#error "STM32_USART1_HANDLER not defined"
-#endif
-/**
- * @brief USART1 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
-#if !defined(STM32_USART2_SUPPRESS_ISR)
-#if !defined(STM32_USART2_HANDLER)
-#error "STM32_USART2_HANDLER not defined"
-#endif
-/**
- * @brief USART2 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD2);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
-#if !defined(STM32_USART3_SUPPRESS_ISR)
-#if !defined(STM32_USART3_HANDLER)
-#error "STM32_USART3_HANDLER not defined"
-#endif
-/**
- * @brief USART3 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
-#if !defined(STM32_UART4_SUPPRESS_ISR)
-#if !defined(STM32_UART4_HANDLER)
-#error "STM32_UART4_HANDLER not defined"
-#endif
-/**
- * @brief UART4 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD4);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
-#if !defined(STM32_UART5_SUPPRESS_ISR)
-#if !defined(STM32_UART5_HANDLER)
-#error "STM32_UART5_HANDLER not defined"
-#endif
-/**
- * @brief UART5 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD5);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
-#if !defined(STM32_USART6_SUPPRESS_ISR)
-#if !defined(STM32_USART6_HANDLER)
-#error "STM32_USART6_HANDLER not defined"
-#endif
-/**
- * @brief USART6 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD6);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
-#if !defined(STM32_UART7_SUPPRESS_ISR)
-#if !defined(STM32_UART7_HANDLER)
-#error "STM32_UART7_HANDLER not defined"
-#endif
-/**
- * @brief UART7 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD7);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
-#if !defined(STM32_UART8_SUPPRESS_ISR)
-#if !defined(STM32_UART8_HANDLER)
-#error "STM32_UART8_HANDLER not defined"
-#endif
-/**
- * @brief UART8 IRQ handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
- uart_lld_serve_interrupt(&UARTD8);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level UART driver initialization.
- *
- * @notapi
- */
-void uart_lld_init(void) {
-
-#if STM32_UART_USE_USART1
- uartObjectInit(&UARTD1);
- UARTD1.usart = USART1;
- UARTD1.clock = STM32_USART1CLK;
- UARTD1.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD1.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD1.dmarx = NULL;
- UARTD1.dmatx = NULL;
-#if !defined(STM32_USART1_SUPPRESS_ISR) && defined(STM32_USART1_NUMBER)
- nvicEnableVector(STM32_USART1_NUMBER, STM32_UART_USART1_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_USART2
- uartObjectInit(&UARTD2);
- UARTD2.usart = USART2;
- UARTD2.clock = STM32_USART2CLK;
- UARTD2.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD2.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD2.dmarx = NULL;
- UARTD2.dmatx = NULL;
-#if !defined(STM32_USART2_SUPPRESS_ISR) && defined(STM32_USART2_NUMBER)
- nvicEnableVector(STM32_USART2_NUMBER, STM32_UART_USART2_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_USART3
- uartObjectInit(&UARTD3);
- UARTD3.usart = USART3;
- UARTD3.clock = STM32_USART3CLK;
- UARTD3.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD3.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD3.dmarx = NULL;
- UARTD3.dmatx = NULL;
-#if !defined(STM32_USART3_SUPPRESS_ISR) && defined(STM32_USART3_NUMBER)
- nvicEnableVector(STM32_USART3_NUMBER, STM32_UART_USART3_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_UART4
- uartObjectInit(&UARTD4);
- UARTD4.usart = UART4;
- UARTD4.clock = STM32_UART4CLK;
- UARTD4.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD4.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD4.dmarx = NULL;
- UARTD4.dmatx = NULL;
-#if !defined(STM32_UART4_SUPPRESS_ISR) && defined(STM32_UART4_NUMBER)
- nvicEnableVector(STM32_UART4_NUMBER, STM32_UART_UART4_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_UART5
- uartObjectInit(&UARTD5);
- UARTD5.usart = UART5;
- UARTD5.clock = STM32_UART5CLK;
- UARTD5.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD5.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD5.dmarx = NULL;
- UARTD5.dmatx = NULL;
-#if !defined(STM32_UART5_SUPPRESS_ISR) && defined(STM32_UART5_NUMBER)
- nvicEnableVector(STM32_UART5_NUMBER, STM32_UART_UART5_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_USART6
- uartObjectInit(&UARTD6);
- UARTD6.usart = USART6;
- UARTD6.clock = STM32_USART6CLK;
- UARTD6.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD6.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD6.dmarx = NULL;
- UARTD6.dmatx = NULL;
-#if !defined(STM32_USART6_SUPPRESS_ISR) && defined(STM32_USART6_NUMBER)
- nvicEnableVector(STM32_USART6_NUMBER, STM32_UART_USART6_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_UART7
- uartObjectInit(&UARTD7);
- UARTD7.usart = UART7;
- UARTD7.clock = STM32_UART7CLK;
- UARTD7.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD7.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD7.dmarx = NULL;
- UARTD7.dmatx = NULL;
-#if !defined(STM32_UART7_SUPPRESS_ISR) && defined(STM32_UART7_NUMBER)
- nvicEnableVector(STM32_UART7_NUMBER, STM32_UART_UART7_IRQ_PRIORITY);
-#endif
-#endif
-
-#if STM32_UART_USE_UART8
- uartObjectInit(&UARTD8);
- UARTD8.usart = UART8;
- UARTD8.clock = STM32_UART8CLK;
- UARTD8.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD8.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- UARTD8.dmarx = NULL;
- UARTD8.dmatx = NULL;
-#if !defined(STM32_UART8_SUPPRESS_ISR) && defined(STM32_UART8_NUMBER)
- nvicEnableVector(STM32_UART8_NUMBER, STM32_UART_UART8_IRQ_PRIORITY);
-#endif
-#endif
-}
-
-/**
- * @brief Configures and activates the UART peripheral.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @notapi
- */
-void uart_lld_start(UARTDriver *uartp) {
-
- if (uartp->state == UART_STOP) {
-#if STM32_UART_USE_USART1
- if (&UARTD1 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART1_RX_DMA_STREAM,
- STM32_UART_USART1_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART1_TX_DMA_STREAM,
- STM32_UART_USART1_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART1(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART1_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART1_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART1_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_USART2
- if (&UARTD2 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART2_RX_DMA_STREAM,
- STM32_UART_USART2_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART2_TX_DMA_STREAM,
- STM32_UART_USART2_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART2(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART2_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART2_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART2_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_USART3
- if (&UARTD3 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART3_RX_DMA_STREAM,
- STM32_UART_USART3_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART3_TX_DMA_STREAM,
- STM32_UART_USART3_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART3(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART3_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART3_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART3_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_UART4
- if (&UARTD4 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART4_RX_DMA_STREAM,
- STM32_UART_UART4_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART4_TX_DMA_STREAM,
- STM32_UART_UART4_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART4(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART4_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART4_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART4_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_UART5
- if (&UARTD5 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART5_RX_DMA_STREAM,
- STM32_UART_UART5_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART5_TX_DMA_STREAM,
- STM32_UART_UART5_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART5(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART5_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART5_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART5_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_USART6
- if (&UARTD6 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_USART6_RX_DMA_STREAM,
- STM32_UART_USART6_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_USART6_TX_DMA_STREAM,
- STM32_UART_USART6_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUSART6(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART6_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART6_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART6_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_UART7
- if (&UARTD7 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART7_RX_DMA_STREAM,
- STM32_UART_UART7_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART7_TX_DMA_STREAM,
- STM32_UART_UART7_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART7(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART7_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART7_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART7_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART7_TX);
-#endif
- }
-#endif
-
-#if STM32_UART_USE_UART8
- if (&UARTD8 == uartp) {
- uartp->dmarx = dmaStreamAllocI(STM32_UART_UART8_RX_DMA_STREAM,
- STM32_UART_UART8_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
- uartp->dmatx = dmaStreamAllocI(STM32_UART_UART8_TX_DMA_STREAM,
- STM32_UART_UART8_IRQ_PRIORITY,
- (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
- (void *)uartp);
- osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
-
- rccEnableUART8(true);
- uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART8_RX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
- uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART8_TX_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
-#if STM32_DMA_SUPPORTS_DMAMUX
- dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART8_RX);
- dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART8_TX);
-#endif
- }
-#endif
-
- /* Static DMA setup, the transfer size depends on the USART settings,
- it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
- if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M0) {
- uartp->dmarxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- uartp->dmatxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
- }
- dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->RDR);
- dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->TDR);
- uartp->rxbuf = 0;
- }
-
- uartp->rxstate = UART_RX_IDLE;
- uartp->txstate = UART_TX_IDLE;
- usart_start(uartp);
-}
-
-/**
- * @brief Deactivates the UART peripheral.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @notapi
- */
-void uart_lld_stop(UARTDriver *uartp) {
-
- if (uartp->state == UART_READY) {
- usart_stop(uartp);
- dmaStreamFreeI(uartp->dmarx);
- dmaStreamFreeI(uartp->dmatx);
- uartp->dmarx = NULL;
- uartp->dmatx = NULL;
-
-#if STM32_UART_USE_USART1
- if (&UARTD1 == uartp) {
- rccDisableUSART1();
- return;
- }
-#endif
-
-#if STM32_UART_USE_USART2
- if (&UARTD2 == uartp) {
- rccDisableUSART2();
- return;
- }
-#endif
-
-#if STM32_UART_USE_USART3
- if (&UARTD3 == uartp) {
- rccDisableUSART3();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART4
- if (&UARTD4 == uartp) {
- rccDisableUART4();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART5
- if (&UARTD5 == uartp) {
- rccDisableUART5();
- return;
- }
-#endif
-
-#if STM32_UART_USE_USART6
- if (&UARTD6 == uartp) {
- rccDisableUSART6();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART7
- if (&UARTD7 == uartp) {
- rccDisableUART7();
- return;
- }
-#endif
-
-#if STM32_UART_USE_UART8
- if (&UARTD8 == uartp) {
- rccDisableUART8();
- return;
- }
-#endif
- }
-}
-
-/**
- * @brief Starts a transmission on the UART peripheral.
- * @note The buffers are organized as uint8_t arrays for data sizes below
- * or equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] n number of data frames to send
- * @param[in] txbuf the pointer to the transmit buffer
- *
- * @notapi
- */
-void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
-
- /* TX DMA channel preparation.*/
- dmaStreamSetMemory0(uartp->dmatx, txbuf);
- dmaStreamSetTransactionSize(uartp->dmatx, n);
- dmaStreamSetMode(uartp->dmatx, uartp->dmatxmode | STM32_DMA_CR_DIR_M2P |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
-
- /* Only enable TC interrupt if there's a callback attached to it or
- if called from uartSendFullTimeout(). Also we need to clear TC flag
- which could be set before.*/
-#if UART_USE_WAIT == TRUE
- if ((uartp->config->txend2_cb != NULL) || (uartp->early == false)) {
-#else
- if (uartp->config->txend2_cb != NULL) {
-#endif
- uartp->usart->ICR = USART_ICR_TCCF;
- uartp->usart->CR1 |= USART_CR1_TCIE;
- }
-
- /* Starting transfer.*/
- dmaStreamEnable(uartp->dmatx);
-}
-
-/**
- * @brief Stops any ongoing transmission.
- * @note Stopping a transmission also suppresses the transmission callbacks.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @return The number of data frames not transmitted by the
- * stopped transmit operation.
- *
- * @notapi
- */
-size_t uart_lld_stop_send(UARTDriver *uartp) {
-
- dmaStreamDisable(uartp->dmatx);
-
- return dmaStreamGetTransactionSize(uartp->dmatx);
-}
-
-/**
- * @brief Starts a receive operation on the UART peripheral.
- * @note The buffers are organized as uint8_t arrays for data sizes below
- * or equal to 8 bits else it is organized as uint16_t arrays.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] n number of data frames to send
- * @param[out] rxbuf the pointer to the receive buffer
- *
- * @notapi
- */
-void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
-
- /* Stopping previous activity (idle state).*/
- dmaStreamDisable(uartp->dmarx);
-
- /* RX DMA channel preparation.*/
- dmaStreamSetMemory0(uartp->dmarx, rxbuf);
- dmaStreamSetTransactionSize(uartp->dmarx, n);
- dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
-
- /* Starting transfer.*/
- dmaStreamEnable(uartp->dmarx);
-}
-
-/**
- * @brief Stops any ongoing receive operation.
- * @note Stopping a receive operation also suppresses the receive callbacks.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- *
- * @return The number of data frames not received by the
- * stopped receive operation.
- *
- * @notapi
- */
-size_t uart_lld_stop_receive(UARTDriver *uartp) {
- size_t n;
-
- dmaStreamDisable(uartp->dmarx);
- n = dmaStreamGetTransactionSize(uartp->dmarx);
- uart_enter_rx_idle_loop(uartp);
-
- return n;
-}
-
-/**
- * @brief USART common service routine.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-void uart_lld_serve_interrupt(UARTDriver *uartp) {
- uint32_t isr;
- USART_TypeDef *u = uartp->usart;
- uint32_t cr1 = u->CR1;
-
- /* Reading and clearing status.*/
- isr = u->ISR;
- u->ICR = isr;
-
- if (isr & (USART_ISR_LBDF | USART_ISR_ORE | USART_ISR_NE |
- USART_ISR_FE | USART_ISR_PE)) {
- _uart_rx_error_isr_code(uartp, translate_errors(isr));
- }
-
- if ((isr & USART_ISR_TC) && (cr1 & USART_CR1_TCIE)) {
- /* TC interrupt disabled.*/
- u->CR1 = cr1 & ~USART_CR1_TCIE;
-
- /* End of transmission, a callback is generated.*/
- _uart_tx2_isr_code(uartp);
- }
-
- /* Timeout interrupt sources are only checked if enabled in CR1.*/
- if (((cr1 & USART_CR1_IDLEIE) && (isr & USART_ISR_IDLE)) ||
- ((cr1 & USART_CR1_RTOIE) && (isr & USART_ISR_RTOF))) {
- _uart_timeout_isr_code(uartp);
- }
-}
-
-#endif /* HAL_USE_UART */
-
-/** @} */
+/*
+ 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 USARTv2/hal_uart_lld.c
+ * @brief STM32 low level UART driver code.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/* For compatibility for those devices without LIN support in the USARTs.*/
+#if !defined(USART_ISR_LBDF)
+#define USART_ISR_LBDF 0
+#endif
+
+#if !defined(USART_CR2_LBDIE)
+#define USART_CR2_LBDIE 0
+#endif
+
+/* STM32L0xx/STM32F7xx ST headers difference.*/
+#if !defined(USART_ISR_LBDF)
+#define USART_ISR_LBDF USART_ISR_LBD
+#endif
+
+/* STM32L0xx/STM32F7xx ST headers difference.*/
+#if !defined(USART_ISR_LBDF)
+#define USART_ISR_LBDF USART_ISR_LBD
+#endif
+
+#define USART1_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART1_RX_DMA_STREAM, \
+ STM32_USART1_RX_DMA_CHN)
+
+#define USART1_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART1_TX_DMA_STREAM, \
+ STM32_USART1_TX_DMA_CHN)
+
+#define USART2_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART2_RX_DMA_STREAM, \
+ STM32_USART2_RX_DMA_CHN)
+
+#define USART2_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART2_TX_DMA_STREAM, \
+ STM32_USART2_TX_DMA_CHN)
+
+#define USART3_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART3_RX_DMA_STREAM, \
+ STM32_USART3_RX_DMA_CHN)
+
+#define USART3_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART3_TX_DMA_STREAM, \
+ STM32_USART3_TX_DMA_CHN)
+
+#define UART4_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART4_RX_DMA_STREAM, \
+ STM32_UART4_RX_DMA_CHN)
+
+#define UART4_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART4_TX_DMA_STREAM, \
+ STM32_UART4_TX_DMA_CHN)
+
+#define UART5_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART5_RX_DMA_STREAM, \
+ STM32_UART5_RX_DMA_CHN)
+
+#define UART5_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART5_TX_DMA_STREAM, \
+ STM32_UART5_TX_DMA_CHN)
+
+#define USART6_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART6_RX_DMA_STREAM, \
+ STM32_USART6_RX_DMA_CHN)
+
+#define USART6_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_USART6_TX_DMA_STREAM, \
+ STM32_USART6_TX_DMA_CHN)
+
+#define UART7_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART7_RX_DMA_STREAM, \
+ STM32_UART7_RX_DMA_CHN)
+
+#define UART7_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART7_TX_DMA_STREAM, \
+ STM32_UART7_TX_DMA_CHN)
+
+#define UART8_RX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART8_RX_DMA_STREAM, \
+ STM32_UART8_RX_DMA_CHN)
+
+#define UART8_TX_DMA_CHANNEL \
+ STM32_DMA_GETCHANNEL(STM32_UART_UART8_TX_DMA_STREAM, \
+ STM32_UART8_TX_DMA_CHN)
+
+/* Workarounds for those devices where UARTs are USARTs.*/
+#if defined(USART4)
+#define UART4 USART4
+#endif
+#if defined(USART5)
+#define UART5 USART5
+#endif
+#if defined(USART7)
+#define UART7 USART7
+#endif
+#if defined(USART8)
+#define UART8 USART8
+#endif
+
+/* Workaround for more differences in headers.*/
+#if !defined(USART_CR1_M0)
+#define USART_CR1_M0 USART_CR1_M
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief USART1 UART driver identifier.*/
+#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
+UARTDriver UARTD1;
+#endif
+
+/** @brief USART2 UART driver identifier.*/
+#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
+UARTDriver UARTD2;
+#endif
+
+/** @brief USART3 UART driver identifier.*/
+#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
+UARTDriver UARTD3;
+#endif
+
+/** @brief UART4 UART driver identifier.*/
+#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
+UARTDriver UARTD4;
+#endif
+
+/** @brief UART5 UART driver identifier.*/
+#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
+UARTDriver UARTD5;
+#endif
+
+/** @brief USART6 UART driver identifier.*/
+#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
+UARTDriver UARTD6;
+#endif
+
+/** @brief UART7 UART driver identifier.*/
+#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
+UARTDriver UARTD7;
+#endif
+
+/** @brief UART8 UART driver identifier.*/
+#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
+UARTDriver UARTD8;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Status bits translation.
+ *
+ * @param[in] isr USART SR register value
+ *
+ * @return The error flags.
+ */
+static uartflags_t translate_errors(uint32_t isr) {
+ uartflags_t sts = 0;
+
+ if (isr & USART_ISR_ORE)
+ sts |= UART_OVERRUN_ERROR;
+ if (isr & USART_ISR_PE)
+ sts |= UART_PARITY_ERROR;
+ if (isr & USART_ISR_FE)
+ sts |= UART_FRAMING_ERROR;
+ if (isr & USART_ISR_NE)
+ sts |= UART_NOISE_ERROR;
+ if (isr & USART_ISR_LBDF)
+ sts |= UART_BREAK_DETECTED;
+ return sts;
+}
+
+/**
+ * @brief Puts the receiver in the UART_RX_IDLE state.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void uart_enter_rx_idle_loop(UARTDriver *uartp) {
+ uint32_t mode;
+
+ /* RX DMA channel preparation, if the char callback is defined then the
+ TCIE interrupt is enabled too.*/
+ if (uartp->config->rxchar_cb == NULL)
+ mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC;
+ else
+ mode = STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_CIRC | STM32_DMA_CR_TCIE;
+ dmaStreamSetMemory0(uartp->dmarx, &uartp->rxbuf);
+ dmaStreamSetTransactionSize(uartp->dmarx, 1);
+ dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | mode);
+ dmaStreamEnable(uartp->dmarx);
+}
+
+/**
+ * @brief USART de-initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_stop(UARTDriver *uartp) {
+
+ /* Stops RX and TX DMA channels.*/
+ dmaStreamDisable(uartp->dmarx);
+ dmaStreamDisable(uartp->dmatx);
+
+ /* Stops USART operations.*/
+ uartp->usart->CR1 = 0;
+ uartp->usart->CR2 = 0;
+ uartp->usart->CR3 = 0;
+}
+
+/**
+ * @brief USART initialization.
+ * @details This function must be invoked with interrupts disabled.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+static void usart_start(UARTDriver *uartp) {
+ uint32_t fck;
+ uint32_t cr1;
+ const uint32_t tmo = uartp->config->timeout;
+ USART_TypeDef *u = uartp->usart;
+
+ /* Defensive programming, starting from a clean state.*/
+ usart_stop(uartp);
+
+ /* Baud rate setting.*/
+ fck = (uint32_t)(uartp->clock / uartp->config->speed);
+
+ /* Correcting USARTDIV when oversampling by 8 instead of 16.
+ Fraction is still 4 bits wide, but only lower 3 bits used.
+ Mantissa is doubled, but Fraction is left the same.*/
+ if (uartp->config->cr1 & USART_CR1_OVER8)
+ fck = ((fck & ~7) * 2) | (fck & 7);
+ u->BRR = fck;
+
+ /* Resetting eventual pending status flags.*/
+ u->ICR = 0xFFFFFFFFU;
+
+ /* Note that some bits are enforced because required for correct driver
+ operations.*/
+ u->CR2 = uartp->config->cr2 | USART_CR2_LBDIE;
+ u->CR3 = uartp->config->cr3 | USART_CR3_DMAT | USART_CR3_DMAR |
+ USART_CR3_EIE;
+
+ /* Mustn't ever set TCIE here - if done, it causes an immediate
+ interrupt.*/
+ cr1 = USART_CR1_UE | USART_CR1_PEIE | USART_CR1_TE | USART_CR1_RE;
+ u->CR1 = uartp->config->cr1 | cr1;
+
+ /* Set receive timeout and checks if it is really applied.*/
+ if (tmo > 0) {
+ osalDbgAssert(tmo <= USART_RTOR_RTO, "Timeout overflow");
+ u->RTOR = tmo;
+ osalDbgAssert(tmo == u->RTOR, "Timeout feature unsupported in this UART");
+ }
+
+ /* Starting the receiver idle loop.*/
+ uart_enter_rx_idle_loop(uartp);
+}
+
+/**
+ * @brief RX DMA common service routine.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void uart_lld_serve_rx_end_irq(UARTDriver *uartp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ if (uartp->rxstate == UART_RX_IDLE) {
+ /* Receiver in idle state, a callback is generated, if enabled, for each
+ received character and then the driver stays in the same state.*/
+ _uart_rx_idle_code(uartp);
+ }
+ else {
+ /* Receiver in active state, a callback is generated, if enabled, after
+ a completed transfer.*/
+ dmaStreamDisable(uartp->dmarx);
+ _uart_rx_complete_isr_code(uartp);
+ }
+}
+
+/**
+ * @brief TX DMA common service routine.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+#if defined(STM32_UART_DMA_ERROR_HOOK)
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ STM32_UART_DMA_ERROR_HOOK(uartp);
+ }
+#else
+ (void)flags;
+#endif
+
+ dmaStreamDisable(uartp->dmatx);
+
+ /* A callback is generated, if enabled, after a completed transfer.*/
+ _uart_tx1_isr_code(uartp);
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_UART_USE_USART1 || defined(__DOXYGEN__)
+#if !defined(STM32_USART1_SUPPRESS_ISR)
+#if !defined(STM32_USART1_HANDLER)
+#error "STM32_USART1_HANDLER not defined"
+#endif
+/**
+ * @brief USART1 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
+#if !defined(STM32_USART2_SUPPRESS_ISR)
+#if !defined(STM32_USART2_HANDLER)
+#error "STM32_USART2_HANDLER not defined"
+#endif
+/**
+ * @brief USART2 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD2);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
+#if !defined(STM32_USART3_SUPPRESS_ISR)
+#if !defined(STM32_USART3_HANDLER)
+#error "STM32_USART3_HANDLER not defined"
+#endif
+/**
+ * @brief USART3 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART3_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_UART4 || defined(__DOXYGEN__)
+#if !defined(STM32_UART4_SUPPRESS_ISR)
+#if !defined(STM32_UART4_HANDLER)
+#error "STM32_UART4_HANDLER not defined"
+#endif
+/**
+ * @brief UART4 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART4_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD4);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_UART5 || defined(__DOXYGEN__)
+#if !defined(STM32_UART5_SUPPRESS_ISR)
+#if !defined(STM32_UART5_HANDLER)
+#error "STM32_UART5_HANDLER not defined"
+#endif
+/**
+ * @brief UART5 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART5_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD5);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_USART6 || defined(__DOXYGEN__)
+#if !defined(STM32_USART6_SUPPRESS_ISR)
+#if !defined(STM32_USART6_HANDLER)
+#error "STM32_USART6_HANDLER not defined"
+#endif
+/**
+ * @brief USART6 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART6_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD6);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_UART7 || defined(__DOXYGEN__)
+#if !defined(STM32_UART7_SUPPRESS_ISR)
+#if !defined(STM32_UART7_HANDLER)
+#error "STM32_UART7_HANDLER not defined"
+#endif
+/**
+ * @brief UART7 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART7_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD7);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+#if STM32_UART_USE_UART8 || defined(__DOXYGEN__)
+#if !defined(STM32_UART8_SUPPRESS_ISR)
+#if !defined(STM32_UART8_HANDLER)
+#error "STM32_UART8_HANDLER not defined"
+#endif
+/**
+ * @brief UART8 IRQ handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_UART8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+ uart_lld_serve_interrupt(&UARTD8);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level UART driver initialization.
+ *
+ * @notapi
+ */
+void uart_lld_init(void) {
+
+#if STM32_UART_USE_USART1
+ uartObjectInit(&UARTD1);
+ UARTD1.usart = USART1;
+ UARTD1.clock = STM32_USART1CLK;
+ UARTD1.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD1.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD1.dmarx = NULL;
+ UARTD1.dmatx = NULL;
+#if !defined(STM32_USART1_SUPPRESS_ISR) && defined(STM32_USART1_NUMBER)
+ nvicEnableVector(STM32_USART1_NUMBER, STM32_UART_USART1_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_USART2
+ uartObjectInit(&UARTD2);
+ UARTD2.usart = USART2;
+ UARTD2.clock = STM32_USART2CLK;
+ UARTD2.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD2.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD2.dmarx = NULL;
+ UARTD2.dmatx = NULL;
+#if !defined(STM32_USART2_SUPPRESS_ISR) && defined(STM32_USART2_NUMBER)
+ nvicEnableVector(STM32_USART2_NUMBER, STM32_UART_USART2_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_USART3
+ uartObjectInit(&UARTD3);
+ UARTD3.usart = USART3;
+ UARTD3.clock = STM32_USART3CLK;
+ UARTD3.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD3.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD3.dmarx = NULL;
+ UARTD3.dmatx = NULL;
+#if !defined(STM32_USART3_SUPPRESS_ISR) && defined(STM32_USART3_NUMBER)
+ nvicEnableVector(STM32_USART3_NUMBER, STM32_UART_USART3_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_UART4
+ uartObjectInit(&UARTD4);
+ UARTD4.usart = UART4;
+ UARTD4.clock = STM32_UART4CLK;
+ UARTD4.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD4.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD4.dmarx = NULL;
+ UARTD4.dmatx = NULL;
+#if !defined(STM32_UART4_SUPPRESS_ISR) && defined(STM32_UART4_NUMBER)
+ nvicEnableVector(STM32_UART4_NUMBER, STM32_UART_UART4_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_UART5
+ uartObjectInit(&UARTD5);
+ UARTD5.usart = UART5;
+ UARTD5.clock = STM32_UART5CLK;
+ UARTD5.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD5.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD5.dmarx = NULL;
+ UARTD5.dmatx = NULL;
+#if !defined(STM32_UART5_SUPPRESS_ISR) && defined(STM32_UART5_NUMBER)
+ nvicEnableVector(STM32_UART5_NUMBER, STM32_UART_UART5_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_USART6
+ uartObjectInit(&UARTD6);
+ UARTD6.usart = USART6;
+ UARTD6.clock = STM32_USART6CLK;
+ UARTD6.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD6.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD6.dmarx = NULL;
+ UARTD6.dmatx = NULL;
+#if !defined(STM32_USART6_SUPPRESS_ISR) && defined(STM32_USART6_NUMBER)
+ nvicEnableVector(STM32_USART6_NUMBER, STM32_UART_USART6_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_UART7
+ uartObjectInit(&UARTD7);
+ UARTD7.usart = UART7;
+ UARTD7.clock = STM32_UART7CLK;
+ UARTD7.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD7.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD7.dmarx = NULL;
+ UARTD7.dmatx = NULL;
+#if !defined(STM32_UART7_SUPPRESS_ISR) && defined(STM32_UART7_NUMBER)
+ nvicEnableVector(STM32_UART7_NUMBER, STM32_UART_UART7_IRQ_PRIORITY);
+#endif
+#endif
+
+#if STM32_UART_USE_UART8
+ uartObjectInit(&UARTD8);
+ UARTD8.usart = UART8;
+ UARTD8.clock = STM32_UART8CLK;
+ UARTD8.dmarxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD8.dmatxmode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ UARTD8.dmarx = NULL;
+ UARTD8.dmatx = NULL;
+#if !defined(STM32_UART8_SUPPRESS_ISR) && defined(STM32_UART8_NUMBER)
+ nvicEnableVector(STM32_UART8_NUMBER, STM32_UART_UART8_IRQ_PRIORITY);
+#endif
+#endif
+}
+
+/**
+ * @brief Configures and activates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+void uart_lld_start(UARTDriver *uartp) {
+
+ if (uartp->state == UART_STOP) {
+#if STM32_UART_USE_USART1
+ if (&UARTD1 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART1_RX_DMA_STREAM,
+ STM32_UART_USART1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART1_TX_DMA_STREAM,
+ STM32_UART_USART1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART1(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART1_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART1_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART1_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_USART2
+ if (&UARTD2 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART2_RX_DMA_STREAM,
+ STM32_UART_USART2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART2_TX_DMA_STREAM,
+ STM32_UART_USART2_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART2(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART2_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART2_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART2_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_USART3
+ if (&UARTD3 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART3_RX_DMA_STREAM,
+ STM32_UART_USART3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART3_TX_DMA_STREAM,
+ STM32_UART_USART3_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART3(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART3_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART3_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART3_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_UART4
+ if (&UARTD4 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART4_RX_DMA_STREAM,
+ STM32_UART_UART4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART4_TX_DMA_STREAM,
+ STM32_UART_UART4_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART4(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART4_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART4_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART4_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_UART5
+ if (&UARTD5 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART5_RX_DMA_STREAM,
+ STM32_UART_UART5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART5_TX_DMA_STREAM,
+ STM32_UART_UART5_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART5(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART5_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART5_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART5_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_USART6
+ if (&UARTD6 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_USART6_RX_DMA_STREAM,
+ STM32_UART_USART6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_USART6_TX_DMA_STREAM,
+ STM32_UART_USART6_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUSART6(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(USART6_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_USART6_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_USART6_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_UART7
+ if (&UARTD7 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART7_RX_DMA_STREAM,
+ STM32_UART_UART7_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART7_TX_DMA_STREAM,
+ STM32_UART_UART7_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART7(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART7_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART7_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART7_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART7_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART7_TX);
+#endif
+ }
+#endif
+
+#if STM32_UART_USE_UART8
+ if (&UARTD8 == uartp) {
+ uartp->dmarx = dmaStreamAllocI(STM32_UART_UART8_RX_DMA_STREAM,
+ STM32_UART_UART8_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_rx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmarx != NULL, "unable to allocate stream");
+ uartp->dmatx = dmaStreamAllocI(STM32_UART_UART8_TX_DMA_STREAM,
+ STM32_UART_UART8_IRQ_PRIORITY,
+ (stm32_dmaisr_t)uart_lld_serve_tx_end_irq,
+ (void *)uartp);
+ osalDbgAssert(uartp->dmatx != NULL, "unable to allocate stream");
+
+ rccEnableUART8(true);
+ uartp->dmarxmode |= STM32_DMA_CR_CHSEL(UART8_RX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
+ uartp->dmatxmode |= STM32_DMA_CR_CHSEL(UART8_TX_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_UART_UART8_DMA_PRIORITY);
+#if STM32_DMA_SUPPORTS_DMAMUX
+ dmaSetRequestSource(uartp->dmarx, STM32_DMAMUX1_UART8_RX);
+ dmaSetRequestSource(uartp->dmatx, STM32_DMAMUX1_UART8_TX);
+#endif
+ }
+#endif
+
+ /* Static DMA setup, the transfer size depends on the USART settings,
+ it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
+ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M0) {
+ uartp->dmarxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ uartp->dmatxmode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
+ }
+ dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->RDR);
+ dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->TDR);
+ uartp->rxbuf = 0;
+ }
+
+ uartp->rxstate = UART_RX_IDLE;
+ uartp->txstate = UART_TX_IDLE;
+ usart_start(uartp);
+}
+
+/**
+ * @brief Deactivates the UART peripheral.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @notapi
+ */
+void uart_lld_stop(UARTDriver *uartp) {
+
+ if (uartp->state == UART_READY) {
+ usart_stop(uartp);
+ dmaStreamFreeI(uartp->dmarx);
+ dmaStreamFreeI(uartp->dmatx);
+ uartp->dmarx = NULL;
+ uartp->dmatx = NULL;
+
+#if STM32_UART_USE_USART1
+ if (&UARTD1 == uartp) {
+ rccDisableUSART1();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_USART2
+ if (&UARTD2 == uartp) {
+ rccDisableUSART2();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_USART3
+ if (&UARTD3 == uartp) {
+ rccDisableUSART3();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART4
+ if (&UARTD4 == uartp) {
+ rccDisableUART4();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART5
+ if (&UARTD5 == uartp) {
+ rccDisableUART5();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_USART6
+ if (&UARTD6 == uartp) {
+ rccDisableUSART6();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART7
+ if (&UARTD7 == uartp) {
+ rccDisableUART7();
+ return;
+ }
+#endif
+
+#if STM32_UART_USE_UART8
+ if (&UARTD8 == uartp) {
+ rccDisableUART8();
+ return;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts a transmission on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[in] txbuf the pointer to the transmit buffer
+ *
+ * @notapi
+ */
+void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
+
+ /* TX DMA channel preparation.*/
+ dmaStreamSetMemory0(uartp->dmatx, txbuf);
+ dmaStreamSetTransactionSize(uartp->dmatx, n);
+ dmaStreamSetMode(uartp->dmatx, uartp->dmatxmode | STM32_DMA_CR_DIR_M2P |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
+
+ /* Only enable TC interrupt if there's a callback attached to it or
+ if called from uartSendFullTimeout(). Also we need to clear TC flag
+ which could be set before.*/
+#if UART_USE_WAIT == TRUE
+ if ((uartp->config->txend2_cb != NULL) || (uartp->early == false)) {
+#else
+ if (uartp->config->txend2_cb != NULL) {
+#endif
+ uartp->usart->ICR = USART_ICR_TCCF;
+ uartp->usart->CR1 |= USART_CR1_TCIE;
+ }
+
+ /* Starting transfer.*/
+ dmaStreamEnable(uartp->dmatx);
+}
+
+/**
+ * @brief Stops any ongoing transmission.
+ * @note Stopping a transmission also suppresses the transmission callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not transmitted by the
+ * stopped transmit operation.
+ *
+ * @notapi
+ */
+size_t uart_lld_stop_send(UARTDriver *uartp) {
+
+ dmaStreamDisable(uartp->dmatx);
+
+ return dmaStreamGetTransactionSize(uartp->dmatx);
+}
+
+/**
+ * @brief Starts a receive operation on the UART peripheral.
+ * @note The buffers are organized as uint8_t arrays for data sizes below
+ * or equal to 8 bits else it is organized as uint16_t arrays.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] n number of data frames to send
+ * @param[out] rxbuf the pointer to the receive buffer
+ *
+ * @notapi
+ */
+void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
+
+ /* Stopping previous activity (idle state).*/
+ dmaStreamDisable(uartp->dmarx);
+
+ /* RX DMA channel preparation.*/
+ dmaStreamSetMemory0(uartp->dmarx, rxbuf);
+ dmaStreamSetTransactionSize(uartp->dmarx, n);
+ dmaStreamSetMode(uartp->dmarx, uartp->dmarxmode | STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE);
+
+ /* Starting transfer.*/
+ dmaStreamEnable(uartp->dmarx);
+}
+
+/**
+ * @brief Stops any ongoing receive operation.
+ * @note Stopping a receive operation also suppresses the receive callbacks.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ *
+ * @return The number of data frames not received by the
+ * stopped receive operation.
+ *
+ * @notapi
+ */
+size_t uart_lld_stop_receive(UARTDriver *uartp) {
+ size_t n;
+
+ dmaStreamDisable(uartp->dmarx);
+ n = dmaStreamGetTransactionSize(uartp->dmarx);
+ uart_enter_rx_idle_loop(uartp);
+
+ return n;
+}
+
+/**
+ * @brief USART common service routine.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+void uart_lld_serve_interrupt(UARTDriver *uartp) {
+ uint32_t isr;
+ USART_TypeDef *u = uartp->usart;
+ uint32_t cr1 = u->CR1;
+
+ /* Reading and clearing status.*/
+ isr = u->ISR;
+ u->ICR = isr;
+
+ if (isr & (USART_ISR_LBDF | USART_ISR_ORE | USART_ISR_NE |
+ USART_ISR_FE | USART_ISR_PE)) {
+ _uart_rx_error_isr_code(uartp, translate_errors(isr));
+ }
+
+ if ((isr & USART_ISR_TC) && (cr1 & USART_CR1_TCIE)) {
+ /* TC interrupt disabled.*/
+ u->CR1 = cr1 & ~USART_CR1_TCIE;
+
+ /* End of transmission, a callback is generated.*/
+ _uart_tx2_isr_code(uartp);
+ }
+
+ /* Timeout interrupt sources are only checked if enabled in CR1.*/
+ if (((cr1 & USART_CR1_IDLEIE) && (isr & USART_ISR_IDLE)) ||
+ ((cr1 & USART_CR1_RTOIE) && (isr & USART_ISR_RTOF))) {
+ _uart_timeout_isr_code(uartp);
+ }
+}
+
+#endif /* HAL_USE_UART */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h
index ec5a6949e7..a68beb90da 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h
+++ b/os/hal/ports/STM32/LLD/USARTv2/hal_uart_lld.h
@@ -1,842 +1,842 @@
-/*
- 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 USARTv2/hal_uart_lld.h
- * @brief STM32 low level UART driver header.
- *
- * @addtogroup UART
- * @{
- */
-
-#ifndef HAL_UART_LLD_H
-#define HAL_UART_LLD_H
-
-#if HAL_USE_UART || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief UART driver on USART1 enable switch.
- * @details If set to @p TRUE the support for USART1 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART1 FALSE
-#endif
-
-/**
- * @brief UART driver on USART2 enable switch.
- * @details If set to @p TRUE the support for USART2 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART2 FALSE
-#endif
-
-/**
- * @brief UART driver on USART3 enable switch.
- * @details If set to @p TRUE the support for USART3 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART3 FALSE
-#endif
-
-/**
- * @brief UART driver on UART4 enable switch.
- * @details If set to @p TRUE the support for UART4 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART4 FALSE
-#endif
-
-/**
- * @brief UART driver on UART5 enable switch.
- * @details If set to @p TRUE the support for UART5 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART5) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART5 FALSE
-#endif
-
-/**
- * @brief UART driver on USART6 enable switch.
- * @details If set to @p TRUE the support for USART6 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_USART6) || defined(__DOXYGEN__)
-#define STM32_UART_USE_USART6 FALSE
-#endif
-
-/**
- * @brief UART driver on UART7 enable switch.
- * @details If set to @p TRUE the support for UART7 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART7) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART7 FALSE
-#endif
-
-/**
- * @brief UART driver on UART8 enable switch.
- * @details If set to @p TRUE the support for UART8 is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_UART_USE_UART8) || defined(__DOXYGEN__)
-#define STM32_UART_USE_UART8 FALSE
-#endif
-
-/**
- * @brief USART1 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART2 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART3 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART4 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART4_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART5 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART5_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART6 interrupt priority level setting.
- */
-#if !defined(STM32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART6_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART7 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART7_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART7_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief UART8 interrupt priority level setting.
- */
-#if !defined(STM32_UART_UART8_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART8_IRQ_PRIORITY 12
-#endif
-
-/**
- * @brief USART1 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART2 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART2_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART3 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART3_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART4 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART4_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART4_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART5 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART5_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART5_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief USART6 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_USART6_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_USART6_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART7 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART7_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART7_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART8 DMA priority (0..3|lowest..highest).
- * @note The priority level is used for both the TX and RX DMA channels but
- * because of the channels ordering the RX channel has always priority
- * over the TX channel.
- */
-#if !defined(STM32_UART_UART8_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_UART_UART8_DMA_PRIORITY 0
-#endif
-
-/**
- * @brief UART DMA error hook.
- * @note The default action for DMA errors is a system halt because DMA
- * error can only happen because programming errors.
- */
-#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
-#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_UART_USE_USART1 && !STM32_HAS_USART1
-#error "USART1 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_USART2 && !STM32_HAS_USART2
-#error "USART2 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_USART3 && !STM32_HAS_USART3
-#error "USART3 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART4 && !STM32_HAS_UART4
-#error "UART4 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART5 && !STM32_HAS_UART5
-#error "UART5 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART7 && !STM32_HAS_UART7
-#error "UART7 not present in the selected device"
-#endif
-
-#if STM32_UART_USE_UART8 && !STM32_HAS_UART8
-#error "UART8 not present in the selected device"
-#endif
-
-#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \
- !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4 && \
- !STM32_UART_USE_UART5 && !STM32_UART_USE_USART6 && \
- !STM32_UART_USE_UART7 && !STM32_UART_USE_UART8
-#error "UART driver activated but no USART/UART peripheral assigned"
-#endif
-
-#if !defined(STM32_USART1_SUPPRESS_ISR) && \
- STM32_UART_USE_USART1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART1"
-#endif
-
-#if !defined(STM32_USART2_SUPPRESS_ISR) && \
- STM32_UART_USE_USART2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART2"
-#endif
-
-#if !defined(STM32_USART3_SUPPRESS_ISR) && \
- STM32_UART_USE_USART3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART3"
-#endif
-
-#if !defined(STM32_UART4_SUPPRESS_ISR) && \
- STM32_UART_USE_UART4 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART4_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART4"
-#endif
-
-#if !defined(STM32_UART5_SUPPRESS_ISR) && \
- STM32_UART_USE_UART5 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART5_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART5"
-#endif
-
-#if !defined(STM32_USART6_SUPPRESS_ISR) && \
- STM32_UART_USE_USART6 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART6_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USART6"
-#endif
-
-#if !defined(STM32_UART7_SUPPRESS_ISR) && \
- STM32_UART_USE_UART7 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART7_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART7"
-#endif
-
-#if !defined(STM32_UART8_SUPPRESS_ISR) && \
- STM32_UART_USE_UART8 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART8_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to UART8"
-#endif
-
-/* Check on DMA priorities.*/
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART1"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART2"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART3"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART4_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART4"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART5_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART5"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART6_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to USART6"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART7_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART7"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART8_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to UART8"
-#endif
-
-/* Check on the presence of the DMA streams settings in mcuconf.h.*/
-#if STM32_UART_USE_USART1 && (!defined(STM32_UART_USART1_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART1_TX_DMA_STREAM))
-#error "USART1 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_USART2 && (!defined(STM32_UART_USART2_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART2_TX_DMA_STREAM))
-#error "USART2 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_USART3 && (!defined(STM32_UART_USART3_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART3_TX_DMA_STREAM))
-#error "USART3 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART4 && (!defined(STM32_UART_UART4_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART4_TX_DMA_STREAM))
-#error "UART4 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART5 && (!defined(STM32_UART_UART5_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART5_TX_DMA_STREAM))
-#error "UART5 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_USART6 && (!defined(STM32_UART_USART6_RX_DMA_STREAM) || \
- !defined(STM32_UART_USART6_TX_DMA_STREAM))
-#error "USART6 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART7 && (!defined(STM32_UART_UART7_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART7_TX_DMA_STREAM))
-#error "UART7 DMA streams not defined"
-#endif
-
-#if STM32_UART_USE_UART8 && (!defined(STM32_UART_UART8_RX_DMA_STREAM) || \
- !defined(STM32_UART_UART8_TX_DMA_STREAM))
-#error "UART8 DMA streams not defined"
-#endif
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART1_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART1 RX"
-#endif
-
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART1_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART1 TX"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART2_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART2 RX"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART2_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART2 TX"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART3_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART3 RX"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART3_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART3 TX"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART4_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART4 RX"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART4_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART4 TX"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART5_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART5 RX"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART5_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART5 TX"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART6_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART6 RX"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART6_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to USART6 TX"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART7_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART7 RX"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART7_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART7 TX"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART8_RX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART8 RX"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART8_TX_DMA_STREAM)
-#error "Invalid DMA channel assigned to UART8 TX"
-#endif
-
-/* Devices without DMAMUX require an additional check.*/
-#if STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX
-
-/* Check on the validity of the assigned DMA channels.*/
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \
- STM32_USART1_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART1 RX"
-#endif
-
-#if STM32_UART_USE_USART1 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_TX_DMA_STREAM, \
- STM32_USART1_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART1 TX"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_RX_DMA_STREAM, \
- STM32_USART2_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART2 RX"
-#endif
-
-#if STM32_UART_USE_USART2 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_TX_DMA_STREAM, \
- STM32_USART2_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART2 TX"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_RX_DMA_STREAM, \
- STM32_USART3_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART3 RX"
-#endif
-
-#if STM32_UART_USE_USART3 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_TX_DMA_STREAM, \
- STM32_USART3_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART3 TX"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_RX_DMA_STREAM, \
- STM32_UART4_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART4 RX"
-#endif
-
-#if STM32_UART_USE_UART4 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_TX_DMA_STREAM, \
- STM32_UART4_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART4 TX"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_RX_DMA_STREAM, \
- STM32_UART5_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART5 RX"
-#endif
-
-#if STM32_UART_USE_UART5 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_TX_DMA_STREAM, \
- STM32_UART5_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART5 TX"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_RX_DMA_STREAM, \
- STM32_USART6_RX_DMA_MSK)
-#error "invalid DMA stream associated to USART6 RX"
-#endif
-
-#if STM32_UART_USE_USART6 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_TX_DMA_STREAM, \
- STM32_USART6_TX_DMA_MSK)
-#error "invalid DMA stream associated to USART6 TX"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_RX_DMA_STREAM, \
- STM32_UART7_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART7 RX"
-#endif
-
-#if STM32_UART_USE_UART7 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_TX_DMA_STREAM, \
- STM32_UART7_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART7 TX"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_RX_DMA_STREAM, \
- STM32_UART8_RX_DMA_MSK)
-#error "invalid DMA stream associated to UART8 RX"
-#endif
-
-#if STM32_UART_USE_UART8 && \
- !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_TX_DMA_STREAM, \
- STM32_UART8_TX_DMA_MSK)
-#error "invalid DMA stream associated to UART8 TX"
-#endif
-
-#endif /* STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX */
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief UART driver condition flags type.
- */
-typedef uint32_t uartflags_t;
-
-/**
- * @brief Structure representing an UART driver.
- */
-typedef struct UARTDriver UARTDriver;
-
-/**
- * @brief Generic UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- */
-typedef void (*uartcb_t)(UARTDriver *uartp);
-
-/**
- * @brief Character received UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] c received character
- */
-typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
-
-/**
- * @brief Receive error UART notification callback type.
- *
- * @param[in] uartp pointer to the @p UARTDriver object
- * @param[in] e receive error mask
- */
-typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief End of transmission buffer callback.
- */
- uartcb_t txend1_cb;
- /**
- * @brief Physical end of transmission callback.
- */
- uartcb_t txend2_cb;
- /**
- * @brief Receive buffer filled callback.
- */
- uartcb_t rxend_cb;
- /**
- * @brief Character received while out if the @p UART_RECEIVE state.
- */
- uartccb_t rxchar_cb;
- /**
- * @brief Receive error callback.
- */
- uartecb_t rxerr_cb;
- /* End of the mandatory fields.*/
- /**
- * @brief Receiver timeout callback.
- * @details Handles both idle and timeout interrupts depending on configured
- * flags in CR registers and supported hardware features.
- */
- uartcb_t timeout_cb;
- /**
- * @brief Receiver timeout value in terms of number of bit duration.
- * @details Set it to 0 when you want to handle idle interrupt instead of
- * hardware timeout.
- */
- uint32_t timeout;
- /**
- * @brief Bit rate.
- */
- uint32_t speed;
- /**
- * @brief Initialization value for the CR1 register.
- */
- uint32_t cr1;
- /**
- * @brief Initialization value for the CR2 register.
- */
- uint32_t cr2;
- /**
- * @brief Initialization value for the CR3 register.
- */
- uint32_t cr3;
-} UARTConfig;
-
-/**
- * @brief Structure representing an UART driver.
- */
-struct UARTDriver {
- /**
- * @brief Driver state.
- */
- uartstate_t state;
- /**
- * @brief Transmitter state.
- */
- uarttxstate_t txstate;
- /**
- * @brief Receiver state.
- */
- uartrxstate_t rxstate;
- /**
- * @brief Current configuration data.
- */
- const UARTConfig *config;
-#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Synchronization flag for transmit operations.
- */
- bool early;
- /**
- * @brief Waiting thread on RX.
- */
- thread_reference_t threadrx;
- /**
- * @brief Waiting thread on TX.
- */
- thread_reference_t threadtx;
-#endif /* UART_USE_WAIT */
-#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Mutex protecting the peripheral.
- */
- mutex_t mutex;
-#endif /* UART_USE_MUTUAL_EXCLUSION */
-#if defined(UART_DRIVER_EXT_FIELDS)
- UART_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the USART registers block.
- */
- USART_TypeDef *usart;
- /**
- * @brief Clock frequency for the associated USART/UART.
- */
- uint32_t clock;
- /**
- * @brief Receive DMA mode bit mask.
- */
- uint32_t dmarxmode;
- /**
- * @brief Send DMA mode bit mask.
- */
- uint32_t dmatxmode;
- /**
- * @brief Receive DMA channel.
- */
- const stm32_dma_stream_t *dmarx;
- /**
- * @brief Transmit DMA channel.
- */
- const stm32_dma_stream_t *dmatx;
- /**
- * @brief Default receive buffer while into @p UART_RX_IDLE state.
- */
- volatile uint16_t rxbuf;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD1;
-#endif
-
-#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD2;
-#endif
-
-#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD3;
-#endif
-
-#if STM32_UART_USE_UART4 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD4;
-#endif
-
-#if STM32_UART_USE_UART5 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD5;
-#endif
-
-#if STM32_UART_USE_USART6 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD6;
-#endif
-
-#if STM32_UART_USE_UART7 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD7;
-#endif
-
-#if STM32_UART_USE_UART8 && !defined(__DOXYGEN__)
-extern UARTDriver UARTD8;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void uart_lld_init(void);
- void uart_lld_start(UARTDriver *uartp);
- void uart_lld_stop(UARTDriver *uartp);
- void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
- size_t uart_lld_stop_send(UARTDriver *uartp);
- void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
- size_t uart_lld_stop_receive(UARTDriver *uartp);
- void uart_lld_serve_interrupt(UARTDriver *uartp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_UART */
-
-#endif /* HAL_UART_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 USARTv2/hal_uart_lld.h
+ * @brief STM32 low level UART driver header.
+ *
+ * @addtogroup UART
+ * @{
+ */
+
+#ifndef HAL_UART_LLD_H
+#define HAL_UART_LLD_H
+
+#if HAL_USE_UART || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief UART driver on USART1 enable switch.
+ * @details If set to @p TRUE the support for USART1 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART1) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART1 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART2 enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART2 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART3 enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART3 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART4 enable switch.
+ * @details If set to @p TRUE the support for UART4 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART4) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART4 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART5 enable switch.
+ * @details If set to @p TRUE the support for UART5 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART5) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART5 FALSE
+#endif
+
+/**
+ * @brief UART driver on USART6 enable switch.
+ * @details If set to @p TRUE the support for USART6 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART6) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART6 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART7 enable switch.
+ * @details If set to @p TRUE the support for UART7 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART7) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART7 FALSE
+#endif
+
+/**
+ * @brief UART driver on UART8 enable switch.
+ * @details If set to @p TRUE the support for UART8 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_UART8) || defined(__DOXYGEN__)
+#define STM32_UART_USE_UART8 FALSE
+#endif
+
+/**
+ * @brief USART1 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART1_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART2 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART2_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART3 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART3_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART4 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART4_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART4_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART5 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART5_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART5_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART6 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART6_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART6_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART7 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART7_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART7_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief UART8 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_UART8_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART8_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART1 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART3_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART4 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART4_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART4_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART5 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART5_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART5_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART6 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART6_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_USART6_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART7 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART7_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART7_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART8 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_UART8_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_UART_UART8_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief UART DMA error hook.
+ * @note The default action for DMA errors is a system halt because DMA
+ * error can only happen because programming errors.
+ */
+#if !defined(STM32_UART_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_UART_USE_USART1 && !STM32_HAS_USART1
+#error "USART1 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_USART2 && !STM32_HAS_USART2
+#error "USART2 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_USART3 && !STM32_HAS_USART3
+#error "USART3 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART4 && !STM32_HAS_UART4
+#error "UART4 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART5 && !STM32_HAS_UART5
+#error "UART5 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART7 && !STM32_HAS_UART7
+#error "UART7 not present in the selected device"
+#endif
+
+#if STM32_UART_USE_UART8 && !STM32_HAS_UART8
+#error "UART8 not present in the selected device"
+#endif
+
+#if !STM32_UART_USE_USART1 && !STM32_UART_USE_USART2 && \
+ !STM32_UART_USE_USART3 && !STM32_UART_USE_UART4 && \
+ !STM32_UART_USE_UART5 && !STM32_UART_USE_USART6 && \
+ !STM32_UART_USE_UART7 && !STM32_UART_USE_UART8
+#error "UART driver activated but no USART/UART peripheral assigned"
+#endif
+
+#if !defined(STM32_USART1_SUPPRESS_ISR) && \
+ STM32_UART_USE_USART1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART1"
+#endif
+
+#if !defined(STM32_USART2_SUPPRESS_ISR) && \
+ STM32_UART_USE_USART2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART2"
+#endif
+
+#if !defined(STM32_USART3_SUPPRESS_ISR) && \
+ STM32_UART_USE_USART3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART3"
+#endif
+
+#if !defined(STM32_UART4_SUPPRESS_ISR) && \
+ STM32_UART_USE_UART4 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART4_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART4"
+#endif
+
+#if !defined(STM32_UART5_SUPPRESS_ISR) && \
+ STM32_UART_USE_UART5 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART5_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART5"
+#endif
+
+#if !defined(STM32_USART6_SUPPRESS_ISR) && \
+ STM32_UART_USE_USART6 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_USART6_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USART6"
+#endif
+
+#if !defined(STM32_UART7_SUPPRESS_ISR) && \
+ STM32_UART_USE_UART7 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART7_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART7"
+#endif
+
+#if !defined(STM32_UART8_SUPPRESS_ISR) && \
+ STM32_UART_USE_UART8 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_UART_UART8_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to UART8"
+#endif
+
+/* Check on DMA priorities.*/
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART1"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART2"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART3"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART4_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART4"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART5_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART5"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_USART6_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to USART6"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART7_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART7"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_UART_UART8_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to UART8"
+#endif
+
+/* Check on the presence of the DMA streams settings in mcuconf.h.*/
+#if STM32_UART_USE_USART1 && (!defined(STM32_UART_USART1_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART1_TX_DMA_STREAM))
+#error "USART1 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_USART2 && (!defined(STM32_UART_USART2_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART2_TX_DMA_STREAM))
+#error "USART2 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_USART3 && (!defined(STM32_UART_USART3_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART3_TX_DMA_STREAM))
+#error "USART3 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART4 && (!defined(STM32_UART_UART4_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART4_TX_DMA_STREAM))
+#error "UART4 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART5 && (!defined(STM32_UART_UART5_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART5_TX_DMA_STREAM))
+#error "UART5 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_USART6 && (!defined(STM32_UART_USART6_RX_DMA_STREAM) || \
+ !defined(STM32_UART_USART6_TX_DMA_STREAM))
+#error "USART6 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART7 && (!defined(STM32_UART_UART7_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART7_TX_DMA_STREAM))
+#error "UART7 DMA streams not defined"
+#endif
+
+#if STM32_UART_USE_UART8 && (!defined(STM32_UART_UART8_RX_DMA_STREAM) || \
+ !defined(STM32_UART_UART8_TX_DMA_STREAM))
+#error "UART8 DMA streams not defined"
+#endif
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART1_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART1 RX"
+#endif
+
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART1_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART1 TX"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART2_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART2 RX"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART2_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART2 TX"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART3_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART3 RX"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART3_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART3 TX"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART4_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART4 RX"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART4_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART4 TX"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART5_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART5 RX"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART5_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART5 TX"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART6_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART6 RX"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_USART6_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to USART6 TX"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART7_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART7 RX"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART7_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART7 TX"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART8_RX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART8 RX"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_STREAM(STM32_UART_UART8_TX_DMA_STREAM)
+#error "Invalid DMA channel assigned to UART8 TX"
+#endif
+
+/* Devices without DMAMUX require an additional check.*/
+#if STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX
+
+/* Check on the validity of the assigned DMA channels.*/
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_RX_DMA_STREAM, \
+ STM32_USART1_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART1 RX"
+#endif
+
+#if STM32_UART_USE_USART1 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART1_TX_DMA_STREAM, \
+ STM32_USART1_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART1 TX"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_RX_DMA_STREAM, \
+ STM32_USART2_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART2 RX"
+#endif
+
+#if STM32_UART_USE_USART2 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART2_TX_DMA_STREAM, \
+ STM32_USART2_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART2 TX"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_RX_DMA_STREAM, \
+ STM32_USART3_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART3 RX"
+#endif
+
+#if STM32_UART_USE_USART3 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART3_TX_DMA_STREAM, \
+ STM32_USART3_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART3 TX"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_RX_DMA_STREAM, \
+ STM32_UART4_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART4 RX"
+#endif
+
+#if STM32_UART_USE_UART4 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART4_TX_DMA_STREAM, \
+ STM32_UART4_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART4 TX"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_RX_DMA_STREAM, \
+ STM32_UART5_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART5 RX"
+#endif
+
+#if STM32_UART_USE_UART5 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART5_TX_DMA_STREAM, \
+ STM32_UART5_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART5 TX"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_RX_DMA_STREAM, \
+ STM32_USART6_RX_DMA_MSK)
+#error "invalid DMA stream associated to USART6 RX"
+#endif
+
+#if STM32_UART_USE_USART6 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_USART6_TX_DMA_STREAM, \
+ STM32_USART6_TX_DMA_MSK)
+#error "invalid DMA stream associated to USART6 TX"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_RX_DMA_STREAM, \
+ STM32_UART7_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART7 RX"
+#endif
+
+#if STM32_UART_USE_UART7 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART7_TX_DMA_STREAM, \
+ STM32_UART7_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART7 TX"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_RX_DMA_STREAM, \
+ STM32_UART8_RX_DMA_MSK)
+#error "invalid DMA stream associated to UART8 RX"
+#endif
+
+#if STM32_UART_USE_UART8 && \
+ !STM32_DMA_IS_VALID_ID(STM32_UART_UART8_TX_DMA_STREAM, \
+ STM32_UART8_TX_DMA_MSK)
+#error "invalid DMA stream associated to UART8 TX"
+#endif
+
+#endif /* STM32_ADVANCED_DMA && !STM32_DMA_SUPPORTS_DMAMUX */
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief UART driver condition flags type.
+ */
+typedef uint32_t uartflags_t;
+
+/**
+ * @brief Structure representing an UART driver.
+ */
+typedef struct UARTDriver UARTDriver;
+
+/**
+ * @brief Generic UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ */
+typedef void (*uartcb_t)(UARTDriver *uartp);
+
+/**
+ * @brief Character received UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] c received character
+ */
+typedef void (*uartccb_t)(UARTDriver *uartp, uint16_t c);
+
+/**
+ * @brief Receive error UART notification callback type.
+ *
+ * @param[in] uartp pointer to the @p UARTDriver object
+ * @param[in] e receive error mask
+ */
+typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief End of transmission buffer callback.
+ */
+ uartcb_t txend1_cb;
+ /**
+ * @brief Physical end of transmission callback.
+ */
+ uartcb_t txend2_cb;
+ /**
+ * @brief Receive buffer filled callback.
+ */
+ uartcb_t rxend_cb;
+ /**
+ * @brief Character received while out if the @p UART_RECEIVE state.
+ */
+ uartccb_t rxchar_cb;
+ /**
+ * @brief Receive error callback.
+ */
+ uartecb_t rxerr_cb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Receiver timeout callback.
+ * @details Handles both idle and timeout interrupts depending on configured
+ * flags in CR registers and supported hardware features.
+ */
+ uartcb_t timeout_cb;
+ /**
+ * @brief Receiver timeout value in terms of number of bit duration.
+ * @details Set it to 0 when you want to handle idle interrupt instead of
+ * hardware timeout.
+ */
+ uint32_t timeout;
+ /**
+ * @brief Bit rate.
+ */
+ uint32_t speed;
+ /**
+ * @brief Initialization value for the CR1 register.
+ */
+ uint32_t cr1;
+ /**
+ * @brief Initialization value for the CR2 register.
+ */
+ uint32_t cr2;
+ /**
+ * @brief Initialization value for the CR3 register.
+ */
+ uint32_t cr3;
+} UARTConfig;
+
+/**
+ * @brief Structure representing an UART driver.
+ */
+struct UARTDriver {
+ /**
+ * @brief Driver state.
+ */
+ uartstate_t state;
+ /**
+ * @brief Transmitter state.
+ */
+ uarttxstate_t txstate;
+ /**
+ * @brief Receiver state.
+ */
+ uartrxstate_t rxstate;
+ /**
+ * @brief Current configuration data.
+ */
+ const UARTConfig *config;
+#if (UART_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Synchronization flag for transmit operations.
+ */
+ bool early;
+ /**
+ * @brief Waiting thread on RX.
+ */
+ thread_reference_t threadrx;
+ /**
+ * @brief Waiting thread on TX.
+ */
+ thread_reference_t threadtx;
+#endif /* UART_USE_WAIT */
+#if (UART_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the peripheral.
+ */
+ mutex_t mutex;
+#endif /* UART_USE_MUTUAL_EXCLUSION */
+#if defined(UART_DRIVER_EXT_FIELDS)
+ UART_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the USART registers block.
+ */
+ USART_TypeDef *usart;
+ /**
+ * @brief Clock frequency for the associated USART/UART.
+ */
+ uint32_t clock;
+ /**
+ * @brief Receive DMA mode bit mask.
+ */
+ uint32_t dmarxmode;
+ /**
+ * @brief Send DMA mode bit mask.
+ */
+ uint32_t dmatxmode;
+ /**
+ * @brief Receive DMA channel.
+ */
+ const stm32_dma_stream_t *dmarx;
+ /**
+ * @brief Transmit DMA channel.
+ */
+ const stm32_dma_stream_t *dmatx;
+ /**
+ * @brief Default receive buffer while into @p UART_RX_IDLE state.
+ */
+ volatile uint16_t rxbuf;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD1;
+#endif
+
+#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD2;
+#endif
+
+#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD3;
+#endif
+
+#if STM32_UART_USE_UART4 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD4;
+#endif
+
+#if STM32_UART_USE_UART5 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD5;
+#endif
+
+#if STM32_UART_USE_USART6 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD6;
+#endif
+
+#if STM32_UART_USE_UART7 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD7;
+#endif
+
+#if STM32_UART_USE_UART8 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD8;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void uart_lld_init(void);
+ void uart_lld_start(UARTDriver *uartp);
+ void uart_lld_stop(UARTDriver *uartp);
+ void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf);
+ size_t uart_lld_stop_send(UARTDriver *uartp);
+ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf);
+ size_t uart_lld_stop_receive(UARTDriver *uartp);
+ void uart_lld_serve_interrupt(UARTDriver *uartp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_UART */
+
+#endif /* HAL_UART_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USBv1/driver.mk b/os/hal/ports/STM32/LLD/USBv1/driver.mk
index 1a6d862280..5d7811155f 100644
--- a/os/hal/ports/STM32/LLD/USBv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/USBv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1
diff --git a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
index 9ca5c6a53a..6c53986832 100644
--- a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
+++ b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.c
@@ -1,874 +1,874 @@
-/*
- 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 USBv1/hal_usb_lld.c
- * @brief STM32 USB subsystem low level driver source.
- *
- * @addtogroup USB
- * @{
- */
-
-#include
-
-#include "hal.h"
-
-#if HAL_USE_USB || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define BTABLE_ADDR 0x0000
-
-#define EPR_EP_TYPE_IS_ISO(bits) ((bits & EPR_EP_TYPE_MASK) == EPR_EP_TYPE_ISO)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief USB1 driver identifier.*/
-#if STM32_USB_USE_USB1 || defined(__DOXYGEN__)
-USBDriver USBD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/**
- * @brief EP0 state.
- * @note It is an union because IN and OUT endpoints are never used at the
- * same time for EP0.
- */
-static union {
- /**
- * @brief IN EP0 state.
- */
- USBInEndpointState in;
- /**
- * @brief OUT EP0 state.
- */
- USBOutEndpointState out;
-} ep0_state;
-
-/**
- * @brief Buffer for the EP0 setup packets.
- */
-static uint8_t ep0setup_buffer[8];
-
-/**
- * @brief EP0 initialization structure.
- */
-static const USBEndpointConfig ep0config = {
- USB_EP_MODE_TYPE_CTRL,
- _usb_ep0setup,
- _usb_ep0in,
- _usb_ep0out,
- 0x40,
- 0x40,
- &ep0_state.in,
- &ep0_state.out,
- 1,
- ep0setup_buffer
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Resets the packet memory allocator.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- */
-static void usb_pm_reset(USBDriver *usbp) {
-
- /* The first 64 bytes are reserved for the descriptors table. The effective
- available RAM for endpoint buffers is just 448 bytes.*/
- usbp->pmnext = 64;
-}
-
-/**
- * @brief Resets the packet memory allocator.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] size size of the packet buffer to allocate
- * @return The packet buffer address.
- */
-static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) {
- uint32_t next;
-
- next = usbp->pmnext;
- usbp->pmnext += (size + 1) & ~1;
- osalDbgAssert(usbp->pmnext <= STM32_USB_PMA_SIZE, "PMA overflow");
- return next;
-}
-
-/**
- * @brief Reads from a dedicated packet buffer.
- *
- * @param[in] ep endpoint number
- * @param[out] buf buffer where to copy the packet data
- * @return The size of the receivee packet.
- *
- * @notapi
- */
-static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
- size_t i, n;
- stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
- stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->RXADDR0);
-#if STM32_USB_USE_ISOCHRONOUS
- uint32_t epr = STM32_USB->EPR[ep];
-
- /* Double buffering is always enabled for isochronous endpoints, and
- although we overlap the two buffers for simplicity, we still need
- to read from the right counter. The DTOG_RX bit indicates the buffer
- that is currently in use by the USB peripheral, that is, the buffer
- in which the next received packet will be stored, so we need to
- read the counter of the OTHER buffer, which is where the last
- received packet was stored.*/
- if (EPR_EP_TYPE_IS_ISO(epr) && ((epr & EPR_DTOG_RX) != 0U))
- n = (size_t)udp->RXCOUNT1 & RXCOUNT_COUNT_MASK;
- else
- n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
-#else
- n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
-#endif
-
- i = n;
-
-#if STM32_USB_USE_FAST_COPY
- while (i >= 16) {
- uint32_t w;
-
- w = *(pmap + 0);
- *(buf + 0) = (uint8_t)w;
- *(buf + 1) = (uint8_t)(w >> 8);
- w = *(pmap + 1);
- *(buf + 2) = (uint8_t)w;
- *(buf + 3) = (uint8_t)(w >> 8);
- w = *(pmap + 2);
- *(buf + 4) = (uint8_t)w;
- *(buf + 5) = (uint8_t)(w >> 8);
- w = *(pmap + 3);
- *(buf + 6) = (uint8_t)w;
- *(buf + 7) = (uint8_t)(w >> 8);
- w = *(pmap + 4);
- *(buf + 8) = (uint8_t)w;
- *(buf + 9) = (uint8_t)(w >> 8);
- w = *(pmap + 5);
- *(buf + 10) = (uint8_t)w;
- *(buf + 11) = (uint8_t)(w >> 8);
- w = *(pmap + 6);
- *(buf + 12) = (uint8_t)w;
- *(buf + 13) = (uint8_t)(w >> 8);
- w = *(pmap + 7);
- *(buf + 14) = (uint8_t)w;
- *(buf + 15) = (uint8_t)(w >> 8);
-
- i -= 16;
- buf += 16;
- pmap += 8;
- }
-#endif /* STM32_USB_USE_FAST_COPY */
-
- while (i >= 2) {
- uint32_t w = *pmap++;
- *buf++ = (uint8_t)w;
- *buf++ = (uint8_t)(w >> 8);
- i -= 2;
- }
-
- if (i >= 1) {
- *buf = (uint8_t)*pmap;
- }
-
- return n;
-}
-
-/**
- * @brief Writes to a dedicated packet buffer.
- *
- * @param[in] ep endpoint number
- * @param[in] buf buffer where to fetch the packet data
- * @param[in] n maximum number of bytes to copy. This value must
- * not exceed the maximum packet size for this endpoint.
- *
- * @notapi
- */
-static void usb_packet_write_from_buffer(usbep_t ep,
- const uint8_t *buf,
- size_t n) {
- stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
- stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0);
- int i = (int)n;
-
-#if STM32_USB_USE_ISOCHRONOUS
- uint32_t epr = STM32_USB->EPR[ep];
-
- /* Double buffering is always enabled for isochronous endpoints, and
- although we overlap the two buffers for simplicity, we still need
- to write to the right counter. The DTOG_TX bit indicates the buffer
- that is currently in use by the USB peripheral, that is, the buffer
- from which the next packet will be sent, so we need to write the
- counter of that buffer.*/
- if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX))
- udp->TXCOUNT1 = (stm32_usb_pma_t)n;
- else
- udp->TXCOUNT0 = (stm32_usb_pma_t)n;
-#else
- udp->TXCOUNT0 = (stm32_usb_pma_t)n;
-#endif
-
-#if STM32_USB_USE_FAST_COPY
- while (i >= 16) {
- uint32_t w;
-
- w = *(buf + 0);
- w |= *(buf + 1) << 8;
- *(pmap + 0) = (stm32_usb_pma_t)w;
- w = *(buf + 2);
- w |= *(buf + 3) << 8;
- *(pmap + 1) = (stm32_usb_pma_t)w;
- w = *(buf + 4);
- w |= *(buf + 5) << 8;
- *(pmap + 2) = (stm32_usb_pma_t)w;
- w = *(buf + 6);
- w |= *(buf + 7) << 8;
- *(pmap + 3) = (stm32_usb_pma_t)w;
- w = *(buf + 8);
- w |= *(buf + 9) << 8;
- *(pmap + 4) = (stm32_usb_pma_t)w;
- w = *(buf + 10);
- w |= *(buf + 11) << 8;
- *(pmap + 5) = (stm32_usb_pma_t)w;
- w = *(buf + 12);
- w |= *(buf + 13) << 8;
- *(pmap + 6) = (stm32_usb_pma_t)w;
- w = *(buf + 14);
- w |= *(buf + 15) << 8;
- *(pmap + 7) = (stm32_usb_pma_t)w;
-
- i -= 16;
- buf += 16;
- pmap += 8;
- }
-#endif /* STM32_USB_USE_FAST_COPY */
-
- while (i > 0) {
- uint32_t w;
-
- w = *buf++;
- w |= *buf++ << 8;
- *pmap++ = (stm32_usb_pma_t)w;
- i -= 2;
- }
-}
-
-/**
- * @brief Common ISR code, serves the EP-related interrupts.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
- size_t n;
- uint32_t epr = STM32_USB->EPR[ep];
- const USBEndpointConfig *epcp = usbp->epc[ep];
-
- if (epr & EPR_CTR_TX) {
- /* IN endpoint, transmission.*/
- USBInEndpointState *isp = epcp->in_state;
-
- EPR_CLEAR_CTR_TX(ep);
-
- isp->txcnt += isp->txlast;
- n = isp->txsize - isp->txcnt;
- if (n > 0) {
- /* Transfer not completed, there are more packets to send.*/
- if (n > epcp->in_maxsize)
- n = epcp->in_maxsize;
-
- /* Writes the packet from the defined buffer.*/
- isp->txbuf += isp->txlast;
- isp->txlast = n;
- usb_packet_write_from_buffer(ep, isp->txbuf, n);
-
- /* Starting IN operation.*/
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
- }
- else {
- /* Transfer completed, invokes the callback.*/
- _usb_isr_invoke_in_cb(usbp, ep);
- }
- }
- if (epr & EPR_CTR_RX) {
- /* OUT endpoint, receive.*/
-
- EPR_CLEAR_CTR_RX(ep);
-
- if (epr & EPR_SETUP) {
- /* Setup packets handling, setup packets are handled using a
- specific callback.*/
- _usb_isr_invoke_setup_cb(usbp, ep);
- }
- else {
- USBOutEndpointState *osp = epcp->out_state;
-
- /* Reads the packet into the defined buffer.*/
- n = usb_packet_read_to_buffer(ep, osp->rxbuf);
- osp->rxbuf += n;
-
- /* Transaction data updated.*/
- osp->rxcnt += n;
- osp->rxsize -= n;
- osp->rxpkts -= 1;
-
- /* The transaction is completed if the specified number of packets
- has been received or the current packet is a short packet.*/
- if ((n < epcp->out_maxsize) || (osp->rxpkts == 0)) {
- /* Transfer complete, invokes the callback.*/
- _usb_isr_invoke_out_cb(usbp, ep);
- }
- else {
- /* Transfer not complete, there are more packets to receive.*/
- EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
- }
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_USB_USE_USB1 || defined(__DOXYGEN__)
-#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
-#if STM32_USB_USE_ISOCHRONOUS
-/**
- * @brief USB high priority interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USB1_HP_HANDLER) {
- uint32_t istr;
- USBDriver *usbp = &USBD1;
-
- OSAL_IRQ_PROLOGUE();
-
- /* Endpoint events handling.*/
- istr = STM32_USB->ISTR;
- while (istr & ISTR_CTR) {
- usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK);
- istr = STM32_USB->ISTR;
- }
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_USB_USE_ISOCHRONOUS */
-#endif /* STM32_USB1_LP_NUMBER != STM32_USB1_HP_NUMBER */
-
-/**
- * @brief USB low priority interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
- uint32_t istr;
- USBDriver *usbp = &USBD1;
-
- OSAL_IRQ_PROLOGUE();
-
- istr = STM32_USB->ISTR;
-
- /* USB bus reset condition handling.*/
- if (istr & ISTR_RESET) {
- STM32_USB->ISTR = ~ISTR_RESET;
-
- _usb_reset(usbp);
- }
-
- /* USB bus SUSPEND condition handling.*/
- if (istr & ISTR_SUSP) {
- STM32_USB->CNTR |= CNTR_FSUSP;
-#if STM32_USB_LOW_POWER_ON_SUSPEND
- STM32_USB->CNTR |= CNTR_LP_MODE;
-#endif
- STM32_USB->ISTR = ~ISTR_SUSP;
-
- _usb_suspend(usbp);
- }
-
- /* USB bus WAKEUP condition handling.*/
- if (istr & ISTR_WKUP) {
- uint32_t fnr = STM32_USB->FNR;
- if (!(fnr & FNR_RXDP)) {
- STM32_USB->CNTR &= ~CNTR_FSUSP;
-
- _usb_wakeup(usbp);
- }
-#if STM32_USB_LOW_POWER_ON_SUSPEND
- else {
- /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
- table 169.*/
- STM32_USB->CNTR |= CNTR_LP_MODE;
- }
-#endif
- STM32_USB->ISTR = ~ISTR_WKUP;
- }
-
- /* SOF handling.*/
- if (istr & ISTR_SOF) {
- _usb_isr_invoke_sof_cb(usbp);
- STM32_USB->ISTR = ~ISTR_SOF;
- }
-
- /* Endpoint events handling.*/
- while (istr & ISTR_CTR) {
- usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK);
- istr = STM32_USB->ISTR;
- }
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_USB_USE_USB1 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level USB driver initialization.
- *
- * @notapi
- */
-void usb_lld_init(void) {
-
- /* Driver initialization.*/
- usbObjectInit(&USBD1);
-}
-
-/**
- * @brief Configures and activates the USB peripheral.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_start(USBDriver *usbp) {
-
- if (usbp->state == USB_STOP) {
- /* Clock activation.*/
-#if STM32_USB_USE_USB1
- if (&USBD1 == usbp) {
- /* USB clock enabled.*/
- rccEnableUSB(true);
- /* Powers up the transceiver while holding the USB in reset state.*/
- STM32_USB->CNTR = CNTR_FRES;
- /* Enabling the USB IRQ vectors, this also gives enough time to allow
- the transceiver power up (1uS).*/
-#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
- nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY);
-#endif
- nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY);
- /* Releases the USB reset.*/
- STM32_USB->CNTR = 0;
- }
-#endif
- /* Reset procedure enforced on driver start.*/
- usb_lld_reset(usbp);
- }
-}
-
-/**
- * @brief Deactivates the USB peripheral.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_stop(USBDriver *usbp) {
-
- /* If in ready state then disables the USB clock.*/
- if (usbp->state != USB_STOP) {
-#if STM32_USB_USE_USB1
- if (&USBD1 == usbp) {
-#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
- nvicDisableVector(STM32_USB1_HP_NUMBER);
-#endif
- nvicDisableVector(STM32_USB1_LP_NUMBER);
- STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES;
- rccDisableUSB();
- }
-#endif
- }
-}
-
-/**
- * @brief USB low level reset routine.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_reset(USBDriver *usbp) {
- uint32_t cntr;
-
- /* Post reset initialization.*/
- STM32_USB->BTABLE = BTABLE_ADDR;
- STM32_USB->ISTR = 0;
- STM32_USB->DADDR = DADDR_EF;
- cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM |
- CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
- /* The SOF interrupt is only enabled if a callback is defined for
- this service because it is an high rate source.*/
- if (usbp->config->sof_cb != NULL)
- cntr |= CNTR_SOFM;
- STM32_USB->CNTR = cntr;
-
- /* Resets the packet memory allocator.*/
- usb_pm_reset(usbp);
-
- /* EP0 initialization.*/
- usbp->epc[0] = &ep0config;
- usb_lld_init_endpoint(usbp, 0);
-}
-
-/**
- * @brief Sets the USB address.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_set_address(USBDriver *usbp) {
-
- STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF;
-}
-
-/**
- * @brief Enables an endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
- uint16_t epr;
- stm32_usb_descriptor_t *dp;
- const USBEndpointConfig *epcp = usbp->epc[ep];
-
- /* Setting the endpoint type. Note that isochronous endpoints cannot be
- bidirectional because it uses double buffering and both transmit and
- receive descriptor fields are used for either direction.*/
- switch (epcp->ep_mode & USB_EP_MODE_TYPE) {
- case USB_EP_MODE_TYPE_ISOC:
-#if STM32_USB_USE_ISOCHRONOUS
- osalDbgAssert((epcp->in_state == NULL) || (epcp->out_state == NULL),
- "isochronous EP cannot be IN and OUT");
- epr = EPR_EP_TYPE_ISO;
- break;
-#else
- osalDbgAssert(false, "isochronous support disabled");
-#endif
- /* Falls through.*/
- case USB_EP_MODE_TYPE_BULK:
- epr = EPR_EP_TYPE_BULK;
- break;
- case USB_EP_MODE_TYPE_INTR:
- epr = EPR_EP_TYPE_INTERRUPT;
- break;
- default:
- epr = EPR_EP_TYPE_CONTROL;
- }
-
- dp = USB_GET_DESCRIPTOR(ep);
-
- /* IN endpoint handling.*/
- if (epcp->in_state != NULL) {
- dp->TXCOUNT0 = 0;
- dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize);
-
-#if STM32_USB_USE_ISOCHRONOUS
- if (epr == EPR_EP_TYPE_ISO) {
- epr |= EPR_STAT_TX_VALID;
- dp->TXCOUNT1 = dp->TXCOUNT0;
- dp->TXADDR1 = dp->TXADDR0; /* Both buffers overlapped.*/
- }
- else {
- epr |= EPR_STAT_TX_NAK;
- }
-#else
- epr |= EPR_STAT_TX_NAK;
-#endif
- }
-
- /* OUT endpoint handling.*/
- if (epcp->out_state != NULL) {
- uint16_t nblocks;
-
- /* Endpoint size and address initialization.*/
- if (epcp->out_maxsize > 62)
- nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
- 0x8000;
- else
- nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10;
- dp->RXCOUNT0 = nblocks;
- dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize);
-
-#if STM32_USB_USE_ISOCHRONOUS
- if (epr == EPR_EP_TYPE_ISO) {
- epr |= EPR_STAT_RX_VALID;
- dp->RXCOUNT1 = dp->RXCOUNT0;
- dp->RXADDR1 = dp->RXADDR0; /* Both buffers overlapped.*/
- }
- else {
- epr |= EPR_STAT_RX_NAK;
- }
-#else
- epr |= EPR_STAT_RX_NAK;
-#endif
- }
-
- /* Resetting the data toggling bits for this endpoint.*/
- if (STM32_USB->EPR[ep] & EPR_DTOG_RX) {
- epr |= EPR_DTOG_RX;
- }
-
- if (STM32_USB->EPR[ep] & EPR_DTOG_TX) {
- epr |= EPR_DTOG_TX;
- }
-
- /* EPxR register setup.*/
- EPR_SET(ep, epr | ep);
- EPR_TOGGLE(ep, epr);
-}
-
-/**
- * @brief Disables all the active endpoints except the endpoint zero.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- *
- * @notapi
- */
-void usb_lld_disable_endpoints(USBDriver *usbp) {
- unsigned i;
-
- /* Resets the packet memory allocator.*/
- usb_pm_reset(usbp);
-
- /* Disabling all endpoints.*/
- for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) {
- EPR_TOGGLE(i, 0);
- EPR_SET(i, 0);
- }
-}
-
-/**
- * @brief Returns the status of an OUT endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @return The endpoint status.
- * @retval EP_STATUS_DISABLED The endpoint is not active.
- * @retval EP_STATUS_STALLED The endpoint is stalled.
- * @retval EP_STATUS_ACTIVE The endpoint is active.
- *
- * @notapi
- */
-usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
- switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
- case EPR_STAT_RX_DIS:
- return EP_STATUS_DISABLED;
- case EPR_STAT_RX_STALL:
- return EP_STATUS_STALLED;
- default:
- return EP_STATUS_ACTIVE;
- }
-}
-
-/**
- * @brief Returns the status of an IN endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @return The endpoint status.
- * @retval EP_STATUS_DISABLED The endpoint is not active.
- * @retval EP_STATUS_STALLED The endpoint is stalled.
- * @retval EP_STATUS_ACTIVE The endpoint is active.
- *
- * @notapi
- */
-usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
- switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
- case EPR_STAT_TX_DIS:
- return EP_STATUS_DISABLED;
- case EPR_STAT_TX_STALL:
- return EP_STATUS_STALLED;
- default:
- return EP_STATUS_ACTIVE;
- }
-}
-
-/**
- * @brief Reads a setup packet from the dedicated packet buffer.
- * @details This function must be invoked in the context of the @p setup_cb
- * callback in order to read the received setup packet.
- * @pre In order to use this function the endpoint must have been
- * initialized as a control endpoint.
- * @post The endpoint is ready to accept another packet.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @param[out] buf buffer where to copy the packet data
- *
- * @notapi
- */
-void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
- stm32_usb_pma_t *pmap;
- stm32_usb_descriptor_t *udp;
- uint32_t n;
-
- (void)usbp;
- udp = USB_GET_DESCRIPTOR(ep);
- pmap = USB_ADDR2PTR(udp->RXADDR0);
- for (n = 0; n < 4; n++) {
- *(uint16_t *)buf = (uint16_t)*pmap++;
- buf += 2;
- }
-}
-
-/**
- * @brief Starts a receive operation on an OUT endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
- USBOutEndpointState *osp = usbp->epc[ep]->out_state;
-
- /* Transfer initialization.*/
- if (osp->rxsize == 0) /* Special case for zero sized packets.*/
- osp->rxpkts = 1;
- else
- osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
- usbp->epc[ep]->out_maxsize);
-
- EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
-}
-
-/**
- * @brief Starts a transmit operation on an IN endpoint.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
- size_t n;
- USBInEndpointState *isp = usbp->epc[ep]->in_state;
-
- /* Transfer initialization.*/
- n = isp->txsize;
- if (n > (size_t)usbp->epc[ep]->in_maxsize)
- n = (size_t)usbp->epc[ep]->in_maxsize;
-
- isp->txlast = n;
- usb_packet_write_from_buffer(ep, isp->txbuf, n);
-
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
-}
-
-/**
- * @brief Brings an OUT endpoint in the stalled state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
-
- EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
-}
-
-/**
- * @brief Brings an IN endpoint in the stalled state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
-
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
-}
-
-/**
- * @brief Brings an OUT endpoint in the active state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
-
- /* Makes sure to not put to NAK an endpoint that is already
- transferring.*/
- if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
- EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK);
-}
-
-/**
- * @brief Brings an IN endpoint in the active state.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- *
- * @notapi
- */
-void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
-
- (void)usbp;
-
- /* Makes sure to not put to NAK an endpoint that is already
- transferring.*/
- if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
- EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
-}
-
-#endif /* HAL_USE_USB */
-
-/** @} */
+/*
+ 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 USBv1/hal_usb_lld.c
+ * @brief STM32 USB subsystem low level driver source.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#include
+
+#include "hal.h"
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define BTABLE_ADDR 0x0000
+
+#define EPR_EP_TYPE_IS_ISO(bits) ((bits & EPR_EP_TYPE_MASK) == EPR_EP_TYPE_ISO)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief USB1 driver identifier.*/
+#if STM32_USB_USE_USB1 || defined(__DOXYGEN__)
+USBDriver USBD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/**
+ * @brief EP0 state.
+ * @note It is an union because IN and OUT endpoints are never used at the
+ * same time for EP0.
+ */
+static union {
+ /**
+ * @brief IN EP0 state.
+ */
+ USBInEndpointState in;
+ /**
+ * @brief OUT EP0 state.
+ */
+ USBOutEndpointState out;
+} ep0_state;
+
+/**
+ * @brief Buffer for the EP0 setup packets.
+ */
+static uint8_t ep0setup_buffer[8];
+
+/**
+ * @brief EP0 initialization structure.
+ */
+static const USBEndpointConfig ep0config = {
+ USB_EP_MODE_TYPE_CTRL,
+ _usb_ep0setup,
+ _usb_ep0in,
+ _usb_ep0out,
+ 0x40,
+ 0x40,
+ &ep0_state.in,
+ &ep0_state.out,
+ 1,
+ ep0setup_buffer
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Resets the packet memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ */
+static void usb_pm_reset(USBDriver *usbp) {
+
+ /* The first 64 bytes are reserved for the descriptors table. The effective
+ available RAM for endpoint buffers is just 448 bytes.*/
+ usbp->pmnext = 64;
+}
+
+/**
+ * @brief Resets the packet memory allocator.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] size size of the packet buffer to allocate
+ * @return The packet buffer address.
+ */
+static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) {
+ uint32_t next;
+
+ next = usbp->pmnext;
+ usbp->pmnext += (size + 1) & ~1;
+ osalDbgAssert(usbp->pmnext <= STM32_USB_PMA_SIZE, "PMA overflow");
+ return next;
+}
+
+/**
+ * @brief Reads from a dedicated packet buffer.
+ *
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ * @return The size of the receivee packet.
+ *
+ * @notapi
+ */
+static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
+ size_t i, n;
+ stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
+ stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->RXADDR0);
+#if STM32_USB_USE_ISOCHRONOUS
+ uint32_t epr = STM32_USB->EPR[ep];
+
+ /* Double buffering is always enabled for isochronous endpoints, and
+ although we overlap the two buffers for simplicity, we still need
+ to read from the right counter. The DTOG_RX bit indicates the buffer
+ that is currently in use by the USB peripheral, that is, the buffer
+ in which the next received packet will be stored, so we need to
+ read the counter of the OTHER buffer, which is where the last
+ received packet was stored.*/
+ if (EPR_EP_TYPE_IS_ISO(epr) && ((epr & EPR_DTOG_RX) != 0U))
+ n = (size_t)udp->RXCOUNT1 & RXCOUNT_COUNT_MASK;
+ else
+ n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
+#else
+ n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
+#endif
+
+ i = n;
+
+#if STM32_USB_USE_FAST_COPY
+ while (i >= 16) {
+ uint32_t w;
+
+ w = *(pmap + 0);
+ *(buf + 0) = (uint8_t)w;
+ *(buf + 1) = (uint8_t)(w >> 8);
+ w = *(pmap + 1);
+ *(buf + 2) = (uint8_t)w;
+ *(buf + 3) = (uint8_t)(w >> 8);
+ w = *(pmap + 2);
+ *(buf + 4) = (uint8_t)w;
+ *(buf + 5) = (uint8_t)(w >> 8);
+ w = *(pmap + 3);
+ *(buf + 6) = (uint8_t)w;
+ *(buf + 7) = (uint8_t)(w >> 8);
+ w = *(pmap + 4);
+ *(buf + 8) = (uint8_t)w;
+ *(buf + 9) = (uint8_t)(w >> 8);
+ w = *(pmap + 5);
+ *(buf + 10) = (uint8_t)w;
+ *(buf + 11) = (uint8_t)(w >> 8);
+ w = *(pmap + 6);
+ *(buf + 12) = (uint8_t)w;
+ *(buf + 13) = (uint8_t)(w >> 8);
+ w = *(pmap + 7);
+ *(buf + 14) = (uint8_t)w;
+ *(buf + 15) = (uint8_t)(w >> 8);
+
+ i -= 16;
+ buf += 16;
+ pmap += 8;
+ }
+#endif /* STM32_USB_USE_FAST_COPY */
+
+ while (i >= 2) {
+ uint32_t w = *pmap++;
+ *buf++ = (uint8_t)w;
+ *buf++ = (uint8_t)(w >> 8);
+ i -= 2;
+ }
+
+ if (i >= 1) {
+ *buf = (uint8_t)*pmap;
+ }
+
+ return n;
+}
+
+/**
+ * @brief Writes to a dedicated packet buffer.
+ *
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ *
+ * @notapi
+ */
+static void usb_packet_write_from_buffer(usbep_t ep,
+ const uint8_t *buf,
+ size_t n) {
+ stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
+ stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0);
+ int i = (int)n;
+
+#if STM32_USB_USE_ISOCHRONOUS
+ uint32_t epr = STM32_USB->EPR[ep];
+
+ /* Double buffering is always enabled for isochronous endpoints, and
+ although we overlap the two buffers for simplicity, we still need
+ to write to the right counter. The DTOG_TX bit indicates the buffer
+ that is currently in use by the USB peripheral, that is, the buffer
+ from which the next packet will be sent, so we need to write the
+ counter of that buffer.*/
+ if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX))
+ udp->TXCOUNT1 = (stm32_usb_pma_t)n;
+ else
+ udp->TXCOUNT0 = (stm32_usb_pma_t)n;
+#else
+ udp->TXCOUNT0 = (stm32_usb_pma_t)n;
+#endif
+
+#if STM32_USB_USE_FAST_COPY
+ while (i >= 16) {
+ uint32_t w;
+
+ w = *(buf + 0);
+ w |= *(buf + 1) << 8;
+ *(pmap + 0) = (stm32_usb_pma_t)w;
+ w = *(buf + 2);
+ w |= *(buf + 3) << 8;
+ *(pmap + 1) = (stm32_usb_pma_t)w;
+ w = *(buf + 4);
+ w |= *(buf + 5) << 8;
+ *(pmap + 2) = (stm32_usb_pma_t)w;
+ w = *(buf + 6);
+ w |= *(buf + 7) << 8;
+ *(pmap + 3) = (stm32_usb_pma_t)w;
+ w = *(buf + 8);
+ w |= *(buf + 9) << 8;
+ *(pmap + 4) = (stm32_usb_pma_t)w;
+ w = *(buf + 10);
+ w |= *(buf + 11) << 8;
+ *(pmap + 5) = (stm32_usb_pma_t)w;
+ w = *(buf + 12);
+ w |= *(buf + 13) << 8;
+ *(pmap + 6) = (stm32_usb_pma_t)w;
+ w = *(buf + 14);
+ w |= *(buf + 15) << 8;
+ *(pmap + 7) = (stm32_usb_pma_t)w;
+
+ i -= 16;
+ buf += 16;
+ pmap += 8;
+ }
+#endif /* STM32_USB_USE_FAST_COPY */
+
+ while (i > 0) {
+ uint32_t w;
+
+ w = *buf++;
+ w |= *buf++ << 8;
+ *pmap++ = (stm32_usb_pma_t)w;
+ i -= 2;
+ }
+}
+
+/**
+ * @brief Common ISR code, serves the EP-related interrupts.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
+ size_t n;
+ uint32_t epr = STM32_USB->EPR[ep];
+ const USBEndpointConfig *epcp = usbp->epc[ep];
+
+ if (epr & EPR_CTR_TX) {
+ /* IN endpoint, transmission.*/
+ USBInEndpointState *isp = epcp->in_state;
+
+ EPR_CLEAR_CTR_TX(ep);
+
+ isp->txcnt += isp->txlast;
+ n = isp->txsize - isp->txcnt;
+ if (n > 0) {
+ /* Transfer not completed, there are more packets to send.*/
+ if (n > epcp->in_maxsize)
+ n = epcp->in_maxsize;
+
+ /* Writes the packet from the defined buffer.*/
+ isp->txbuf += isp->txlast;
+ isp->txlast = n;
+ usb_packet_write_from_buffer(ep, isp->txbuf, n);
+
+ /* Starting IN operation.*/
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
+ }
+ else {
+ /* Transfer completed, invokes the callback.*/
+ _usb_isr_invoke_in_cb(usbp, ep);
+ }
+ }
+ if (epr & EPR_CTR_RX) {
+ /* OUT endpoint, receive.*/
+
+ EPR_CLEAR_CTR_RX(ep);
+
+ if (epr & EPR_SETUP) {
+ /* Setup packets handling, setup packets are handled using a
+ specific callback.*/
+ _usb_isr_invoke_setup_cb(usbp, ep);
+ }
+ else {
+ USBOutEndpointState *osp = epcp->out_state;
+
+ /* Reads the packet into the defined buffer.*/
+ n = usb_packet_read_to_buffer(ep, osp->rxbuf);
+ osp->rxbuf += n;
+
+ /* Transaction data updated.*/
+ osp->rxcnt += n;
+ osp->rxsize -= n;
+ osp->rxpkts -= 1;
+
+ /* The transaction is completed if the specified number of packets
+ has been received or the current packet is a short packet.*/
+ if ((n < epcp->out_maxsize) || (osp->rxpkts == 0)) {
+ /* Transfer complete, invokes the callback.*/
+ _usb_isr_invoke_out_cb(usbp, ep);
+ }
+ else {
+ /* Transfer not complete, there are more packets to receive.*/
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+ }
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_USB1 || defined(__DOXYGEN__)
+#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
+#if STM32_USB_USE_ISOCHRONOUS
+/**
+ * @brief USB high priority interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USB1_HP_HANDLER) {
+ uint32_t istr;
+ USBDriver *usbp = &USBD1;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Endpoint events handling.*/
+ istr = STM32_USB->ISTR;
+ while (istr & ISTR_CTR) {
+ usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK);
+ istr = STM32_USB->ISTR;
+ }
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_USB_USE_ISOCHRONOUS */
+#endif /* STM32_USB1_LP_NUMBER != STM32_USB1_HP_NUMBER */
+
+/**
+ * @brief USB low priority interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
+ uint32_t istr;
+ USBDriver *usbp = &USBD1;
+
+ OSAL_IRQ_PROLOGUE();
+
+ istr = STM32_USB->ISTR;
+
+ /* USB bus reset condition handling.*/
+ if (istr & ISTR_RESET) {
+ STM32_USB->ISTR = ~ISTR_RESET;
+
+ _usb_reset(usbp);
+ }
+
+ /* USB bus SUSPEND condition handling.*/
+ if (istr & ISTR_SUSP) {
+ STM32_USB->CNTR |= CNTR_FSUSP;
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+#endif
+ STM32_USB->ISTR = ~ISTR_SUSP;
+
+ _usb_suspend(usbp);
+ }
+
+ /* USB bus WAKEUP condition handling.*/
+ if (istr & ISTR_WKUP) {
+ uint32_t fnr = STM32_USB->FNR;
+ if (!(fnr & FNR_RXDP)) {
+ STM32_USB->CNTR &= ~CNTR_FSUSP;
+
+ _usb_wakeup(usbp);
+ }
+#if STM32_USB_LOW_POWER_ON_SUSPEND
+ else {
+ /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
+ table 169.*/
+ STM32_USB->CNTR |= CNTR_LP_MODE;
+ }
+#endif
+ STM32_USB->ISTR = ~ISTR_WKUP;
+ }
+
+ /* SOF handling.*/
+ if (istr & ISTR_SOF) {
+ _usb_isr_invoke_sof_cb(usbp);
+ STM32_USB->ISTR = ~ISTR_SOF;
+ }
+
+ /* Endpoint events handling.*/
+ while (istr & ISTR_CTR) {
+ usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK);
+ istr = STM32_USB->ISTR;
+ }
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_USB_USE_USB1 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level USB driver initialization.
+ *
+ * @notapi
+ */
+void usb_lld_init(void) {
+
+ /* Driver initialization.*/
+ usbObjectInit(&USBD1);
+}
+
+/**
+ * @brief Configures and activates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_start(USBDriver *usbp) {
+
+ if (usbp->state == USB_STOP) {
+ /* Clock activation.*/
+#if STM32_USB_USE_USB1
+ if (&USBD1 == usbp) {
+ /* USB clock enabled.*/
+ rccEnableUSB(true);
+ /* Powers up the transceiver while holding the USB in reset state.*/
+ STM32_USB->CNTR = CNTR_FRES;
+ /* Enabling the USB IRQ vectors, this also gives enough time to allow
+ the transceiver power up (1uS).*/
+#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
+ nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY);
+#endif
+ nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY);
+ /* Releases the USB reset.*/
+ STM32_USB->CNTR = 0;
+ }
+#endif
+ /* Reset procedure enforced on driver start.*/
+ usb_lld_reset(usbp);
+ }
+}
+
+/**
+ * @brief Deactivates the USB peripheral.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_stop(USBDriver *usbp) {
+
+ /* If in ready state then disables the USB clock.*/
+ if (usbp->state != USB_STOP) {
+#if STM32_USB_USE_USB1
+ if (&USBD1 == usbp) {
+#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
+ nvicDisableVector(STM32_USB1_HP_NUMBER);
+#endif
+ nvicDisableVector(STM32_USB1_LP_NUMBER);
+ STM32_USB->CNTR = CNTR_PDWN | CNTR_FRES;
+ rccDisableUSB();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief USB low level reset routine.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_reset(USBDriver *usbp) {
+ uint32_t cntr;
+
+ /* Post reset initialization.*/
+ STM32_USB->BTABLE = BTABLE_ADDR;
+ STM32_USB->ISTR = 0;
+ STM32_USB->DADDR = DADDR_EF;
+ cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM |
+ CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
+ /* The SOF interrupt is only enabled if a callback is defined for
+ this service because it is an high rate source.*/
+ if (usbp->config->sof_cb != NULL)
+ cntr |= CNTR_SOFM;
+ STM32_USB->CNTR = cntr;
+
+ /* Resets the packet memory allocator.*/
+ usb_pm_reset(usbp);
+
+ /* EP0 initialization.*/
+ usbp->epc[0] = &ep0config;
+ usb_lld_init_endpoint(usbp, 0);
+}
+
+/**
+ * @brief Sets the USB address.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_set_address(USBDriver *usbp) {
+
+ STM32_USB->DADDR = (uint32_t)(usbp->address) | DADDR_EF;
+}
+
+/**
+ * @brief Enables an endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
+ uint16_t epr;
+ stm32_usb_descriptor_t *dp;
+ const USBEndpointConfig *epcp = usbp->epc[ep];
+
+ /* Setting the endpoint type. Note that isochronous endpoints cannot be
+ bidirectional because it uses double buffering and both transmit and
+ receive descriptor fields are used for either direction.*/
+ switch (epcp->ep_mode & USB_EP_MODE_TYPE) {
+ case USB_EP_MODE_TYPE_ISOC:
+#if STM32_USB_USE_ISOCHRONOUS
+ osalDbgAssert((epcp->in_state == NULL) || (epcp->out_state == NULL),
+ "isochronous EP cannot be IN and OUT");
+ epr = EPR_EP_TYPE_ISO;
+ break;
+#else
+ osalDbgAssert(false, "isochronous support disabled");
+#endif
+ /* Falls through.*/
+ case USB_EP_MODE_TYPE_BULK:
+ epr = EPR_EP_TYPE_BULK;
+ break;
+ case USB_EP_MODE_TYPE_INTR:
+ epr = EPR_EP_TYPE_INTERRUPT;
+ break;
+ default:
+ epr = EPR_EP_TYPE_CONTROL;
+ }
+
+ dp = USB_GET_DESCRIPTOR(ep);
+
+ /* IN endpoint handling.*/
+ if (epcp->in_state != NULL) {
+ dp->TXCOUNT0 = 0;
+ dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize);
+
+#if STM32_USB_USE_ISOCHRONOUS
+ if (epr == EPR_EP_TYPE_ISO) {
+ epr |= EPR_STAT_TX_VALID;
+ dp->TXCOUNT1 = dp->TXCOUNT0;
+ dp->TXADDR1 = dp->TXADDR0; /* Both buffers overlapped.*/
+ }
+ else {
+ epr |= EPR_STAT_TX_NAK;
+ }
+#else
+ epr |= EPR_STAT_TX_NAK;
+#endif
+ }
+
+ /* OUT endpoint handling.*/
+ if (epcp->out_state != NULL) {
+ uint16_t nblocks;
+
+ /* Endpoint size and address initialization.*/
+ if (epcp->out_maxsize > 62)
+ nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
+ 0x8000;
+ else
+ nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10;
+ dp->RXCOUNT0 = nblocks;
+ dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize);
+
+#if STM32_USB_USE_ISOCHRONOUS
+ if (epr == EPR_EP_TYPE_ISO) {
+ epr |= EPR_STAT_RX_VALID;
+ dp->RXCOUNT1 = dp->RXCOUNT0;
+ dp->RXADDR1 = dp->RXADDR0; /* Both buffers overlapped.*/
+ }
+ else {
+ epr |= EPR_STAT_RX_NAK;
+ }
+#else
+ epr |= EPR_STAT_RX_NAK;
+#endif
+ }
+
+ /* Resetting the data toggling bits for this endpoint.*/
+ if (STM32_USB->EPR[ep] & EPR_DTOG_RX) {
+ epr |= EPR_DTOG_RX;
+ }
+
+ if (STM32_USB->EPR[ep] & EPR_DTOG_TX) {
+ epr |= EPR_DTOG_TX;
+ }
+
+ /* EPxR register setup.*/
+ EPR_SET(ep, epr | ep);
+ EPR_TOGGLE(ep, epr);
+}
+
+/**
+ * @brief Disables all the active endpoints except the endpoint zero.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ *
+ * @notapi
+ */
+void usb_lld_disable_endpoints(USBDriver *usbp) {
+ unsigned i;
+
+ /* Resets the packet memory allocator.*/
+ usb_pm_reset(usbp);
+
+ /* Disabling all endpoints.*/
+ for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) {
+ EPR_TOGGLE(i, 0);
+ EPR_SET(i, 0);
+ }
+}
+
+/**
+ * @brief Returns the status of an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
+ case EPR_STAT_RX_DIS:
+ return EP_STATUS_DISABLED;
+ case EPR_STAT_RX_STALL:
+ return EP_STATUS_STALLED;
+ default:
+ return EP_STATUS_ACTIVE;
+ }
+}
+
+/**
+ * @brief Returns the status of an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return The endpoint status.
+ * @retval EP_STATUS_DISABLED The endpoint is not active.
+ * @retval EP_STATUS_STALLED The endpoint is stalled.
+ * @retval EP_STATUS_ACTIVE The endpoint is active.
+ *
+ * @notapi
+ */
+usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+ switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
+ case EPR_STAT_TX_DIS:
+ return EP_STATUS_DISABLED;
+ case EPR_STAT_TX_STALL:
+ return EP_STATUS_STALLED;
+ default:
+ return EP_STATUS_ACTIVE;
+ }
+}
+
+/**
+ * @brief Reads a setup packet from the dedicated packet buffer.
+ * @details This function must be invoked in the context of the @p setup_cb
+ * callback in order to read the received setup packet.
+ * @pre In order to use this function the endpoint must have been
+ * initialized as a control endpoint.
+ * @post The endpoint is ready to accept another packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[out] buf buffer where to copy the packet data
+ *
+ * @notapi
+ */
+void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
+ stm32_usb_pma_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ uint32_t n;
+
+ (void)usbp;
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->RXADDR0);
+ for (n = 0; n < 4; n++) {
+ *(uint16_t *)buf = (uint16_t)*pmap++;
+ buf += 2;
+ }
+}
+
+/**
+ * @brief Starts a receive operation on an OUT endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
+ USBOutEndpointState *osp = usbp->epc[ep]->out_state;
+
+ /* Transfer initialization.*/
+ if (osp->rxsize == 0) /* Special case for zero sized packets.*/
+ osp->rxpkts = 1;
+ else
+ osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
+ usbp->epc[ep]->out_maxsize);
+
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+}
+
+/**
+ * @brief Starts a transmit operation on an IN endpoint.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
+ size_t n;
+ USBInEndpointState *isp = usbp->epc[ep]->in_state;
+
+ /* Transfer initialization.*/
+ n = isp->txsize;
+ if (n > (size_t)usbp->epc[ep]->in_maxsize)
+ n = (size_t)usbp->epc[ep]->in_maxsize;
+
+ isp->txlast = n;
+ usb_packet_write_from_buffer(ep, isp->txbuf, n);
+
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
+}
+
+/**
+ * @brief Brings an OUT endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
+}
+
+/**
+ * @brief Brings an IN endpoint in the stalled state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
+}
+
+/**
+ * @brief Brings an OUT endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ /* Makes sure to not put to NAK an endpoint that is already
+ transferring.*/
+ if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
+ EPR_SET_STAT_TX(ep, EPR_STAT_RX_NAK);
+}
+
+/**
+ * @brief Brings an IN endpoint in the active state.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ *
+ * @notapi
+ */
+void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
+
+ (void)usbp;
+
+ /* Makes sure to not put to NAK an endpoint that is already
+ transferring.*/
+ if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
+}
+
+#endif /* HAL_USE_USB */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h
index 1270172fc4..83c369ea8d 100644
--- a/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h
+++ b/os/hal/ports/STM32/LLD/USBv1/hal_usb_lld.h
@@ -1,521 +1,521 @@
-/*
- 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 USBv1/hal_usb_lld.h
- * @brief STM32 USB subsystem low level driver header.
- *
- * @addtogroup USB
- * @{
- */
-
-#ifndef HAL_USB_LLD_H
-#define HAL_USB_LLD_H
-
-#if HAL_USE_USB || defined(__DOXYGEN__)
-
-#include "stm32_usb.h"
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @brief Maximum endpoint address.
- */
-#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER
-
-/**
- * @brief Status stage handling method.
- */
-#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
-
-/**
- * @brief This device requires the address change after the status packet.
- */
-#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
-
-/**
- * @brief Method for set address acknowledge.
- */
-#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @brief USB1 driver enable switch.
- * @details If set to @p TRUE the support for USB1 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_USB_USE_USB1) || defined(__DOXYGEN__)
-#define STM32_USB_USE_USB1 FALSE
-#endif
-
-/**
- * @brief Enables the USB device low power mode on suspend.
- */
-#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__)
-#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
-#endif
-
-/**
- * @brief USB1 interrupt priority level setting.
- */
-#if (!defined(STM32_USB_USB1_HP_IRQ_PRIORITY) && \
- (STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER)) || defined(__DOXYGEN__)
-#define STM32_USB_USB1_HP_IRQ_PRIORITY 13
-#endif
-
-/**
- * @brief USB1 interrupt priority level setting.
- */
-#if !defined(STM32_USB_USB1_LP_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
-#endif
-
-/**
- * @brief Enables isochronous support.
- * @note Isochronous support requires special handling and this makes the
- * code size increase significantly.
- */
-#if !defined(STM32_USB_USE_ISOCHRONOUS) || defined(__DOXYGEN__)
-#define STM32_USB_USE_ISOCHRONOUS FALSE
-#endif
-
-/**
- * @brief Use faster copy for packets.
- * @note Makes the driver larger.
- */
-#if !defined(STM32_USB_USE_FAST_COPY) || defined(__DOXYGEN__)
-#define STM32_USB_USE_FAST_COPY FALSE
-#endif
-
-/**
- * @brief Host wake-up procedure duration.
- */
-#if !defined(STM32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
-#define STM32_USB_HOST_WAKEUP_DURATION 2
-#endif
-
-/**
- * @brief Allowed deviation for the 48MHz clock.
- */
-#if !defined(STM32_USB_48MHZ_DELTA) || defined(__DOXYGEN__)
-#define STM32_USB_48MHZ_DELTA 0
-#endif
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_USB_USE_USB1 && !STM32_HAS_USB
-#error "USB not present in the selected device"
-#endif
-
-#if !STM32_USB_USE_USB1
-#error "USB driver activated but no USB peripheral assigned"
-#endif
-
-#if STM32_USB_USE_USB1 && \
- (STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER) && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_USB1_HP_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USB HP"
-#endif
-
-#if STM32_USB_USE_USB1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_USB1_LP_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to USB LP"
-#endif
-
-#if !defined(STM32_USB1_HP_HANDLER)
-#error "STM32_USB1_HP_HANDLER not defined"
-#endif
-
-#if !defined(STM32_USB1_HP_NUMBER)
-#error "STM32_USB1_HP_NUMBER not defined"
-#endif
-
-#if !defined(STM32_USB1_LP_HANDLER)
-#error "STM32_USB1_LP_HANDLER not defined"
-#endif
-
-#if !defined(STM32_USB1_LP_NUMBER)
-#error "STM32_USB1_LP_NUMBER not defined"
-#endif
-
-#if (STM32_USB_HOST_WAKEUP_DURATION < 2) || (STM32_USB_HOST_WAKEUP_DURATION > 15)
-#error "invalid STM32_USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
-#endif
-
-#if (STM32_USB_48MHZ_DELTA < 0) || (STM32_USB_48MHZ_DELTA > 250000)
-#error "invalid STM32_USB_48MHZ_DELTA setting, it must not exceed 250000"
-#endif
-
-#if (STM32_USBCLK < (48000000 - STM32_USB_48MHZ_DELTA)) || \
- (STM32_USBCLK > (48000000 + STM32_USB_48MHZ_DELTA))
-#error "the USB driver requires a 48MHz clock"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of an IN endpoint state structure.
- */
-typedef struct {
- /**
- * @brief Requested transmit transfer size.
- */
- size_t txsize;
- /**
- * @brief Transmitted bytes so far.
- */
- size_t txcnt;
- /**
- * @brief Pointer to the transmission linear buffer.
- */
- const uint8_t *txbuf;
-#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Waiting thread.
- */
- thread_reference_t thread;
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Size of the last transmitted packet.
- */
- size_t txlast;
-} USBInEndpointState;
-
-/**
- * @brief Type of an OUT endpoint state structure.
- */
-typedef struct {
- /**
- * @brief Requested receive transfer size.
- */
- size_t rxsize;
- /**
- * @brief Received bytes so far.
- */
- size_t rxcnt;
- /**
- * @brief Pointer to the receive linear buffer.
- */
- uint8_t *rxbuf;
-#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
- /**
- * @brief Waiting thread.
- */
- thread_reference_t thread;
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Number of packets to receive.
- */
- uint16_t rxpkts;
-} USBOutEndpointState;
-
-/**
- * @brief Type of an USB endpoint configuration structure.
- * @note Platform specific restrictions may apply to endpoints.
- */
-typedef struct {
- /**
- * @brief Type and mode of the endpoint.
- */
- uint32_t ep_mode;
- /**
- * @brief Setup packet notification callback.
- * @details This callback is invoked when a setup packet has been
- * received.
- * @post The application must immediately call @p usbReadPacket() in
- * order to access the received packet.
- * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
- * endpoints, it should be set to @p NULL for other endpoint
- * types.
- */
- usbepcallback_t setup_cb;
- /**
- * @brief IN endpoint notification callback.
- * @details This field must be set to @p NULL if callback is not required.
- */
- usbepcallback_t in_cb;
- /**
- * @brief OUT endpoint notification callback.
- * @details This field must be set to @p NULL if callback is not required.
- */
- usbepcallback_t out_cb;
- /**
- * @brief IN endpoint maximum packet size.
- * @details This field must be set to zero if the IN endpoint is not used.
- */
- uint16_t in_maxsize;
- /**
- * @brief OUT endpoint maximum packet size.
- * @details This field must be set to zero if the OUT endpoint is not used.
- */
- uint16_t out_maxsize;
- /**
- * @brief @p USBEndpointState associated to the IN endpoint.
- * @details This field must be set to @p NULL if the IN endpoint is not
- * used.
- */
- USBInEndpointState *in_state;
- /**
- * @brief @p USBEndpointState associated to the OUT endpoint.
- * @details This field must be set to @p NULL if the OUT endpoint is not
- * used.
- */
- USBOutEndpointState *out_state;
- /* End of the mandatory fields.*/
- /**
- * @brief Reserved field, not currently used.
- * @note Initialize this field to 1 in order to be forward compatible.
- */
- uint16_t ep_buffers;
- /**
- * @brief Pointer to a buffer for setup packets.
- * @details Setup packets require a dedicated 8-bytes buffer, set this
- * field to @p NULL for non-control endpoints.
- */
- uint8_t *setup_buf;
-} USBEndpointConfig;
-
-/**
- * @brief Type of an USB driver configuration structure.
- */
-typedef struct {
- /**
- * @brief USB events callback.
- * @details This callback is invoked when an USB driver event is registered.
- */
- usbeventcb_t event_cb;
- /**
- * @brief Device GET_DESCRIPTOR request callback.
- * @note This callback is mandatory and cannot be set to @p NULL.
- */
- usbgetdescriptor_t get_descriptor_cb;
- /**
- * @brief Requests hook callback.
- * @details This hook allows to be notified of standard requests or to
- * handle non standard requests.
- */
- usbreqhandler_t requests_hook_cb;
- /**
- * @brief Start Of Frame callback.
- */
- usbcallback_t sof_cb;
- /* End of the mandatory fields.*/
-} USBConfig;
-
-/**
- * @brief Structure representing an USB driver.
- */
-struct USBDriver {
- /**
- * @brief Driver state.
- */
- usbstate_t state;
- /**
- * @brief Current configuration data.
- */
- const USBConfig *config;
- /**
- * @brief Bit map of the transmitting IN endpoints.
- */
- uint16_t transmitting;
- /**
- * @brief Bit map of the receiving OUT endpoints.
- */
- uint16_t receiving;
- /**
- * @brief Active endpoints configurations.
- */
- const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
- /**
- * @brief Fields available to user, it can be used to associate an
- * application-defined handler to an IN endpoint.
- * @note The base index is one, the endpoint zero does not have a
- * reserved element in this array.
- */
- void *in_params[USB_MAX_ENDPOINTS];
- /**
- * @brief Fields available to user, it can be used to associate an
- * application-defined handler to an OUT endpoint.
- * @note The base index is one, the endpoint zero does not have a
- * reserved element in this array.
- */
- void *out_params[USB_MAX_ENDPOINTS];
- /**
- * @brief Endpoint 0 state.
- */
- usbep0state_t ep0state;
- /**
- * @brief Next position in the buffer to be transferred through endpoint 0.
- */
- uint8_t *ep0next;
- /**
- * @brief Number of bytes yet to be transferred through endpoint 0.
- */
- size_t ep0n;
- /**
- * @brief Endpoint 0 end transaction callback.
- */
- usbcallback_t ep0endcb;
- /**
- * @brief Setup packet buffer.
- */
- uint8_t setup[8];
- /**
- * @brief Current USB device status.
- */
- uint16_t status;
- /**
- * @brief Assigned USB address.
- */
- uint8_t address;
- /**
- * @brief Current USB device configuration.
- */
- uint8_t configuration;
- /**
- * @brief State of the driver when a suspend happened.
- */
- usbstate_t saved_state;
-#if defined(USB_DRIVER_EXT_FIELDS)
- USB_DRIVER_EXT_FIELDS
-#endif
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the next address in the packet memory.
- */
- uint32_t pmnext;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Returns the current frame number.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @return The current frame number.
- *
- * @notapi
- */
-#define usb_lld_get_frame_number(usbp) (STM32_USB->FNR & FNR_FN_MASK)
-
-/**
- * @brief Returns the exact size of a receive transaction.
- * @details The received size can be different from the size specified in
- * @p usbStartReceiveI() because the last packet could have a size
- * different from the expected one.
- * @pre The OUT endpoint must have been configured in transaction mode
- * in order to use this function.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @return Received data size.
- *
- * @notapi
- */
-#define usb_lld_get_transaction_size(usbp, ep) \
- ((usbp)->epc[ep]->out_state->rxcnt)
-
-#if STM32_USB_HAS_BCDR || defined(__DOXYGEN__)
-/**
- * @brief Connects the USB device.
- *
- * @notapi
- */
-#if !defined(usb_lld_connect_bus)
-#define usb_lld_connect_bus(usbp) (STM32_USB->BCDR |= USB_BCDR_DPPU)
-#endif
-
-/**
- * @brief Disconnect the USB device.
- *
- * @notapi
- */
-#if !defined(usb_lld_disconnect_bus)
-#define usb_lld_disconnect_bus(usbp) (STM32_USB->BCDR &= ~USB_BCDR_DPPU)
-#endif
-#endif /* STM32_USB_HAS_BCDR */
-
-#if defined(STM32L1XX)
-#if !defined(usb_lld_connect_bus)
-#define usb_lld_connect_bus(usbp) (SYSCFG->PMC |= SYSCFG_PMC_USB_PU)
-#endif
-
-#if !defined(usb_lld_disconnect_bus)
-#define usb_lld_disconnect_bus(usbp) (SYSCFG->PMC &= ~SYSCFG_PMC_USB_PU)
-#endif
-#endif /* STM32L1XX */
-
-/**
- * @brief Start of host wake-up procedure.
- *
- * @notapi
- */
-#define usb_lld_wakeup_host(usbp) \
- do { \
- STM32_USB->CNTR |= USB_CNTR_RESUME; \
- osalThreadSleepMilliseconds(STM32_USB_HOST_WAKEUP_DURATION); \
- STM32_USB->CNTR &= ~USB_CNTR_RESUME; \
- } while (false)
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_USB_USE_USB1 && !defined(__DOXYGEN__)
-extern USBDriver USBD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void usb_lld_init(void);
- void usb_lld_start(USBDriver *usbp);
- void usb_lld_stop(USBDriver *usbp);
- void usb_lld_reset(USBDriver *usbp);
- void usb_lld_set_address(USBDriver *usbp);
- void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
- void usb_lld_disable_endpoints(USBDriver *usbp);
- usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
- usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
- void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
- void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
- void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
- void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_USB */
-
-#endif /* HAL_USB_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 USBv1/hal_usb_lld.h
+ * @brief STM32 USB subsystem low level driver header.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef HAL_USB_LLD_H
+#define HAL_USB_LLD_H
+
+#if HAL_USE_USB || defined(__DOXYGEN__)
+
+#include "stm32_usb.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Maximum endpoint address.
+ */
+#define USB_MAX_ENDPOINTS USB_ENDOPOINTS_NUMBER
+
+/**
+ * @brief Status stage handling method.
+ */
+#define USB_EP0_STATUS_STAGE USB_EP0_STATUS_STAGE_SW
+
+/**
+ * @brief This device requires the address change after the status packet.
+ */
+#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
+
+/**
+ * @brief Method for set address acknowledge.
+ */
+#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief USB1 driver enable switch.
+ * @details If set to @p TRUE the support for USB1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_USB_USE_USB1) || defined(__DOXYGEN__)
+#define STM32_USB_USE_USB1 FALSE
+#endif
+
+/**
+ * @brief Enables the USB device low power mode on suspend.
+ */
+#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__)
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#endif
+
+/**
+ * @brief USB1 interrupt priority level setting.
+ */
+#if (!defined(STM32_USB_USB1_HP_IRQ_PRIORITY) && \
+ (STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER)) || defined(__DOXYGEN__)
+#define STM32_USB_USB1_HP_IRQ_PRIORITY 13
+#endif
+
+/**
+ * @brief USB1 interrupt priority level setting.
+ */
+#if !defined(STM32_USB_USB1_LP_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
+#endif
+
+/**
+ * @brief Enables isochronous support.
+ * @note Isochronous support requires special handling and this makes the
+ * code size increase significantly.
+ */
+#if !defined(STM32_USB_USE_ISOCHRONOUS) || defined(__DOXYGEN__)
+#define STM32_USB_USE_ISOCHRONOUS FALSE
+#endif
+
+/**
+ * @brief Use faster copy for packets.
+ * @note Makes the driver larger.
+ */
+#if !defined(STM32_USB_USE_FAST_COPY) || defined(__DOXYGEN__)
+#define STM32_USB_USE_FAST_COPY FALSE
+#endif
+
+/**
+ * @brief Host wake-up procedure duration.
+ */
+#if !defined(STM32_USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
+#define STM32_USB_HOST_WAKEUP_DURATION 2
+#endif
+
+/**
+ * @brief Allowed deviation for the 48MHz clock.
+ */
+#if !defined(STM32_USB_48MHZ_DELTA) || defined(__DOXYGEN__)
+#define STM32_USB_48MHZ_DELTA 0
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_USB1 && !STM32_HAS_USB
+#error "USB not present in the selected device"
+#endif
+
+#if !STM32_USB_USE_USB1
+#error "USB driver activated but no USB peripheral assigned"
+#endif
+
+#if STM32_USB_USE_USB1 && \
+ (STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER) && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_USB1_HP_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USB HP"
+#endif
+
+#if STM32_USB_USE_USB1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_USB_USB1_LP_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to USB LP"
+#endif
+
+#if !defined(STM32_USB1_HP_HANDLER)
+#error "STM32_USB1_HP_HANDLER not defined"
+#endif
+
+#if !defined(STM32_USB1_HP_NUMBER)
+#error "STM32_USB1_HP_NUMBER not defined"
+#endif
+
+#if !defined(STM32_USB1_LP_HANDLER)
+#error "STM32_USB1_LP_HANDLER not defined"
+#endif
+
+#if !defined(STM32_USB1_LP_NUMBER)
+#error "STM32_USB1_LP_NUMBER not defined"
+#endif
+
+#if (STM32_USB_HOST_WAKEUP_DURATION < 2) || (STM32_USB_HOST_WAKEUP_DURATION > 15)
+#error "invalid STM32_USB_HOST_WAKEUP_DURATION setting, it must be between 2 and 15"
+#endif
+
+#if (STM32_USB_48MHZ_DELTA < 0) || (STM32_USB_48MHZ_DELTA > 250000)
+#error "invalid STM32_USB_48MHZ_DELTA setting, it must not exceed 250000"
+#endif
+
+#if (STM32_USBCLK < (48000000 - STM32_USB_48MHZ_DELTA)) || \
+ (STM32_USBCLK > (48000000 + STM32_USB_48MHZ_DELTA))
+#error "the USB driver requires a 48MHz clock"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of an IN endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Requested transmit transfer size.
+ */
+ size_t txsize;
+ /**
+ * @brief Transmitted bytes so far.
+ */
+ size_t txcnt;
+ /**
+ * @brief Pointer to the transmission linear buffer.
+ */
+ const uint8_t *txbuf;
+#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ thread_reference_t thread;
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Size of the last transmitted packet.
+ */
+ size_t txlast;
+} USBInEndpointState;
+
+/**
+ * @brief Type of an OUT endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Requested receive transfer size.
+ */
+ size_t rxsize;
+ /**
+ * @brief Received bytes so far.
+ */
+ size_t rxcnt;
+ /**
+ * @brief Pointer to the receive linear buffer.
+ */
+ uint8_t *rxbuf;
+#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ thread_reference_t thread;
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Number of packets to receive.
+ */
+ uint16_t rxpkts;
+} USBOutEndpointState;
+
+/**
+ * @brief Type of an USB endpoint configuration structure.
+ * @note Platform specific restrictions may apply to endpoints.
+ */
+typedef struct {
+ /**
+ * @brief Type and mode of the endpoint.
+ */
+ uint32_t ep_mode;
+ /**
+ * @brief Setup packet notification callback.
+ * @details This callback is invoked when a setup packet has been
+ * received.
+ * @post The application must immediately call @p usbReadPacket() in
+ * order to access the received packet.
+ * @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
+ * endpoints, it should be set to @p NULL for other endpoint
+ * types.
+ */
+ usbepcallback_t setup_cb;
+ /**
+ * @brief IN endpoint notification callback.
+ * @details This field must be set to @p NULL if callback is not required.
+ */
+ usbepcallback_t in_cb;
+ /**
+ * @brief OUT endpoint notification callback.
+ * @details This field must be set to @p NULL if callback is not required.
+ */
+ usbepcallback_t out_cb;
+ /**
+ * @brief IN endpoint maximum packet size.
+ * @details This field must be set to zero if the IN endpoint is not used.
+ */
+ uint16_t in_maxsize;
+ /**
+ * @brief OUT endpoint maximum packet size.
+ * @details This field must be set to zero if the OUT endpoint is not used.
+ */
+ uint16_t out_maxsize;
+ /**
+ * @brief @p USBEndpointState associated to the IN endpoint.
+ * @details This field must be set to @p NULL if the IN endpoint is not
+ * used.
+ */
+ USBInEndpointState *in_state;
+ /**
+ * @brief @p USBEndpointState associated to the OUT endpoint.
+ * @details This field must be set to @p NULL if the OUT endpoint is not
+ * used.
+ */
+ USBOutEndpointState *out_state;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Reserved field, not currently used.
+ * @note Initialize this field to 1 in order to be forward compatible.
+ */
+ uint16_t ep_buffers;
+ /**
+ * @brief Pointer to a buffer for setup packets.
+ * @details Setup packets require a dedicated 8-bytes buffer, set this
+ * field to @p NULL for non-control endpoints.
+ */
+ uint8_t *setup_buf;
+} USBEndpointConfig;
+
+/**
+ * @brief Type of an USB driver configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief USB events callback.
+ * @details This callback is invoked when an USB driver event is registered.
+ */
+ usbeventcb_t event_cb;
+ /**
+ * @brief Device GET_DESCRIPTOR request callback.
+ * @note This callback is mandatory and cannot be set to @p NULL.
+ */
+ usbgetdescriptor_t get_descriptor_cb;
+ /**
+ * @brief Requests hook callback.
+ * @details This hook allows to be notified of standard requests or to
+ * handle non standard requests.
+ */
+ usbreqhandler_t requests_hook_cb;
+ /**
+ * @brief Start Of Frame callback.
+ */
+ usbcallback_t sof_cb;
+ /* End of the mandatory fields.*/
+} USBConfig;
+
+/**
+ * @brief Structure representing an USB driver.
+ */
+struct USBDriver {
+ /**
+ * @brief Driver state.
+ */
+ usbstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const USBConfig *config;
+ /**
+ * @brief Bit map of the transmitting IN endpoints.
+ */
+ uint16_t transmitting;
+ /**
+ * @brief Bit map of the receiving OUT endpoints.
+ */
+ uint16_t receiving;
+ /**
+ * @brief Active endpoints configurations.
+ */
+ const USBEndpointConfig *epc[USB_MAX_ENDPOINTS + 1];
+ /**
+ * @brief Fields available to user, it can be used to associate an
+ * application-defined handler to an IN endpoint.
+ * @note The base index is one, the endpoint zero does not have a
+ * reserved element in this array.
+ */
+ void *in_params[USB_MAX_ENDPOINTS];
+ /**
+ * @brief Fields available to user, it can be used to associate an
+ * application-defined handler to an OUT endpoint.
+ * @note The base index is one, the endpoint zero does not have a
+ * reserved element in this array.
+ */
+ void *out_params[USB_MAX_ENDPOINTS];
+ /**
+ * @brief Endpoint 0 state.
+ */
+ usbep0state_t ep0state;
+ /**
+ * @brief Next position in the buffer to be transferred through endpoint 0.
+ */
+ uint8_t *ep0next;
+ /**
+ * @brief Number of bytes yet to be transferred through endpoint 0.
+ */
+ size_t ep0n;
+ /**
+ * @brief Endpoint 0 end transaction callback.
+ */
+ usbcallback_t ep0endcb;
+ /**
+ * @brief Setup packet buffer.
+ */
+ uint8_t setup[8];
+ /**
+ * @brief Current USB device status.
+ */
+ uint16_t status;
+ /**
+ * @brief Assigned USB address.
+ */
+ uint8_t address;
+ /**
+ * @brief Current USB device configuration.
+ */
+ uint8_t configuration;
+ /**
+ * @brief State of the driver when a suspend happened.
+ */
+ usbstate_t saved_state;
+#if defined(USB_DRIVER_EXT_FIELDS)
+ USB_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the next address in the packet memory.
+ */
+ uint32_t pmnext;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the current frame number.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @return The current frame number.
+ *
+ * @notapi
+ */
+#define usb_lld_get_frame_number(usbp) (STM32_USB->FNR & FNR_FN_MASK)
+
+/**
+ * @brief Returns the exact size of a receive transaction.
+ * @details The received size can be different from the size specified in
+ * @p usbStartReceiveI() because the last packet could have a size
+ * different from the expected one.
+ * @pre The OUT endpoint must have been configured in transaction mode
+ * in order to use this function.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @return Received data size.
+ *
+ * @notapi
+ */
+#define usb_lld_get_transaction_size(usbp, ep) \
+ ((usbp)->epc[ep]->out_state->rxcnt)
+
+#if STM32_USB_HAS_BCDR || defined(__DOXYGEN__)
+/**
+ * @brief Connects the USB device.
+ *
+ * @notapi
+ */
+#if !defined(usb_lld_connect_bus)
+#define usb_lld_connect_bus(usbp) (STM32_USB->BCDR |= USB_BCDR_DPPU)
+#endif
+
+/**
+ * @brief Disconnect the USB device.
+ *
+ * @notapi
+ */
+#if !defined(usb_lld_disconnect_bus)
+#define usb_lld_disconnect_bus(usbp) (STM32_USB->BCDR &= ~USB_BCDR_DPPU)
+#endif
+#endif /* STM32_USB_HAS_BCDR */
+
+#if defined(STM32L1XX)
+#if !defined(usb_lld_connect_bus)
+#define usb_lld_connect_bus(usbp) (SYSCFG->PMC |= SYSCFG_PMC_USB_PU)
+#endif
+
+#if !defined(usb_lld_disconnect_bus)
+#define usb_lld_disconnect_bus(usbp) (SYSCFG->PMC &= ~SYSCFG_PMC_USB_PU)
+#endif
+#endif /* STM32L1XX */
+
+/**
+ * @brief Start of host wake-up procedure.
+ *
+ * @notapi
+ */
+#define usb_lld_wakeup_host(usbp) \
+ do { \
+ STM32_USB->CNTR |= USB_CNTR_RESUME; \
+ osalThreadSleepMilliseconds(STM32_USB_HOST_WAKEUP_DURATION); \
+ STM32_USB->CNTR &= ~USB_CNTR_RESUME; \
+ } while (false)
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_USB_USE_USB1 && !defined(__DOXYGEN__)
+extern USBDriver USBD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void usb_lld_init(void);
+ void usb_lld_start(USBDriver *usbp);
+ void usb_lld_stop(USBDriver *usbp);
+ void usb_lld_reset(USBDriver *usbp);
+ void usb_lld_set_address(USBDriver *usbp);
+ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
+ void usb_lld_disable_endpoints(USBDriver *usbp);
+ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
+ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
+ void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
+ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_USB */
+
+#endif /* HAL_USB_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/USBv1/stm32_usb.h b/os/hal/ports/STM32/LLD/USBv1/stm32_usb.h
index 9a8595eadf..bd9be355cf 100644
--- a/os/hal/ports/STM32/LLD/USBv1/stm32_usb.h
+++ b/os/hal/ports/STM32/LLD/USBv1/stm32_usb.h
@@ -1,266 +1,266 @@
-/*
- 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 USBv1/stm32_usb.h
- * @brief STM32 USB registers layout header.
- * @note This file requires definitions from the ST STM32 header files
- * stm32f10x.h or stm32l1xx.h.
- *
- * @addtogroup USB
- * @{
- */
-
-#ifndef STM32_USB_H
-#define STM32_USB_H
-
-/**
- * @brief Number of the available endpoints.
- * @details This value does not include the endpoint 0 which is always present.
- */
-#define USB_ENDOPOINTS_NUMBER 7
-
-/**
- * @brief Width of USB packet memory accesses.
- */
-#if STM32_USB_ACCESS_SCHEME_2x16
-typedef uint16_t stm32_usb_pma_t;
-#else
-typedef uint32_t stm32_usb_pma_t;
-#endif
-
-/**
- * @brief USB registers block.
- */
-typedef struct {
- /**
- * @brief Endpoint registers.
- */
- volatile uint32_t EPR[USB_ENDOPOINTS_NUMBER + 1];
- /*
- * @brief Reserved space.
- */
- volatile uint32_t _r20[8];
- /*
- * @brief Control Register.
- */
- volatile uint32_t CNTR;
- /*
- * @brief Interrupt Status Register.
- */
- volatile uint32_t ISTR;
- /*
- * @brief Frame Number Register.
- */
- volatile uint32_t FNR;
- /*
- * @brief Device Address Register.
- */
- volatile uint32_t DADDR;
- /*
- * @brief Buffer Table Address.
- */
- volatile uint32_t BTABLE;
- /*
- * @brief LPM Control and Status Register.
- */
- volatile uint32_t LPMCSR;
-#if STM32_USB_HAS_BCDR
- /*
- * @brief Battery Charging Detector
- */
- volatile uint32_t BCDR;
-#endif
-} stm32_usb_t;
-
-/**
- * @brief USB descriptor registers block.
- */
-typedef struct {
- /**
- * @brief TX buffer offset register.
- */
- volatile stm32_usb_pma_t TXADDR0;
- /**
- * @brief TX counter register 0.
- */
- volatile stm32_usb_pma_t TXCOUNT0;
- /**
- * @brief RX buffer offset register.
- */
- volatile stm32_usb_pma_t RXADDR0;
- /**
- * @brief RX counter register 0.
- */
- volatile stm32_usb_pma_t RXCOUNT0;
-} stm32_usb_descriptor_t;
-
-/**
- * @name Register aliases
- * @{
- */
-#define RXCOUNT1 TXCOUNT0
-#define TXCOUNT1 RXCOUNT0
-#define RXADDR1 TXADDR0
-#define TXADDR1 RXADDR0
-/** @} */
-
-/**
- * @brief USB registers block numeric address.
- */
-#if defined(USB_BASE) || defined(__DOXYGEN__)
-#define STM32_USB_BASE USB_BASE
-#else
-#define STM32_USB_BASE (APB1PERIPH_BASE + 0x5C00)
-#endif
-
-/**
- * @brief USB RAM numeric address.
- */
-#if defined(USB_PMAADDR) || defined(__DOXYGEN__)
-#define STM32_USBRAM_BASE USB_PMAADDR
-#else
-#define STM32_USBRAM_BASE (APB1PERIPH_BASE + 0x6000)
-#endif
-
-/**
- * @brief Pointer to the USB registers block.
- */
-#define STM32_USB ((stm32_usb_t *)STM32_USB_BASE)
-
-/**
- * @brief Pointer to the USB RAM.
- */
-#define STM32_USBRAM ((stm32_usb_pma_t *)STM32_USBRAM_BASE)
-
-/**
- * @brief Mask of all the toggling bits in the EPR register.
- */
-#define EPR_TOGGLE_MASK (EPR_STAT_TX_MASK | EPR_DTOG_TX | \
- EPR_STAT_RX_MASK | EPR_DTOG_RX | \
- EPR_SETUP)
-
-#define EPR_EA_MASK 0x000F
-#define EPR_STAT_TX_MASK 0x0030
-#define EPR_STAT_TX_DIS 0x0000
-#define EPR_STAT_TX_STALL 0x0010
-#define EPR_STAT_TX_NAK 0x0020
-#define EPR_STAT_TX_VALID 0x0030
-#define EPR_DTOG_TX 0x0040
-#define EPR_SWBUF_RX EPR_DTOG_TX
-#define EPR_CTR_TX 0x0080
-#define EPR_EP_KIND 0x0100
-#define EPR_EP_DBL_BUF EPR_EP_KIND
-#define EPR_EP_STATUS_OUT EPR_EP_KIND
-#define EPR_EP_TYPE_MASK 0x0600
-#define EPR_EP_TYPE_BULK 0x0000
-#define EPR_EP_TYPE_CONTROL 0x0200
-#define EPR_EP_TYPE_ISO 0x0400
-#define EPR_EP_TYPE_INTERRUPT 0x0600
-#define EPR_SETUP 0x0800
-#define EPR_STAT_RX_MASK 0x3000
-#define EPR_STAT_RX_DIS 0x0000
-#define EPR_STAT_RX_STALL 0x1000
-#define EPR_STAT_RX_NAK 0x2000
-#define EPR_STAT_RX_VALID 0x3000
-#define EPR_DTOG_RX 0x4000
-#define EPR_SWBUF_TX EPR_DTOG_RX
-#define EPR_CTR_RX 0x8000
-
-#define CNTR_FRES 0x0001
-#define CNTR_PDWN 0x0002
-#define CNTR_LP_MODE 0x0004
-#define CNTR_FSUSP 0x0008
-#define CNTR_RESUME 0x0010
-#define CNTR_ESOFM 0x0100
-#define CNTR_SOFM 0x0200
-#define CNTR_RESETM 0x0400
-#define CNTR_SUSPM 0x0800
-#define CNTR_WKUPM 0x1000
-#define CNTR_ERRM 0x2000
-#define CNTR_PMAOVRM 0x4000
-#define CNTR_CTRM 0x8000
-
-#define ISTR_EP_ID_MASK 0x000F
-#define ISTR_DIR 0x0010
-#define ISTR_ESOF 0x0100
-#define ISTR_SOF 0x0200
-#define ISTR_RESET 0x0400
-#define ISTR_SUSP 0x0800
-#define ISTR_WKUP 0x1000
-#define ISTR_ERR 0x2000
-#define ISTR_PMAOVR 0x4000
-#define ISTR_CTR 0x8000
-
-#define FNR_FN_MASK 0x07FF
-#define FNR_LSOF 0x1800
-#define FNR_LCK 0x2000
-#define FNR_RXDM 0x4000
-#define FNR_RXDP 0x8000
-
-#define DADDR_ADD_MASK 0x007F
-#define DADDR_EF 0x0080
-
-#define RXCOUNT_COUNT_MASK 0x03FF
-#define TXCOUNT_COUNT_MASK 0x03FF
-
-#define EPR_CTR_MASK (EPR_CTR_TX | EPR_CTR_RX)
-
-#define EPR_SET(ep, epr) \
- STM32_USB->EPR[ep] = ((epr) & ~EPR_TOGGLE_MASK) | EPR_CTR_MASK
-
-#define EPR_TOGGLE(ep, epr) \
- STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] ^ ((epr) & EPR_TOGGLE_MASK)) \
- | EPR_CTR_MASK
-
-#define EPR_SET_STAT_RX(ep, epr) \
- STM32_USB->EPR[ep] = ((STM32_USB->EPR[ep] & \
- ~(EPR_TOGGLE_MASK & ~EPR_STAT_RX_MASK)) ^ \
- (epr)) | EPR_CTR_MASK
-
-#define EPR_SET_STAT_TX(ep, epr) \
- STM32_USB->EPR[ep] = ((STM32_USB->EPR[ep] & \
- ~(EPR_TOGGLE_MASK & ~EPR_STAT_TX_MASK)) ^ \
- (epr)) | EPR_CTR_MASK
-
-#define EPR_CLEAR_CTR_RX(ep) \
- STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & ~EPR_CTR_RX & ~EPR_TOGGLE_MASK)\
- | EPR_CTR_TX
-
-#define EPR_CLEAR_CTR_TX(ep) \
- STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & ~EPR_CTR_TX & ~EPR_TOGGLE_MASK)\
- | EPR_CTR_RX
-
-/**
- * @brief Returns an endpoint descriptor pointer.
- */
-#define USB_GET_DESCRIPTOR(ep) \
- ((stm32_usb_descriptor_t *)((uint32_t)STM32_USBRAM_BASE + \
- (uint32_t)STM32_USB->BTABLE + \
- (uint32_t)(ep) * \
- sizeof(stm32_usb_descriptor_t)))
-
-/**
- * @brief Converts from a PMA address to a physical address.
- */
-#define USB_ADDR2PTR(addr) \
- ((stm32_usb_pma_t *)((addr) * \
- (sizeof(stm32_usb_pma_t) / 2) + \
- STM32_USBRAM_BASE))
-
-#endif /* STM32_USB_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 USBv1/stm32_usb.h
+ * @brief STM32 USB registers layout header.
+ * @note This file requires definitions from the ST STM32 header files
+ * stm32f10x.h or stm32l1xx.h.
+ *
+ * @addtogroup USB
+ * @{
+ */
+
+#ifndef STM32_USB_H
+#define STM32_USB_H
+
+/**
+ * @brief Number of the available endpoints.
+ * @details This value does not include the endpoint 0 which is always present.
+ */
+#define USB_ENDOPOINTS_NUMBER 7
+
+/**
+ * @brief Width of USB packet memory accesses.
+ */
+#if STM32_USB_ACCESS_SCHEME_2x16
+typedef uint16_t stm32_usb_pma_t;
+#else
+typedef uint32_t stm32_usb_pma_t;
+#endif
+
+/**
+ * @brief USB registers block.
+ */
+typedef struct {
+ /**
+ * @brief Endpoint registers.
+ */
+ volatile uint32_t EPR[USB_ENDOPOINTS_NUMBER + 1];
+ /*
+ * @brief Reserved space.
+ */
+ volatile uint32_t _r20[8];
+ /*
+ * @brief Control Register.
+ */
+ volatile uint32_t CNTR;
+ /*
+ * @brief Interrupt Status Register.
+ */
+ volatile uint32_t ISTR;
+ /*
+ * @brief Frame Number Register.
+ */
+ volatile uint32_t FNR;
+ /*
+ * @brief Device Address Register.
+ */
+ volatile uint32_t DADDR;
+ /*
+ * @brief Buffer Table Address.
+ */
+ volatile uint32_t BTABLE;
+ /*
+ * @brief LPM Control and Status Register.
+ */
+ volatile uint32_t LPMCSR;
+#if STM32_USB_HAS_BCDR
+ /*
+ * @brief Battery Charging Detector
+ */
+ volatile uint32_t BCDR;
+#endif
+} stm32_usb_t;
+
+/**
+ * @brief USB descriptor registers block.
+ */
+typedef struct {
+ /**
+ * @brief TX buffer offset register.
+ */
+ volatile stm32_usb_pma_t TXADDR0;
+ /**
+ * @brief TX counter register 0.
+ */
+ volatile stm32_usb_pma_t TXCOUNT0;
+ /**
+ * @brief RX buffer offset register.
+ */
+ volatile stm32_usb_pma_t RXADDR0;
+ /**
+ * @brief RX counter register 0.
+ */
+ volatile stm32_usb_pma_t RXCOUNT0;
+} stm32_usb_descriptor_t;
+
+/**
+ * @name Register aliases
+ * @{
+ */
+#define RXCOUNT1 TXCOUNT0
+#define TXCOUNT1 RXCOUNT0
+#define RXADDR1 TXADDR0
+#define TXADDR1 RXADDR0
+/** @} */
+
+/**
+ * @brief USB registers block numeric address.
+ */
+#if defined(USB_BASE) || defined(__DOXYGEN__)
+#define STM32_USB_BASE USB_BASE
+#else
+#define STM32_USB_BASE (APB1PERIPH_BASE + 0x5C00)
+#endif
+
+/**
+ * @brief USB RAM numeric address.
+ */
+#if defined(USB_PMAADDR) || defined(__DOXYGEN__)
+#define STM32_USBRAM_BASE USB_PMAADDR
+#else
+#define STM32_USBRAM_BASE (APB1PERIPH_BASE + 0x6000)
+#endif
+
+/**
+ * @brief Pointer to the USB registers block.
+ */
+#define STM32_USB ((stm32_usb_t *)STM32_USB_BASE)
+
+/**
+ * @brief Pointer to the USB RAM.
+ */
+#define STM32_USBRAM ((stm32_usb_pma_t *)STM32_USBRAM_BASE)
+
+/**
+ * @brief Mask of all the toggling bits in the EPR register.
+ */
+#define EPR_TOGGLE_MASK (EPR_STAT_TX_MASK | EPR_DTOG_TX | \
+ EPR_STAT_RX_MASK | EPR_DTOG_RX | \
+ EPR_SETUP)
+
+#define EPR_EA_MASK 0x000F
+#define EPR_STAT_TX_MASK 0x0030
+#define EPR_STAT_TX_DIS 0x0000
+#define EPR_STAT_TX_STALL 0x0010
+#define EPR_STAT_TX_NAK 0x0020
+#define EPR_STAT_TX_VALID 0x0030
+#define EPR_DTOG_TX 0x0040
+#define EPR_SWBUF_RX EPR_DTOG_TX
+#define EPR_CTR_TX 0x0080
+#define EPR_EP_KIND 0x0100
+#define EPR_EP_DBL_BUF EPR_EP_KIND
+#define EPR_EP_STATUS_OUT EPR_EP_KIND
+#define EPR_EP_TYPE_MASK 0x0600
+#define EPR_EP_TYPE_BULK 0x0000
+#define EPR_EP_TYPE_CONTROL 0x0200
+#define EPR_EP_TYPE_ISO 0x0400
+#define EPR_EP_TYPE_INTERRUPT 0x0600
+#define EPR_SETUP 0x0800
+#define EPR_STAT_RX_MASK 0x3000
+#define EPR_STAT_RX_DIS 0x0000
+#define EPR_STAT_RX_STALL 0x1000
+#define EPR_STAT_RX_NAK 0x2000
+#define EPR_STAT_RX_VALID 0x3000
+#define EPR_DTOG_RX 0x4000
+#define EPR_SWBUF_TX EPR_DTOG_RX
+#define EPR_CTR_RX 0x8000
+
+#define CNTR_FRES 0x0001
+#define CNTR_PDWN 0x0002
+#define CNTR_LP_MODE 0x0004
+#define CNTR_FSUSP 0x0008
+#define CNTR_RESUME 0x0010
+#define CNTR_ESOFM 0x0100
+#define CNTR_SOFM 0x0200
+#define CNTR_RESETM 0x0400
+#define CNTR_SUSPM 0x0800
+#define CNTR_WKUPM 0x1000
+#define CNTR_ERRM 0x2000
+#define CNTR_PMAOVRM 0x4000
+#define CNTR_CTRM 0x8000
+
+#define ISTR_EP_ID_MASK 0x000F
+#define ISTR_DIR 0x0010
+#define ISTR_ESOF 0x0100
+#define ISTR_SOF 0x0200
+#define ISTR_RESET 0x0400
+#define ISTR_SUSP 0x0800
+#define ISTR_WKUP 0x1000
+#define ISTR_ERR 0x2000
+#define ISTR_PMAOVR 0x4000
+#define ISTR_CTR 0x8000
+
+#define FNR_FN_MASK 0x07FF
+#define FNR_LSOF 0x1800
+#define FNR_LCK 0x2000
+#define FNR_RXDM 0x4000
+#define FNR_RXDP 0x8000
+
+#define DADDR_ADD_MASK 0x007F
+#define DADDR_EF 0x0080
+
+#define RXCOUNT_COUNT_MASK 0x03FF
+#define TXCOUNT_COUNT_MASK 0x03FF
+
+#define EPR_CTR_MASK (EPR_CTR_TX | EPR_CTR_RX)
+
+#define EPR_SET(ep, epr) \
+ STM32_USB->EPR[ep] = ((epr) & ~EPR_TOGGLE_MASK) | EPR_CTR_MASK
+
+#define EPR_TOGGLE(ep, epr) \
+ STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] ^ ((epr) & EPR_TOGGLE_MASK)) \
+ | EPR_CTR_MASK
+
+#define EPR_SET_STAT_RX(ep, epr) \
+ STM32_USB->EPR[ep] = ((STM32_USB->EPR[ep] & \
+ ~(EPR_TOGGLE_MASK & ~EPR_STAT_RX_MASK)) ^ \
+ (epr)) | EPR_CTR_MASK
+
+#define EPR_SET_STAT_TX(ep, epr) \
+ STM32_USB->EPR[ep] = ((STM32_USB->EPR[ep] & \
+ ~(EPR_TOGGLE_MASK & ~EPR_STAT_TX_MASK)) ^ \
+ (epr)) | EPR_CTR_MASK
+
+#define EPR_CLEAR_CTR_RX(ep) \
+ STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & ~EPR_CTR_RX & ~EPR_TOGGLE_MASK)\
+ | EPR_CTR_TX
+
+#define EPR_CLEAR_CTR_TX(ep) \
+ STM32_USB->EPR[ep] = (STM32_USB->EPR[ep] & ~EPR_CTR_TX & ~EPR_TOGGLE_MASK)\
+ | EPR_CTR_RX
+
+/**
+ * @brief Returns an endpoint descriptor pointer.
+ */
+#define USB_GET_DESCRIPTOR(ep) \
+ ((stm32_usb_descriptor_t *)((uint32_t)STM32_USBRAM_BASE + \
+ (uint32_t)STM32_USB->BTABLE + \
+ (uint32_t)(ep) * \
+ sizeof(stm32_usb_descriptor_t)))
+
+/**
+ * @brief Converts from a PMA address to a physical address.
+ */
+#define USB_ADDR2PTR(addr) \
+ ((stm32_usb_pma_t *)((addr) * \
+ (sizeof(stm32_usb_pma_t) / 2) + \
+ STM32_USBRAM_BASE))
+
+#endif /* STM32_USB_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/xWDGv1/driver.mk b/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
index a4d8bddaa4..e6314fdff2 100644
--- a/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
+++ b/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
@@ -1,9 +1,9 @@
-ifeq ($(USE_SMART_BUILD),yes)
-ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
-endif
-
-PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1
+ifeq ($(USE_SMART_BUILD),yes)
+ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
+endif
+
+PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1
diff --git a/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c b/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
index 07c17a1ee0..44bdf14e55 100644
--- a/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
+++ b/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.c
@@ -1,135 +1,135 @@
-/*
- 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 xWDGv1/hal_wdg_lld.c
- * @brief WDG Driver subsystem low level driver source.
- *
- * @addtogroup WDG
- * @{
- */
-
-#include "hal.h"
-
-#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define KR_KEY_RELOAD 0xAAAAU
-#define KR_KEY_ENABLE 0xCCCCU
-#define KR_KEY_WRITE 0x5555U
-#define KR_KEY_PROTECT 0x0000U
-
-#if !defined(IWDG) && defined(IWDG1)
-#define IWDG IWDG1
-#endif
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-#if STM32_WDG_USE_IWDG || defined(__DOXYGEN__)
-WDGDriver WDGD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level WDG driver initialization.
- *
- * @notapi
- */
-void wdg_lld_init(void) {
-
-#if STM32_WDG_USE_IWDG
- WDGD1.state = WDG_STOP;
- WDGD1.wdg = IWDG;
-#endif
-}
-
-/**
- * @brief Configures and activates the WDG peripheral.
- *
- * @param[in] wdgp pointer to the @p WDGDriver object
- *
- * @notapi
- */
-void wdg_lld_start(WDGDriver *wdgp) {
-
- /* Enable IWDG and unlock for write.*/
- wdgp->wdg->KR = KR_KEY_ENABLE;
- wdgp->wdg->KR = KR_KEY_WRITE;
-
- /* Write configuration.*/
- wdgp->wdg->PR = wdgp->config->pr;
- wdgp->wdg->RLR = wdgp->config->rlr;
-
- /* Wait the registers to be updated.*/
- while (wdgp->wdg->SR != 0)
- ;
-
-#if STM32_IWDG_IS_WINDOWED
- /* This also triggers a refresh.*/
- wdgp->wdg->WINR = wdgp->config->winr;
-#else
- wdgp->wdg->KR = KR_KEY_RELOAD;
-#endif
-}
-
-/**
- * @brief Deactivates the WDG peripheral.
- *
- * @param[in] wdgp pointer to the @p WDGDriver object
- *
- * @notapi
- */
-void wdg_lld_stop(WDGDriver *wdgp) {
-
- osalDbgAssert(wdgp->state == WDG_STOP,
- "IWDG cannot be stopped once activated");
-}
-
-/**
- * @brief Reloads WDG's counter.
- *
- * @param[in] wdgp pointer to the @p WDGDriver object
- *
- * @notapi
- */
-void wdg_lld_reset(WDGDriver * wdgp) {
-
- wdgp->wdg->KR = KR_KEY_RELOAD;
-}
-
-#endif /* HAL_USE_WDG == 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 xWDGv1/hal_wdg_lld.c
+ * @brief WDG Driver subsystem low level driver source.
+ *
+ * @addtogroup WDG
+ * @{
+ */
+
+#include "hal.h"
+
+#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define KR_KEY_RELOAD 0xAAAAU
+#define KR_KEY_ENABLE 0xCCCCU
+#define KR_KEY_WRITE 0x5555U
+#define KR_KEY_PROTECT 0x0000U
+
+#if !defined(IWDG) && defined(IWDG1)
+#define IWDG IWDG1
+#endif
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+#if STM32_WDG_USE_IWDG || defined(__DOXYGEN__)
+WDGDriver WDGD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level WDG driver initialization.
+ *
+ * @notapi
+ */
+void wdg_lld_init(void) {
+
+#if STM32_WDG_USE_IWDG
+ WDGD1.state = WDG_STOP;
+ WDGD1.wdg = IWDG;
+#endif
+}
+
+/**
+ * @brief Configures and activates the WDG peripheral.
+ *
+ * @param[in] wdgp pointer to the @p WDGDriver object
+ *
+ * @notapi
+ */
+void wdg_lld_start(WDGDriver *wdgp) {
+
+ /* Enable IWDG and unlock for write.*/
+ wdgp->wdg->KR = KR_KEY_ENABLE;
+ wdgp->wdg->KR = KR_KEY_WRITE;
+
+ /* Write configuration.*/
+ wdgp->wdg->PR = wdgp->config->pr;
+ wdgp->wdg->RLR = wdgp->config->rlr;
+
+ /* Wait the registers to be updated.*/
+ while (wdgp->wdg->SR != 0)
+ ;
+
+#if STM32_IWDG_IS_WINDOWED
+ /* This also triggers a refresh.*/
+ wdgp->wdg->WINR = wdgp->config->winr;
+#else
+ wdgp->wdg->KR = KR_KEY_RELOAD;
+#endif
+}
+
+/**
+ * @brief Deactivates the WDG peripheral.
+ *
+ * @param[in] wdgp pointer to the @p WDGDriver object
+ *
+ * @notapi
+ */
+void wdg_lld_stop(WDGDriver *wdgp) {
+
+ osalDbgAssert(wdgp->state == WDG_STOP,
+ "IWDG cannot be stopped once activated");
+}
+
+/**
+ * @brief Reloads WDG's counter.
+ *
+ * @param[in] wdgp pointer to the @p WDGDriver object
+ *
+ * @notapi
+ */
+void wdg_lld_reset(WDGDriver * wdgp) {
+
+ wdgp->wdg->KR = KR_KEY_RELOAD;
+}
+
+#endif /* HAL_USE_WDG == TRUE */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.h b/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.h
index 752889976e..24979498a5 100644
--- a/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.h
+++ b/os/hal/ports/STM32/LLD/xWDGv1/hal_wdg_lld.h
@@ -1,183 +1,183 @@
-/*
- 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 xWDGv1/hal_wdg_lld.h
- * @brief WDG Driver subsystem low level driver header.
- *
- * @addtogroup WDG
- * @{
- */
-
-#ifndef HAL_WDG_LLD_H
-#define HAL_WDG_LLD_H
-
-#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name RLR register definitions
- * @{
- */
-#define STM32_IWDG_RL_MASK (0x00000FFF << 0)
-#define STM32_IWDG_RL(n) ((n) << 0)
-/** @} */
-
-/**
- * @name PR register definitions
- * @{
- */
-#define STM32_IWDG_PR_MASK (7 << 0)
-#define STM32_IWDG_PR_4 0U
-#define STM32_IWDG_PR_8 1U
-#define STM32_IWDG_PR_16 2U
-#define STM32_IWDG_PR_32 3U
-#define STM32_IWDG_PR_64 4U
-#define STM32_IWDG_PR_128 5U
-#define STM32_IWDG_PR_256 6U
-/** @} */
-
-/**
- * @name WINR register definitions
- * @{
- */
-#define STM32_IWDG_WIN_MASK (0x00000FFF << 0)
-#define STM32_IWDG_WIN(n) ((n) << 0)
-#define STM32_IWDG_WIN_DISABLED STM32_IWDG_WIN(0x00000FFF)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief IWDG driver enable switch.
- * @details If set to @p TRUE the support for IWDG is included.
- * @note The default is @p FALSE.
- */
-#if !defined(STM32_WDG_USE_IWDG) || defined(__DOXYGEN__)
-#define STM32_WDG_USE_IWDG FALSE
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_WDG_USE_IWDG && !STM32_HAS_IWDG
-#error "IWDG not present in the selected device"
-#endif
-
-#if !STM32_WDG_USE_IWDG
-#error "WDG driver activated but no xWDG peripheral assigned"
-#endif
-
-#if !defined(STM32_LSI_ENABLED)
-#error "STM32_LSI_ENABLED not defined"
-#endif
-
-#if (STM32_WDG_USE_IWDG == TRUE) && (STM32_LSI_ENABLED == FALSE)
-#error "IWDG requires LSI clock"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief Type of a structure representing an WDG driver.
- */
-typedef struct WDGDriver WDGDriver;
-
-/**
- * @brief Driver configuration structure.
- * @note It could be empty on some architectures.
- */
-typedef struct {
- /**
- * @brief Configuration of the IWDG_PR register.
- * @details See the STM32 reference manual for details.
- */
- uint32_t pr;
- /**
- * @brief Configuration of the IWDG_RLR register.
- * @details See the STM32 reference manual for details.
- */
- uint32_t rlr;
-#if STM32_IWDG_IS_WINDOWED || defined(__DOXYGEN__)
- /**
- * @brief Configuration of the IWDG_WINR register.
- * @details See the STM32 reference manual for details.
- * @note This field is not present in F1, F2, F4, L1 sub-families.
- */
- uint32_t winr;
-#endif
-} WDGConfig;
-
-/**
- * @brief Structure representing an WDG driver.
- */
-struct WDGDriver {
- /**
- * @brief Driver state.
- */
- wdgstate_t state;
- /**
- * @brief Current configuration data.
- */
- const WDGConfig *config;
- /* End of the mandatory fields.*/
- /**
- * @brief Pointer to the IWDG registers block.
- */
- IWDG_TypeDef *wdg;
-};
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_WDG_USE_IWDG && !defined(__DOXYGEN__)
-extern WDGDriver WDGD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void wdg_lld_init(void);
- void wdg_lld_start(WDGDriver *wdgp);
- void wdg_lld_stop(WDGDriver *wdgp);
- void wdg_lld_reset(WDGDriver *wdgp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_WDG == TRUE */
-
-#endif /* HAL_WDG_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 xWDGv1/hal_wdg_lld.h
+ * @brief WDG Driver subsystem low level driver header.
+ *
+ * @addtogroup WDG
+ * @{
+ */
+
+#ifndef HAL_WDG_LLD_H
+#define HAL_WDG_LLD_H
+
+#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name RLR register definitions
+ * @{
+ */
+#define STM32_IWDG_RL_MASK (0x00000FFF << 0)
+#define STM32_IWDG_RL(n) ((n) << 0)
+/** @} */
+
+/**
+ * @name PR register definitions
+ * @{
+ */
+#define STM32_IWDG_PR_MASK (7 << 0)
+#define STM32_IWDG_PR_4 0U
+#define STM32_IWDG_PR_8 1U
+#define STM32_IWDG_PR_16 2U
+#define STM32_IWDG_PR_32 3U
+#define STM32_IWDG_PR_64 4U
+#define STM32_IWDG_PR_128 5U
+#define STM32_IWDG_PR_256 6U
+/** @} */
+
+/**
+ * @name WINR register definitions
+ * @{
+ */
+#define STM32_IWDG_WIN_MASK (0x00000FFF << 0)
+#define STM32_IWDG_WIN(n) ((n) << 0)
+#define STM32_IWDG_WIN_DISABLED STM32_IWDG_WIN(0x00000FFF)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief IWDG driver enable switch.
+ * @details If set to @p TRUE the support for IWDG is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_WDG_USE_IWDG) || defined(__DOXYGEN__)
+#define STM32_WDG_USE_IWDG FALSE
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_WDG_USE_IWDG && !STM32_HAS_IWDG
+#error "IWDG not present in the selected device"
+#endif
+
+#if !STM32_WDG_USE_IWDG
+#error "WDG driver activated but no xWDG peripheral assigned"
+#endif
+
+#if !defined(STM32_LSI_ENABLED)
+#error "STM32_LSI_ENABLED not defined"
+#endif
+
+#if (STM32_WDG_USE_IWDG == TRUE) && (STM32_LSI_ENABLED == FALSE)
+#error "IWDG requires LSI clock"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a structure representing an WDG driver.
+ */
+typedef struct WDGDriver WDGDriver;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Configuration of the IWDG_PR register.
+ * @details See the STM32 reference manual for details.
+ */
+ uint32_t pr;
+ /**
+ * @brief Configuration of the IWDG_RLR register.
+ * @details See the STM32 reference manual for details.
+ */
+ uint32_t rlr;
+#if STM32_IWDG_IS_WINDOWED || defined(__DOXYGEN__)
+ /**
+ * @brief Configuration of the IWDG_WINR register.
+ * @details See the STM32 reference manual for details.
+ * @note This field is not present in F1, F2, F4, L1 sub-families.
+ */
+ uint32_t winr;
+#endif
+} WDGConfig;
+
+/**
+ * @brief Structure representing an WDG driver.
+ */
+struct WDGDriver {
+ /**
+ * @brief Driver state.
+ */
+ wdgstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const WDGConfig *config;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the IWDG registers block.
+ */
+ IWDG_TypeDef *wdg;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_WDG_USE_IWDG && !defined(__DOXYGEN__)
+extern WDGDriver WDGD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void wdg_lld_init(void);
+ void wdg_lld_start(WDGDriver *wdgp);
+ void wdg_lld_stop(WDGDriver *wdgp);
+ void wdg_lld_reset(WDGDriver *wdgp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_WDG == TRUE */
+
+#endif /* HAL_WDG_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F0xx/hal_lld.c b/os/hal/ports/STM32/STM32F0xx/hal_lld.c
index 2815d5f611..cc81125119 100644
--- a/os/hal/ports/STM32/STM32F0xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F0xx/hal_lld.c
@@ -1,363 +1,364 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..df7ff7fe7b 100644
--- a/os/hal/ports/STM32/STM32F0xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32F0xx/hal_lld.h
@@ -1,1025 +1,1033 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32F0xx/platform.mk b/os/hal/ports/STM32/STM32F0xx/platform.mk
index b8975be7eb..276f3556ae 100644
--- a/os/hal/ports/STM32/STM32F0xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F0xx/platform.mk
@@ -1,44 +1,44 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx
-
-# 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/ADCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx
+
+# 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/ADCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/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/STM32F0xx/stm32_isr.c b/os/hal/ports/STM32/STM32F0xx/stm32_isr.c
index 489388e24a..6077862e1b 100644
--- a/os/hal/ports/STM32/STM32F0xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32F0xx/stm32_isr.c
@@ -1,286 +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 STM32F0xx/stm32_isr.c
- * @brief STM32F0xx ISR handler code.
- *
- * @addtogroup STM32F0xx_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_1_HANDLER)
-/**
- * @brief EXTI[0]...EXTI[1] interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector54) {
- uint32_t pr;
-
- OSAL_IRQ_PROLOGUE();
-
- pr = EXTI->PR;
- pr &= ((1U << 0) | (1U << 1));
- EXTI->PR = pr;
-
- exti_serve_irq(pr, 0);
- exti_serve_irq(pr, 1);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if !defined(STM32_DISABLE_EXTI2_3_HANDLER)
-/**
- * @brief EXTI[2]...EXTI[3] interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector58) {
- uint32_t pr;
-
- OSAL_IRQ_PROLOGUE();
-
- pr = EXTI->PR;
- pr &= ((1U << 2) | (1U << 3));
- EXTI->PR = pr;
-
- exti_serve_irq(pr, 2);
- exti_serve_irq(pr, 3);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if !defined(STM32_DISABLE_EXTI4_15_HANDLER)
-/**
- * @brief EXTI[4]...EXTI[15] interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector5C) {
- uint32_t pr;
-
- OSAL_IRQ_PROLOGUE();
-
- pr = EXTI->PR;
- pr &= ((1U << 4) | (1U << 5) | (1U << 6) | (1U << 7) | (1U << 8) |
- (1U << 9) | (1U << 10) | (1U << 11) | (1U << 12) | (1U << 13) |
- (1U << 14) | (1U << 15));
- EXTI->PR = pr;
-
- exti_serve_irq(pr, 4);
- 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);
- 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) */
-
-#if HAL_USE_SERIAL || HAL_USE_UART || defined(__DOXYGEN__)
-#if !defined(STM32_DISABLE_USART1_HANDLER)
-/**
- * @brief USART1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_SERIAL
-#if STM32_SERIAL_USE_USART1
- sd_lld_serve_interrupt(&SD1);
-#endif
-#endif
-#if HAL_USE_UART
-#if STM32_UART_USE_USART1
- uart_lld_serve_interrupt(&UARTD1);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if !defined(STM32_DISABLE_USART2_HANDLER)
-/**
- * @brief USART2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_SERIAL
-#if STM32_SERIAL_USE_USART2
- sd_lld_serve_interrupt(&SD2);
-#endif
-#endif
-#if HAL_USE_UART
-#if STM32_UART_USE_USART2
- uart_lld_serve_interrupt(&UARTD2);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-#if !defined(STM32_DISABLE_USART38_HANDLER)
-/**
- * @brief USART3..8 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(STM32_USART3_8_HANDLER) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_SERIAL
-#if STM32_SERIAL_USE_USART3
- sd_lld_serve_interrupt(&SD3);
-#endif
-#if STM32_SERIAL_USE_UART4
- sd_lld_serve_interrupt(&SD4);
-#endif
-#if STM32_SERIAL_USE_UART5
- sd_lld_serve_interrupt(&SD5);
-#endif
-#if STM32_SERIAL_USE_USART6
- sd_lld_serve_interrupt(&SD6);
-#endif
-#if STM32_SERIAL_USE_UART7
- sd_lld_serve_interrupt(&SD7);
-#endif
-#if STM32_SERIAL_USE_UART8
- sd_lld_serve_interrupt(&SD8);
-#endif
-#endif
-#if HAL_USE_UART
-#if STM32_UART_USE_USART3
- uart_lld_serve_interrupt(&UARTD3);
-#endif
-#if STM32_UART_USE_UART4
- uart_lld_serve_interrupt(&UARTD4);
-#endif
-#if STM32_UART_USE_UART5
- uart_lld_serve_interrupt(&UARTD5);
-#endif
-#if STM32_UART_USE_USART6
- uart_lld_serve_interrupt(&UARTD6);
-#endif
-#if STM32_UART_USE_UART7
- uart_lld_serve_interrupt(&UARTD7);
-#endif
-#if STM32_UART_USE_UART8
- uart_lld_serve_interrupt(&UARTD8);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-#endif /* HAL_USE_SERIAL || HAL_USE_UART */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
-#if HAL_USE_PAL
- nvicEnableVector(EXTI0_1_IRQn, STM32_IRQ_EXTI0_1_PRIORITY);
- nvicEnableVector(EXTI2_3_IRQn, STM32_IRQ_EXTI2_3_PRIORITY);
- nvicEnableVector(EXTI4_15_IRQn, STM32_IRQ_EXTI4_15_PRIORITY);
-#endif
-
-#if HAL_USE_SERIAL || HAL_USE_UART
- nvicEnableVector(STM32_USART1_NUMBER, STM32_IRQ_USART1_PRIORITY);
- nvicEnableVector(STM32_USART2_NUMBER, STM32_IRQ_USART2_PRIORITY);
- nvicEnableVector(STM32_USART3_8_NUMBER, STM32_IRQ_USART3_8_PRIORITY);
-#endif
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
-#if HAL_USE_PAL
- nvicDisableVector(EXTI0_1_IRQn);
- nvicDisableVector(EXTI2_3_IRQn);
- nvicDisableVector(EXTI4_15_IRQn);
-#endif
-
-#if HAL_USE_SERIAL || HAL_USE_UART
- nvicDisableVector(STM32_USART1_NUMBER);
- nvicDisableVector(STM32_USART2_NUMBER);
- nvicDisableVector(STM32_USART3_8_NUMBER);
-#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 STM32F0xx/stm32_isr.c
+ * @brief STM32F0xx ISR handler code.
+ *
+ * @addtogroup STM32F0xx_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_1_HANDLER)
+/**
+ * @brief EXTI[0]...EXTI[1] interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector54) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR;
+ pr &= ((1U << 0) | (1U << 1));
+ EXTI->PR = pr;
+
+ exti_serve_irq(pr, 0);
+ exti_serve_irq(pr, 1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if !defined(STM32_DISABLE_EXTI2_3_HANDLER)
+/**
+ * @brief EXTI[2]...EXTI[3] interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector58) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR;
+ pr &= ((1U << 2) | (1U << 3));
+ EXTI->PR = pr;
+
+ exti_serve_irq(pr, 2);
+ exti_serve_irq(pr, 3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if !defined(STM32_DISABLE_EXTI4_15_HANDLER)
+/**
+ * @brief EXTI[4]...EXTI[15] interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector5C) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR;
+ pr &= ((1U << 4) | (1U << 5) | (1U << 6) | (1U << 7) | (1U << 8) |
+ (1U << 9) | (1U << 10) | (1U << 11) | (1U << 12) | (1U << 13) |
+ (1U << 14) | (1U << 15));
+ EXTI->PR = pr;
+
+ exti_serve_irq(pr, 4);
+ 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);
+ 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) */
+
+#if HAL_USE_SERIAL || HAL_USE_UART || defined(__DOXYGEN__)
+#if !defined(STM32_DISABLE_USART1_HANDLER)
+/**
+ * @brief USART1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART1_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_SERIAL
+#if STM32_SERIAL_USE_USART1
+ sd_lld_serve_interrupt(&SD1);
+#endif
+#endif
+#if HAL_USE_UART
+#if STM32_UART_USE_USART1
+ uart_lld_serve_interrupt(&UARTD1);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if !defined(STM32_DISABLE_USART2_HANDLER)
+/**
+ * @brief USART2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART2_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_SERIAL
+#if STM32_SERIAL_USE_USART2
+ sd_lld_serve_interrupt(&SD2);
+#endif
+#endif
+#if HAL_USE_UART
+#if STM32_UART_USE_USART2
+ uart_lld_serve_interrupt(&UARTD2);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+#if !defined(STM32_DISABLE_USART38_HANDLER)
+/**
+ * @brief USART3..8 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_USART3_8_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_SERIAL
+#if STM32_SERIAL_USE_USART3
+ sd_lld_serve_interrupt(&SD3);
+#endif
+#if STM32_SERIAL_USE_UART4
+ sd_lld_serve_interrupt(&SD4);
+#endif
+#if STM32_SERIAL_USE_UART5
+ sd_lld_serve_interrupt(&SD5);
+#endif
+#if STM32_SERIAL_USE_USART6
+ sd_lld_serve_interrupt(&SD6);
+#endif
+#if STM32_SERIAL_USE_UART7
+ sd_lld_serve_interrupt(&SD7);
+#endif
+#if STM32_SERIAL_USE_UART8
+ sd_lld_serve_interrupt(&SD8);
+#endif
+#endif
+#if HAL_USE_UART
+#if STM32_UART_USE_USART3
+ uart_lld_serve_interrupt(&UARTD3);
+#endif
+#if STM32_UART_USE_UART4
+ uart_lld_serve_interrupt(&UARTD4);
+#endif
+#if STM32_UART_USE_UART5
+ uart_lld_serve_interrupt(&UARTD5);
+#endif
+#if STM32_UART_USE_USART6
+ uart_lld_serve_interrupt(&UARTD6);
+#endif
+#if STM32_UART_USE_UART7
+ uart_lld_serve_interrupt(&UARTD7);
+#endif
+#if STM32_UART_USE_UART8
+ uart_lld_serve_interrupt(&UARTD8);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+#endif /* HAL_USE_SERIAL || HAL_USE_UART */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+#if HAL_USE_PAL
+ nvicEnableVector(EXTI0_1_IRQn, STM32_IRQ_EXTI0_1_PRIORITY);
+ nvicEnableVector(EXTI2_3_IRQn, STM32_IRQ_EXTI2_3_PRIORITY);
+ nvicEnableVector(EXTI4_15_IRQn, STM32_IRQ_EXTI4_15_PRIORITY);
+#endif
+
+#if HAL_USE_SERIAL || HAL_USE_UART
+ nvicEnableVector(STM32_USART1_NUMBER, STM32_IRQ_USART1_PRIORITY);
+ nvicEnableVector(STM32_USART2_NUMBER, STM32_IRQ_USART2_PRIORITY);
+ nvicEnableVector(STM32_USART3_8_NUMBER, STM32_IRQ_USART3_8_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+#if HAL_USE_PAL
+ nvicDisableVector(EXTI0_1_IRQn);
+ nvicDisableVector(EXTI2_3_IRQn);
+ nvicDisableVector(EXTI4_15_IRQn);
+#endif
+
+#if HAL_USE_SERIAL || HAL_USE_UART
+ nvicDisableVector(STM32_USART1_NUMBER);
+ nvicDisableVector(STM32_USART2_NUMBER);
+ nvicDisableVector(STM32_USART3_8_NUMBER);
+#endif
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_isr.h b/os/hal/ports/STM32/STM32F0xx/stm32_isr.h
index e3ebc44faf..25b4cef356 100644
--- a/os/hal/ports/STM32/STM32F0xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32F0xx/stm32_isr.h
@@ -1,246 +1,246 @@
-/*
- 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/stm32_isr.h
- * @brief STM32F0xx ISR handler header.
- *
- * @addtogroup STM32F0xx_ISR
- * @{
- */
-
-#ifndef STM32_ISR_H
-#define STM32_ISR_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name ISRs suppressed in standard drivers
- * @{
- */
-#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
-/** @} */
-
-/**
- * @name ISR names and numbers remapping
- * @{
- */
-/*
- * CAN units.
- */
-#define STM32_CAN1_UNIFIED_HANDLER VectorB8
-#define STM32_CAN1_UNIFIED_NUMBER 30
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_GLOBAL_HANDLER Vector9C
-#define STM32_I2C1_GLOBAL_NUMBER 23
-
-#define STM32_I2C2_GLOBAL_HANDLER VectorA0
-#define STM32_I2C2_GLOBAL_NUMBER 24
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_UP_HANDLER Vector74
-#define STM32_TIM1_CC_HANDLER Vector78
-#define STM32_TIM2_HANDLER Vector7C
-#define STM32_TIM3_HANDLER Vector80
-#define STM32_TIM6_HANDLER Vector84
-#define STM32_TIM7_HANDLER Vector88
-#define STM32_TIM14_HANDLER Vector8C
-#define STM32_TIM15_HANDLER Vector90
-#define STM32_TIM16_HANDLER Vector94
-#define STM32_TIM17_HANDLER Vector98
-
-#define STM32_TIM1_UP_NUMBER 13
-#define STM32_TIM1_CC_NUMBER 14
-#define STM32_TIM2_NUMBER 15
-#define STM32_TIM3_NUMBER 16
-#define STM32_TIM6_NUMBER 17
-#define STM32_TIM7_NUMBER 18
-#define STM32_TIM14_NUMBER 19
-#define STM32_TIM15_NUMBER 20
-#define STM32_TIM16_NUMBER 21
-#define STM32_TIM17_NUMBER 22
-
-/*
- * USART units.
- */
-#define STM32_USART1_HANDLER VectorAC
-#define STM32_USART2_HANDLER VectorB0
-#define STM32_USART3_8_HANDLER VectorB4
-
-#define STM32_USART1_NUMBER 27
-#define STM32_USART2_NUMBER 28
-#define STM32_USART3_8_NUMBER 29
-
-/*
- * USB units.
- */
-#define STM32_USB1_LP_HANDLER VectorBC
-#define STM32_USB1_LP_NUMBER 31
-#define STM32_USB1_HP_HANDLER VectorBC
-#define STM32_USB1_HP_NUMBER 31
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief EXTI0..1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI0_1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI0_1_PRIORITY 3
-#endif
-
-/**
- * @brief EXTI2..3 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI2_3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI2_3_PRIORITY 3
-#endif
-
-/**
- * @brief EXTI4..15 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI4_15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI4_15_PRIORITY 3
-#endif
-
-/**
- * @brief EXTI16 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI16_PRIORITY 3
-#endif
-
-/**
- * @brief EXTI17,19,20 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI17_20_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI17_20_PRIORITY 3
-#endif
-
-/**
- * @brief EXTI21,22 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI21_22_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI21_22_PRIORITY 3
-#endif
-
-/**
- * @brief USART1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_USART1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_USART1_PRIORITY 3
-#endif
-
-/**
- * @brief USART2 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_USART2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_USART2_PRIORITY 3
-#endif
-
-/**
- * @brief USART3..8 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_USART3_8_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_USART3_8_PRIORITY 3
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* IRQ priority checks.*/
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI0_1_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI0_1_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI2_3_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI2_3_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI4_15_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI4_15_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI16_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI16_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI17_20_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI17_20_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI21_22_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI21_22_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_USART1_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_USART1_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_USART2_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_USART2_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_USART3_8_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_USART3_8_PRIORITY"
-#endif
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32F0xx ISR handler header.
+ *
+ * @addtogroup STM32F0xx_ISR
+ * @{
+ */
+
+#ifndef STM32_ISR_H
+#define STM32_ISR_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name ISRs suppressed in standard drivers
+ * @{
+ */
+#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
+/** @} */
+
+/**
+ * @name ISR names and numbers remapping
+ * @{
+ */
+/*
+ * CAN units.
+ */
+#define STM32_CAN1_UNIFIED_HANDLER VectorB8
+#define STM32_CAN1_UNIFIED_NUMBER 30
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_GLOBAL_HANDLER Vector9C
+#define STM32_I2C1_GLOBAL_NUMBER 23
+
+#define STM32_I2C2_GLOBAL_HANDLER VectorA0
+#define STM32_I2C2_GLOBAL_NUMBER 24
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_UP_HANDLER Vector74
+#define STM32_TIM1_CC_HANDLER Vector78
+#define STM32_TIM2_HANDLER Vector7C
+#define STM32_TIM3_HANDLER Vector80
+#define STM32_TIM6_HANDLER Vector84
+#define STM32_TIM7_HANDLER Vector88
+#define STM32_TIM14_HANDLER Vector8C
+#define STM32_TIM15_HANDLER Vector90
+#define STM32_TIM16_HANDLER Vector94
+#define STM32_TIM17_HANDLER Vector98
+
+#define STM32_TIM1_UP_NUMBER 13
+#define STM32_TIM1_CC_NUMBER 14
+#define STM32_TIM2_NUMBER 15
+#define STM32_TIM3_NUMBER 16
+#define STM32_TIM6_NUMBER 17
+#define STM32_TIM7_NUMBER 18
+#define STM32_TIM14_NUMBER 19
+#define STM32_TIM15_NUMBER 20
+#define STM32_TIM16_NUMBER 21
+#define STM32_TIM17_NUMBER 22
+
+/*
+ * USART units.
+ */
+#define STM32_USART1_HANDLER VectorAC
+#define STM32_USART2_HANDLER VectorB0
+#define STM32_USART3_8_HANDLER VectorB4
+
+#define STM32_USART1_NUMBER 27
+#define STM32_USART2_NUMBER 28
+#define STM32_USART3_8_NUMBER 29
+
+/*
+ * USB units.
+ */
+#define STM32_USB1_LP_HANDLER VectorBC
+#define STM32_USB1_LP_NUMBER 31
+#define STM32_USB1_HP_HANDLER VectorBC
+#define STM32_USB1_HP_NUMBER 31
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0..1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI0_1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI0_1_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI2..3 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI2_3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI2_3_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI4..15 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI4_15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI4_15_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI16 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI16_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI17,19,20 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI17_20_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI17_20_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI21,22 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI21_22_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI21_22_PRIORITY 3
+#endif
+
+/**
+ * @brief USART1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_USART1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_USART1_PRIORITY 3
+#endif
+
+/**
+ * @brief USART2 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_USART2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_USART2_PRIORITY 3
+#endif
+
+/**
+ * @brief USART3..8 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_USART3_8_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_USART3_8_PRIORITY 3
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* IRQ priority checks.*/
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI0_1_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI0_1_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI2_3_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI2_3_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI4_15_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI4_15_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI16_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI16_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI17_20_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI17_20_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI21_22_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI21_22_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_USART1_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_USART1_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_USART2_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_USART2_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_USART3_8_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_USART3_8_PRIORITY"
+#endif
+
+/*===========================================================================*/
+/* 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/STM32/STM32F0xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h
index 94bc779558..b0ef86d1f7 100644
--- a/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F0xx/stm32_rcc.h
@@ -1,965 +1,965 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32f0xx.h.
- *
- * @addtogroup STM32F0xx_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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask APB1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1(mask, lp) { \
- RCC->APB1ENR |= (mask); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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 AHB bus.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ADC1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-/** @} */
-
-/**
- * @name CAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CAN1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CANEN, lp)
-
-/**
- * @brief Disables the CAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CANEN)
-
-/**
- * @brief Resets the CAN1 peripheral.
- *
- * @api
- */
-#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 DMA peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMA1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- * @note Not supported in this family, does nothing.
- *
- * @api
- */
-#define rccResetDMA1()
-
-/**
- * @brief Enables the DMA2 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
-
-/**
- * @brief Disables the DMA2 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
-
-/**
- * @brief Resets the DMA2 peripheral.
- * @note Not supported in this family, does nothing.
- *
- * @api
- */
-#define rccResetDMA2()
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name SPI peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SPI1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the TIM1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 TIM6 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 TIM14 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 TIM15 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-/** @} */
-
-/**
- * @name USART/UART peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USART1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 USART4 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPB1(RCC_APB1ENR_USART4EN, lp)
-
-/**
- * @brief Disables the USART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1(RCC_APB1ENR_USART4EN)
-
-/**
- * @brief Resets the USART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1(RCC_APB1RSTR_USART4RST)
-
-/**
- * @brief Enables the USART5 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_USART5EN, lp)
-
-/**
- * @brief Disables the USART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1(RCC_APB1ENR_USART5EN)
-
-/**
- * @brief Resets the USART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_USART5RST)
-
-/**
- * @brief Enables the USART6 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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) rccEnableAPB2(RCC_APB2ENR_USART7EN, lp)
-
-/**
- * @brief Disables the UART7 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART7() rccDisableAPB2(RCC_APB2ENR_USART7EN)
-
-/**
- * @brief Resets the UART7 peripheral.
- *
- * @api
- */
-#define rccResetUART7() rccResetAPB2(RCC_APB2RSTR_USART7RST)
-
-/**
- * @brief Enables the UART8 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART8(lp) rccEnableAPB2(RCC_APB2ENR_USART8EN, lp)
-
-/**
- * @brief Disables the UART8 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART8() rccDisableAPB2(RCC_APB2ENR_USART8EN)
-
-/**
- * @brief Resets the UART8 peripheral.
- *
- * @api
- */
-#define rccResetUART8() rccResetAPB2(RCC_APB2RSTR_USART8RST)
-/** @} */
-
-/**
- * @name USB peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
-/** @} */
-
-/**
- * @name CRC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRC peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
-
-/**
- * @brief Disables the CRC peripheral clock.
- *
- * @api
- */
-#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
-
-/**
- * @brief Resets the CRC peripheral.
- *
- * @api
- */
-#define rccResetCRC() rccResetAHB(RCC_AHBRSTR_CRCRST)
-/** @} */
-
-/**
- * @name WWDG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the WWDG peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableWWDG(lp) rccEnableAPB1(RCC_APB1ENR_WWDGEN, lp)
-
-/**
- * @brief Disables the WWDG peripheral clock.
- *
- * @api
- */
-#define rccDisableWWDG() rccDisableAPB1(RCC_APB1ENR_WWDGEN)
-
-/**
- * @brief Resets the WWDG peripheral.
- *
- * @api
- */
-#define rccResetWWDG() rccResetAPB1(RCC_APB1RSTR_WWDGRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32f0xx.h.
+ *
+ * @addtogroup STM32F0xx_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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask APB1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1(mask, lp) { \
+ RCC->APB1ENR |= (mask); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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 AHB bus.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ADC1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+/** @} */
+
+/**
+ * @name CAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CAN1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CANEN, lp)
+
+/**
+ * @brief Disables the CAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CANEN)
+
+/**
+ * @brief Resets the CAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 DMA peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMA1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ * @note Not supported in this family, does nothing.
+ *
+ * @api
+ */
+#define rccResetDMA1()
+
+/**
+ * @brief Enables the DMA2 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
+
+/**
+ * @brief Disables the DMA2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
+
+/**
+ * @brief Resets the DMA2 peripheral.
+ * @note Not supported in this family, does nothing.
+ *
+ * @api
+ */
+#define rccResetDMA2()
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name SPI peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SPI1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the TIM1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 TIM6 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 TIM14 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 TIM15 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+/** @} */
+
+/**
+ * @name USART/UART peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USART1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 USART4 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPB1(RCC_APB1ENR_USART4EN, lp)
+
+/**
+ * @brief Disables the USART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1(RCC_APB1ENR_USART4EN)
+
+/**
+ * @brief Resets the USART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1(RCC_APB1RSTR_USART4RST)
+
+/**
+ * @brief Enables the USART5 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_USART5EN, lp)
+
+/**
+ * @brief Disables the USART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1(RCC_APB1ENR_USART5EN)
+
+/**
+ * @brief Resets the USART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1(RCC_APB1RSTR_USART5RST)
+
+/**
+ * @brief Enables the USART6 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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) rccEnableAPB2(RCC_APB2ENR_USART7EN, lp)
+
+/**
+ * @brief Disables the UART7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART7() rccDisableAPB2(RCC_APB2ENR_USART7EN)
+
+/**
+ * @brief Resets the UART7 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART7() rccResetAPB2(RCC_APB2RSTR_USART7RST)
+
+/**
+ * @brief Enables the UART8 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART8(lp) rccEnableAPB2(RCC_APB2ENR_USART8EN, lp)
+
+/**
+ * @brief Disables the UART8 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART8() rccDisableAPB2(RCC_APB2ENR_USART8EN)
+
+/**
+ * @brief Resets the UART8 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART8() rccResetAPB2(RCC_APB2RSTR_USART8RST)
+/** @} */
+
+/**
+ * @name USB peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
+/** @} */
+
+/**
+ * @name CRC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRC peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
+
+/**
+ * @brief Disables the CRC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
+
+/**
+ * @brief Resets the CRC peripheral.
+ *
+ * @api
+ */
+#define rccResetCRC() rccResetAHB(RCC_AHBRSTR_CRCRST)
+/** @} */
+
+/**
+ * @name WWDG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the WWDG peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableWWDG(lp) rccEnableAPB1(RCC_APB1ENR_WWDGEN, lp)
+
+/**
+ * @brief Disables the WWDG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableWWDG() rccDisableAPB1(RCC_APB1ENR_WWDGEN)
+
+/**
+ * @brief Resets the WWDG peripheral.
+ *
+ * @api
+ */
+#define rccResetWWDG() rccResetAPB1(RCC_APB1RSTR_WWDGRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
index f658daa30f..2c97ab4a72 100644
--- a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
@@ -1,2222 +1,2222 @@
-/*
- 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/stm32_registry.h
- * @brief STM32F0xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-#if !defined(STM32F0XX) || defined(__DOXYGEN__)
-#define STM32F0XX
-#endif
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32F0xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 FALSE
-
-/*===========================================================================*/
-/* STM32F030x4, STM32F030x6, STM32F030x8, STM32F030xC. */
-/*===========================================================================*/
-#if defined(STM32F030x4) || defined(STM32F030x6) || \
- defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
-
-/* Common identifier of all STM32F030 devices.*/
-#define STM32F030
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 FALSE
-#if defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_HSI_PREDIV TRUE
-#else
-#define STM32_HAS_HSI_PREDIV FALSE
-#endif
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000011
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#if defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#else
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#endif
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 20
-#define STM32_EXTI_IMR1_MASK 0xFFF50000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#if !defined(STM32F030x4) && !defined(STM32F030x6)
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD TRUE
-#else
-#define STM32_HAS_GPIOC FALSE
-#define STM32_HAS_GPIOD FALSE
-#endif
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C1_RX_DMA_CHN 0x00000200
-#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C1_TX_DMA_CHN 0x00000020
-
-#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00020000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00002000
-#else
-#define STM32_HAS_I2C2 FALSE
-#endif
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#if defined (STM32F030xC)
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#else
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
-#endif
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000030
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000300
-
-#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_SPI2_RX_DMA_CHN 0x00003000
-#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_SPI2_TX_DMA_CHN 0x00030000
-#else
-#define STM32_HAS_SPI2 FALSE
-#endif
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM3 TRUE
-#define STM32_TIM3_IS_32BITS FALSE
-#define STM32_TIM3_CHANNELS 4
-
-#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-#else
-#define STM32_HAS_TIM6 FALSE
-#endif
-
-#if defined(STM32F030xC)
-#define STM32_HAS_TIM7 TRUE
-#define STM32_TIM7_IS_32BITS FALSE
-#define STM32_TIM7_CHANNELS 0
-#else
-#define STM32_HAS_TIM7 FALSE
-#endif
-
-#define STM32_HAS_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-#else
-#define STM32_HAS_TIM15 FALSE
-#endif
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM2 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00080808
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00008080
-
-#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART2_RX_DMA_CHN 0x00090909
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART2_TX_DMA_CHN 0x00009090
-#else
-#define STM32_HAS_USART2 FALSE
-#endif
-
-#if defined(STM32F030xC) || defined(__DOXYGEN__)
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART3_RX_DMA_CHN 0x000A0A0A
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART3_TX_DMA_CHN 0x0000A0A0
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_UART4_RX_DMA_CHN 0x000B0B0B
-#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_UART4_TX_DMA_CHN 0x0000B0B0
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_UART5_RX_DMA_CHN 0x000C0C0C
-#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_UART5_TX_DMA_CHN 0x0000C0C0
-
-#define STM32_HAS_USART6 TRUE
-#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART6_RX_DMA_CHN 0x000D0D0D
-#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART6_TX_DMA_CHN 0x0000D0D0
-
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-#else
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-#endif
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-/*===========================================================================*/
-/* STM32F031x6, STM32F038xx. */
-/*===========================================================================*/
-#elif defined(STM32F031x6) || defined(STM32F038xx)
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 FALSE
-#define STM32_HAS_HSI_PREDIV FALSE
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x0FF40000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C1_RX_DMA_CHN 0x00000000
-#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000000
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM15 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(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00000000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART2 FALSE
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32F042x6. */
-/*===========================================================================*/
-#elif defined(STM32F042x6)
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 TRUE
-#define STM32_HAS_HSI_PREDIV TRUE
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x7FF40000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C1_RX_DMA_CHN 0x00000000
-#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000000
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM15 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(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00000000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_USART2_RX_DMA_CHN 0x00000000
-#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_USART2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32F048xx. */
-/*===========================================================================*/
-#elif defined(STM32F048xx)
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 TRUE
-#define STM32_HAS_HSI_PREDIV TRUE
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x7FF40000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C1_RX_DMA_CHN 0x00000000
-#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000000
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_SPI2_RX_DMA_CHN 0x00000000
-#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_SPI2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM15 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(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00000000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_USART2_RX_DMA_CHN 0x00000000
-#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_USART2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR TRUE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32F051x8, STM32F058xx. */
-/*===========================================================================*/
-#elif defined(STM32F051x8) || defined(STM32F058xx)
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 FALSE
-#define STM32_HAS_HSI_PREDIV FALSE
-#define STM32_HAS_MCO_PREDIV FALSE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_DAC1_CH1_DMA_CHN 0x00000000
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x0F940000U
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C1_RX_DMA_CHN 0x00000000
-#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00000000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000000
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_SPI2_RX_DMA_CHN 0x00000000
-#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_SPI2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00000000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_USART2_RX_DMA_CHN 0x00000000
-#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_USART2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32F070x6, STM32F070xB. */
-/*===========================================================================*/
-#elif defined(STM32F070x6) || defined(STM32F070xB)
-
-/* Common identifier of all STM32F070 devices.*/
-#define STM32F070
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 FALSE
-#define STM32_HAS_HSI_PREDIV TRUE
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x7F840000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#if defined(STM32F070x6)
-#define STM32_HAS_GPIOD FALSE
-#else
-#define STM32_HAS_GPIOD TRUE
-#endif
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C1_RX_DMA_CHN 0x00000000
-#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00000000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#if defined (STM32F070xB)
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#else
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
-#endif
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000000
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_SPI2_RX_DMA_CHN 0x00000000
-#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_SPI2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM3 TRUE
-#define STM32_TIM3_IS_32BITS FALSE
-#define STM32_TIM3_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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM2 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00000000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_USART2_RX_DMA_CHN 0x00000000
-#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_USART2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_USART3_RX_DMA_CHN 0x00000000
-#define STM32_USART3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_USART3_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK 0
-#define STM32_UART4_RX_DMA_CHN 0x00000000
-#define STM32_UART4_TX_DMA_MSK 0
-#define STM32_UART4_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-/*===========================================================================*/
-/* STM32F071xB, STM32F072xB, STM32F078xx. */
-/*===========================================================================*/
-#elif defined(STM32F071xB) || defined(STM32F072xB) || \
- defined(STM32F078xx)
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 TRUE
-#define STM32_HAS_HSI_PREDIV TRUE
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#if defined(STM32F072xB)
-#define STM32_HAS_CAN1 TRUE
-#define STM32_CAN_MAX_FILTERS 14
-#else
-#define STM32_HAS_CAN1 FALSE
-#endif
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_DAC1_CH1_DMA_CHN 0x00000000
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_DAC1_CH2_DMA_CHN 0x00000000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH4567_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x7F840000U
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x00000000
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00000000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_SPI1_RX_DMA_CHN 0x00000000
-#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_SPI1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_RX_DMA_CHN 0x00000000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_SPI2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00000000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00000000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_USART3_RX_DMA_CHN 0x00000000
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_USART3_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6)
-#define STM32_UART4_RX_DMA_CHN 0x00000000
-#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7)
-#define STM32_UART4_TX_DMA_CHN 0x00000000
-
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#if defined(STM32F072xB) || defined(STM32F078xx)
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR TRUE
-#else
-#define STM32_HAS_USB FALSE
-#endif
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32F091xC, STM32F098xx. */
-/*===========================================================================*/
-#elif defined(STM32F091xC) || defined(STM32F098xx)
-
-/* RCC attributes. */
-#define STM32_HAS_HSI48 TRUE
-#define STM32_HAS_HSI_PREDIV TRUE
-#define STM32_HAS_MCO_PREDIV TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER FALSE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_ADC1_DMA_CHN 0x00100011
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_DAC1_CH1_DMA_CHN 0x00000100
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_DAC1_CH2_DMA_CHN 0x00001000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 5
-
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA12_CH23_CH12_HANDLER Vector68
-#define STM32_DMA12_CH4567_CH345_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA12_CH23_CH12_NUMBER 10
-#define STM32_DMA12_CH4567_CH345_NUMBER 11
-
-#define STM32_DMA1_CH2_NUMBER STM32_DMA12_CH23_CH12_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA12_CH23_CH12_NUMBER
-#define STM32_DMA2_CH1_NUMBER STM32_DMA12_CH23_CH12_NUMBER
-#define STM32_DMA2_CH2_NUMBER STM32_DMA12_CH23_CH12_NUMBER
-#define STM32_DMA1_CH2_CMASK 0x00000186U
-#define STM32_DMA1_CH3_CMASK 0x00000186U
-#define STM32_DMA2_CH1_CMASK 0x00000186U
-#define STM32_DMA2_CH2_CMASK 0x00000186U
-
-#define STM32_DMA1_CH4_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA2_CH3_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA2_CH4_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA2_CH5_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
-#define STM32_DMA1_CH4_CMASK 0x00000E78U
-#define STM32_DMA1_CH5_CMASK 0x00000E78U
-#define STM32_DMA1_CH6_CMASK 0x00000E78U
-#define STM32_DMA1_CH7_CMASK 0x00000E78U
-#define STM32_DMA2_CH3_CMASK 0x00000E78U
-#define STM32_DMA2_CH4_CMASK 0x00000E78U
-#define STM32_DMA2_CH5_CMASK 0x00000E78U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 32
-#define STM32_EXTI_IMR1_MASK 0x7F840000U
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x02000200
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00200020
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_I2C2_RX_DMA_CHN 0x00020020
-#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_I2C2_TX_DMA_CHN 0x00002002
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 0
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_RX_DMA_CHN 0x00000330
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI1_TX_DMA_CHN 0x00003300
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_RX_DMA_CHN 0x00303000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_SPI2_TX_DMA_CHN 0x03030000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_USART1_RX_DMA_CHN 0x00880888
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_USART1_TX_DMA_CHN 0x08088088
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_USART2_RX_DMA_CHN 0x00990999
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_USART2_TX_DMA_CHN 0x09099099
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_USART3_RX_DMA_CHN 0x00AA0AAA
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_USART3_TX_DMA_CHN 0x0A0AA0AA
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_UART4_RX_DMA_CHN 0x00BB0BBB
-#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_UART4_TX_DMA_CHN 0x0B0BB0BB
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_UART5_RX_DMA_CHN 0x00CC0CCC
-#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_UART5_TX_DMA_CHN 0x0C0CC0CC
-
-#define STM32_HAS_USART6 TRUE
-#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_USART6_RX_DMA_CHN 0x00DD0DDD
-#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_USART6_TX_DMA_CHN 0x0D0DD0DD
-
-#define STM32_HAS_UART7 TRUE
-#define STM32_UART7_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_UART7_RX_DMA_CHN 0x00EE0EEE
-#define STM32_UART7_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_UART7_TX_DMA_CHN 0x0E0EE0EE
-
-#define STM32_HAS_UART8 TRUE
-#define STM32_UART8_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_UART8_RX_DMA_CHN 0x00FF0FFF
-#define STM32_UART8_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_UART8_TX_DMA_CHN 0x0F0FF0FF
-
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#else
-#error "STM32F0xx device not specified"
-#endif
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32F0xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+#if !defined(STM32F0XX) || defined(__DOXYGEN__)
+#define STM32F0XX
+#endif
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32F0xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 FALSE
+
+/*===========================================================================*/
+/* STM32F030x4, STM32F030x6, STM32F030x8, STM32F030xC. */
+/*===========================================================================*/
+#if defined(STM32F030x4) || defined(STM32F030x6) || \
+ defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
+
+/* Common identifier of all STM32F030 devices.*/
+#define STM32F030
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 FALSE
+#if defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_HSI_PREDIV TRUE
+#else
+#define STM32_HAS_HSI_PREDIV FALSE
+#endif
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000011
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#if defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#else
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#endif
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 20
+#define STM32_EXTI_IMR1_MASK 0xFFF50000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#if !defined(STM32F030x4) && !defined(STM32F030x6)
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD TRUE
+#else
+#define STM32_HAS_GPIOC FALSE
+#define STM32_HAS_GPIOD FALSE
+#endif
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C1_RX_DMA_CHN 0x00000200
+#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C1_TX_DMA_CHN 0x00000020
+
+#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00020000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00002000
+#else
+#define STM32_HAS_I2C2 FALSE
+#endif
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#if defined (STM32F030xC)
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#else
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
+#endif
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000030
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000300
+
+#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_SPI2_RX_DMA_CHN 0x00003000
+#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_SPI2_TX_DMA_CHN 0x00030000
+#else
+#define STM32_HAS_SPI2 FALSE
+#endif
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM3 TRUE
+#define STM32_TIM3_IS_32BITS FALSE
+#define STM32_TIM3_CHANNELS 4
+
+#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+#else
+#define STM32_HAS_TIM6 FALSE
+#endif
+
+#if defined(STM32F030xC)
+#define STM32_HAS_TIM7 TRUE
+#define STM32_TIM7_IS_32BITS FALSE
+#define STM32_TIM7_CHANNELS 0
+#else
+#define STM32_HAS_TIM7 FALSE
+#endif
+
+#define STM32_HAS_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+#else
+#define STM32_HAS_TIM15 FALSE
+#endif
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM2 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00080808
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00008080
+
+#if defined(STM32F030x8) || defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART2_RX_DMA_CHN 0x00090909
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART2_TX_DMA_CHN 0x00009090
+#else
+#define STM32_HAS_USART2 FALSE
+#endif
+
+#if defined(STM32F030xC) || defined(__DOXYGEN__)
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART3_RX_DMA_CHN 0x000A0A0A
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART3_TX_DMA_CHN 0x0000A0A0
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_UART4_RX_DMA_CHN 0x000B0B0B
+#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_UART4_TX_DMA_CHN 0x0000B0B0
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_UART5_RX_DMA_CHN 0x000C0C0C
+#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_UART5_TX_DMA_CHN 0x0000C0C0
+
+#define STM32_HAS_USART6 TRUE
+#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART6_RX_DMA_CHN 0x000D0D0D
+#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART6_TX_DMA_CHN 0x0000D0D0
+
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+#else
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+#endif
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+/*===========================================================================*/
+/* STM32F031x6, STM32F038xx. */
+/*===========================================================================*/
+#elif defined(STM32F031x6) || defined(STM32F038xx)
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 FALSE
+#define STM32_HAS_HSI_PREDIV FALSE
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x0FF40000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C1_RX_DMA_CHN 0x00000000
+#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000000
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM15 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(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00000000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART2 FALSE
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32F042x6. */
+/*===========================================================================*/
+#elif defined(STM32F042x6)
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 TRUE
+#define STM32_HAS_HSI_PREDIV TRUE
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x7FF40000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C1_RX_DMA_CHN 0x00000000
+#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000000
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM15 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(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00000000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_USART2_RX_DMA_CHN 0x00000000
+#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_USART2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32F048xx. */
+/*===========================================================================*/
+#elif defined(STM32F048xx)
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 TRUE
+#define STM32_HAS_HSI_PREDIV TRUE
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x7FF40000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C1_RX_DMA_CHN 0x00000000
+#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000000
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_SPI2_RX_DMA_CHN 0x00000000
+#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_SPI2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM15 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(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00000000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_USART2_RX_DMA_CHN 0x00000000
+#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_USART2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR TRUE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32F051x8, STM32F058xx. */
+/*===========================================================================*/
+#elif defined(STM32F051x8) || defined(STM32F058xx)
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 FALSE
+#define STM32_HAS_HSI_PREDIV FALSE
+#define STM32_HAS_MCO_PREDIV FALSE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_DAC1_CH1_DMA_CHN 0x00000000
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x0F940000U
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C1_RX_DMA_CHN 0x00000000
+#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00000000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000000
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_SPI2_RX_DMA_CHN 0x00000000
+#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_SPI2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00000000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_USART2_RX_DMA_CHN 0x00000000
+#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_USART2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32F070x6, STM32F070xB. */
+/*===========================================================================*/
+#elif defined(STM32F070x6) || defined(STM32F070xB)
+
+/* Common identifier of all STM32F070 devices.*/
+#define STM32F070
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 FALSE
+#define STM32_HAS_HSI_PREDIV TRUE
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x7F840000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#if defined(STM32F070x6)
+#define STM32_HAS_GPIOD FALSE
+#else
+#define STM32_HAS_GPIOD TRUE
+#endif
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C1_RX_DMA_CHN 0x00000000
+#define STM32_I2C1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00000000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#if defined (STM32F070xB)
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#else
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS FALSE
+#endif
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000000
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_SPI2_RX_DMA_CHN 0x00000000
+#define STM32_SPI2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_SPI2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM3 TRUE
+#define STM32_TIM3_IS_32BITS FALSE
+#define STM32_TIM3_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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM2 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00000000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_USART2_RX_DMA_CHN 0x00000000
+#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_USART2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_USART3_RX_DMA_CHN 0x00000000
+#define STM32_USART3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_USART3_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK 0
+#define STM32_UART4_RX_DMA_CHN 0x00000000
+#define STM32_UART4_TX_DMA_MSK 0
+#define STM32_UART4_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+/*===========================================================================*/
+/* STM32F071xB, STM32F072xB, STM32F078xx. */
+/*===========================================================================*/
+#elif defined(STM32F071xB) || defined(STM32F072xB) || \
+ defined(STM32F078xx)
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 TRUE
+#define STM32_HAS_HSI_PREDIV TRUE
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#if defined(STM32F072xB)
+#define STM32_HAS_CAN1 TRUE
+#define STM32_CAN_MAX_FILTERS 14
+#else
+#define STM32_HAS_CAN1 FALSE
+#endif
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_DAC1_CH1_DMA_CHN 0x00000000
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_DAC1_CH2_DMA_CHN 0x00000000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH4567_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x7F840000U
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x00000000
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00000000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI1_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_SPI1_RX_DMA_CHN 0x00000000
+#define STM32_SPI1_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_SPI1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_RX_DMA_CHN 0x00000000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_SPI2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00000000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00000000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_USART3_RX_DMA_CHN 0x00000000
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_USART3_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6)
+#define STM32_UART4_RX_DMA_CHN 0x00000000
+#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 7)
+#define STM32_UART4_TX_DMA_CHN 0x00000000
+
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#if defined(STM32F072xB) || defined(STM32F078xx)
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR TRUE
+#else
+#define STM32_HAS_USB FALSE
+#endif
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32F091xC, STM32F098xx. */
+/*===========================================================================*/
+#elif defined(STM32F091xC) || defined(STM32F098xx)
+
+/* RCC attributes. */
+#define STM32_HAS_HSI48 TRUE
+#define STM32_HAS_HSI_PREDIV TRUE
+#define STM32_HAS_MCO_PREDIV TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER FALSE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING FALSE
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_ADC1_DMA_CHN 0x00100011
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_DAC1_CH1_DMA_CHN 0x00000100
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_DAC1_CH2_DMA_CHN 0x00001000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 5
+
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA12_CH23_CH12_HANDLER Vector68
+#define STM32_DMA12_CH4567_CH345_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA12_CH23_CH12_NUMBER 10
+#define STM32_DMA12_CH4567_CH345_NUMBER 11
+
+#define STM32_DMA1_CH2_NUMBER STM32_DMA12_CH23_CH12_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA12_CH23_CH12_NUMBER
+#define STM32_DMA2_CH1_NUMBER STM32_DMA12_CH23_CH12_NUMBER
+#define STM32_DMA2_CH2_NUMBER STM32_DMA12_CH23_CH12_NUMBER
+#define STM32_DMA1_CH2_CMASK 0x00000186U
+#define STM32_DMA1_CH3_CMASK 0x00000186U
+#define STM32_DMA2_CH1_CMASK 0x00000186U
+#define STM32_DMA2_CH2_CMASK 0x00000186U
+
+#define STM32_DMA1_CH4_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA2_CH3_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA2_CH4_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA2_CH5_NUMBER STM32_DMA12_CH4567_CH345_NUMBER
+#define STM32_DMA1_CH4_CMASK 0x00000E78U
+#define STM32_DMA1_CH5_CMASK 0x00000E78U
+#define STM32_DMA1_CH6_CMASK 0x00000E78U
+#define STM32_DMA1_CH7_CMASK 0x00000E78U
+#define STM32_DMA2_CH3_CMASK 0x00000E78U
+#define STM32_DMA2_CH4_CMASK 0x00000E78U
+#define STM32_DMA2_CH5_CMASK 0x00000E78U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 32
+#define STM32_EXTI_IMR1_MASK 0x7F840000U
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x02000200
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00200020
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_I2C2_RX_DMA_CHN 0x00020020
+#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_I2C2_TX_DMA_CHN 0x00002002
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 0
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_IRQ_PRIORITY)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_RX_DMA_CHN 0x00000330
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI1_TX_DMA_CHN 0x00003300
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_RX_DMA_CHN 0x00303000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_SPI2_TX_DMA_CHN 0x03030000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_USART1_RX_DMA_CHN 0x00880888
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_USART1_TX_DMA_CHN 0x08088088
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_USART2_RX_DMA_CHN 0x00990999
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_USART2_TX_DMA_CHN 0x09099099
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_USART3_RX_DMA_CHN 0x00AA0AAA
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_USART3_TX_DMA_CHN 0x0A0AA0AA
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_UART4_RX_DMA_CHN 0x00BB0BBB
+#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_UART4_TX_DMA_CHN 0x0B0BB0BB
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_UART5_RX_DMA_CHN 0x00CC0CCC
+#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_UART5_TX_DMA_CHN 0x0C0CC0CC
+
+#define STM32_HAS_USART6 TRUE
+#define STM32_USART6_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_USART6_RX_DMA_CHN 0x00DD0DDD
+#define STM32_USART6_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_USART6_TX_DMA_CHN 0x0D0DD0DD
+
+#define STM32_HAS_UART7 TRUE
+#define STM32_UART7_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_UART7_RX_DMA_CHN 0x00EE0EEE
+#define STM32_UART7_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_UART7_TX_DMA_CHN 0x0E0EE0EE
+
+#define STM32_HAS_UART8 TRUE
+#define STM32_UART8_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_UART8_RX_DMA_CHN 0x00FF0FFF
+#define STM32_UART8_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_UART8_TX_DMA_CHN 0x0F0FF0FF
+
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#else
+#error "STM32F0xx device not specified"
+#endif
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c b/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
index 9f29a911c2..ac44ea553c 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
+++ b/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
@@ -1,235 +1,235 @@
-/*
- 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_adc_lld.c
- * @brief STM32F1xx ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Shared ADC DMA ISR service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & STM32_DMA_ISR_TEIF) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = ADC1;
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_TEIE;
-
- /* Temporary activation.*/
- rccEnableADC1(true);
- ADC1->CR1 = 0;
- ADC1->CR2 = ADC_CR2_ADON;
-
- /* Reset calibration just to be safe.*/
- ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
- while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
- ;
-
- /* Calibration.*/
- ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
- while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
- ;
-
- /* Return the ADC in low power mode.*/
- ADC1->CR2 = 0;
- rccDisableADC1();
-#endif
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1),
- STM32_ADC_ADC1_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
- dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
- rccEnableADC1(true);
- }
-#endif
-
- /* ADC setup, the calibration procedure has already been performed
- during initialization.*/
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock.*/
- if (adcp->state == ADC_READY) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- ADC1->CR1 = 0;
- ADC1->CR2 = 0;
-
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
- rccDisableADC1();
- }
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t mode, cr2;
- const ADCConversionGroup *grpp = adcp->grpp;
-
- /* DMA setup.*/
- mode = adcp->dmamode;
- if (grpp->circular) {
- mode |= STM32_DMA_CR_CIRC;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- mode |= STM32_DMA_CR_HTIE;
- }
- }
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
- dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- dmaStreamSetMode(adcp->dmastp, mode);
- dmaStreamEnable(adcp->dmastp);
-
- /* ADC setup.*/
- adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
- cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
- if ((cr2 & (ADC_CR2_EXTTRIG | ADC_CR2_JEXTTRIG)) == 0)
- cr2 |= ADC_CR2_CONT;
- adcp->adc->CR2 = grpp->cr2 | cr2;
- adcp->adc->SMPR1 = grpp->smpr1;
- adcp->adc->SMPR2 = grpp->smpr2;
- adcp->adc->SQR1 = grpp->sqr1;
- adcp->adc->SQR2 = grpp->sqr2;
- adcp->adc->SQR3 = grpp->sqr3;
-
- /* ADC start by writing ADC_CR2_ADON a second time.*/
- adcp->adc->CR2 = cr2;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- dmaStreamDisable(adcp->dmastp);
- adcp->adc->CR2 = 0;
-}
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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_adc_lld.c
+ * @brief STM32F1xx ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Shared ADC DMA ISR service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & STM32_DMA_ISR_TEIF) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = ADC1;
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_TEIE;
+
+ /* Temporary activation.*/
+ rccEnableADC1(true);
+ ADC1->CR1 = 0;
+ ADC1->CR2 = ADC_CR2_ADON;
+
+ /* Reset calibration just to be safe.*/
+ ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
+ while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
+ ;
+
+ /* Calibration.*/
+ ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
+ while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
+ ;
+
+ /* Return the ADC in low power mode.*/
+ ADC1->CR2 = 0;
+ rccDisableADC1();
+#endif
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1),
+ STM32_ADC_ADC1_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+ rccEnableADC1(true);
+ }
+#endif
+
+ /* ADC setup, the calibration procedure has already been performed
+ during initialization.*/
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock.*/
+ if (adcp->state == ADC_READY) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ ADC1->CR1 = 0;
+ ADC1->CR2 = 0;
+
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+ rccDisableADC1();
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t mode, cr2;
+ const ADCConversionGroup *grpp = adcp->grpp;
+
+ /* DMA setup.*/
+ mode = adcp->dmamode;
+ if (grpp->circular) {
+ mode |= STM32_DMA_CR_CIRC;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ mode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+ dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ dmaStreamSetMode(adcp->dmastp, mode);
+ dmaStreamEnable(adcp->dmastp);
+
+ /* ADC setup.*/
+ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_SCAN;
+ cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
+ if ((cr2 & (ADC_CR2_EXTTRIG | ADC_CR2_JEXTTRIG)) == 0)
+ cr2 |= ADC_CR2_CONT;
+ adcp->adc->CR2 = grpp->cr2 | cr2;
+ adcp->adc->SMPR1 = grpp->smpr1;
+ adcp->adc->SMPR2 = grpp->smpr2;
+ adcp->adc->SQR1 = grpp->sqr1;
+ adcp->adc->SQR2 = grpp->sqr2;
+ adcp->adc->SQR3 = grpp->sqr3;
+
+ /* ADC start by writing ADC_CR2_ADON a second time.*/
+ adcp->adc->CR2 = cr2;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ dmaStreamDisable(adcp->dmastp);
+ adcp->adc->CR2 = 0;
+}
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.h b/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.h
index 38772cab9a..6060ad423e 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.h
+++ b/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.h
@@ -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 STM32F1xx/hal_adc_lld.h
- * @brief STM32F1xx ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Triggers selection
- * @{
- */
-#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
-#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */
-/** @} */
-
-/**
- * @name Available analog channels
- * @{
- */
-#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
-#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
-#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
-#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
-#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
-#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
-#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
-#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
-#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
-#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
-#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
-#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
-#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
-#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
-#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
-#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
-#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
-#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
-#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
-#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
-#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
-#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
-#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
-#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
-#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC1 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-#if !STM32_ADC_USE_ADC1
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Possible ADC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */
-} adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* Dummy configuration, it is not needed.*/ \
- uint32_t dummy
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_configuration_group_fields \
- /* ADC CR1 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
- uint32_t cr1; \
- /* ADC CR2 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
- enforced inside the driver.*/ \
- uint32_t cr2; \
- /* ADC SMPR1 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 10...17.*/ \
- uint32_t smpr1; \
- /* ADC SMPR2 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 0...9.*/ \
- uint32_t smpr2; \
- /* ADC SQR1 register initialization data. \
- NOTE: Conversion group sequence 13...16 + sequence length.*/ \
- uint32_t sqr1; \
- /* ADC SQR2 register initialization data. \
- NOTE: Conversion group sequence 7...12.*/ \
- uint32_t sqr2; \
- /* ADC SQR3 register initialization data. \
- NOTE: Conversion group sequence 1...6.*/ \
- uint32_t sqr3
-
-/**
- * @name Sequences building helper macros
- * @{
- */
-/**
- * @brief Number of channels in a conversion sequence.
- */
-#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
-
-#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
-#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
-#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
-#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
-#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
-#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
-
-#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
-#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
-#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
-#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
-#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
-#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
-
-#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
-#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
-#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
-#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
-/** @} */
-
-/**
- * @name Sampling rate settings helper macros
- * @{
- */
-#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
-#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
-#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
-#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
-#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
-#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
-#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
-#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
-#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
-#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
-
-#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
-#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
-#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
-#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
-#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
-#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
-#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
- sampling time. */
-#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
- sampling time. */
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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_adc_lld.h
+ * @brief STM32F1xx ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Triggers selection
+ * @{
+ */
+#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
+#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */
+/** @} */
+
+/**
+ * @name Available analog channels
+ * @{
+ */
+#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
+#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
+#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
+#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
+#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
+#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
+#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
+#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
+#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
+#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
+#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
+#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
+#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
+#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
+#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
+#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
+#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
+#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
+#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
+#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
+#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
+#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
+#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
+#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
+#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC1 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_IRQ_PRIORITY 5
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+#if !STM32_ADC_USE_ADC1
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint16_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */
+} adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* Dummy configuration, it is not needed.*/ \
+ uint32_t dummy
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_configuration_group_fields \
+ /* ADC CR1 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
+ uint32_t cr1; \
+ /* ADC CR2 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
+ enforced inside the driver.*/ \
+ uint32_t cr2; \
+ /* ADC SMPR1 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 10...17.*/ \
+ uint32_t smpr1; \
+ /* ADC SMPR2 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 0...9.*/ \
+ uint32_t smpr2; \
+ /* ADC SQR1 register initialization data. \
+ NOTE: Conversion group sequence 13...16 + sequence length.*/ \
+ uint32_t sqr1; \
+ /* ADC SQR2 register initialization data. \
+ NOTE: Conversion group sequence 7...12.*/ \
+ uint32_t sqr2; \
+ /* ADC SQR3 register initialization data. \
+ NOTE: Conversion group sequence 1...6.*/ \
+ uint32_t sqr3
+
+/**
+ * @name Sequences building helper macros
+ * @{
+ */
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
+#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
+
+#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
+#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
+#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
+#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
+#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
+#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
+
+#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
+#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
+#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
+#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
+#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
+#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
+
+#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
+#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
+#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
+#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
+/** @} */
+
+/**
+ * @name Sampling rate settings helper macros
+ * @{
+ */
+#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
+#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
+#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
+#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
+#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
+#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
+#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
+#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
+#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
+#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
+
+#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
+#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
+#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
+#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
+#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
+#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
+#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
+ sampling time. */
+#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
+ sampling time. */
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
index 3032085fa2..a4885f097d 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
+++ b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
@@ -1,489 +1,489 @@
-/*
- 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 hal_efl_lld.c
- * @brief STM32F1xx 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 2U
-#define STM32_FLASH_LINE_MASK (STM32_FLASH_LINE_SIZE - 1U)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief EFL1 driver identifier.
- */
-EFlashDriver EFLD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const flash_descriptor_t efl_lld_descriptor = {
- .attributes = FLASH_ATTR_ERASED_IS_ONE |
- FLASH_ATTR_MEMORY_MAPPED,
- .page_size = STM32_FLASH_LINE_SIZE,
- .sectors_count = STM32_FLASH_NUMBER_OF_BANKS *
- STM32_FLASH_SECTORS_PER_BANK,
- .sectors = NULL,
- .sectors_size = STM32_FLASH_SECTOR_SIZE,
- .address = (uint8_t *)FLASH_BASE,
- .size = STM32_FLASH_NUMBER_OF_BANKS *
- STM32_FLASH_SECTORS_PER_BANK *
- STM32_FLASH_SECTOR_SIZE
-};
-
-/*===========================================================================*/
-/* 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) {
-
- 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 = 0x0000001FU;
-}
-
-static inline uint32_t stm32_flash_is_busy(EFlashDriver *eflp) {
-
- return (eflp->flash->SR & FLASH_SR_BSY);
-}
-
-static inline void stm32_flash_wait_busy(EFlashDriver *eflp) {
-
- /* Wait for busy bit clear.*/
- while (stm32_flash_is_busy(eflp) != 0U) {
- }
-}
-
-static inline flash_error_t stm32_flash_check_errors(EFlashDriver *eflp) {
- uint32_t sr = eflp->flash->SR;
-
- /* Clearing error conditions.*/
- eflp->flash->SR = sr & 0x0000001FU;
-
- /* Decoding relevant errors.*/
- if ((sr & FLASH_SR_WRPRTERR) != 0U) {
- return FLASH_ERROR_HW_FAILURE;
- }
-
- if ((sr & FLASH_SR_PGERR) != 0U) {
- return FLASH_ERROR_PROGRAM; /* There is no error on 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;
-}
-
-/**
- * @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.
- *
- * @notapi
- */
-const flash_descriptor_t *efl_lld_get_descriptor(void *instance) {
-
- (void)instance;
-
- return &efl_lld_descriptor;
-}
-
-/**
- * @brief Read operation.
- *
- * @param[in] ip pointer to a @p EFlashDriver instance
- * @param[in] offset flash offset
- * @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));
- osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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_READY 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_descriptor.address + offset, n);
-
- /* Ready state again.*/
- devp->state = FLASH_READY;
-
- return err;
-}
-
-/**
- * @brief Program operation.
- * @note It is only possible to write erased pages once except
- * when writing all zeroes.
- *
- * @param[in] ip pointer to a @p EFlashDriver instance
- * @param[in] offset flash offset
- * @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;
- flash_error_t err = FLASH_NO_ERROR;
-
- osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
- osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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 uint16_t *address;
-
- union {
- uint16_t hw[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.*/
- line.hw[0] = 0xFFFFU;
-
- /* Programming address aligned to flash lines.*/
- address = (volatile uint16_t *)(efl_lld_descriptor.address +
- (offset & ~STM32_FLASH_LINE_MASK));
-
- /* Copying data inside the prepared line.*/
- do {
- line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
- offset++;
- n--;
- pp++;
- }
- while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
-
- /* Programming line.*/
- address[0] = line.hw[0];
- stm32_flash_wait_busy(devp);
-
- err = stm32_flash_check_errors(devp);
- if (err != FLASH_NO_ERROR) {
- break;
- }
- /* Check for flash error.*/
- if (address[0] != line.hw[0]) {
- err = FLASH_ERROR_PROGRAM;
- 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 does nothing, the flash memory is where the program
- * is running on.
- *
- * @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) {
- (void) instance;
-
- 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
- * @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;
-
- osalDbgCheck(instance != NULL);
- osalDbgCheck(sector < efl_lld_descriptor.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 page erase.*/
- devp->flash->CR |= FLASH_CR_PER;
-
- /* Set the page.*/
- devp->flash->AR = (uint32_t)(efl_lld_descriptor.address +
- flashGetSectorOffset(getBaseFlash(devp), sector));
-
- /* Start the erase.*/
- devp->flash->CR |= FLASH_CR_STRT;
-
- return FLASH_NO_ERROR;
-}
-
-/**
- * @brief Queries the driver for erase operation progress.
- *
- * @param[in] ip pointer to a @p EFlashDriver instance
- * @param[out] wait_time 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 *wait_time) {
- 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 (stm32_flash_is_busy(devp) == 0U) {
-
- /* Disabling the various erase control bits.*/
- devp->flash->CR &= ~(FLASH_CR_OPTER | FLASH_CR_OPTPG |
- FLASH_CR_MER | FLASH_CR_PER);
-
- /* Back to ready state.*/
- devp->state = FLASH_READY;
-
- err = FLASH_NO_ERROR;
- }
- else {
- /* Recommended time before polling again, this is a simplified
- implementation.*/
- if (wait_time != NULL) {
- *wait_time = (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;
- flash_error_t err = FLASH_NO_ERROR;
- unsigned i;
-
- osalDbgCheck(instance != NULL);
- osalDbgCheck(sector < efl_lld_descriptor.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.*/
- address = (uint32_t *)(efl_lld_descriptor.address +
- flashGetSectorOffset(getBaseFlash(devp), sector));
-
- /* FLASH_READY state while the operation is performed.*/
- devp->state = FLASH_READ;
-
- /* Scanning the sector space.*/
- for (i = 0U; i < STM32_FLASH_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 */
-
-/** @} */
+/*
+ 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 hal_efl_lld.c
+ * @brief STM32F1xx 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 2U
+#define STM32_FLASH_LINE_MASK (STM32_FLASH_LINE_SIZE - 1U)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EFL1 driver identifier.
+ */
+EFlashDriver EFLD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const flash_descriptor_t efl_lld_descriptor = {
+ .attributes = FLASH_ATTR_ERASED_IS_ONE |
+ FLASH_ATTR_MEMORY_MAPPED,
+ .page_size = STM32_FLASH_LINE_SIZE,
+ .sectors_count = STM32_FLASH_NUMBER_OF_BANKS *
+ STM32_FLASH_SECTORS_PER_BANK,
+ .sectors = NULL,
+ .sectors_size = STM32_FLASH_SECTOR_SIZE,
+ .address = (uint8_t *)FLASH_BASE,
+ .size = STM32_FLASH_NUMBER_OF_BANKS *
+ STM32_FLASH_SECTORS_PER_BANK *
+ STM32_FLASH_SECTOR_SIZE
+};
+
+/*===========================================================================*/
+/* 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) {
+
+ 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 = 0x0000001FU;
+}
+
+static inline uint32_t stm32_flash_is_busy(EFlashDriver *eflp) {
+
+ return (eflp->flash->SR & FLASH_SR_BSY);
+}
+
+static inline void stm32_flash_wait_busy(EFlashDriver *eflp) {
+
+ /* Wait for busy bit clear.*/
+ while (stm32_flash_is_busy(eflp) != 0U) {
+ }
+}
+
+static inline flash_error_t stm32_flash_check_errors(EFlashDriver *eflp) {
+ uint32_t sr = eflp->flash->SR;
+
+ /* Clearing error conditions.*/
+ eflp->flash->SR = sr & 0x0000001FU;
+
+ /* Decoding relevant errors.*/
+ if ((sr & FLASH_SR_WRPRTERR) != 0U) {
+ return FLASH_ERROR_HW_FAILURE;
+ }
+
+ if ((sr & FLASH_SR_PGERR) != 0U) {
+ return FLASH_ERROR_PROGRAM; /* There is no error on 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;
+}
+
+/**
+ * @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.
+ *
+ * @notapi
+ */
+const flash_descriptor_t *efl_lld_get_descriptor(void *instance) {
+
+ (void)instance;
+
+ return &efl_lld_descriptor;
+}
+
+/**
+ * @brief Read operation.
+ *
+ * @param[in] ip pointer to a @p EFlashDriver instance
+ * @param[in] offset flash offset
+ * @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));
+ osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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_READY 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_descriptor.address + offset, n);
+
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ return err;
+}
+
+/**
+ * @brief Program operation.
+ * @note It is only possible to write erased pages once except
+ * when writing all zeroes.
+ *
+ * @param[in] ip pointer to a @p EFlashDriver instance
+ * @param[in] offset flash offset
+ * @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;
+ flash_error_t err = FLASH_NO_ERROR;
+
+ osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
+ osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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 uint16_t *address;
+
+ union {
+ uint16_t hw[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.*/
+ line.hw[0] = 0xFFFFU;
+
+ /* Programming address aligned to flash lines.*/
+ address = (volatile uint16_t *)(efl_lld_descriptor.address +
+ (offset & ~STM32_FLASH_LINE_MASK));
+
+ /* Copying data inside the prepared line.*/
+ do {
+ line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
+ offset++;
+ n--;
+ pp++;
+ }
+ while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
+
+ /* Programming line.*/
+ address[0] = line.hw[0];
+ stm32_flash_wait_busy(devp);
+
+ err = stm32_flash_check_errors(devp);
+ if (err != FLASH_NO_ERROR) {
+ break;
+ }
+ /* Check for flash error.*/
+ if (address[0] != line.hw[0]) {
+ err = FLASH_ERROR_PROGRAM;
+ 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 does nothing, the flash memory is where the program
+ * is running on.
+ *
+ * @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) {
+ (void) instance;
+
+ 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
+ * @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;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgCheck(sector < efl_lld_descriptor.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 page erase.*/
+ devp->flash->CR |= FLASH_CR_PER;
+
+ /* Set the page.*/
+ devp->flash->AR = (uint32_t)(efl_lld_descriptor.address +
+ flashGetSectorOffset(getBaseFlash(devp), sector));
+
+ /* Start the erase.*/
+ devp->flash->CR |= FLASH_CR_STRT;
+
+ return FLASH_NO_ERROR;
+}
+
+/**
+ * @brief Queries the driver for erase operation progress.
+ *
+ * @param[in] ip pointer to a @p EFlashDriver instance
+ * @param[out] wait_time 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 *wait_time) {
+ 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 (stm32_flash_is_busy(devp) == 0U) {
+
+ /* Disabling the various erase control bits.*/
+ devp->flash->CR &= ~(FLASH_CR_OPTER | FLASH_CR_OPTPG |
+ FLASH_CR_MER | FLASH_CR_PER);
+
+ /* Back to ready state.*/
+ devp->state = FLASH_READY;
+
+ err = FLASH_NO_ERROR;
+ }
+ else {
+ /* Recommended time before polling again, this is a simplified
+ implementation.*/
+ if (wait_time != NULL) {
+ *wait_time = (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;
+ flash_error_t err = FLASH_NO_ERROR;
+ unsigned i;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgCheck(sector < efl_lld_descriptor.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.*/
+ address = (uint32_t *)(efl_lld_descriptor.address +
+ flashGetSectorOffset(getBaseFlash(devp), sector));
+
+ /* FLASH_READY state while the operation is performed.*/
+ devp->state = FLASH_READ;
+
+ /* Scanning the sector space.*/
+ for (i = 0U; i < STM32_FLASH_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/STM32/STM32F1xx/hal_efl_lld.h b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.h
index 33708d24a9..8b3d741285 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.h
+++ b/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.h
@@ -1,120 +1,120 @@
-/*
- 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 hal_efl_lld.h
- * @brief STM32F1xx 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 STM32F1xx 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 1
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if !defined(STM32_FLASH_SECTOR_SIZE)
-#error "STM32_FLASH_SECTOR_SIZE not defined in registry"
-#endif
-
-#if !defined(STM32_FLASH_NUMBER_OF_BANKS)
-#error "STM32_FLASH_NUMBER_OF_BANKS not defined in registry"
-#endif
-
-#if !defined(STM32_FLASH_SECTORS_PER_BANK)
-#error "STM32_FLASH_SECTORS_PER_BANK not defined in registry"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the embedded flash driver structure.
- */
-#define efl_lld_driver_fields \
- /* Flash registers.*/ \
- FLASH_TypeDef *flash
-
-/**
- * @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 *wait_time);
- 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 */
-
-/** @} */
+/*
+ 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 hal_efl_lld.h
+ * @brief STM32F1xx 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 STM32F1xx 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 1
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(STM32_FLASH_SECTOR_SIZE)
+#error "STM32_FLASH_SECTOR_SIZE not defined in registry"
+#endif
+
+#if !defined(STM32_FLASH_NUMBER_OF_BANKS)
+#error "STM32_FLASH_NUMBER_OF_BANKS not defined in registry"
+#endif
+
+#if !defined(STM32_FLASH_SECTORS_PER_BANK)
+#error "STM32_FLASH_SECTORS_PER_BANK not defined in registry"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the embedded flash driver structure.
+ */
+#define efl_lld_driver_fields \
+ /* Flash registers.*/ \
+ FLASH_TypeDef *flash
+
+/**
+ * @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 *wait_time);
+ 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/STM32/STM32F1xx/hal_lld.c b/os/hal/ports/STM32/STM32F1xx/hal_lld.c
index 271abd2fb1..59d6d0a7d5 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F1xx/hal_lld.c
@@ -1,346 +1,347 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..46c1d2cedf 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_lld_f100.h
+++ b/os/hal/ports/STM32/STM32F1xx/hal_lld_f100.h
@@ -1,575 +1,583 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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..cb1bdb8748 100644
--- a/os/hal/ports/STM32/STM32F1xx/hal_lld_f103.h
+++ b/os/hal/ports/STM32/STM32F1xx/hal_lld_f103.h
@@ -1,604 +1,612 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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..e429dff5f7 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,822 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32F1xx/platform.mk b/os/hal/ports/STM32/STM32F1xx/platform.mk
index 8ff4f53316..ddef923c70 100644
--- a/os/hal/ports/STM32/STM32F1xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F1xx/platform.mk
@@ -1,48 +1,48 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx
-
-# 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"))
-
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
-endif
-
-# Drivers compatible with the platform.
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/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/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_efl_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx
+
+# 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"))
+
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
+endif
+
+# Drivers compatible with the platform.
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDIOv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/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/USBv1/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/STM32F1xx/platform_f105_f107.mk b/os/hal/ports/STM32/STM32F1xx/platform_f105_f107.mk
index f44a0a3195..f4890d8999 100644
--- a/os/hal/ports/STM32/STM32F1xx/platform_f105_f107.mk
+++ b/os/hal/ports/STM32/STM32F1xx/platform_f105_f107.mk
@@ -1,47 +1,47 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx
-
-# 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"))
-
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
-endif
-
-# Drivers compatible with the platform.
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/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/RTCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/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)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx
+
+# 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"))
+
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/hal_adc_lld.c
+endif
+
+# Drivers compatible with the platform.
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv1/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/RTCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/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/STM32F1xx/stm32_isr.c b/os/hal/ports/STM32/STM32F1xx/stm32_isr.c
index e0d0cfb224..1096c4643e 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_isr.c
@@ -1,255 +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 STM32F1xx/stm32_isr.c
- * @brief STM32F1xx ISR handler code.
- *
- * @addtogroup STM32F1xx_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 */
-
-/*===========================================================================*/
-/* 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
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32F1xx ISR handler code.
+ *
+ * @addtogroup STM32F1xx_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 */
+
+/*===========================================================================*/
+/* 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/STM32/STM32F1xx/stm32_isr.h b/os/hal/ports/STM32/STM32F1xx/stm32_isr.h
index 5b455912f8..11a9022c77 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_isr.h
@@ -1,266 +1,266 @@
-/*
- 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/stm32_isr.h
- * @brief STM32F3xx ISR handler header.
- *
- * @addtogroup STM32F1xx_ISR
- * @{
- */
-
-#ifndef STM32_ISR_H
-#define STM32_ISR_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name ISR names and numbers remapping
- * @{
- */
-/*
- * 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_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
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_EVENT_HANDLER VectorBC
-#define STM32_I2C1_ERROR_HANDLER VectorC0
-#define STM32_I2C1_EVENT_NUMBER 31
-#define STM32_I2C1_ERROR_NUMBER 32
-
-#define STM32_I2C2_EVENT_HANDLER VectorC4
-#define STM32_I2C2_ERROR_HANDLER VectorC8
-#define STM32_I2C2_EVENT_NUMBER 33
-#define STM32_I2C2_ERROR_NUMBER 34
-
-/*
- * OTG units.
- */
-#define STM32_OTG1_HANDLER Vector14C
-
-#define STM32_OTG1_NUMBER 67
-
-/*
- * SDIO unit.
- */
-#define STM32_SDIO_HANDLER Vector104
-
-#define STM32_SDIO_NUMBER 49
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_UP_HANDLER VectorA4
-#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_UP_HANDLER VectorF0
-#define STM32_TIM8_CC_HANDLER VectorF8
-#define STM32_TIM9_HANDLER VectorA0 /* Note: same as STM32_TIM1_BRK */
-#define STM32_TIM10_HANDLER VectorA4 /* Note: same as STM32_TIM1_UP */
-#define STM32_TIM11_HANDLER VectorA8 /* Note: same as STM32_TIM1_TRG_COM */
-#define STM32_TIM12_HANDLER VectorEC /* Note: same as STM32_TIM8_BRK */
-#define STM32_TIM13_HANDLER VectorF0 /* Note: same as STM32_TIM8_UP */
-#define STM32_TIM14_HANDLER VectorF4 /* Note: same as STM32_TIM8_TRG_COM */
-
-#define STM32_TIM1_UP_NUMBER 25
-#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_UP_NUMBER 44
-#define STM32_TIM8_CC_NUMBER 46
-#define STM32_TIM9_NUMBER 24 /* Note: same as STM32_TIM1_BRK */
-#define STM32_TIM10_NUMBER 25 /* Note: same as STM32_TIM1_UP */
-#define STM32_TIM11_NUMBER 26 /* Note: same as STM32_TIM1_TRG_COM */
-#define STM32_TIM12_NUMBER 43 /* Note: same as STM32_TIM8_BRK */
-#define STM32_TIM13_NUMBER 44 /* Note: same as STM32_TIM8_UP */
-#define STM32_TIM14_NUMBER 45 /* Note: same as STM32_TIM8_TRG_COM */
-
-/*
- * 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_USART1_NUMBER 37
-#define STM32_USART2_NUMBER 38
-#define STM32_USART3_NUMBER 39
-#define STM32_UART4_NUMBER 52
-#define STM32_UART5_NUMBER 53
-
-/*
- * USB units.
- */
-#define STM32_USB1_HP_HANDLER Vector8C
-#define STM32_USB1_LP_HANDLER Vector90
-
-#define STM32_USB1_HP_NUMBER 19
-#define STM32_USB1_LP_NUMBER 20
-
-/*
- * RTC unit
- */
-#define STM32_RTC1_HANDLER Vector4C
-
-#define STM32_RTC1_NUMBER 3
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief EXTI0 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI0_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI1_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI2 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI2_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI3 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI3_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI4 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI4_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI9..5 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI5_9_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI15..10 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI10_15_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI16 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI16_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI17 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI17_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI18 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI18_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI19 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI19_PRIORITY 6
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32F3xx ISR handler header.
+ *
+ * @addtogroup STM32F1xx_ISR
+ * @{
+ */
+
+#ifndef STM32_ISR_H
+#define STM32_ISR_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name ISR names and numbers remapping
+ * @{
+ */
+/*
+ * 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_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
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_EVENT_HANDLER VectorBC
+#define STM32_I2C1_ERROR_HANDLER VectorC0
+#define STM32_I2C1_EVENT_NUMBER 31
+#define STM32_I2C1_ERROR_NUMBER 32
+
+#define STM32_I2C2_EVENT_HANDLER VectorC4
+#define STM32_I2C2_ERROR_HANDLER VectorC8
+#define STM32_I2C2_EVENT_NUMBER 33
+#define STM32_I2C2_ERROR_NUMBER 34
+
+/*
+ * OTG units.
+ */
+#define STM32_OTG1_HANDLER Vector14C
+
+#define STM32_OTG1_NUMBER 67
+
+/*
+ * SDIO unit.
+ */
+#define STM32_SDIO_HANDLER Vector104
+
+#define STM32_SDIO_NUMBER 49
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_UP_HANDLER VectorA4
+#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_UP_HANDLER VectorF0
+#define STM32_TIM8_CC_HANDLER VectorF8
+#define STM32_TIM9_HANDLER VectorA0 /* Note: same as STM32_TIM1_BRK */
+#define STM32_TIM10_HANDLER VectorA4 /* Note: same as STM32_TIM1_UP */
+#define STM32_TIM11_HANDLER VectorA8 /* Note: same as STM32_TIM1_TRG_COM */
+#define STM32_TIM12_HANDLER VectorEC /* Note: same as STM32_TIM8_BRK */
+#define STM32_TIM13_HANDLER VectorF0 /* Note: same as STM32_TIM8_UP */
+#define STM32_TIM14_HANDLER VectorF4 /* Note: same as STM32_TIM8_TRG_COM */
+
+#define STM32_TIM1_UP_NUMBER 25
+#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_UP_NUMBER 44
+#define STM32_TIM8_CC_NUMBER 46
+#define STM32_TIM9_NUMBER 24 /* Note: same as STM32_TIM1_BRK */
+#define STM32_TIM10_NUMBER 25 /* Note: same as STM32_TIM1_UP */
+#define STM32_TIM11_NUMBER 26 /* Note: same as STM32_TIM1_TRG_COM */
+#define STM32_TIM12_NUMBER 43 /* Note: same as STM32_TIM8_BRK */
+#define STM32_TIM13_NUMBER 44 /* Note: same as STM32_TIM8_UP */
+#define STM32_TIM14_NUMBER 45 /* Note: same as STM32_TIM8_TRG_COM */
+
+/*
+ * 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_USART1_NUMBER 37
+#define STM32_USART2_NUMBER 38
+#define STM32_USART3_NUMBER 39
+#define STM32_UART4_NUMBER 52
+#define STM32_UART5_NUMBER 53
+
+/*
+ * USB units.
+ */
+#define STM32_USB1_HP_HANDLER Vector8C
+#define STM32_USB1_LP_HANDLER Vector90
+
+#define STM32_USB1_HP_NUMBER 19
+#define STM32_USB1_LP_NUMBER 20
+
+/*
+ * RTC unit
+ */
+#define STM32_RTC1_HANDLER Vector4C
+
+#define STM32_RTC1_NUMBER 3
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI0_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI1_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI2 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI2_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI3 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI3_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI4 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI4_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI9..5 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI5_9_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI15..10 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI10_15_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI16 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI16_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI17 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI17_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI18 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI18_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI19 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI19_PRIORITY 6
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32F1xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F1xx/stm32_rcc.h
index 9578bf1453..67a0841ac5 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_rcc.h
@@ -1,1230 +1,1230 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32f10x.h.
- *
- * @addtogroup STM32F1xx_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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask APB1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1(mask, lp) { \
- RCC->APB1ENR |= (mask); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask APB1 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1(mask) { \
- RCC->APB1ENR &= ~(mask); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB2 bus.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask APB2 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB2(mask) { \
- RCC->APB2ENR &= ~(mask); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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 AHB bus.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ADC1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-/** @} */
-
-/**
- * @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 Backup domain interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the BKP interface clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableBKPInterface(lp) rccEnableAPB1((RCC_APB1ENR_BKPEN), lp)
-
-/**
- * @brief Disables BKP interface clock.
- *
- * @api
- */
-#define rccDisableBKPInterface() rccDisableAPB1(RCC_APB1ENR_BKPEN)
-
-/**
- * @brief Resets the Backup Domain interface.
- *
- * @api
- */
-#define rccResetBKPInterface() rccResetAPB1(RCC_APB1ENR_BKPRST)
-
-/**
- * @brief Resets the entire Backup Domain.
- *
- * @api
- */
-#define rccResetBKP() (RCC->BDCR |= RCC_BDCR_BDRST)
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name DMA peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMA1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- * @note Not supported in this family, does nothing.
- *
- * @api
- */
-#define rccResetDMA1()
-
-/**
- * @brief Enables the DMA2 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
-
-/**
- * @brief Disables the DMA2 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- * @note Not supported in this family, does nothing.
- *
- * @api
- */
-#define rccResetDMA2()
-/** @} */
-
-/**
- * @name ETH peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ETH peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableETH(lp) rccEnableAHB(RCC_AHBENR_ETHMACEN | \
- RCC_AHBENR_ETHMACTXEN | \
- RCC_AHBENR_ETHMACRXEN, lp)
-
-/**
- * @brief Disables the ETH peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccDisableETH() rccDisableAHB(RCC_AHBENR_ETHMACEN | \
- RCC_AHBENR_ETHMACTXEN | \
- RCC_AHBENR_ETHMACRXEN)
-
-/**
- * @brief Resets the ETH peripheral.
- *
- * @api
- */
-#define rccResetETH() rccResetAHB(RCC_AHBRSTR_ETHMACRST)
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @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) rccEnableAHB(RCC_AHBENR_OTGFSEN, lp)
-
-/**
- * @brief Disables the OTG_FS peripheral clock.
- *
- * @api
- */
-#define rccDisableOTG_FS() rccDisableAHB(RCC_AHBENR_OTGFSEN)
-
-/**
- * @brief Resets the OTG_FS peripheral.
- *
- * @api
- */
-#define rccResetOTG_FS() rccResetAHB(RCC_AHBRSTR_OTGFSRST)
-/** @} */
-
-/**
- * @name SDIO peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDIO peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDIO(lp) rccEnableAHB(RCC_AHBENR_SDIOEN, lp)
-
-/**
- * @brief Disables the SDIO peripheral clock.
- *
- * @api
- */
-#define rccDisableSDIO() rccDisableAHB(RCC_AHBENR_SDIOEN)
-
-/**
- * @brief Resets the SDIO peripheral.
- * @note Not supported in this family, does nothing.
- *
- * @api
- */
-#define rccResetSDIO()
-/** @} */
-
-/**
- * @name SPI peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SPI1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the TIM1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
-
- * @note The @p lp parameter is ignored in this family.
-
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 TIM15 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-/** @} */
-
-/**
- * @name USART/UART peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USART1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
-/** @} */
-
-/**
- * @name FSMC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FSMC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableFSMC(lp) rccEnableAHB(RCC_AHBENR_FSMCEN, lp)
-
-/**
- * @brief Disables the FSMC peripheral clock.
- *
- * @api
- */
-#define rccDisableFSMC() rccDisableAHB(RCC_AHBENR_FSMCEN)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32f10x.h.
+ *
+ * @addtogroup STM32F1xx_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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask APB1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1(mask, lp) { \
+ RCC->APB1ENR |= (mask); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask APB1 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1(mask) { \
+ RCC->APB1ENR &= ~(mask); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB2 bus.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask APB2 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB2(mask) { \
+ RCC->APB2ENR &= ~(mask); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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 AHB bus.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ADC1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+/** @} */
+
+/**
+ * @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 Backup domain interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the BKP interface clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableBKPInterface(lp) rccEnableAPB1((RCC_APB1ENR_BKPEN), lp)
+
+/**
+ * @brief Disables BKP interface clock.
+ *
+ * @api
+ */
+#define rccDisableBKPInterface() rccDisableAPB1(RCC_APB1ENR_BKPEN)
+
+/**
+ * @brief Resets the Backup Domain interface.
+ *
+ * @api
+ */
+#define rccResetBKPInterface() rccResetAPB1(RCC_APB1ENR_BKPRST)
+
+/**
+ * @brief Resets the entire Backup Domain.
+ *
+ * @api
+ */
+#define rccResetBKP() (RCC->BDCR |= RCC_BDCR_BDRST)
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name DMA peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMA1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ * @note Not supported in this family, does nothing.
+ *
+ * @api
+ */
+#define rccResetDMA1()
+
+/**
+ * @brief Enables the DMA2 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
+
+/**
+ * @brief Disables the DMA2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ * @note Not supported in this family, does nothing.
+ *
+ * @api
+ */
+#define rccResetDMA2()
+/** @} */
+
+/**
+ * @name ETH peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ETH peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableETH(lp) rccEnableAHB(RCC_AHBENR_ETHMACEN | \
+ RCC_AHBENR_ETHMACTXEN | \
+ RCC_AHBENR_ETHMACRXEN, lp)
+
+/**
+ * @brief Disables the ETH peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccDisableETH() rccDisableAHB(RCC_AHBENR_ETHMACEN | \
+ RCC_AHBENR_ETHMACTXEN | \
+ RCC_AHBENR_ETHMACRXEN)
+
+/**
+ * @brief Resets the ETH peripheral.
+ *
+ * @api
+ */
+#define rccResetETH() rccResetAHB(RCC_AHBRSTR_ETHMACRST)
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @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) rccEnableAHB(RCC_AHBENR_OTGFSEN, lp)
+
+/**
+ * @brief Disables the OTG_FS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableOTG_FS() rccDisableAHB(RCC_AHBENR_OTGFSEN)
+
+/**
+ * @brief Resets the OTG_FS peripheral.
+ *
+ * @api
+ */
+#define rccResetOTG_FS() rccResetAHB(RCC_AHBRSTR_OTGFSRST)
+/** @} */
+
+/**
+ * @name SDIO peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDIO peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDIO(lp) rccEnableAHB(RCC_AHBENR_SDIOEN, lp)
+
+/**
+ * @brief Disables the SDIO peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDIO() rccDisableAHB(RCC_AHBENR_SDIOEN)
+
+/**
+ * @brief Resets the SDIO peripheral.
+ * @note Not supported in this family, does nothing.
+ *
+ * @api
+ */
+#define rccResetSDIO()
+/** @} */
+
+/**
+ * @name SPI peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SPI1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the TIM1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+
+ * @note The @p lp parameter is ignored in this family.
+
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 TIM15 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+/** @} */
+
+/**
+ * @name USART/UART peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USART1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
+/** @} */
+
+/**
+ * @name FSMC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FSMC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableFSMC(lp) rccEnableAHB(RCC_AHBENR_FSMCEN, lp)
+
+/**
+ * @brief Disables the FSMC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFSMC() rccDisableAHB(RCC_AHBENR_FSMCEN)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
index e06ed276ce..b5dbc2aa59 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
@@ -1,1422 +1,1422 @@
-/*
- 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/stm32_registry.h
- * @brief STM32F1xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-#if defined(STM32F100xB)
-#define STM32F10X_MD_VL
-
-#elif defined(STM32F100xE)
-#define STM32F10X_HD_VL
-
-#elif defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6)
-#define STM32F10X_LD
-
-#elif defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
-#define STM32F10X_MD
-
-#elif defined(STM32F101xE) || defined(STM32F103xE)
-#define STM32F10X_HD
-
-#elif defined(STM32F101xG) || defined(STM32F103xG)
-#define STM32F10X_XL
-
-#elif defined(STM32F105xC) || defined(STM32F107xC)
-#define STM32F10X_CL
-
-#else
-#error "unsupported or unrecognized STM32F1xx member"
-#endif
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-#if defined(STM32F10X_MD_VL) || defined(__DOXYGEN__)
-/**
- * @name STM32F100 MD capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 0
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 19
-#define STM32_EXTI_IMR_MASK 0x00000000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#define STM32_FLASH_SECTOR_SIZE 1024U
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 32 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_IS_CALENDAR FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#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_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_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_UART9 FALSE
-#define STM32_HAS_UART10 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-/** @} */
-#endif /* defined(STM32F10X_MD_VL) */
-
-#if defined(STM32F10X_LD) || defined(__DOXYGEN__)
-/**
- * @name STM32F103 LD capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 19
-#define STM32_EXTI_IMR_MASK 0x00000000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#define STM32_FLASH_SECTOR_SIZE 1024U
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 32 /* Maximum, can be redefined.*/
-#endif
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_IS_CALENDAR FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#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 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_UART9 FALSE
-#define STM32_HAS_UART10 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#if defined(STM32F103x6)
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#else
-#define STM32_HAS_USB FALSE
-#endif
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-/** @} */
-#endif /* defined(STM32F10X_LD) */
-
-#if defined(STM32F10X_MD) || defined(__DOXYGEN__)
-/**
- * @name STM32F103 MD capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 19
-#define STM32_EXTI_IMR_MASK 0x00000000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#define STM32_FLASH_SECTOR_SIZE 1024U
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_IS_CALENDAR FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#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 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_UART9 FALSE
-#define STM32_HAS_UART10 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#if defined(STM32F103xB)
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#else
-#define STM32_HAS_USB FALSE
-#endif
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-/** @} */
-#endif /* defined(STM32F10X_MD) */
-
-#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
-/**
- * @name STM32F103 HD capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 TRUE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH45_HANDLER Vector12C
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH45_NUMBER 59
-
-#define STM32_DMA2_CH4_NUMBER STM32_DMA2_CH45_NUMBER
-#define STM32_DMA2_CH5_NUMBER STM32_DMA2_CH45_NUMBER
-#define DMA2_CH4_CMASK 0x00000C00U
-#define DMA2_CH5_CMASK 0x00000C00U
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 19
-#define STM32_EXTI_IMR_MASK 0x00000000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#define STM32_FLASH_SECTOR_SIZE 2048U
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_IS_CALENDAR FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO TRUE
-#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#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 FALSE
-#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 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_UART9 FALSE
-#define STM32_HAS_UART10 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-#define STM32_FSMC_IS_FMC FALSE
-#define STM32_FSMC_HANDLER Vector100
-#define STM32_FSMC_NUMBER 48
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-/** @} */
-#endif /* defined(STM32F10X_HD) */
-
-#if defined(STM32F10X_XL) || defined(__DOXYGEN__)
-/**
- * @name STM32F103 XL capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 TRUE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 19
-#define STM32_EXTI_IMR_MASK 0x00000000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-#define STM32_FLASH_SECTOR_SIZE 2048U
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_IS_CALENDAR FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO TRUE
-#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#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 FALSE
-#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_UART9 FALSE
-#define STM32_HAS_UART10 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-#define STM32_FSMC_IS_FMC FALSE
-#define STM32_FSMC_HANDLER Vector100
-#define STM32_FSMC_NUMBER 48
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-/** @} */
-#endif /* defined(STM32F10X_XL) */
-
-#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
-/**
- * @name STM32F105/F107 CL capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 FALSE
-#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_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH TRUE
-#define STM32_ETH_HANDLER Vector134
-#define STM32_ETH_NUMBER 61
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 20
-#define STM32_EXTI_IMR_MASK 0x00000000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#define STM32_FLASH_SECTOR_SIZE 2048U
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_IS_CALENDAR FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#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 FALSE
-#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 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_UART9 FALSE
-#define STM32_HAS_UART10 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 1
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 3
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-/** @} */
-#endif /* defined(STM32F10X_CL) */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32F1xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+#if defined(STM32F100xB)
+#define STM32F10X_MD_VL
+
+#elif defined(STM32F100xE)
+#define STM32F10X_HD_VL
+
+#elif defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6)
+#define STM32F10X_LD
+
+#elif defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
+#define STM32F10X_MD
+
+#elif defined(STM32F101xE) || defined(STM32F103xE)
+#define STM32F10X_HD
+
+#elif defined(STM32F101xG) || defined(STM32F103xG)
+#define STM32F10X_XL
+
+#elif defined(STM32F105xC) || defined(STM32F107xC)
+#define STM32F10X_CL
+
+#else
+#error "unsupported or unrecognized STM32F1xx member"
+#endif
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+#if defined(STM32F10X_MD_VL) || defined(__DOXYGEN__)
+/**
+ * @name STM32F100 MD capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 0
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 19
+#define STM32_EXTI_IMR_MASK 0x00000000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#define STM32_FLASH_SECTOR_SIZE 1024U
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 32 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_IS_CALENDAR FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#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_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_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_UART9 FALSE
+#define STM32_HAS_UART10 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+/** @} */
+#endif /* defined(STM32F10X_MD_VL) */
+
+#if defined(STM32F10X_LD) || defined(__DOXYGEN__)
+/**
+ * @name STM32F103 LD capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 19
+#define STM32_EXTI_IMR_MASK 0x00000000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#define STM32_FLASH_SECTOR_SIZE 1024U
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 32 /* Maximum, can be redefined.*/
+#endif
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_IS_CALENDAR FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#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 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_UART9 FALSE
+#define STM32_HAS_UART10 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#if defined(STM32F103x6)
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#else
+#define STM32_HAS_USB FALSE
+#endif
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+/** @} */
+#endif /* defined(STM32F10X_LD) */
+
+#if defined(STM32F10X_MD) || defined(__DOXYGEN__)
+/**
+ * @name STM32F103 MD capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 19
+#define STM32_EXTI_IMR_MASK 0x00000000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#define STM32_FLASH_SECTOR_SIZE 1024U
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_IS_CALENDAR FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#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 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_UART9 FALSE
+#define STM32_HAS_UART10 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#if defined(STM32F103xB)
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#else
+#define STM32_HAS_USB FALSE
+#endif
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+/** @} */
+#endif /* defined(STM32F10X_MD) */
+
+#if defined(STM32F10X_HD) || defined(__DOXYGEN__)
+/**
+ * @name STM32F103 HD capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 TRUE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH45_HANDLER Vector12C
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH45_NUMBER 59
+
+#define STM32_DMA2_CH4_NUMBER STM32_DMA2_CH45_NUMBER
+#define STM32_DMA2_CH5_NUMBER STM32_DMA2_CH45_NUMBER
+#define DMA2_CH4_CMASK 0x00000C00U
+#define DMA2_CH5_CMASK 0x00000C00U
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 19
+#define STM32_EXTI_IMR_MASK 0x00000000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#define STM32_FLASH_SECTOR_SIZE 2048U
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_IS_CALENDAR FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO TRUE
+#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#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 FALSE
+#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 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_UART9 FALSE
+#define STM32_HAS_UART10 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+#define STM32_FSMC_IS_FMC FALSE
+#define STM32_FSMC_HANDLER Vector100
+#define STM32_FSMC_NUMBER 48
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+/** @} */
+#endif /* defined(STM32F10X_HD) */
+
+#if defined(STM32F10X_XL) || defined(__DOXYGEN__)
+/**
+ * @name STM32F103 XL capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 TRUE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 19
+#define STM32_EXTI_IMR_MASK 0x00000000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+#define STM32_FLASH_SECTOR_SIZE 2048U
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_IS_CALENDAR FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO TRUE
+#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#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 FALSE
+#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_UART9 FALSE
+#define STM32_HAS_UART10 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+#define STM32_FSMC_IS_FMC FALSE
+#define STM32_FSMC_HANDLER Vector100
+#define STM32_FSMC_NUMBER 48
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+/** @} */
+#endif /* defined(STM32F10X_XL) */
+
+#if defined(STM32F10X_CL) || defined(__DOXYGEN__)
+/**
+ * @name STM32F105/F107 CL capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 FALSE
+#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_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH TRUE
+#define STM32_ETH_HANDLER Vector134
+#define STM32_ETH_NUMBER 61
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 20
+#define STM32_EXTI_IMR_MASK 0x00000000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#define STM32_FLASH_SECTOR_SIZE 2048U
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 128 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_IS_CALENDAR FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#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 FALSE
+#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 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_UART9 FALSE
+#define STM32_HAS_UART10 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 1
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 3
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+/** @} */
+#endif /* defined(STM32F10X_CL) */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c b/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
index 1001eb86c1..0631b5e484 100644
--- a/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
+++ b/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
@@ -1,740 +1,740 @@
-/*
- 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_adc_lld.c
- * @brief STM32F37x ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define SDADC_FORBIDDEN_CR1_FLAGS (SDADC_CR1_INIT | SDADC_CR1_RDMAEN | \
- SDADC_CR1_RSYNC | SDADC_CR1_JSYNC | \
- SDADC_CR1_ROVRIE | SDADC_CR1_REOCIE | \
- SDADC_CR1_JEOCIE | SDADC_CR1_EOCALIE)
-
-#define SDADC_ENFORCED_CR1_FLAGS (SDADC_CR1_JDMAEN | SDADC_CR1_JOVRIE)
-
-#define SDADC_FORBIDDEN_CR2_FLAGS (SDADC_CR2_RSWSTART | \
- SDADC_CR2_RCONT | \
- SDADC_CR2_RCH | \
- SDADC_CR2_JCONT | \
- SDADC_CR2_STARTCALIB | \
- SDADC_CR2_CALIBCNT)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/** @brief SDADC1 driver identifier.*/
-#if STM32_ADC_USE_SDADC1 || defined(__DOXYGEN__)
-ADCDriver SDADCD1;
-#endif
-
-/** @brief SDADC2 driver identifier.*/
-#if STM32_ADC_USE_SDADC2 || defined(__DOXYGEN__)
-ADCDriver SDADCD2;
-#endif
-
-/** @brief SDADC3 driver identifier.*/
-#if STM32_ADC_USE_SDADC3 || defined(__DOXYGEN__)
-ADCDriver SDADCD3;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const ADCConfig adc_lld_default_config = {
-#if STM32_ADC_USE_SDADC
- 0,
- {
- 0,
- 0,
- 0
- }
-#else /* !STM32_ADC_USE_SDADC */
- 0
-#endif /* !STM32_ADC_USE_SDADC */
-};
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Stops, reconfigures and restarts an ADC/SDADC.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- */
-static void adc_lld_reconfig(ADCDriver *adcp) {
-
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- if (adcp->adc != NULL)
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_ADC
- {
- /* ADC initial setup, starting the analog part here in order to reduce
- the latency when starting a conversion.*/
- uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
- adcp->adc->CR2 = cr2;
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = cr2 | ADC_CR2_ADON;
-
- }
-#endif /* STM32_ADC_USE_ADC */
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- else if (adcp->sdadc != NULL)
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_SDADC
- {
- /* SDADC initial setup, starting the analog part here in order to reduce
- the latency when starting a conversion.*/
- adcp->sdadc->CR2 = 0;
- adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
- ~SDADC_FORBIDDEN_CR1_FLAGS;
- adcp->sdadc->CONF0R = (adcp->sdadc->CONF0R & SDADC_CONFR_OFFSET_MASK) |
- adcp->config->confxr[0];
- adcp->sdadc->CONF1R = (adcp->sdadc->CONF1R & SDADC_CONFR_OFFSET_MASK) |
- adcp->config->confxr[1];
- adcp->sdadc->CONF2R = (adcp->sdadc->CONF2R & SDADC_CONFR_OFFSET_MASK) |
- adcp->config->confxr[2];
- adcp->sdadc->CR2 = SDADC_CR2_ADON;
- }
-#endif /* STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
-else {
- osalDbgAssert(FALSE, "invalid state");
- }
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-}
-
-/**
- * @brief ADC DMA ISR service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- *
- * @notapi
- */
-static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-
-#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
-/**
- * @brief ADC ISR service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] sr content of the ISR register
- *
- * @notapi
- */
-static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t sr) {
-
- /* It could be a spurious interrupt caused by overflows after DMA disabling,
- just ignore it in this case.*/
- if (adcp->grpp != NULL) {
- if (sr & ADC_SR_AWD) {
- /* Analog watchdog error.*/
- _adc_isr_error_code(adcp, ADC_ERR_AWD1);
- }
- }
-}
-#endif /* STM32_ADC_USE_ADC */
-
-#if STM32_ADC_USE_SDADC || defined(__DOXYGEN__)
-/**
- * @brief ADC ISR service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] isr content of the ISR register
- *
- * @notapi
- */
-static void sdadc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
-
- /* It could be a spurious interrupt caused by overflows after DMA disabling,
- just ignore it in this case.*/
- if (adcp->grpp != NULL) {
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((isr & SDADC_ISR_JOVRF) &&
- (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
- }
- }
-}
-#endif /* STM32_ADC_USE_SDADC */
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-/**
- * @brief ADC1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector88) {
- uint32_t sr;
-
- OSAL_IRQ_PROLOGUE();
-
- sr = ADC1->SR;
- ADC1->SR = 0;
- adc_lld_serve_interrupt(&ADCD1, sr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_SDADC1 || defined(__DOXYGEN__)
-/**
- * @brief SDADC1 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector134) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = SDADC1->ISR;
- SDADC1->CLRISR = isr;
- sdadc_lld_serve_interrupt(&SDADCD1, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_SDADC1 */
-
-#if STM32_ADC_USE_SDADC2 || defined(__DOXYGEN__)
-/**
- * @brief SDADC2 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector138) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = SDADC2->ISR;
- SDADC2->CLRISR = isr;
- sdadc_lld_serve_interrupt(&SDADCD2, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_SDADC2 */
-
-#if STM32_ADC_USE_SDADC3 || defined(__DOXYGEN__)
-/**
- * @brief SDADC3 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector13C) {
- uint32_t isr;
-
- OSAL_IRQ_PROLOGUE();
-
- isr = SDADC3->ISR;
- SDADC3->CLRISR = isr;
- sdadc_lld_serve_interrupt(&SDADCD3, isr);
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* STM32_ADC_USE_SDADC3 */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = ADC1;
-#if STM32_ADC_USE_SDADC
- ADCD1.sdadc = NULL;
-#endif
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- nvicEnableVector(ADC1_IRQn, STM32_ADC_ADC1_IRQ_PRIORITY);
-#endif
-
-#if STM32_ADC_USE_SDADC1
- /* Driver initialization.*/
- adcObjectInit(&SDADCD1);
-#if STM32_ADC_USE_ADC
- SDADCD1.adc = NULL;
-#endif
- SDADCD1.sdadc = SDADC1;
- SDADCD1.dmastp = NULL;
- SDADCD1.dmamode = STM32_DMA_CR_CHSEL(SDADC1_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_SDADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- nvicEnableVector(SDADC1_IRQn, STM32_ADC_SDADC1_IRQ_PRIORITY);
-#endif
-
-#if STM32_ADC_USE_SDADC2
- /* Driver initialization.*/
- adcObjectInit(&SDADCD2);
-#if STM32_ADC_USE_ADC
- SDADCD2.adc = NULL;
-#endif
- SDADCD2.sdadc = SDADC2;
- SDADCD2.dmastp = NULL;
- SDADCD2.dmamode = STM32_DMA_CR_CHSEL(SDADC2_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_SDADC2_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- nvicEnableVector(SDADC2_IRQn, STM32_ADC_SDADC2_IRQ_PRIORITY);
-#endif
-
-#if STM32_ADC_USE_SDADC3
- /* Driver initialization.*/
- adcObjectInit(&SDADCD3);
-#if STM32_ADC_USE_ADC
- SDADCD3.adc = NULL;
-#endif
- SDADCD3.sdadc = SDADC3;
- SDADCD3.dmastp = NULL;
- SDADCD3.dmamode = STM32_DMA_CR_CHSEL(SDADC3_DMA_CHANNEL) |
- STM32_DMA_CR_PL(STM32_ADC_SDADC3_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
- nvicEnableVector(SDADC3_IRQn, STM32_ADC_SDADC3_IRQ_PRIORITY);
-#endif
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- if (adcp->config == NULL)
- adcp->config = &adc_lld_default_config;
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1),
- STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
- rccEnableADC1(true);
- }
-#endif /* STM32_ADC_USE_ADC1 */
-
-#if STM32_ADC_USE_SDADC1
- if (&SDADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(2, 3),
- STM32_ADC_SDADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- dmaStreamSetPeripheral(adcp->dmastp, &SDADC1->JDATAR);
- rccEnableSDADC1(true);
- PWR->CR |= PWR_CR_SDADC1EN;
- adcp->sdadc->CR2 = 0;
- adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
- ~SDADC_FORBIDDEN_CR1_FLAGS;
- adcp->sdadc->CR2 = SDADC_CR2_ADON;
- }
-#endif /* STM32_ADC_USE_SDADC1 */
-
-#if STM32_ADC_USE_SDADC2
- if (&SDADCD2 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(2, 4),
- STM32_ADC_SDADC2_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- dmaStreamSetPeripheral(adcp->dmastp, &SDADC2->JDATAR);
- rccEnableSDADC2(true);
- PWR->CR |= PWR_CR_SDADC2EN;
- adcp->sdadc->CR2 = 0;
- adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
- ~SDADC_FORBIDDEN_CR1_FLAGS;
- adcp->sdadc->CR2 = SDADC_CR2_ADON;
- }
-#endif /* STM32_ADC_USE_SDADC2 */
-
-#if STM32_ADC_USE_SDADC3
- if (&SDADCD3 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(2, 5),
- STM32_ADC_SDADC3_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- dmaStreamSetPeripheral(adcp->dmastp, &SDADC3->JDATAR);
- rccEnableSDADC3(true);
- PWR->CR |= PWR_CR_SDADC3EN;
- adcp->sdadc->CR2 = 0;
- adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
- ~SDADC_FORBIDDEN_CR1_FLAGS;
- adcp->sdadc->CR2 = SDADC_CR2_ADON;
- }
-#endif /* STM32_ADC_USE_SDADC3 */
- }
-
- adc_lld_reconfig(adcp);
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock.*/
- if (adcp->state == ADC_READY) {
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
- rccDisableADC1();
- }
-#endif
-
-#if STM32_ADC_USE_SDADC1
- if (&SDADCD1 == adcp) {
- adcp->sdadc->CR1 = 0;
- adcp->sdadc->CR2 = 0;
- rccDisableSDADC1();
- PWR->CR &= ~PWR_CR_SDADC1EN;
- }
-#endif
-
-#if STM32_ADC_USE_SDADC2
- if (&SDADCD2 == adcp) {
- adcp->sdadc->CR1 = 0;
- adcp->sdadc->CR2 = 0;
- rccDisableSDADC2();
- PWR->CR &= ~PWR_CR_SDADC2EN;
- }
-#endif
-
-#if STM32_ADC_USE_SDADC3
- if (&SDADCD3 == adcp) {
- adcp->sdadc->CR1 = 0;
- adcp->sdadc->CR2 = 0;
- rccDisableSDADC3();
- PWR->CR &= ~PWR_CR_SDADC3EN;
- }
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t mode;
- const ADCConversionGroup* grpp = adcp->grpp;
-
- /* DMA setup.*/
- mode = adcp->dmamode;
- if (grpp->circular) {
- mode |= STM32_DMA_CR_CIRC;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- mode |= STM32_DMA_CR_HTIE;
- }
- }
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
- dmaStreamSetTransactionSize(adcp->dmastp,
- (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- dmaStreamSetMode(adcp->dmastp, mode);
- dmaStreamEnable(adcp->dmastp);
-
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- if (adcp->adc != NULL)
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_ADC
- {
- uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
- cr2 |= grpp->u.adc.cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
- if ((cr2 & ADC_CR2_SWSTART) != 0)
- cr2 |= ADC_CR2_CONT;
- adcp->adc->CR2 = cr2;
-
- /* ADC setup.*/
- adcp->adc->SR = 0;
- adcp->adc->LTR = grpp->u.adc.ltr;
- adcp->adc->HTR = grpp->u.adc.htr;
- adcp->adc->SMPR1 = grpp->u.adc.smpr[0];
- adcp->adc->SMPR2 = grpp->u.adc.smpr[1];
- adcp->adc->SQR1 = grpp->u.adc.sqr[0] |
- ADC_SQR1_NUM_CH(grpp->num_channels);
- adcp->adc->SQR2 = grpp->u.adc.sqr[1];
- adcp->adc->SQR3 = grpp->u.adc.sqr[2];
-
- /* ADC conversion start, the start is performed using the method
- specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/
- adcp->adc->CR1 = grpp->u.adc.cr1 | ADC_CR1_AWDIE | ADC_CR1_SCAN;
- adcp->adc->CR2 = adcp->adc->CR2; /* Triggers the conversion start.*/
- }
-#endif /* STM32_ADC_USE_ADC */
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- else if (adcp->sdadc != NULL)
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_SDADC
- {
- uint32_t cr2 = (grpp->u.sdadc.cr2 & ~SDADC_FORBIDDEN_CR2_FLAGS) |
- SDADC_CR2_ADON;
- if ((grpp->u.sdadc.cr2 & SDADC_CR2_JSWSTART) != 0)
- cr2 |= SDADC_CR2_JCONT;
-
- /* Entering initialization mode.*/
- adcp->sdadc->CR1 |= SDADC_CR1_INIT;
- while ((adcp->sdadc->ISR & SDADC_ISR_INITRDY) == 0)
- ;
-
- /* SDADC setup.*/
- adcp->sdadc->JCHGR = grpp->u.sdadc.jchgr;
- adcp->sdadc->CONFCHR1 = grpp->u.sdadc.confchr[0];
- adcp->sdadc->CONFCHR2 = grpp->u.sdadc.confchr[1];
-
- /* SDADC trigger modes, this write must be performed when
- SDADC_CR1_INIT=1.*/
- adcp->sdadc->CR2 = cr2;
-
- /* Leaving initialization mode.*/
- adcp->sdadc->CR1 &= ~SDADC_CR1_INIT;
-
- /* Special case, if SDADC_CR2_JSWSTART is specified it has to be
- written after SDADC_CR1_INIT has been set to zero. Just a write is
- performed, any other bit is ingore if not in initialization mode.*/
- adcp->sdadc->CR2 = cr2;
- }
-#endif /* STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- else {
- osalDbgAssert(FALSE, "invalid state");
- }
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- /* Disabling the associated DMA stream.*/
- dmaStreamDisable(adcp->dmastp);
-
- /* Stopping and restarting the whole ADC, apparently the only way to stop
- a conversion.*/
- adc_lld_reconfig(adcp);
-}
-
-/**
- * @brief Calibrates an ADC unit.
- * @note The calibration must be performed after calling @p adcStart().
- * @note For SDADC units it is assumed that the field SDADC_CR2_CALIBCNT
- * has been
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @api
- */
-void adcSTM32Calibrate(ADCDriver *adcp) {
-
- osalDbgAssert((adcp->state == ADC_READY) ||
- (adcp->state == ADC_COMPLETE) ||
- (adcp->state == ADC_ERROR),
- "not ready");
-
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- if (adcp->adc != NULL)
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_ADC
- {
- /* Resetting calibration just to be safe.*/
- ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
- while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
- ;
-
- /* Calibration.*/
- ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
- while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
- ;
- }
-#endif /* STM32_ADC_USE_ADC */
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- else if (adcp->sdadc != NULL)
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_SDADC
- {
- /* Selecting a full calibration in three steps.*/
- adcp->sdadc->CR2 = (adcp->sdadc->CR2 & ~SDADC_CR2_CALIBCNT) |
- SDADC_CR2_CALIBCNT_1;
-
- /* Calibration.*/
- adcp->sdadc->CR2 |= SDADC_CR2_STARTCALIB;
- while ((adcp->sdadc->ISR & SDADC_ISR_EOCALF) == 0)
- ;
-
- /* Clearing the EOCALF flag.*/
- adcp->sdadc->CLRISR |= SDADC_ISR_CLREOCALF;
- }
-#endif /* STM32_ADC_USE_SDADC */
-#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
- else {
- osalDbgAssert(FALSE, "invalid state");
- }
-#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
-}
-
-#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
-/**
- * @brief Enables the TSVREFE bit.
- * @details The TSVREFE bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @api
- */
-void adcSTM32EnableTSVREFE(void) {
-
- ADC1->CR2 |= ADC_CR2_TSVREFE;
-}
-
-/**
- * @brief Disables the TSVREFE bit.
- * @details The TSVREFE bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- *
- * @api
- */
-void adcSTM32DisableTSVREFE(void) {
-
- ADC1->CR2 &= ~ADC_CR2_TSVREFE;
-}
-
-/**
- * @brief Enables the VBATE bit.
- * @details The VBATE bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- *
- * @api
- */
-void adcSTM32EnableVBATE(void) {
-
- SYSCFG->CFGR1 |= SYSCFG_CFGR1_VBAT;
-}
-
-/**
- * @brief Disables the VBATE bit.
- * @details The VBATE bit is required in order to sample the VBAT channel.
- * @note This is an STM32-only functionality.
- *
- * @api
- */
-void adcSTM32DisableVBATE(void) {
-
- SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_VBAT;
-}
-#endif /* STM32_ADC_USE_ADC */
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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_adc_lld.c
+ * @brief STM32F37x ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define SDADC_FORBIDDEN_CR1_FLAGS (SDADC_CR1_INIT | SDADC_CR1_RDMAEN | \
+ SDADC_CR1_RSYNC | SDADC_CR1_JSYNC | \
+ SDADC_CR1_ROVRIE | SDADC_CR1_REOCIE | \
+ SDADC_CR1_JEOCIE | SDADC_CR1_EOCALIE)
+
+#define SDADC_ENFORCED_CR1_FLAGS (SDADC_CR1_JDMAEN | SDADC_CR1_JOVRIE)
+
+#define SDADC_FORBIDDEN_CR2_FLAGS (SDADC_CR2_RSWSTART | \
+ SDADC_CR2_RCONT | \
+ SDADC_CR2_RCH | \
+ SDADC_CR2_JCONT | \
+ SDADC_CR2_STARTCALIB | \
+ SDADC_CR2_CALIBCNT)
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/** @brief SDADC1 driver identifier.*/
+#if STM32_ADC_USE_SDADC1 || defined(__DOXYGEN__)
+ADCDriver SDADCD1;
+#endif
+
+/** @brief SDADC2 driver identifier.*/
+#if STM32_ADC_USE_SDADC2 || defined(__DOXYGEN__)
+ADCDriver SDADCD2;
+#endif
+
+/** @brief SDADC3 driver identifier.*/
+#if STM32_ADC_USE_SDADC3 || defined(__DOXYGEN__)
+ADCDriver SDADCD3;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const ADCConfig adc_lld_default_config = {
+#if STM32_ADC_USE_SDADC
+ 0,
+ {
+ 0,
+ 0,
+ 0
+ }
+#else /* !STM32_ADC_USE_SDADC */
+ 0
+#endif /* !STM32_ADC_USE_SDADC */
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Stops, reconfigures and restarts an ADC/SDADC.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ */
+static void adc_lld_reconfig(ADCDriver *adcp) {
+
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ if (adcp->adc != NULL)
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_ADC
+ {
+ /* ADC initial setup, starting the analog part here in order to reduce
+ the latency when starting a conversion.*/
+ uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
+ adcp->adc->CR2 = cr2;
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = cr2 | ADC_CR2_ADON;
+
+ }
+#endif /* STM32_ADC_USE_ADC */
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ else if (adcp->sdadc != NULL)
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_SDADC
+ {
+ /* SDADC initial setup, starting the analog part here in order to reduce
+ the latency when starting a conversion.*/
+ adcp->sdadc->CR2 = 0;
+ adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
+ ~SDADC_FORBIDDEN_CR1_FLAGS;
+ adcp->sdadc->CONF0R = (adcp->sdadc->CONF0R & SDADC_CONFR_OFFSET_MASK) |
+ adcp->config->confxr[0];
+ adcp->sdadc->CONF1R = (adcp->sdadc->CONF1R & SDADC_CONFR_OFFSET_MASK) |
+ adcp->config->confxr[1];
+ adcp->sdadc->CONF2R = (adcp->sdadc->CONF2R & SDADC_CONFR_OFFSET_MASK) |
+ adcp->config->confxr[2];
+ adcp->sdadc->CR2 = SDADC_CR2_ADON;
+ }
+#endif /* STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+else {
+ osalDbgAssert(FALSE, "invalid state");
+ }
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+}
+
+/**
+ * @brief ADC DMA ISR service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ *
+ * @notapi
+ */
+static void adc_lld_serve_dma_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+
+#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
+/**
+ * @brief ADC ISR service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] sr content of the ISR register
+ *
+ * @notapi
+ */
+static void adc_lld_serve_interrupt(ADCDriver *adcp, uint32_t sr) {
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (adcp->grpp != NULL) {
+ if (sr & ADC_SR_AWD) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(adcp, ADC_ERR_AWD1);
+ }
+ }
+}
+#endif /* STM32_ADC_USE_ADC */
+
+#if STM32_ADC_USE_SDADC || defined(__DOXYGEN__)
+/**
+ * @brief ADC ISR service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] isr content of the ISR register
+ *
+ * @notapi
+ */
+static void sdadc_lld_serve_interrupt(ADCDriver *adcp, uint32_t isr) {
+
+ /* It could be a spurious interrupt caused by overflows after DMA disabling,
+ just ignore it in this case.*/
+ if (adcp->grpp != NULL) {
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((isr & SDADC_ISR_JOVRF) &&
+ (dmaStreamGetTransactionSize(adcp->dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ _adc_isr_error_code(adcp, ADC_ERR_OVERFLOW);
+ }
+ }
+}
+#endif /* STM32_ADC_USE_SDADC */
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+/**
+ * @brief ADC1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector88) {
+ uint32_t sr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ sr = ADC1->SR;
+ ADC1->SR = 0;
+ adc_lld_serve_interrupt(&ADCD1, sr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_SDADC1 || defined(__DOXYGEN__)
+/**
+ * @brief SDADC1 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector134) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = SDADC1->ISR;
+ SDADC1->CLRISR = isr;
+ sdadc_lld_serve_interrupt(&SDADCD1, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_SDADC1 */
+
+#if STM32_ADC_USE_SDADC2 || defined(__DOXYGEN__)
+/**
+ * @brief SDADC2 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector138) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = SDADC2->ISR;
+ SDADC2->CLRISR = isr;
+ sdadc_lld_serve_interrupt(&SDADCD2, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_SDADC2 */
+
+#if STM32_ADC_USE_SDADC3 || defined(__DOXYGEN__)
+/**
+ * @brief SDADC3 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector13C) {
+ uint32_t isr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ isr = SDADC3->ISR;
+ SDADC3->CLRISR = isr;
+ sdadc_lld_serve_interrupt(&SDADCD3, isr);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* STM32_ADC_USE_SDADC3 */
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = ADC1;
+#if STM32_ADC_USE_SDADC
+ ADCD1.sdadc = NULL;
+#endif
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ nvicEnableVector(ADC1_IRQn, STM32_ADC_ADC1_IRQ_PRIORITY);
+#endif
+
+#if STM32_ADC_USE_SDADC1
+ /* Driver initialization.*/
+ adcObjectInit(&SDADCD1);
+#if STM32_ADC_USE_ADC
+ SDADCD1.adc = NULL;
+#endif
+ SDADCD1.sdadc = SDADC1;
+ SDADCD1.dmastp = NULL;
+ SDADCD1.dmamode = STM32_DMA_CR_CHSEL(SDADC1_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_SDADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ nvicEnableVector(SDADC1_IRQn, STM32_ADC_SDADC1_IRQ_PRIORITY);
+#endif
+
+#if STM32_ADC_USE_SDADC2
+ /* Driver initialization.*/
+ adcObjectInit(&SDADCD2);
+#if STM32_ADC_USE_ADC
+ SDADCD2.adc = NULL;
+#endif
+ SDADCD2.sdadc = SDADC2;
+ SDADCD2.dmastp = NULL;
+ SDADCD2.dmamode = STM32_DMA_CR_CHSEL(SDADC2_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_SDADC2_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ nvicEnableVector(SDADC2_IRQn, STM32_ADC_SDADC2_IRQ_PRIORITY);
+#endif
+
+#if STM32_ADC_USE_SDADC3
+ /* Driver initialization.*/
+ adcObjectInit(&SDADCD3);
+#if STM32_ADC_USE_ADC
+ SDADCD3.adc = NULL;
+#endif
+ SDADCD3.sdadc = SDADC3;
+ SDADCD3.dmastp = NULL;
+ SDADCD3.dmamode = STM32_DMA_CR_CHSEL(SDADC3_DMA_CHANNEL) |
+ STM32_DMA_CR_PL(STM32_ADC_SDADC3_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+ nvicEnableVector(SDADC3_IRQn, STM32_ADC_SDADC3_IRQ_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ if (adcp->config == NULL)
+ adcp->config = &adc_lld_default_config;
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1),
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+ rccEnableADC1(true);
+ }
+#endif /* STM32_ADC_USE_ADC1 */
+
+#if STM32_ADC_USE_SDADC1
+ if (&SDADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(2, 3),
+ STM32_ADC_SDADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ dmaStreamSetPeripheral(adcp->dmastp, &SDADC1->JDATAR);
+ rccEnableSDADC1(true);
+ PWR->CR |= PWR_CR_SDADC1EN;
+ adcp->sdadc->CR2 = 0;
+ adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
+ ~SDADC_FORBIDDEN_CR1_FLAGS;
+ adcp->sdadc->CR2 = SDADC_CR2_ADON;
+ }
+#endif /* STM32_ADC_USE_SDADC1 */
+
+#if STM32_ADC_USE_SDADC2
+ if (&SDADCD2 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(2, 4),
+ STM32_ADC_SDADC2_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ dmaStreamSetPeripheral(adcp->dmastp, &SDADC2->JDATAR);
+ rccEnableSDADC2(true);
+ PWR->CR |= PWR_CR_SDADC2EN;
+ adcp->sdadc->CR2 = 0;
+ adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
+ ~SDADC_FORBIDDEN_CR1_FLAGS;
+ adcp->sdadc->CR2 = SDADC_CR2_ADON;
+ }
+#endif /* STM32_ADC_USE_SDADC2 */
+
+#if STM32_ADC_USE_SDADC3
+ if (&SDADCD3 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(2, 5),
+ STM32_ADC_SDADC3_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_dma_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ dmaStreamSetPeripheral(adcp->dmastp, &SDADC3->JDATAR);
+ rccEnableSDADC3(true);
+ PWR->CR |= PWR_CR_SDADC3EN;
+ adcp->sdadc->CR2 = 0;
+ adcp->sdadc->CR1 = (adcp->config->cr1 | SDADC_ENFORCED_CR1_FLAGS) &
+ ~SDADC_FORBIDDEN_CR1_FLAGS;
+ adcp->sdadc->CR2 = SDADC_CR2_ADON;
+ }
+#endif /* STM32_ADC_USE_SDADC3 */
+ }
+
+ adc_lld_reconfig(adcp);
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock.*/
+ if (adcp->state == ADC_READY) {
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+ rccDisableADC1();
+ }
+#endif
+
+#if STM32_ADC_USE_SDADC1
+ if (&SDADCD1 == adcp) {
+ adcp->sdadc->CR1 = 0;
+ adcp->sdadc->CR2 = 0;
+ rccDisableSDADC1();
+ PWR->CR &= ~PWR_CR_SDADC1EN;
+ }
+#endif
+
+#if STM32_ADC_USE_SDADC2
+ if (&SDADCD2 == adcp) {
+ adcp->sdadc->CR1 = 0;
+ adcp->sdadc->CR2 = 0;
+ rccDisableSDADC2();
+ PWR->CR &= ~PWR_CR_SDADC2EN;
+ }
+#endif
+
+#if STM32_ADC_USE_SDADC3
+ if (&SDADCD3 == adcp) {
+ adcp->sdadc->CR1 = 0;
+ adcp->sdadc->CR2 = 0;
+ rccDisableSDADC3();
+ PWR->CR &= ~PWR_CR_SDADC3EN;
+ }
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t mode;
+ const ADCConversionGroup* grpp = adcp->grpp;
+
+ /* DMA setup.*/
+ mode = adcp->dmamode;
+ if (grpp->circular) {
+ mode |= STM32_DMA_CR_CIRC;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ mode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+ dmaStreamSetTransactionSize(adcp->dmastp,
+ (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ dmaStreamSetMode(adcp->dmastp, mode);
+ dmaStreamEnable(adcp->dmastp);
+
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ if (adcp->adc != NULL)
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_ADC
+ {
+ uint32_t cr2 = adcp->adc->CR2 & ADC_CR2_TSVREFE;
+ cr2 |= grpp->u.adc.cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
+ if ((cr2 & ADC_CR2_SWSTART) != 0)
+ cr2 |= ADC_CR2_CONT;
+ adcp->adc->CR2 = cr2;
+
+ /* ADC setup.*/
+ adcp->adc->SR = 0;
+ adcp->adc->LTR = grpp->u.adc.ltr;
+ adcp->adc->HTR = grpp->u.adc.htr;
+ adcp->adc->SMPR1 = grpp->u.adc.smpr[0];
+ adcp->adc->SMPR2 = grpp->u.adc.smpr[1];
+ adcp->adc->SQR1 = grpp->u.adc.sqr[0] |
+ ADC_SQR1_NUM_CH(grpp->num_channels);
+ adcp->adc->SQR2 = grpp->u.adc.sqr[1];
+ adcp->adc->SQR3 = grpp->u.adc.sqr[2];
+
+ /* ADC conversion start, the start is performed using the method
+ specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/
+ adcp->adc->CR1 = grpp->u.adc.cr1 | ADC_CR1_AWDIE | ADC_CR1_SCAN;
+ adcp->adc->CR2 = adcp->adc->CR2; /* Triggers the conversion start.*/
+ }
+#endif /* STM32_ADC_USE_ADC */
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ else if (adcp->sdadc != NULL)
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_SDADC
+ {
+ uint32_t cr2 = (grpp->u.sdadc.cr2 & ~SDADC_FORBIDDEN_CR2_FLAGS) |
+ SDADC_CR2_ADON;
+ if ((grpp->u.sdadc.cr2 & SDADC_CR2_JSWSTART) != 0)
+ cr2 |= SDADC_CR2_JCONT;
+
+ /* Entering initialization mode.*/
+ adcp->sdadc->CR1 |= SDADC_CR1_INIT;
+ while ((adcp->sdadc->ISR & SDADC_ISR_INITRDY) == 0)
+ ;
+
+ /* SDADC setup.*/
+ adcp->sdadc->JCHGR = grpp->u.sdadc.jchgr;
+ adcp->sdadc->CONFCHR1 = grpp->u.sdadc.confchr[0];
+ adcp->sdadc->CONFCHR2 = grpp->u.sdadc.confchr[1];
+
+ /* SDADC trigger modes, this write must be performed when
+ SDADC_CR1_INIT=1.*/
+ adcp->sdadc->CR2 = cr2;
+
+ /* Leaving initialization mode.*/
+ adcp->sdadc->CR1 &= ~SDADC_CR1_INIT;
+
+ /* Special case, if SDADC_CR2_JSWSTART is specified it has to be
+ written after SDADC_CR1_INIT has been set to zero. Just a write is
+ performed, any other bit is ingore if not in initialization mode.*/
+ adcp->sdadc->CR2 = cr2;
+ }
+#endif /* STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ else {
+ osalDbgAssert(FALSE, "invalid state");
+ }
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ /* Disabling the associated DMA stream.*/
+ dmaStreamDisable(adcp->dmastp);
+
+ /* Stopping and restarting the whole ADC, apparently the only way to stop
+ a conversion.*/
+ adc_lld_reconfig(adcp);
+}
+
+/**
+ * @brief Calibrates an ADC unit.
+ * @note The calibration must be performed after calling @p adcStart().
+ * @note For SDADC units it is assumed that the field SDADC_CR2_CALIBCNT
+ * has been
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @api
+ */
+void adcSTM32Calibrate(ADCDriver *adcp) {
+
+ osalDbgAssert((adcp->state == ADC_READY) ||
+ (adcp->state == ADC_COMPLETE) ||
+ (adcp->state == ADC_ERROR),
+ "not ready");
+
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ if (adcp->adc != NULL)
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_ADC
+ {
+ /* Resetting calibration just to be safe.*/
+ ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
+ while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
+ ;
+
+ /* Calibration.*/
+ ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
+ while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
+ ;
+ }
+#endif /* STM32_ADC_USE_ADC */
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ else if (adcp->sdadc != NULL)
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_SDADC
+ {
+ /* Selecting a full calibration in three steps.*/
+ adcp->sdadc->CR2 = (adcp->sdadc->CR2 & ~SDADC_CR2_CALIBCNT) |
+ SDADC_CR2_CALIBCNT_1;
+
+ /* Calibration.*/
+ adcp->sdadc->CR2 |= SDADC_CR2_STARTCALIB;
+ while ((adcp->sdadc->ISR & SDADC_ISR_EOCALF) == 0)
+ ;
+
+ /* Clearing the EOCALF flag.*/
+ adcp->sdadc->CLRISR |= SDADC_ISR_CLREOCALF;
+ }
+#endif /* STM32_ADC_USE_SDADC */
+#if STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC
+ else {
+ osalDbgAssert(FALSE, "invalid state");
+ }
+#endif /* STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC */
+}
+
+#if STM32_ADC_USE_ADC || defined(__DOXYGEN__)
+/**
+ * @brief Enables the TSVREFE bit.
+ * @details The TSVREFE bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @api
+ */
+void adcSTM32EnableTSVREFE(void) {
+
+ ADC1->CR2 |= ADC_CR2_TSVREFE;
+}
+
+/**
+ * @brief Disables the TSVREFE bit.
+ * @details The TSVREFE bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ *
+ * @api
+ */
+void adcSTM32DisableTSVREFE(void) {
+
+ ADC1->CR2 &= ~ADC_CR2_TSVREFE;
+}
+
+/**
+ * @brief Enables the VBATE bit.
+ * @details The VBATE bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ *
+ * @api
+ */
+void adcSTM32EnableVBATE(void) {
+
+ SYSCFG->CFGR1 |= SYSCFG_CFGR1_VBAT;
+}
+
+/**
+ * @brief Disables the VBATE bit.
+ * @details The VBATE bit is required in order to sample the VBAT channel.
+ * @note This is an STM32-only functionality.
+ *
+ * @api
+ */
+void adcSTM32DisableVBATE(void) {
+
+ SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_VBAT;
+}
+#endif /* STM32_ADC_USE_ADC */
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F37x/hal_adc_lld.h b/os/hal/ports/STM32/STM32F37x/hal_adc_lld.h
index 055883a039..dceeaba71f 100644
--- a/os/hal/ports/STM32/STM32F37x/hal_adc_lld.h
+++ b/os/hal/ports/STM32/STM32F37x/hal_adc_lld.h
@@ -1,639 +1,639 @@
-/*
- 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_adc_lld.h
- * @brief STM32F37x ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Triggers selection
- * @{
- */
-#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
-/** @} */
-
-/**
- * @name ADC clock divider settings
- * @{
- */
-#define ADC_CCR_ADCPRE_DIV2 0
-#define ADC_CCR_ADCPRE_DIV4 1
-#define ADC_CCR_ADCPRE_DIV6 2
-#define ADC_CCR_ADCPRE_DIV8 3
-/** @} */
-
-/**
- * @name Available analog channels
- * @{
- */
-#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
-#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
-#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
-#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
-#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
-#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
-#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
-#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
-#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
-#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
-#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
-#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
-#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
-#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
-#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
-#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
-#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
-#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
-#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT. */
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
-#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
-#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
-#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
-#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
-#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
-#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
-#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
-/** @} */
-
-/**
- * @name SDADC JCHGR bit definitions
- * @{
- */
-#define SDADC_JCHG_MASK (511U << 0)
-#define SDADC_JCHG(n) (1U << (n))
-/** @} */
-
-/**
- * @name SDADC channels definitions
- * @{
- */
-#define SDADC_CHANNEL_0 SDADC_JCHG(0)
-#define SDADC_CHANNEL_1 SDADC_JCHG(1)
-#define SDADC_CHANNEL_2 SDADC_JCHG(2)
-#define SDADC_CHANNEL_3 SDADC_JCHG(3)
-#define SDADC_CHANNEL_4 SDADC_JCHG(4)
-#define SDADC_CHANNEL_5 SDADC_JCHG(5)
-#define SDADC_CHANNEL_6 SDADC_JCHG(6)
-#define SDADC_CHANNEL_7 SDADC_JCHG(7)
-#define SDADC_CHANNEL_8 SDADC_JCHG(8)
-#define SDADC_CHANNEL_9 SDADC_JCHG(9)
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief SDADC1 driver enable switch.
- * @details If set to @p TRUE the support for SDADC1 is included.
- */
-#if !defined(STM32_ADC_USE_SDADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_SDADC1 FALSE
-#endif
-
-/**
- * @brief SDADC2 driver enable switch.
- * @details If set to @p TRUE the support for SDADC2 is included.
- */
-#if !defined(STM32_ADC_USE_SDADC2) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_SDADC2 FALSE
-#endif
-
-/**
- * @brief SDADC3 driver enable switch.
- * @details If set to @p TRUE the support for SDADC3 is included.
- */
-#if !defined(STM32_ADC_USE_SDADC3) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_SDADC3 FALSE
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief SDADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_SDADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief SDADC2 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_SDADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC2_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief SDADC3 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_SDADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC3_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief SDADC1 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_SDADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC1_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief SDADC2 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_SDADC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC2_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief SDADC3 interrupt priority level setting.
- */
-#if !defined(STM32_ADC_SDADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC3_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief SDADC1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_SDADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC1_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief SDADC2 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_SDADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC2_DMA_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief SDADC3 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_SDADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_SDADC3_DMA_IRQ_PRIORITY 5
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/**
- * @brief At least an ADC unit is in use.
- */
-#define STM32_ADC_USE_ADC STM32_ADC_USE_ADC1
-
-/**
- * @brief At least an SDADC unit is in use.
- */
-#define STM32_ADC_USE_SDADC (STM32_ADC_USE_SDADC1 || \
- STM32_ADC_USE_SDADC2 || \
- STM32_ADC_USE_SDADC3)
-
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_SDADC1 && !STM32_HAS_SDADC1
-#error "SDADC1 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_SDADC2 && !STM32_HAS_SDADC2
-#error "SDADC2 not present in the selected device"
-#endif
-
-#if STM32_ADC_USE_SDADC3 && !STM32_HAS_SDADC3
-#error "SDADC3 not present in the selected device"
-#endif
-
-#if !STM32_ADC_USE_ADC && !STM32_ADC_USE_SDADC
-#error "ADC driver activated but no ADC/SDADC peripheral assigned"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1 DMA"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_SDADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC1_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDADC1"
-#endif
-
-#if STM32_ADC_USE_SDADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDADC1 DMA"
-#endif
-
-#if STM32_ADC_USE_SDADC1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDADC1"
-#endif
-
-#if STM32_ADC_USE_SDADC2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC2_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDADC2"
-#endif
-
-#if STM32_ADC_USE_SDADC2 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC2_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDADC2 DMA"
-#endif
-
-#if STM32_ADC_USE_SDADC2 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC2_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDADC2"
-#endif
-
-#if STM32_ADC_USE_SDADC3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC3_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDADC3"
-#endif
-
-#if STM32_ADC_USE_SDADC3 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC3_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to SDADC3 DMA"
-#endif
-
-#if STM32_ADC_USE_SDADC3 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC3_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to SDADC3"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Possible ADC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
- ADC_ERR_AWD1 = 2 /**< Watchdog 1 triggered. */
-} adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-#if (STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC) || defined(__DOXYGEN__)
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to the SDADCx registers block.*/ \
- SDADC_TypeDef *sdadc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* SDADC CR1 register initialization data.*/ \
- uint32_t cr1; \
- /* SDADC CONFxR registers initialization data.*/ \
- uint32_t confxr[3]
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_configuration_group_fields \
- union { \
- struct { \
- /* ADC CR1 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
- uint32_t cr1; \
- /* ADC CR2 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
- enforced inside the driver.*/ \
- uint32_t cr2; \
- /* ADC LTR register initialization data.*/ \
- uint32_t ltr; \
- /* ADC HTR register initialization data.*/ \
- uint32_t htr; \
- /* ADC SMPRx registers initialization data.*/ \
- uint32_t smpr[2]; \
- /* ADC SQRx register initialization data.*/ \
- uint32_t sqr[3]; \
- } adc; \
- struct { \
- /* SDADC CR2 register initialization data. \
- NOTE: Only the @p SDADC_CR2_JSWSTART, @p SDADC_CR2_JEXTSEL \
- and @p SDADC_CR2_JEXTEN can be specified in this field.*/ \
- uint32_t cr2; \
- /* SDADC JCHGR register initialization data.*/ \
- uint32_t jchgr; \
- /* SDADC CONFCHxR registers initialization data.*/ \
- uint32_t confchr[2]; \
- } sdadc; \
- } u
-
-#elif STM32_ADC_USE_ADC
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-#define adc_lld_config_fields \
- /* Dummy configuration, it is not needed.*/ \
- uint32_t dummy
-
-#define adc_lld_configuration_group_fields \
- union { \
- struct { \
- /* ADC CR1 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
- uint32_t cr1; \
- /* ADC CR2 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
- enforced inside the driver.*/ \
- uint32_t cr2; \
- /* ADC LTR register initialization data.*/ \
- uint32_t ltr; \
- /* ADC HTR register initialization data.*/ \
- uint32_t htr; \
- /* ADC SMPRx registers initialization data.*/ \
- uint32_t smpr[2]; \
- /* ADC SQRx register initialization data.*/ \
- uint32_t sqr[3]; \
- } adc; \
- } u
-
-#elif STM32_ADC_USE_SDADC
-#define adc_lld_driver_fields \
- /* Pointer to the SDADCx registers block.*/ \
- SDADC_TypeDef *sdadc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-#define adc_lld_config_fields \
- /* SDADC CR1 register initialization data.*/ \
- uint32_t cr1; \
- /* SDADC CONFxR registers initialization data.*/ \
- uint32_t confxr[3]
-
-#define adc_lld_configuration_group_fields \
- union { \
- struct { \
- /* SDADC CR2 register initialization data. \
- NOTE: Only the @p SDADC_CR2_JSWSTART, @p SDADC_CR2_JEXTSEL \
- and @p SDADC_CR2_JEXTEN can be specified in this field.*/ \
- uint32_t cr2; \
- /* SDADC JCHGR register initialization data.*/ \
- uint32_t jchgr; \
- /* SDADC CONFCHxR registers initialization data.*/ \
- uint32_t confchr[2]; \
- } sdadc; \
- } u
-
-#endif
-
-/**
- * @name Sequences building helper macros for ADC
- * @{
- */
-/**
- * @brief Number of channels in a conversion sequence.
- */
-#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
-#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
-#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
-#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
-#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
-
-#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
-#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
-#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
-#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
-#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
-#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
-
-#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
-#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
-#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
-#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
-#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
-#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
-/** @} */
-
-/**
- * @name Sampling rate settings helper macros
- * @{
- */
-#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
-#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
-#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
-#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
-#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
-#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
-#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
-#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
-#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
-#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
-
-#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
-#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
-#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
-#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
-#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
-#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
-#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
- sampling time. */
-#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
- sampling time. */
-#define ADC_SMPR1_SMP_VBAT(n) ((n) << 24) /**< @brief VBAT sampling time. */
-/** @} */
-
-/**
- * @name Sequences building helper macros for SDADC
- * @{
- */
-#define SDADC_JCHGR_CH(n) (1U << (n))
-/** @} */
-
-/**
- * @name Channel configuration number helper macros for SDADC
- * @{
- */
-#define SDADC_CONFCHR1_CH0(n) ((n) << 0)
-#define SDADC_CONFCHR1_CH1(n) ((n) << 4)
-#define SDADC_CONFCHR1_CH2(n) ((n) << 8)
-#define SDADC_CONFCHR1_CH3(n) ((n) << 12)
-#define SDADC_CONFCHR1_CH4(n) ((n) << 16)
-#define SDADC_CONFCHR1_CH5(n) ((n) << 20)
-#define SDADC_CONFCHR1_CH6(n) ((n) << 24)
-#define SDADC_CONFCHR1_CH7(n) ((n) << 28)
-#define SDADC_CONFCHR2_CH8(n) ((n) << 0)
-/** @} */
-
-/**
- * @name Configuration registers helper macros for SDADC
- * @{
- */
-#define SDADC_CONFR_OFFSET_MASK (0xFFFU << 0)
-#define SDADC_CONFR_OFFSET(n) ((n) << 0)
-#define SDADC_CONFR_GAIN_MASK (7U << 20)
-#define SDADC_CONFR_GAIN_1X (0U << 20)
-#define SDADC_CONFR_GAIN_2X (1U << 20)
-#define SDADC_CONFR_GAIN_4X (2U << 20)
-#define SDADC_CONFR_GAIN_8X (3U << 20)
-#define SDADC_CONFR_GAIN_16X (4U << 20)
-#define SDADC_CONFR_GAIN_32X (5U << 20)
-#define SDADC_CONFR_GAIN_0P5X (7U << 20)
-#define SDADC_CONFR_SE_MASK (3U << 26)
-#define SDADC_CONFR_SE_DIFF (0U << 26)
-#define SDADC_CONFR_SE_OFFSET (1U << 26)
-#define SDADC_CONFR_SE_ZERO_VOLT (3U << 26)
-#define SDADC_CONFR_COMMON_MASK (3U << 30)
-#define SDADC_CONFR_COMMON_VSSSD (0U << 30)
-#define SDADC_CONFR_COMMON_VDDSD2 (1U << 30)
-#define SDADC_CONFR_COMMON_VDDSD (2U << 30)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#if STM32_ADC_USE_SDADC1 && !defined(__DOXYGEN__)
-extern ADCDriver SDADCD1;
-#endif
-
-#if STM32_ADC_USE_SDADC2 && !defined(__DOXYGEN__)
-extern ADCDriver SDADCD2;
-#endif
-
-#if STM32_ADC_USE_SDADC3 && !defined(__DOXYGEN__)
-extern ADCDriver SDADCD3;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adcSTM32Calibrate(ADCDriver *adcdp);
-#if STM32_ADC_USE_ADC
- void adcSTM32EnableTSVREFE(void);
- void adcSTM32DisableTSVREFE(void);
- void adcSTM32EnableVBATE(void);
- void adcSTM32DisableVBATE(void);
-#endif /* STM32_ADC_USE_ADC */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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_adc_lld.h
+ * @brief STM32F37x ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Triggers selection
+ * @{
+ */
+#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
+/** @} */
+
+/**
+ * @name ADC clock divider settings
+ * @{
+ */
+#define ADC_CCR_ADCPRE_DIV2 0
+#define ADC_CCR_ADCPRE_DIV4 1
+#define ADC_CCR_ADCPRE_DIV6 2
+#define ADC_CCR_ADCPRE_DIV8 3
+/** @} */
+
+/**
+ * @name Available analog channels
+ * @{
+ */
+#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
+#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
+#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
+#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
+#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
+#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
+#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
+#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
+#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
+#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
+#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
+#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
+#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
+#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
+#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
+#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
+#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
+#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
+#define ADC_CHANNEL_VBAT 18 /**< @brief VBAT. */
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
+#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
+#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
+#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
+#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
+#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
+#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
+#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
+/** @} */
+
+/**
+ * @name SDADC JCHGR bit definitions
+ * @{
+ */
+#define SDADC_JCHG_MASK (511U << 0)
+#define SDADC_JCHG(n) (1U << (n))
+/** @} */
+
+/**
+ * @name SDADC channels definitions
+ * @{
+ */
+#define SDADC_CHANNEL_0 SDADC_JCHG(0)
+#define SDADC_CHANNEL_1 SDADC_JCHG(1)
+#define SDADC_CHANNEL_2 SDADC_JCHG(2)
+#define SDADC_CHANNEL_3 SDADC_JCHG(3)
+#define SDADC_CHANNEL_4 SDADC_JCHG(4)
+#define SDADC_CHANNEL_5 SDADC_JCHG(5)
+#define SDADC_CHANNEL_6 SDADC_JCHG(6)
+#define SDADC_CHANNEL_7 SDADC_JCHG(7)
+#define SDADC_CHANNEL_8 SDADC_JCHG(8)
+#define SDADC_CHANNEL_9 SDADC_JCHG(9)
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief SDADC1 driver enable switch.
+ * @details If set to @p TRUE the support for SDADC1 is included.
+ */
+#if !defined(STM32_ADC_USE_SDADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_SDADC1 FALSE
+#endif
+
+/**
+ * @brief SDADC2 driver enable switch.
+ * @details If set to @p TRUE the support for SDADC2 is included.
+ */
+#if !defined(STM32_ADC_USE_SDADC2) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_SDADC2 FALSE
+#endif
+
+/**
+ * @brief SDADC3 driver enable switch.
+ * @details If set to @p TRUE the support for SDADC3 is included.
+ */
+#if !defined(STM32_ADC_USE_SDADC3) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_SDADC3 FALSE
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief SDADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_SDADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief SDADC2 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_SDADC2_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC2_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief SDADC3 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_SDADC3_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC3_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SDADC1 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_SDADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC1_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SDADC2 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_SDADC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC2_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SDADC3 interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_SDADC3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC3_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SDADC1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_SDADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC1_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SDADC2 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_SDADC2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC2_DMA_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief SDADC3 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_SDADC3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_SDADC3_DMA_IRQ_PRIORITY 5
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/**
+ * @brief At least an ADC unit is in use.
+ */
+#define STM32_ADC_USE_ADC STM32_ADC_USE_ADC1
+
+/**
+ * @brief At least an SDADC unit is in use.
+ */
+#define STM32_ADC_USE_SDADC (STM32_ADC_USE_SDADC1 || \
+ STM32_ADC_USE_SDADC2 || \
+ STM32_ADC_USE_SDADC3)
+
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_SDADC1 && !STM32_HAS_SDADC1
+#error "SDADC1 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_SDADC2 && !STM32_HAS_SDADC2
+#error "SDADC2 not present in the selected device"
+#endif
+
+#if STM32_ADC_USE_SDADC3 && !STM32_HAS_SDADC3
+#error "SDADC3 not present in the selected device"
+#endif
+
+#if !STM32_ADC_USE_ADC && !STM32_ADC_USE_SDADC
+#error "ADC driver activated but no ADC/SDADC peripheral assigned"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1 DMA"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_SDADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC1_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDADC1"
+#endif
+
+#if STM32_ADC_USE_SDADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDADC1 DMA"
+#endif
+
+#if STM32_ADC_USE_SDADC1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDADC1"
+#endif
+
+#if STM32_ADC_USE_SDADC2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC2_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDADC2"
+#endif
+
+#if STM32_ADC_USE_SDADC2 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC2_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDADC2 DMA"
+#endif
+
+#if STM32_ADC_USE_SDADC2 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC2_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDADC2"
+#endif
+
+#if STM32_ADC_USE_SDADC3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC3_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDADC3"
+#endif
+
+#if STM32_ADC_USE_SDADC3 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_SDADC3_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to SDADC3 DMA"
+#endif
+
+#if STM32_ADC_USE_SDADC3 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_SDADC3_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to SDADC3"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint16_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ ADC_ERR_OVERFLOW = 1, /**< ADC overflow condition. */
+ ADC_ERR_AWD1 = 2 /**< Watchdog 1 triggered. */
+} adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+#if (STM32_ADC_USE_ADC && STM32_ADC_USE_SDADC) || defined(__DOXYGEN__)
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to the SDADCx registers block.*/ \
+ SDADC_TypeDef *sdadc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* SDADC CR1 register initialization data.*/ \
+ uint32_t cr1; \
+ /* SDADC CONFxR registers initialization data.*/ \
+ uint32_t confxr[3]
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_configuration_group_fields \
+ union { \
+ struct { \
+ /* ADC CR1 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
+ uint32_t cr1; \
+ /* ADC CR2 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
+ enforced inside the driver.*/ \
+ uint32_t cr2; \
+ /* ADC LTR register initialization data.*/ \
+ uint32_t ltr; \
+ /* ADC HTR register initialization data.*/ \
+ uint32_t htr; \
+ /* ADC SMPRx registers initialization data.*/ \
+ uint32_t smpr[2]; \
+ /* ADC SQRx register initialization data.*/ \
+ uint32_t sqr[3]; \
+ } adc; \
+ struct { \
+ /* SDADC CR2 register initialization data. \
+ NOTE: Only the @p SDADC_CR2_JSWSTART, @p SDADC_CR2_JEXTSEL \
+ and @p SDADC_CR2_JEXTEN can be specified in this field.*/ \
+ uint32_t cr2; \
+ /* SDADC JCHGR register initialization data.*/ \
+ uint32_t jchgr; \
+ /* SDADC CONFCHxR registers initialization data.*/ \
+ uint32_t confchr[2]; \
+ } sdadc; \
+ } u
+
+#elif STM32_ADC_USE_ADC
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+#define adc_lld_config_fields \
+ /* Dummy configuration, it is not needed.*/ \
+ uint32_t dummy
+
+#define adc_lld_configuration_group_fields \
+ union { \
+ struct { \
+ /* ADC CR1 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
+ uint32_t cr1; \
+ /* ADC CR2 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
+ enforced inside the driver.*/ \
+ uint32_t cr2; \
+ /* ADC LTR register initialization data.*/ \
+ uint32_t ltr; \
+ /* ADC HTR register initialization data.*/ \
+ uint32_t htr; \
+ /* ADC SMPRx registers initialization data.*/ \
+ uint32_t smpr[2]; \
+ /* ADC SQRx register initialization data.*/ \
+ uint32_t sqr[3]; \
+ } adc; \
+ } u
+
+#elif STM32_ADC_USE_SDADC
+#define adc_lld_driver_fields \
+ /* Pointer to the SDADCx registers block.*/ \
+ SDADC_TypeDef *sdadc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+#define adc_lld_config_fields \
+ /* SDADC CR1 register initialization data.*/ \
+ uint32_t cr1; \
+ /* SDADC CONFxR registers initialization data.*/ \
+ uint32_t confxr[3]
+
+#define adc_lld_configuration_group_fields \
+ union { \
+ struct { \
+ /* SDADC CR2 register initialization data. \
+ NOTE: Only the @p SDADC_CR2_JSWSTART, @p SDADC_CR2_JEXTSEL \
+ and @p SDADC_CR2_JEXTEN can be specified in this field.*/ \
+ uint32_t cr2; \
+ /* SDADC JCHGR register initialization data.*/ \
+ uint32_t jchgr; \
+ /* SDADC CONFCHxR registers initialization data.*/ \
+ uint32_t confchr[2]; \
+ } sdadc; \
+ } u
+
+#endif
+
+/**
+ * @name Sequences building helper macros for ADC
+ * @{
+ */
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
+#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
+#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
+#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
+#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
+#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
+
+#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
+#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
+#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
+#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
+#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
+#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
+
+#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
+#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
+#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
+#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
+#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
+#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
+/** @} */
+
+/**
+ * @name Sampling rate settings helper macros
+ * @{
+ */
+#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
+#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
+#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
+#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
+#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
+#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
+#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
+#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
+#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
+#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
+
+#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
+#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
+#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
+#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
+#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
+#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
+#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
+ sampling time. */
+#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
+ sampling time. */
+#define ADC_SMPR1_SMP_VBAT(n) ((n) << 24) /**< @brief VBAT sampling time. */
+/** @} */
+
+/**
+ * @name Sequences building helper macros for SDADC
+ * @{
+ */
+#define SDADC_JCHGR_CH(n) (1U << (n))
+/** @} */
+
+/**
+ * @name Channel configuration number helper macros for SDADC
+ * @{
+ */
+#define SDADC_CONFCHR1_CH0(n) ((n) << 0)
+#define SDADC_CONFCHR1_CH1(n) ((n) << 4)
+#define SDADC_CONFCHR1_CH2(n) ((n) << 8)
+#define SDADC_CONFCHR1_CH3(n) ((n) << 12)
+#define SDADC_CONFCHR1_CH4(n) ((n) << 16)
+#define SDADC_CONFCHR1_CH5(n) ((n) << 20)
+#define SDADC_CONFCHR1_CH6(n) ((n) << 24)
+#define SDADC_CONFCHR1_CH7(n) ((n) << 28)
+#define SDADC_CONFCHR2_CH8(n) ((n) << 0)
+/** @} */
+
+/**
+ * @name Configuration registers helper macros for SDADC
+ * @{
+ */
+#define SDADC_CONFR_OFFSET_MASK (0xFFFU << 0)
+#define SDADC_CONFR_OFFSET(n) ((n) << 0)
+#define SDADC_CONFR_GAIN_MASK (7U << 20)
+#define SDADC_CONFR_GAIN_1X (0U << 20)
+#define SDADC_CONFR_GAIN_2X (1U << 20)
+#define SDADC_CONFR_GAIN_4X (2U << 20)
+#define SDADC_CONFR_GAIN_8X (3U << 20)
+#define SDADC_CONFR_GAIN_16X (4U << 20)
+#define SDADC_CONFR_GAIN_32X (5U << 20)
+#define SDADC_CONFR_GAIN_0P5X (7U << 20)
+#define SDADC_CONFR_SE_MASK (3U << 26)
+#define SDADC_CONFR_SE_DIFF (0U << 26)
+#define SDADC_CONFR_SE_OFFSET (1U << 26)
+#define SDADC_CONFR_SE_ZERO_VOLT (3U << 26)
+#define SDADC_CONFR_COMMON_MASK (3U << 30)
+#define SDADC_CONFR_COMMON_VSSSD (0U << 30)
+#define SDADC_CONFR_COMMON_VDDSD2 (1U << 30)
+#define SDADC_CONFR_COMMON_VDDSD (2U << 30)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#if STM32_ADC_USE_SDADC1 && !defined(__DOXYGEN__)
+extern ADCDriver SDADCD1;
+#endif
+
+#if STM32_ADC_USE_SDADC2 && !defined(__DOXYGEN__)
+extern ADCDriver SDADCD2;
+#endif
+
+#if STM32_ADC_USE_SDADC3 && !defined(__DOXYGEN__)
+extern ADCDriver SDADCD3;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adcSTM32Calibrate(ADCDriver *adcdp);
+#if STM32_ADC_USE_ADC
+ void adcSTM32EnableTSVREFE(void);
+ void adcSTM32DisableTSVREFE(void);
+ void adcSTM32EnableVBATE(void);
+ void adcSTM32DisableVBATE(void);
+#endif /* STM32_ADC_USE_ADC */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F37x/hal_lld.c b/os/hal/ports/STM32/STM32F37x/hal_lld.c
index 902f688ac4..42620437ca 100644
--- a/os/hal/ports/STM32/STM32F37x/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F37x/hal_lld.c
@@ -1,223 +1,224 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..0556b28022 100644
--- a/os/hal/ports/STM32/STM32F37x/hal_lld.h
+++ b/os/hal/ports/STM32/STM32F37x/hal_lld.h
@@ -1,1030 +1,1038 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32F37x/platform.mk b/os/hal/ports/STM32/STM32F37x/platform.mk
index f807d3dae4..ad020d7e37 100644
--- a/os/hal/ports/STM32/STM32F37x/platform.mk
+++ b/os/hal/ports/STM32/STM32F37x/platform.mk
@@ -1,47 +1,47 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F37x
-
-# 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"))
-
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
-endif
-
-# Drivers compatible with the platform.
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F37x
+
+# 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"))
+
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F37x/hal_adc_lld.c
+endif
+
+# Drivers compatible with the platform.
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/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/STM32F37x/stm32_isr.c b/os/hal/ports/STM32/STM32F37x/stm32_isr.c
index 64f15b7e59..3336d030b9 100644
--- a/os/hal/ports/STM32/STM32F37x/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32F37x/stm32_isr.c
@@ -1,255 +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 STM32F3xx/stm32_isr.c
- * @brief STM32F3xx ISR handler code.
- *
- * @addtogroup STM32F3xx_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 */
-
-/*===========================================================================*/
-/* 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_TSC_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_TSC_IRQn);
- nvicDisableVector(EXTI3_IRQn);
- nvicDisableVector(EXTI4_IRQn);
- nvicDisableVector(EXTI9_5_IRQn);
- nvicDisableVector(EXTI15_10_IRQn);
-#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 STM32F3xx/stm32_isr.c
+ * @brief STM32F3xx ISR handler code.
+ *
+ * @addtogroup STM32F3xx_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 */
+
+/*===========================================================================*/
+/* 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_TSC_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_TSC_IRQn);
+ nvicDisableVector(EXTI3_IRQn);
+ nvicDisableVector(EXTI4_IRQn);
+ nvicDisableVector(EXTI9_5_IRQn);
+ nvicDisableVector(EXTI15_10_IRQn);
+#endif
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F37x/stm32_isr.h b/os/hal/ports/STM32/STM32F37x/stm32_isr.h
index d649110d35..7690f7d973 100644
--- a/os/hal/ports/STM32/STM32F37x/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32F37x/stm32_isr.h
@@ -1,243 +1,243 @@
-/*
- 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/stm32_isr.h
- * @brief STM32F37x ISR handler header.
- *
- * @addtogroup STM32F37x_ISR
- * @{
- */
-
-#ifndef STM32_ISR_H
-#define STM32_ISR_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name ISR names and numbers remapping
- * @{
- */
-/*
- * 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_CAN1_TX_NUMBER 19
-#define STM32_CAN1_RX0_NUMBER 20
-#define STM32_CAN1_RX1_NUMBER 21
-#define STM32_CAN1_SCE_NUMBER 22
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_EVENT_HANDLER VectorBC
-#define STM32_I2C1_ERROR_HANDLER VectorC0
-#define STM32_I2C1_EVENT_NUMBER 31
-#define STM32_I2C1_ERROR_NUMBER 32
-
-#define STM32_I2C2_EVENT_HANDLER VectorC4
-#define STM32_I2C2_ERROR_HANDLER VectorC8
-#define STM32_I2C2_EVENT_NUMBER 33
-#define STM32_I2C2_ERROR_NUMBER 34
-
-/*
- * TIM units.
- */
-#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_TIM12_HANDLER VectorEC
-#define STM32_TIM13_HANDLER VectorF0
-#define STM32_TIM14_HANDLER VectorF4
-#define STM32_TIM15_HANDLER VectorA0
-#define STM32_TIM16_HANDLER VectorA4
-#define STM32_TIM17_HANDLER VectorA8
-#define STM32_TIM18_HANDLER VectorAC
-#define STM32_TIM19_HANDLER Vector178
-
-#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_TIM12_NUMBER 43
-#define STM32_TIM13_NUMBER 44
-#define STM32_TIM14_NUMBER 45
-#define STM32_TIM15_NUMBER 24
-#define STM32_TIM16_NUMBER 25
-#define STM32_TIM17_NUMBER 26
-#define STM32_TIM18_NUMBER 27
-#define STM32_TIM19_NUMBER 78
-
-/*
- * USART units.
- */
-#define STM32_USART1_HANDLER VectorD4
-#define STM32_USART2_HANDLER VectorD8
-#define STM32_USART3_HANDLER VectorDC
-
-#define STM32_USART1_NUMBER 37
-#define STM32_USART2_NUMBER 38
-#define STM32_USART3_NUMBER 39
-
-/*
- * USB units.
- */
-#define STM32_USB1_HP_HANDLER Vector168
-#define STM32_USB1_LP_HANDLER Vector16C
-
-#define STM32_USB1_HP_NUMBER 74
-#define STM32_USB1_LP_NUMBER 75
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief EXTI0 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI0_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI1_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI2 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI2_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI3 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI3_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI4 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI4_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI5..9 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI5_9_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI10..15 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI10_15_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI16 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI16_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI17 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI17_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI18 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI18_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI19 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI19_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI20 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI20_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI20_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI21..22 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI21_22_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI21_22_PRIORITY 6
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32F37x ISR handler header.
+ *
+ * @addtogroup STM32F37x_ISR
+ * @{
+ */
+
+#ifndef STM32_ISR_H
+#define STM32_ISR_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name ISR names and numbers remapping
+ * @{
+ */
+/*
+ * 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_CAN1_TX_NUMBER 19
+#define STM32_CAN1_RX0_NUMBER 20
+#define STM32_CAN1_RX1_NUMBER 21
+#define STM32_CAN1_SCE_NUMBER 22
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_EVENT_HANDLER VectorBC
+#define STM32_I2C1_ERROR_HANDLER VectorC0
+#define STM32_I2C1_EVENT_NUMBER 31
+#define STM32_I2C1_ERROR_NUMBER 32
+
+#define STM32_I2C2_EVENT_HANDLER VectorC4
+#define STM32_I2C2_ERROR_HANDLER VectorC8
+#define STM32_I2C2_EVENT_NUMBER 33
+#define STM32_I2C2_ERROR_NUMBER 34
+
+/*
+ * TIM units.
+ */
+#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_TIM12_HANDLER VectorEC
+#define STM32_TIM13_HANDLER VectorF0
+#define STM32_TIM14_HANDLER VectorF4
+#define STM32_TIM15_HANDLER VectorA0
+#define STM32_TIM16_HANDLER VectorA4
+#define STM32_TIM17_HANDLER VectorA8
+#define STM32_TIM18_HANDLER VectorAC
+#define STM32_TIM19_HANDLER Vector178
+
+#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_TIM12_NUMBER 43
+#define STM32_TIM13_NUMBER 44
+#define STM32_TIM14_NUMBER 45
+#define STM32_TIM15_NUMBER 24
+#define STM32_TIM16_NUMBER 25
+#define STM32_TIM17_NUMBER 26
+#define STM32_TIM18_NUMBER 27
+#define STM32_TIM19_NUMBER 78
+
+/*
+ * USART units.
+ */
+#define STM32_USART1_HANDLER VectorD4
+#define STM32_USART2_HANDLER VectorD8
+#define STM32_USART3_HANDLER VectorDC
+
+#define STM32_USART1_NUMBER 37
+#define STM32_USART2_NUMBER 38
+#define STM32_USART3_NUMBER 39
+
+/*
+ * USB units.
+ */
+#define STM32_USB1_HP_HANDLER Vector168
+#define STM32_USB1_LP_HANDLER Vector16C
+
+#define STM32_USB1_HP_NUMBER 74
+#define STM32_USB1_LP_NUMBER 75
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI0_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI1_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI2 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI2_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI3 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI3_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI4 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI4_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI5..9 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI5_9_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI10..15 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI10_15_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI16 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI16_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI17 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI17_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI18 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI18_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI19 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI19_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI20 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI20_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI20_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI21..22 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI21_22_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI21_22_PRIORITY 6
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32F37x/stm32_rcc.h b/os/hal/ports/STM32/STM32F37x/stm32_rcc.h
index 4778f0e490..7dbc78beac 100644
--- a/os/hal/ports/STM32/STM32F37x/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F37x/stm32_rcc.h
@@ -1,1020 +1,1020 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32f30x.h.
- *
- * @addtogroup STM32F37x_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); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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 AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC1 peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ADC 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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-/** @} */
-
-/**
- * @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_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPB1(RCC_APB1ENR_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPB1(RCC_APB1RSTR_DAC1RST)
-
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC2(lp) rccEnableAPB1(RCC_APB1ENR_DAC2EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC2() rccDisableAPB1(RCC_APB1ENR_DAC2EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC2() rccResetAPB1(RCC_APB1RSTR_DAC2RST)
-/** @} */
-
-/**
- * @name CAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CAN1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CANEN, lp)
-
-/**
- * @brief Disables the CAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CANEN)
-
-/**
- * @brief Resets the CAN1 peripheral.
- *
- * @api
- */
-#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST)
-/** @} */
-
-/**
- * @name DMA peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMA1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- *
- * @api
- */
-#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
-
-/**
- * @brief Enables the DMA2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
-
-/**
- * @brief Disables the DMA2 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
-
-/**
- * @brief Resets the DMA2 peripheral.
- *
- * @api
- */
-#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 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)
-/** @} */
-
-/**
- * @name SDADC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDADC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDADC1(lp) rccEnableAPB2(RCC_APB2ENR_SDADC1EN, lp)
-
-/**
- * @brief Disables the SDADC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDADC1() rccDisableAPB2(RCC_APB2ENR_SDADC1EN)
-
-/**
- * @brief Resets the SDADC1 peripheral.
- *
- * @api
- */
-#define rccResetSDADC1() rccResetAPB2(RCC_APB2RSTR_SDADC1RST)
-
-/**
- * @brief Enables the SDADC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDADC2(lp) rccEnableAPB2(RCC_APB2ENR_SDADC2EN, lp)
-
-/**
- * @brief Disables the SDADC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDADC2() rccDisableAPB2(RCC_APB2ENR_SDADC2EN)
-
-/**
- * @brief Resets the SDADC2 peripheral.
- *
- * @api
- */
-#define rccResetSDADC2() rccResetAPB2(RCC_APB2RSTR_SDADC2RST)
-
-/**
- * @brief Enables the SDADC3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDADC3(lp) rccEnableAPB2(RCC_APB2ENR_SDADC3EN, lp)
-
-/**
- * @brief Disables the SDADC3 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDADC3() rccDisableAPB2(RCC_APB2ENR_SDADC3EN)
-
-/**
- * @brief Resets the SDADC3 peripheral.
- *
- * @api
- */
-#define rccResetSDADC3() rccResetAPB2(RCC_APB2RSTR_SDADC3RST)
-/** @} */
-
-/**
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @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 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 TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-
-/**
- * @brief Enables the TIM18 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM18(lp) rccEnableAPB1(RCC_APB1ENR_TIM18EN, lp)
-
-/**
- * @brief Disables the TIM18 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM18() rccDisableAPB1(RCC_APB1ENR_TIM18EN)
-
-/**
- * @brief Resets the TIM18 peripheral.
- *
- * @api
- */
-#define rccResetTIM18() rccResetAPB1(RCC_APB1RSTR_TIM18RST)
-
-/**
- * @brief Enables the TIM19 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM19(lp) rccEnableAPB2(RCC_APB2ENR_TIM19EN, lp)
-
-/**
- * @brief Disables the TIM19 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM19() rccDisableAPB2(RCC_APB2ENR_TIM19EN)
-
-/**
- * @brief Resets the TIM19 peripheral.
- *
- * @api
- */
-#define rccResetTIM19() rccResetAPB2(RCC_APB2RSTR_TIM19RST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
-/** @} */
-
-/**
- * @name CRC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
-
-/**
- * @brief Disables the CRC peripheral clock.
- *
- * @api
- */
-#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32f30x.h.
+ *
+ * @addtogroup STM32F37x_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); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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 AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC1 peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ADC 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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+/** @} */
+
+/**
+ * @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_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPB1(RCC_APB1ENR_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPB1(RCC_APB1RSTR_DAC1RST)
+
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC2(lp) rccEnableAPB1(RCC_APB1ENR_DAC2EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC2() rccDisableAPB1(RCC_APB1ENR_DAC2EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC2() rccResetAPB1(RCC_APB1RSTR_DAC2RST)
+/** @} */
+
+/**
+ * @name CAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CAN1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CANEN, lp)
+
+/**
+ * @brief Disables the CAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CANEN)
+
+/**
+ * @brief Resets the CAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST)
+/** @} */
+
+/**
+ * @name DMA peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMA1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
+
+/**
+ * @brief Enables the DMA2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
+
+/**
+ * @brief Disables the DMA2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
+
+/**
+ * @brief Resets the DMA2 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 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)
+/** @} */
+
+/**
+ * @name SDADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDADC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDADC1(lp) rccEnableAPB2(RCC_APB2ENR_SDADC1EN, lp)
+
+/**
+ * @brief Disables the SDADC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDADC1() rccDisableAPB2(RCC_APB2ENR_SDADC1EN)
+
+/**
+ * @brief Resets the SDADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDADC1() rccResetAPB2(RCC_APB2RSTR_SDADC1RST)
+
+/**
+ * @brief Enables the SDADC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDADC2(lp) rccEnableAPB2(RCC_APB2ENR_SDADC2EN, lp)
+
+/**
+ * @brief Disables the SDADC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDADC2() rccDisableAPB2(RCC_APB2ENR_SDADC2EN)
+
+/**
+ * @brief Resets the SDADC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDADC2() rccResetAPB2(RCC_APB2RSTR_SDADC2RST)
+
+/**
+ * @brief Enables the SDADC3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDADC3(lp) rccEnableAPB2(RCC_APB2ENR_SDADC3EN, lp)
+
+/**
+ * @brief Disables the SDADC3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDADC3() rccDisableAPB2(RCC_APB2ENR_SDADC3EN)
+
+/**
+ * @brief Resets the SDADC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDADC3() rccResetAPB2(RCC_APB2RSTR_SDADC3RST)
+/** @} */
+
+/**
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @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 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 TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+
+/**
+ * @brief Enables the TIM18 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM18(lp) rccEnableAPB1(RCC_APB1ENR_TIM18EN, lp)
+
+/**
+ * @brief Disables the TIM18 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM18() rccDisableAPB1(RCC_APB1ENR_TIM18EN)
+
+/**
+ * @brief Resets the TIM18 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM18() rccResetAPB1(RCC_APB1RSTR_TIM18RST)
+
+/**
+ * @brief Enables the TIM19 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM19(lp) rccEnableAPB2(RCC_APB2ENR_TIM19EN, lp)
+
+/**
+ * @brief Disables the TIM19 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM19() rccDisableAPB2(RCC_APB2ENR_TIM19EN)
+
+/**
+ * @brief Resets the TIM19 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM19() rccResetAPB2(RCC_APB2RSTR_TIM19RST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
+/** @} */
+
+/**
+ * @name CRC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
+
+/**
+ * @brief Disables the CRC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F37x/stm32_registry.h b/os/hal/ports/STM32/STM32F37x/stm32_registry.h
index 3a318fdf34..295a538c52 100644
--- a/os/hal/ports/STM32/STM32F37x/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F37x/stm32_registry.h
@@ -1,572 +1,572 @@
-/*
- 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/stm32_registry.h
- * @brief STM32F37x capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32F37x capabilities
- * @{
- */
-/*===========================================================================*/
-/* STM32F373xC. */
-/*===========================================================================*/
-#if defined(STM32F373xC) || defined(__DOXYGEN__)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-#define STM32_HAS_SDADC1 TRUE
-#define STM32_HAS_SDADC2 TRUE
-#define STM32_HAS_SDADC3 TRUE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_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_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 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM18 TRUE
-#define STM32_TIM18_IS_32BITS FALSE
-#define STM32_TIM18_CHANNELS 0
-
-#define STM32_HAS_TIM19 TRUE
-#define STM32_TIM19_IS_32BITS FALSE
-#define STM32_TIM19_CHANNELS 4
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F373xC) */
-
-/*===========================================================================*/
-/* STM32F378xx. */
-/*===========================================================================*/
-#if defined(STM32F378xx) || defined(__DOXYGEN__)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-#define STM32_HAS_SDADC1 TRUE
-#define STM32_HAS_SDADC2 TRUE
-#define STM32_HAS_SDADC3 TRUE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_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_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 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM18 TRUE
-#define STM32_TIM18_IS_32BITS FALSE
-#define STM32_TIM18_CHANNELS 0
-
-#define STM32_HAS_TIM19 TRUE
-#define STM32_TIM19_IS_32BITS FALSE
-#define STM32_TIM19_CHANNELS 4
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F378xx) */
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32F37x capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32F37x capabilities
+ * @{
+ */
+/*===========================================================================*/
+/* STM32F373xC. */
+/*===========================================================================*/
+#if defined(STM32F373xC) || defined(__DOXYGEN__)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+#define STM32_HAS_SDADC1 TRUE
+#define STM32_HAS_SDADC2 TRUE
+#define STM32_HAS_SDADC3 TRUE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_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_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 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM18 TRUE
+#define STM32_TIM18_IS_32BITS FALSE
+#define STM32_TIM18_CHANNELS 0
+
+#define STM32_HAS_TIM19 TRUE
+#define STM32_TIM19_IS_32BITS FALSE
+#define STM32_TIM19_CHANNELS 4
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F373xC) */
+
+/*===========================================================================*/
+/* STM32F378xx. */
+/*===========================================================================*/
+#if defined(STM32F378xx) || defined(__DOXYGEN__)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+#define STM32_HAS_SDADC1 TRUE
+#define STM32_HAS_SDADC2 TRUE
+#define STM32_HAS_SDADC3 TRUE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_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_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 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM18 TRUE
+#define STM32_TIM18_IS_32BITS FALSE
+#define STM32_TIM18_CHANNELS 0
+
+#define STM32_HAS_TIM19 TRUE
+#define STM32_TIM19_IS_32BITS FALSE
+#define STM32_TIM19_CHANNELS 4
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F378xx) */
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F3xx/hal_lld.c b/os/hal/ports/STM32/STM32F3xx/hal_lld.c
index 42fa3a5d4c..b26774ad44 100644
--- a/os/hal/ports/STM32/STM32F3xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F3xx/hal_lld.c
@@ -1,233 +1,234 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..2cc9e3e0c6 100644
--- a/os/hal/ports/STM32/STM32F3xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32F3xx/hal_lld.h
@@ -1,1224 +1,1232 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32F3xx/platform.mk b/os/hal/ports/STM32/STM32F3xx/platform.mk
index 67673bd59f..2a7063a5a7 100644
--- a/os/hal/ports/STM32/STM32F3xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F3xx/platform.mk
@@ -1,44 +1,44 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx
-
-# 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/ADCv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx
+
+# 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/ADCv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/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/STM32F3xx/stm32_isr.c b/os/hal/ports/STM32/STM32F3xx/stm32_isr.c
index 9b43cf7108..f2112492e5 100644
--- a/os/hal/ports/STM32/STM32F3xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32F3xx/stm32_isr.c
@@ -1,382 +1,382 @@
-/*
- 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/stm32_isr.c
- * @brief STM32F3xx ISR handler code.
- *
- * @addtogroup STM32F3xx_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) */
-
-#if HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM || defined(__DOXYGEN__)
-/**
- * @brief TIM1-BRK, TIM15 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(VectorA0) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_GPT
-#if STM32_GPT_USE_TIM15
- gpt_lld_serve_interrupt(&GPTD15);
-#endif
-#endif
-#if HAL_USE_ICU
-#if STM32_ICU_USE_TIM15
- icu_lld_serve_interrupt(&ICUD15);
-#endif
-#endif
-#if HAL_USE_PWM
-#if STM32_PWM_USE_TIM15
- pwm_lld_serve_interrupt(&PWMD15);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief TIM1-UP, TIM16 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(VectorA4) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_GPT
-#if STM32_GPT_USE_TIM1
- gpt_lld_serve_interrupt(&GPTD1);
-#endif
-#if STM32_GPT_USE_TIM16
- gpt_lld_serve_interrupt(&GPTD16);
-#endif
-#endif
-#if HAL_USE_ICU
-#if STM32_ICU_USE_TIM1
- icu_lld_serve_interrupt(&ICUD1);
-#endif
-#endif
-#if HAL_USE_PWM
-#if STM32_PWM_USE_TIM1
- pwm_lld_serve_interrupt(&PWMD1);
-#endif
-#if STM32_PWM_USE_TIM16
- pwm_lld_serve_interrupt(&PWMD16);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief TIM1-TRG-COM, TIM17 interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(VectorA8) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_GPT
-#if STM32_GPT_USE_TIM17
- gpt_lld_serve_interrupt(&GPTD17);
-#endif
-#endif
-#if HAL_USE_ICU
- /* Not used by ICU.*/
-#endif
-#if HAL_USE_PWM
-#if STM32_PWM_USE_TIM17
- pwm_lld_serve_interrupt(&PWMD17);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-
-/**
- * @brief TIM1-CC interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(VectorAC) {
-
- OSAL_IRQ_PROLOGUE();
-
-#if HAL_USE_GPT
- /* Not used by GPT.*/
-#endif
-#if HAL_USE_ICU
-#if STM32_ICU_USE_TIM1
- icu_lld_serve_interrupt(&ICUD1);
-#endif
-#endif
-#if HAL_USE_PWM
-#if STM32_PWM_USE_TIM1
- pwm_lld_serve_interrupt(&PWMD1);
-#endif
-#endif
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif /* HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM */
-
-/*===========================================================================*/
-/* 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_TSC_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
-#if HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM || defined(__DOXYGEN__)
- nvicEnableVector(TIM1_BRK_TIM15_IRQn, STM32_IRQ_TIM1_BRK_TIM15_PRIORITY);
- nvicEnableVector(TIM1_UP_TIM16_IRQn, STM32_IRQ_TIM1_UP_TIM16_PRIORITY);
- nvicEnableVector(TIM1_TRG_COM_TIM17_IRQn, STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY);
- nvicEnableVector(TIM1_CC_IRQn, STM32_IRQ_TIM1_CC_PRIORITY);
-#endif
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
-#if HAL_USE_PAL
- nvicDisableVector(EXTI0_IRQn);
- nvicDisableVector(EXTI1_IRQn);
- nvicDisableVector(EXTI2_TSC_IRQn);
- nvicDisableVector(EXTI3_IRQn);
- nvicDisableVector(EXTI4_IRQn);
- nvicDisableVector(EXTI9_5_IRQn);
- nvicDisableVector(EXTI15_10_IRQn);
-#endif
-#if HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM || defined(__DOXYGEN__)
- nvicDisableVector(TIM1_BRK_TIM15_IRQn);
- nvicDisableVector(TIM1_UP_TIM16_IRQn);
- nvicDisableVector(TIM1_TRG_COM_TIM17_IRQn);
- nvicDisableVector(TIM1_CC_IRQn);
-#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 STM32F3xx/stm32_isr.c
+ * @brief STM32F3xx ISR handler code.
+ *
+ * @addtogroup STM32F3xx_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) */
+
+#if HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM || defined(__DOXYGEN__)
+/**
+ * @brief TIM1-BRK, TIM15 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(VectorA0) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_GPT
+#if STM32_GPT_USE_TIM15
+ gpt_lld_serve_interrupt(&GPTD15);
+#endif
+#endif
+#if HAL_USE_ICU
+#if STM32_ICU_USE_TIM15
+ icu_lld_serve_interrupt(&ICUD15);
+#endif
+#endif
+#if HAL_USE_PWM
+#if STM32_PWM_USE_TIM15
+ pwm_lld_serve_interrupt(&PWMD15);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief TIM1-UP, TIM16 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(VectorA4) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_GPT
+#if STM32_GPT_USE_TIM1
+ gpt_lld_serve_interrupt(&GPTD1);
+#endif
+#if STM32_GPT_USE_TIM16
+ gpt_lld_serve_interrupt(&GPTD16);
+#endif
+#endif
+#if HAL_USE_ICU
+#if STM32_ICU_USE_TIM1
+ icu_lld_serve_interrupt(&ICUD1);
+#endif
+#endif
+#if HAL_USE_PWM
+#if STM32_PWM_USE_TIM1
+ pwm_lld_serve_interrupt(&PWMD1);
+#endif
+#if STM32_PWM_USE_TIM16
+ pwm_lld_serve_interrupt(&PWMD16);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief TIM1-TRG-COM, TIM17 interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(VectorA8) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_GPT
+#if STM32_GPT_USE_TIM17
+ gpt_lld_serve_interrupt(&GPTD17);
+#endif
+#endif
+#if HAL_USE_ICU
+ /* Not used by ICU.*/
+#endif
+#if HAL_USE_PWM
+#if STM32_PWM_USE_TIM17
+ pwm_lld_serve_interrupt(&PWMD17);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief TIM1-CC interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(VectorAC) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_GPT
+ /* Not used by GPT.*/
+#endif
+#if HAL_USE_ICU
+#if STM32_ICU_USE_TIM1
+ icu_lld_serve_interrupt(&ICUD1);
+#endif
+#endif
+#if HAL_USE_PWM
+#if STM32_PWM_USE_TIM1
+ pwm_lld_serve_interrupt(&PWMD1);
+#endif
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM */
+
+/*===========================================================================*/
+/* 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_TSC_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
+#if HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM || defined(__DOXYGEN__)
+ nvicEnableVector(TIM1_BRK_TIM15_IRQn, STM32_IRQ_TIM1_BRK_TIM15_PRIORITY);
+ nvicEnableVector(TIM1_UP_TIM16_IRQn, STM32_IRQ_TIM1_UP_TIM16_PRIORITY);
+ nvicEnableVector(TIM1_TRG_COM_TIM17_IRQn, STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY);
+ nvicEnableVector(TIM1_CC_IRQn, STM32_IRQ_TIM1_CC_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+#if HAL_USE_PAL
+ nvicDisableVector(EXTI0_IRQn);
+ nvicDisableVector(EXTI1_IRQn);
+ nvicDisableVector(EXTI2_TSC_IRQn);
+ nvicDisableVector(EXTI3_IRQn);
+ nvicDisableVector(EXTI4_IRQn);
+ nvicDisableVector(EXTI9_5_IRQn);
+ nvicDisableVector(EXTI15_10_IRQn);
+#endif
+#if HAL_USE_GPT || HAL_USE_ICU || HAL_USE_PWM || defined(__DOXYGEN__)
+ nvicDisableVector(TIM1_BRK_TIM15_IRQn);
+ nvicDisableVector(TIM1_UP_TIM16_IRQn);
+ nvicDisableVector(TIM1_TRG_COM_TIM17_IRQn);
+ nvicDisableVector(TIM1_CC_IRQn);
+#endif
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F3xx/stm32_isr.h b/os/hal/ports/STM32/STM32F3xx/stm32_isr.h
index 38968038e2..67a77e1b55 100644
--- a/os/hal/ports/STM32/STM32F3xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32F3xx/stm32_isr.h
@@ -1,400 +1,400 @@
-/*
- 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/stm32_isr.h
- * @brief STM32F3xx ISR handler header.
- *
- * @addtogroup STM32F3xx_ISR
- * @{
- */
-
-#ifndef STM32_ISR_H
-#define STM32_ISR_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name ISRs suppressed in standard drivers
- * @{
- */
-#define STM32_TIM1_SUPPRESS_ISR
-#define STM32_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers remapping
- * @{
- */
-/*
- * 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_CAN1_TX_NUMBER 19
-#define STM32_CAN1_RX0_NUMBER 20
-#define STM32_CAN1_RX1_NUMBER 21
-#define STM32_CAN1_SCE_NUMBER 22
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_EVENT_HANDLER VectorBC
-#define STM32_I2C1_ERROR_HANDLER VectorC0
-#define STM32_I2C1_EVENT_NUMBER 31
-#define STM32_I2C1_ERROR_NUMBER 32
-
-#define STM32_I2C2_EVENT_HANDLER VectorC4
-#define STM32_I2C2_ERROR_HANDLER VectorC8
-#define STM32_I2C2_EVENT_NUMBER 33
-#define STM32_I2C2_ERROR_NUMBER 34
-
-#define STM32_I2C3_EVENT_HANDLER Vector160
-#define STM32_I2C3_ERROR_HANDLER Vector164
-#define STM32_I2C3_EVENT_NUMBER 72
-#define STM32_I2C3_ERROR_NUMBER 73
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_UP_HANDLER VectorA4
-#define STM32_TIM1_CC_HANDLER VectorAC
-#define STM32_TIM2_HANDLER VectorB0
-#define STM32_TIM3_HANDLER VectorB4
-#define STM32_TIM4_HANDLER VectorB8
-#define STM32_TIM6_HANDLER Vector118
-#define STM32_TIM7_HANDLER Vector11C
-#define STM32_TIM8_UP_HANDLER VectorF0
-#define STM32_TIM8_CC_HANDLER VectorF8
-#define STM32_TIM15_HANDLER VectorA0 /* Note: same as STM32_TIM1_BRK */
-#define STM32_TIM16_HANDLER VectorA4 /* Note: same as STM32_TIM1_UP */
-#define STM32_TIM17_HANDLER VectorA8 /* Note: same as STM32_TIM1_TRG_COM */
-#define STM32_TIM20_UP_HANDLER Vector178
-#define STM32_TIM20_CC_HANDLER Vector180
-
-#define STM32_TIM1_UP_NUMBER 25
-#define STM32_TIM1_CC_NUMBER 27
-#define STM32_TIM2_NUMBER 28
-#define STM32_TIM3_NUMBER 29
-#define STM32_TIM4_NUMBER 30
-#define STM32_TIM6_NUMBER 54
-#define STM32_TIM7_NUMBER 55
-#define STM32_TIM8_UP_NUMBER 44
-#define STM32_TIM8_CC_NUMBER 46
-#define STM32_TIM15_NUMBER 24 /* Note: same as STM32_TIM1_BRK */
-#define STM32_TIM16_NUMBER 25 /* Note: same as STM32_TIM1_UP */
-#define STM32_TIM17_NUMBER 26 /* Note: same as STM32_TIM1_TRG_COM */
-#define STM32_TIM20_UP_NUMBER 78
-#define STM32_TIM20_CC_NUMBER 80
-
-/*
- * HRTIM units (F334)
- */
-#define STM32_HRTIM_MASTER_HANDLER Vector14C
-#define STM32_HRTIM_TIMA_HANDLER Vector150
-#define STM32_HRTIM_TIMB_HANDLER Vector154
-#define STM32_HRTIM_TIMC_HANDLER Vector158
-#define STM32_HRTIM_TIMD_HANDLER Vector15C
-#define STM32_HRTIM_TIME_HANDLER Vector160
-#define STM32_HRTIM_FLT_HANDLER Vector164
-
-#define STM32_HRTIM_MASTER_NUMBER 67
-#define STM32_HRTIM_TIMA_NUMBER 68
-#define STM32_HRTIM_TIMB_NUMBER 69
-#define STM32_HRTIM_TIMC_NUMBER 70
-#define STM32_HRTIM_TIMD_NUMBER 71
-#define STM32_HRTIM_TIME_NUMBER 72
-#define STM32_HRTIM_FLT_NUMBER 73
-
-/*
- * 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_USART1_NUMBER 37
-#define STM32_USART2_NUMBER 38
-#define STM32_USART3_NUMBER 39
-#define STM32_UART4_NUMBER 52
-#define STM32_UART5_NUMBER 53
-
-/*
- * USB units.
- */
-#define STM32_USB1_HP_HANDLER Vector168
-#define STM32_USB1_LP_HANDLER Vector16C
-
-#define STM32_USB1_HP_NUMBER 74
-#define STM32_USB1_LP_NUMBER 75
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief EXTI0 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI0_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI1_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI2 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI2_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI3 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI3_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI4 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI4_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI5..9 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI5_9_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI10..15 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI10_15_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI16 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI16_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI17 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI17_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI18 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI18_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI19 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI19_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI20 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI20_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI20_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI21,22,29 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI21_22_29_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI21_22_29_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI30..32 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI30_32_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI30_32_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI33 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI33_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI33_PRIORITY 6
-#endif
-
-/**
- * @brief TIM1-BRK, TIM15 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_TIM1_BRK_TIM15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7
-#endif
-
-/**
- * @brief TIM1-UP, TIM16 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_TIM1_UP_TIM16_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7
-#endif
-
-/**
- * @brief TIM1-TRG-COM, TIM17 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7
-#endif
-
-/**
- * @brief TIM1-CC interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_TIM1_CC_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_TIM1_CC_PRIORITY 7
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/* IRQ priority checks.*/
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI0_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI0_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI1_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI1_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI2_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI2_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI3_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI3_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI4_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI4_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI5_9_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI5_9_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI10_15_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI10_15_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI16_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI16_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI17_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI17_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI18_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI18_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI19_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI19_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI20_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI20_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI21_22_29_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI21_22_29_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI30_32_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI30_32_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI33_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI33_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_BRK_TIM15_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_BRK_TIM15_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_UP_TIM16_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_UP_TIM16_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY"
-#endif
-
-#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_CC_PRIORITY)
-#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_CC_PRIORITY"
-#endif
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32F3xx ISR handler header.
+ *
+ * @addtogroup STM32F3xx_ISR
+ * @{
+ */
+
+#ifndef STM32_ISR_H
+#define STM32_ISR_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name ISRs suppressed in standard drivers
+ * @{
+ */
+#define STM32_TIM1_SUPPRESS_ISR
+#define STM32_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers remapping
+ * @{
+ */
+/*
+ * 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_CAN1_TX_NUMBER 19
+#define STM32_CAN1_RX0_NUMBER 20
+#define STM32_CAN1_RX1_NUMBER 21
+#define STM32_CAN1_SCE_NUMBER 22
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_EVENT_HANDLER VectorBC
+#define STM32_I2C1_ERROR_HANDLER VectorC0
+#define STM32_I2C1_EVENT_NUMBER 31
+#define STM32_I2C1_ERROR_NUMBER 32
+
+#define STM32_I2C2_EVENT_HANDLER VectorC4
+#define STM32_I2C2_ERROR_HANDLER VectorC8
+#define STM32_I2C2_EVENT_NUMBER 33
+#define STM32_I2C2_ERROR_NUMBER 34
+
+#define STM32_I2C3_EVENT_HANDLER Vector160
+#define STM32_I2C3_ERROR_HANDLER Vector164
+#define STM32_I2C3_EVENT_NUMBER 72
+#define STM32_I2C3_ERROR_NUMBER 73
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_UP_HANDLER VectorA4
+#define STM32_TIM1_CC_HANDLER VectorAC
+#define STM32_TIM2_HANDLER VectorB0
+#define STM32_TIM3_HANDLER VectorB4
+#define STM32_TIM4_HANDLER VectorB8
+#define STM32_TIM6_HANDLER Vector118
+#define STM32_TIM7_HANDLER Vector11C
+#define STM32_TIM8_UP_HANDLER VectorF0
+#define STM32_TIM8_CC_HANDLER VectorF8
+#define STM32_TIM15_HANDLER VectorA0 /* Note: same as STM32_TIM1_BRK */
+#define STM32_TIM16_HANDLER VectorA4 /* Note: same as STM32_TIM1_UP */
+#define STM32_TIM17_HANDLER VectorA8 /* Note: same as STM32_TIM1_TRG_COM */
+#define STM32_TIM20_UP_HANDLER Vector178
+#define STM32_TIM20_CC_HANDLER Vector180
+
+#define STM32_TIM1_UP_NUMBER 25
+#define STM32_TIM1_CC_NUMBER 27
+#define STM32_TIM2_NUMBER 28
+#define STM32_TIM3_NUMBER 29
+#define STM32_TIM4_NUMBER 30
+#define STM32_TIM6_NUMBER 54
+#define STM32_TIM7_NUMBER 55
+#define STM32_TIM8_UP_NUMBER 44
+#define STM32_TIM8_CC_NUMBER 46
+#define STM32_TIM15_NUMBER 24 /* Note: same as STM32_TIM1_BRK */
+#define STM32_TIM16_NUMBER 25 /* Note: same as STM32_TIM1_UP */
+#define STM32_TIM17_NUMBER 26 /* Note: same as STM32_TIM1_TRG_COM */
+#define STM32_TIM20_UP_NUMBER 78
+#define STM32_TIM20_CC_NUMBER 80
+
+/*
+ * HRTIM units (F334)
+ */
+#define STM32_HRTIM_MASTER_HANDLER Vector14C
+#define STM32_HRTIM_TIMA_HANDLER Vector150
+#define STM32_HRTIM_TIMB_HANDLER Vector154
+#define STM32_HRTIM_TIMC_HANDLER Vector158
+#define STM32_HRTIM_TIMD_HANDLER Vector15C
+#define STM32_HRTIM_TIME_HANDLER Vector160
+#define STM32_HRTIM_FLT_HANDLER Vector164
+
+#define STM32_HRTIM_MASTER_NUMBER 67
+#define STM32_HRTIM_TIMA_NUMBER 68
+#define STM32_HRTIM_TIMB_NUMBER 69
+#define STM32_HRTIM_TIMC_NUMBER 70
+#define STM32_HRTIM_TIMD_NUMBER 71
+#define STM32_HRTIM_TIME_NUMBER 72
+#define STM32_HRTIM_FLT_NUMBER 73
+
+/*
+ * 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_USART1_NUMBER 37
+#define STM32_USART2_NUMBER 38
+#define STM32_USART3_NUMBER 39
+#define STM32_UART4_NUMBER 52
+#define STM32_UART5_NUMBER 53
+
+/*
+ * USB units.
+ */
+#define STM32_USB1_HP_HANDLER Vector168
+#define STM32_USB1_LP_HANDLER Vector16C
+
+#define STM32_USB1_HP_NUMBER 74
+#define STM32_USB1_LP_NUMBER 75
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI0_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI1_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI2 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI2_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI3 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI3_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI4 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI4_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI5..9 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI5_9_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI10..15 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI10_15_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI16 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI16_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI17 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI17_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI18 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI18_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI19 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI19_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI20 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI20_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI20_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI21,22,29 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI21_22_29_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI21_22_29_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI30..32 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI30_32_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI30_32_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI33 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI33_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI33_PRIORITY 6
+#endif
+
+/**
+ * @brief TIM1-BRK, TIM15 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_TIM1_BRK_TIM15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7
+#endif
+
+/**
+ * @brief TIM1-UP, TIM16 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_TIM1_UP_TIM16_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7
+#endif
+
+/**
+ * @brief TIM1-TRG-COM, TIM17 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7
+#endif
+
+/**
+ * @brief TIM1-CC interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_TIM1_CC_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_TIM1_CC_PRIORITY 7
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/* IRQ priority checks.*/
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI0_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI0_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI1_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI1_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI2_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI2_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI3_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI3_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI4_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI4_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI5_9_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI5_9_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI10_15_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI10_15_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI16_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI16_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI17_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI17_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI18_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI18_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI19_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI19_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI20_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI20_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI21_22_29_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI21_22_29_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI30_32_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI30_32_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_EXTI33_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_EXTI33_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_BRK_TIM15_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_BRK_TIM15_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_UP_TIM16_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_UP_TIM16_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY"
+#endif
+
+#if !OSAL_IRQ_IS_VALID_PRIORITY(STM32_IRQ_TIM1_CC_PRIORITY)
+#error "Invalid IRQ priority assigned to STM32_IRQ_TIM1_CC_PRIORITY"
+#endif
+
+/*===========================================================================*/
+/* 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/STM32/STM32F3xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F3xx/stm32_rcc.h
index 4db714d80a..04631cc663 100644
--- a/os/hal/ports/STM32/STM32F3xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F3xx/stm32_rcc.h
@@ -1,1026 +1,1026 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32f30x.h.
- *
- * @addtogroup STM32F3xx_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); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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); \
- (void)RCC->APB1ENR; \
-}
-
-/**
- * @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
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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); \
- (void)RCC->APB2ENR; \
-}
-
-/**
- * @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 AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- (void)RCC->AHBENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ADC1/ADC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#if defined(RCC_AHBENR_ADC12EN) || defined(__DOXYGEN__)
-#define rccEnableADC12(lp) rccEnableAHB(RCC_AHBENR_ADC12EN, lp)
-#else
-#define rccEnableADC12(lp) rccEnableAHB(RCC_AHBENR_ADC1EN, lp)
-#endif
-
-/**
- * @brief Disables the ADC1/ADC2 peripheral clock.
- *
- * @api
- */
-#if defined(RCC_AHBENR_ADC12EN) || defined(__DOXYGEN__)
-#define rccDisableADC12() rccDisableAHB(RCC_AHBENR_ADC12EN)
-#else
-#define rccDisableADC12() rccDisableAHB(RCC_AHBENR_ADC1EN)
-#endif
-
-/**
- * @brief Resets the ADC1/ADC2 peripheral.
- *
- * @api
- */
-#if defined(RCC_AHBRSTR_ADC12RST) || defined(__DOXYGEN__)
-#define rccResetADC12() rccResetAHB(RCC_AHBRSTR_ADC12RST)
-#else
-#define rccResetADC12() rccResetAHB(RCC_AHBRSTR_ADC1RST)
-#endif
-
-/**
- * @brief Enables the ADC3/ADC4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#if defined(RCC_AHBENR_ADC34EN) || defined(__DOXYGEN__)
-#define rccEnableADC34(lp) rccEnableAHB(RCC_AHBENR_ADC34EN, lp)
-#else
-#define rccEnableADC34(lp) rccEnableAHB(RCC_AHBENR_ADC3EN, lp)
-#endif
-
-/**
- * @brief Disables the ADC3/ADC4 peripheral clock.
- *
- * @api
- */
-#if defined(RCC_AHBENR_ADC34EN) || defined(__DOXYGEN__)
-#define rccDisableADC34() rccDisableAHB(RCC_AHBENR_ADC34EN)
-#else
-#define rccDisableADC34() rccDisableAHB(RCC_AHBENR_ADC3EN)
-#endif
-
-/**
- * @brief Resets the ADC3/ADC4 peripheral.
- *
- * @api
- */
-#if defined(RCC_AHBRSTR_ADC34RST) || defined(__DOXYGEN__)
-#define rccResetADC34() rccResetAHB(RCC_AHBRSTR_ADC34RST)
-#else
-#define rccResetADC34() rccResetAHB(RCC_AHBRSTR_ADC3RST)
-#endif
-/** @} */
-
-/**
- * @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_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPB1(RCC_APB1ENR_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPB1(RCC_APB1RSTR_DAC1RST)
-
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC2(lp) rccEnableAPB1(RCC_APB1ENR_DAC2EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC2() rccDisableAPB1(RCC_APB1ENR_DAC2EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC2() rccResetAPB1(RCC_APB1RSTR_DAC2RST)
-/** @} */
-
-/**
- * @name CAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CAN1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CANEN, lp)
-
-/**
- * @brief Disables the CAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CANEN)
-
-/**
- * @brief Resets the CAN1 peripheral.
- *
- * @api
- */
-#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST)
-/** @} */
-
-/**
- * @name DMA peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMA1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- *
- * @api
- */
-#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
-
-/**
- * @brief Enables the DMA2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
-
-/**
- * @brief Disables the DMA2 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
-
-/**
- * @brief Resets the DMA2 peripheral.
- *
- * @api
- */
-#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 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)
-/** @} */
-
-/**
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the TIM1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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 TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-
-/**
- * @brief Enables the TIM20 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM20(lp) rccEnableAPB2(RCC_APB2ENR_TIM20EN, lp)
-
-/**
- * @brief Disables the TIM20 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM20(lp) rccDisableAPB2(RCC_APB2ENR_TIM20EN)
-
-/**
- * @brief Resets the TIM20 peripheral.
- *
- * @api
- */
-#define rccResetTIM20() rccResetAPB2(RCC_APB2RSTR_TIM20RST)
-/** @} */
-
-/**
- * @name HRTIM peripheral specific RCC operations
- * @{
- */
-/**
-
- * @brief Enables the HRTIM1 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableHRTIM1(lp) rccEnableAPB2(RCC_APB2ENR_HRTIM1EN, lp)
-
-/**
- * @brief Disables the HRTIM1 peripheral clock.
- *
- * @api
- */
-#define rccDisableHRTIM1(lp) rccDisableAPB2(RCC_APB2ENR_HRTIM1EN)
-
-/**
- * @brief Resets the HRTIM1 peripheral.
- *
- * @api
-
- */
-#define rccResetHRTIM1() rccResetAPB2(RCC_APB2RSTR_HRTIM1RST)
-/** @} */
-
-/**
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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.
- * @note The @p lp parameter is ignored in this family.
- *
- * @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)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
-/** @} */
-
-/**
- * @name FSMC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FMC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableFSMC(lp) rccEnableAHB(RCC_AHBENR_FMCEN, lp)
-
-/**
- * @brief Disables the FMC peripheral clock.
- *
- * @api
- */
-#define rccDisableFSMC() rccDisableAHB(RCC_AHBENR_FMCEN)
-/** @} */
-
-/**
- * @name CRC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
-
-/**
- * @brief Disables the CRC peripheral clock.
- *
- * @api
- */
-#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32f30x.h.
+ *
+ * @addtogroup STM32F3xx_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); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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); \
+ (void)RCC->APB1ENR; \
+}
+
+/**
+ * @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
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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); \
+ (void)RCC->APB2ENR; \
+}
+
+/**
+ * @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 AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ (void)RCC->AHBENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ADC1/ADC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#if defined(RCC_AHBENR_ADC12EN) || defined(__DOXYGEN__)
+#define rccEnableADC12(lp) rccEnableAHB(RCC_AHBENR_ADC12EN, lp)
+#else
+#define rccEnableADC12(lp) rccEnableAHB(RCC_AHBENR_ADC1EN, lp)
+#endif
+
+/**
+ * @brief Disables the ADC1/ADC2 peripheral clock.
+ *
+ * @api
+ */
+#if defined(RCC_AHBENR_ADC12EN) || defined(__DOXYGEN__)
+#define rccDisableADC12() rccDisableAHB(RCC_AHBENR_ADC12EN)
+#else
+#define rccDisableADC12() rccDisableAHB(RCC_AHBENR_ADC1EN)
+#endif
+
+/**
+ * @brief Resets the ADC1/ADC2 peripheral.
+ *
+ * @api
+ */
+#if defined(RCC_AHBRSTR_ADC12RST) || defined(__DOXYGEN__)
+#define rccResetADC12() rccResetAHB(RCC_AHBRSTR_ADC12RST)
+#else
+#define rccResetADC12() rccResetAHB(RCC_AHBRSTR_ADC1RST)
+#endif
+
+/**
+ * @brief Enables the ADC3/ADC4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#if defined(RCC_AHBENR_ADC34EN) || defined(__DOXYGEN__)
+#define rccEnableADC34(lp) rccEnableAHB(RCC_AHBENR_ADC34EN, lp)
+#else
+#define rccEnableADC34(lp) rccEnableAHB(RCC_AHBENR_ADC3EN, lp)
+#endif
+
+/**
+ * @brief Disables the ADC3/ADC4 peripheral clock.
+ *
+ * @api
+ */
+#if defined(RCC_AHBENR_ADC34EN) || defined(__DOXYGEN__)
+#define rccDisableADC34() rccDisableAHB(RCC_AHBENR_ADC34EN)
+#else
+#define rccDisableADC34() rccDisableAHB(RCC_AHBENR_ADC3EN)
+#endif
+
+/**
+ * @brief Resets the ADC3/ADC4 peripheral.
+ *
+ * @api
+ */
+#if defined(RCC_AHBRSTR_ADC34RST) || defined(__DOXYGEN__)
+#define rccResetADC34() rccResetAHB(RCC_AHBRSTR_ADC34RST)
+#else
+#define rccResetADC34() rccResetAHB(RCC_AHBRSTR_ADC3RST)
+#endif
+/** @} */
+
+/**
+ * @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_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPB1(RCC_APB1ENR_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPB1(RCC_APB1RSTR_DAC1RST)
+
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC2(lp) rccEnableAPB1(RCC_APB1ENR_DAC2EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC2() rccDisableAPB1(RCC_APB1ENR_DAC2EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC2() rccResetAPB1(RCC_APB1RSTR_DAC2RST)
+/** @} */
+
+/**
+ * @name CAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CAN1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN1(lp) rccEnableAPB1(RCC_APB1ENR_CANEN, lp)
+
+/**
+ * @brief Disables the CAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN1() rccDisableAPB1(RCC_APB1ENR_CANEN)
+
+/**
+ * @brief Resets the CAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN1() rccResetAPB1(RCC_APB1RSTR_CANRST)
+/** @} */
+
+/**
+ * @name DMA peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMA1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
+
+/**
+ * @brief Enables the DMA2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
+
+/**
+ * @brief Disables the DMA2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
+
+/**
+ * @brief Resets the DMA2 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 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)
+/** @} */
+
+/**
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the TIM1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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 TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+
+/**
+ * @brief Enables the TIM20 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM20(lp) rccEnableAPB2(RCC_APB2ENR_TIM20EN, lp)
+
+/**
+ * @brief Disables the TIM20 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM20(lp) rccDisableAPB2(RCC_APB2ENR_TIM20EN)
+
+/**
+ * @brief Resets the TIM20 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM20() rccResetAPB2(RCC_APB2RSTR_TIM20RST)
+/** @} */
+
+/**
+ * @name HRTIM peripheral specific RCC operations
+ * @{
+ */
+/**
+
+ * @brief Enables the HRTIM1 peripheral clock.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableHRTIM1(lp) rccEnableAPB2(RCC_APB2ENR_HRTIM1EN, lp)
+
+/**
+ * @brief Disables the HRTIM1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableHRTIM1(lp) rccDisableAPB2(RCC_APB2ENR_HRTIM1EN)
+
+/**
+ * @brief Resets the HRTIM1 peripheral.
+ *
+ * @api
+
+ */
+#define rccResetHRTIM1() rccResetAPB2(RCC_APB2RSTR_HRTIM1RST)
+/** @} */
+
+/**
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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.
+ * @note The @p lp parameter is ignored in this family.
+ *
+ * @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)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
+/** @} */
+
+/**
+ * @name FSMC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FMC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableFSMC(lp) rccEnableAHB(RCC_AHBENR_FMCEN, lp)
+
+/**
+ * @brief Disables the FMC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFSMC() rccDisableAHB(RCC_AHBENR_FMCEN)
+/** @} */
+
+/**
+ * @name CRC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
+
+/**
+ * @brief Disables the CRC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F3xx/stm32_registry.h b/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
index e75cf52887..1edbec9866 100644
--- a/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
@@ -1,3130 +1,3130 @@
-/*
- 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/stm32_registry.h
- * @brief STM32F3xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/**
- * @brief Sub-family identifier.
- */
-#if !defined(STM32F3XX) || defined(__DOXYGEN__)
-#define STM32F3XX
-#endif
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32F3xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/*===========================================================================*/
-/* STM32F303xC. */
-/*===========================================================================*/
-#if defined(STM32F303xC) || defined(__DOXYGEN__)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 TRUE
-#define STM32_ADC3_HANDLER VectorFC
-#define STM32_ADC3_NUMBER 47
-#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_ADC3_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC4 TRUE
-#define STM32_ADC4_HANDLER Vector134
-#define STM32_ADC4_NUMBER 61
-#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_ADC4_DMA_CHN 0x00000000
-
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN)
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F303xC) */
-
-/*===========================================================================*/
-/* STM32F303xE. */
-/*===========================================================================*/
-#if defined(STM32F303xE)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 TRUE
-#define STM32_ADC3_HANDLER VectorFC
-#define STM32_ADC3_NUMBER 47
-#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_ADC3_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC4 TRUE
-#define STM32_ADC4_HANDLER Vector134
-#define STM32_ADC4_NUMBER 61
-#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_ADC4_DMA_CHN 0x00000000
-
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN | \
- RCC_AHBENR_GPIOGEN | \
- RCC_AHBENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 TRUE
-#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, 1)
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 TRUE
-#define STM32_SPI4_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM20 TRUE
-#define STM32_TIM20_IS_32BITS FALSE
-#define STM32_TIM20_CHANNELS 6
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#define STM32_HAS_TIM18 FALSE
-#define STM32_HAS_TIM19 FALSE
-#define STM32_HAS_TIM21 FALSE
-#define STM32_HAS_TIM22 FALSE
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F303xE) */
-
-/*===========================================================================*/
-/* STM32F303x8. */
-/*===========================================================================*/
-#if defined(STM32F303x8)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F303x8) */
-
-/*===========================================================================*/
-/* STM32F301x8. */
-/*===========================================================================*/
-#if defined(STM32F301x8)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 TRUE
-#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, 1)
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI1 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS TRUE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F301x8) */
-
-/*===========================================================================*/
-/* STM32F302x8. */
-/*===========================================================================*/
-#if defined(STM32F302x8)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 TRUE
-#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, 1)
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI1 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS TRUE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F302x8) */
-
-/*===========================================================================*/
-/* STM32F302xC. */
-/*===========================================================================*/
-#if defined(STM32F302xC)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F302xC) */
-
-/*===========================================================================*/
-/* STM32F302xE. */
-/*===========================================================================*/
-#if defined(STM32F302xE)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN | \
- RCC_AHBENR_GPIOGEN | \
- RCC_AHBENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 TRUE
-#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, 1)
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 TRUE
-#define STM32_SPI4_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 768
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F302xE) */
-
-/*===========================================================================*/
-/* STM32F318x8. */
-/*===========================================================================*/
-#if defined(STM32F318x8)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 TRUE
-#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, 1)
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI1 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS TRUE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F318x8) */
-
-/*===========================================================================*/
-/* STM32F328x8. */
-/*===========================================================================*/
-#if defined(STM32F328x8)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F328x8) */
-
-/*===========================================================================*/
-/* STM32F358xC. */
-/*===========================================================================*/
-#if defined(STM32F358xC)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F358xC) */
-
-/*===========================================================================*/
-/* STM32F334x8. */
-/*===========================================================================*/
-#if defined(STM32F334x8)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 1
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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
-
-/* HRTIM attributes.*/
-#define STM32_HAS_HRTIM1 TRUE
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F334x8) */
-
-/*===========================================================================*/
-/* STM32F398xx. */
-/*===========================================================================*/
-#if defined(STM32F398xx)
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 TRUE
-#define STM32_ADC3_HANDLER VectorFC
-#define STM32_ADC3_NUMBER 47
-#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_ADC3_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC4 TRUE
-#define STM32_ADC4_HANDLER Vector134
-#define STM32_ADC4_NUMBER 61
-#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_ADC4_DMA_CHN 0x00000000
-
-#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 FALSE
-#define STM32_HAS_CAN3 FALSE
-#define STM32_CAN_MAX_FILTERS 14
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN | \
- RCC_AHBENR_GPIOGEN | \
- RCC_AHBENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 TRUE
-#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, 1)
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 64
-#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 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-
-#define STM32_HAS_SPI4 TRUE
-#define STM32_SPI4_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM20 TRUE
-#define STM32_TIM20_IS_32BITS FALSE
-#define STM32_TIM20_CHANNELS 6
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#define STM32_HAS_TIM18 FALSE
-#define STM32_HAS_TIM19 FALSE
-#define STM32_HAS_TIM21 FALSE
-#define STM32_HAS_TIM22 FALSE
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-#define STM32_FSMC_IS_FMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-#endif /* defined(STM32F398xx) */
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32F3xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/**
+ * @brief Sub-family identifier.
+ */
+#if !defined(STM32F3XX) || defined(__DOXYGEN__)
+#define STM32F3XX
+#endif
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32F3xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/*===========================================================================*/
+/* STM32F303xC. */
+/*===========================================================================*/
+#if defined(STM32F303xC) || defined(__DOXYGEN__)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 TRUE
+#define STM32_ADC3_HANDLER VectorFC
+#define STM32_ADC3_NUMBER 47
+#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_ADC3_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC4 TRUE
+#define STM32_ADC4_HANDLER Vector134
+#define STM32_ADC4_NUMBER 61
+#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_ADC4_DMA_CHN 0x00000000
+
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN)
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F303xC) */
+
+/*===========================================================================*/
+/* STM32F303xE. */
+/*===========================================================================*/
+#if defined(STM32F303xE)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 TRUE
+#define STM32_ADC3_HANDLER VectorFC
+#define STM32_ADC3_NUMBER 47
+#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_ADC3_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC4 TRUE
+#define STM32_ADC4_HANDLER Vector134
+#define STM32_ADC4_NUMBER 61
+#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_ADC4_DMA_CHN 0x00000000
+
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN | \
+ RCC_AHBENR_GPIOGEN | \
+ RCC_AHBENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 TRUE
+#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, 1)
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM20 TRUE
+#define STM32_TIM20_IS_32BITS FALSE
+#define STM32_TIM20_CHANNELS 6
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#define STM32_HAS_TIM18 FALSE
+#define STM32_HAS_TIM19 FALSE
+#define STM32_HAS_TIM21 FALSE
+#define STM32_HAS_TIM22 FALSE
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F303xE) */
+
+/*===========================================================================*/
+/* STM32F303x8. */
+/*===========================================================================*/
+#if defined(STM32F303x8)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F303x8) */
+
+/*===========================================================================*/
+/* STM32F301x8. */
+/*===========================================================================*/
+#if defined(STM32F301x8)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 TRUE
+#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, 1)
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI1 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS TRUE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F301x8) */
+
+/*===========================================================================*/
+/* STM32F302x8. */
+/*===========================================================================*/
+#if defined(STM32F302x8)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 TRUE
+#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, 1)
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI1 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS TRUE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F302x8) */
+
+/*===========================================================================*/
+/* STM32F302xC. */
+/*===========================================================================*/
+#if defined(STM32F302xC)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F302xC) */
+
+/*===========================================================================*/
+/* STM32F302xE. */
+/*===========================================================================*/
+#if defined(STM32F302xE)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN | \
+ RCC_AHBENR_GPIOGEN | \
+ RCC_AHBENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 TRUE
+#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, 1)
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 768
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F302xE) */
+
+/*===========================================================================*/
+/* STM32F318x8. */
+/*===========================================================================*/
+#if defined(STM32F318x8)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 TRUE
+#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, 1)
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI1 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS TRUE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F318x8) */
+
+/*===========================================================================*/
+/* STM32F328x8. */
+/*===========================================================================*/
+#if defined(STM32F328x8)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F328x8) */
+
+/*===========================================================================*/
+/* STM32F358xC. */
+/*===========================================================================*/
+#if defined(STM32F358xC)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F358xC) */
+
+/*===========================================================================*/
+/* STM32F334x8. */
+/*===========================================================================*/
+#if defined(STM32F334x8)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_DAC_DAC2_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 1
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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
+
+/* HRTIM attributes.*/
+#define STM32_HAS_HRTIM1 TRUE
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F334x8) */
+
+/*===========================================================================*/
+/* STM32F398xx. */
+/*===========================================================================*/
+#if defined(STM32F398xx)
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 TRUE
+#define STM32_ADC3_HANDLER VectorFC
+#define STM32_ADC3_NUMBER 47
+#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_ADC3_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC4 TRUE
+#define STM32_ADC4_HANDLER Vector134
+#define STM32_ADC4_NUMBER 61
+#define STM32_ADC4_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_ADC4_DMA_CHN 0x00000000
+
+#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 FALSE
+#define STM32_HAS_CAN3 FALSE
+#define STM32_CAN_MAX_FILTERS 14
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(2, 4)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN | \
+ RCC_AHBENR_GPIOGEN | \
+ RCC_AHBENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 TRUE
+#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, 1)
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 64
+#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 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2S_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_I2C_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_I2S_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_I2S_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM20 TRUE
+#define STM32_TIM20_IS_32BITS FALSE
+#define STM32_TIM20_CHANNELS 6
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#define STM32_HAS_TIM18 FALSE
+#define STM32_HAS_TIM19 FALSE
+#define STM32_HAS_TIM21 FALSE
+#define STM32_HAS_TIM22 FALSE
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+#define STM32_FSMC_IS_FMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+#endif /* defined(STM32F398xx) */
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.c b/os/hal/ports/STM32/STM32F4xx/hal_lld.c
index b2b8a11978..aa51a7ac14 100644
--- a/os/hal/ports/STM32/STM32F4xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.c
@@ -1,341 +1,342 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..473a6a3fdd 100644
--- a/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h
+++ b/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h
@@ -1,2015 +1,2023 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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..789f0bc570 100644
--- a/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h
+++ b/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h
@@ -1,1231 +1,1239 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk
index fdff0bdb8a..65f6845b72 100644
--- a/os/hal/ports/STM32/STM32F4xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F4xx/platform.mk
@@ -1,49 +1,49 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx
-
-# 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)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/hal_efl_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx
+
+# 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/STM32F4xx/stm32_isr.c b/os/hal/ports/STM32/STM32F4xx/stm32_isr.c
index 08237e1c33..f39c6f7b27 100644
--- a/os/hal/ports/STM32/STM32F4xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32F4xx/stm32_isr.c
@@ -1,255 +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
-}
-
-/** @} */
+/*
+ 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/STM32/STM32F4xx/stm32_isr.h b/os/hal/ports/STM32/STM32F4xx/stm32_isr.h
index 6a826f6a37..56b86a12c4 100644
--- a/os/hal/ports/STM32/STM32F4xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32F4xx/stm32_isr.h
@@ -1,275 +1,275 @@
-/*
- 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 ISR names and numbers remapping
- * @{
- */
-/*
- * 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_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
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_EVENT_HANDLER VectorBC
-#define STM32_I2C1_ERROR_HANDLER VectorC0
-#define STM32_I2C1_EVENT_NUMBER 31
-#define STM32_I2C1_ERROR_NUMBER 32
-
-#define STM32_I2C2_EVENT_HANDLER VectorC4
-#define STM32_I2C2_ERROR_HANDLER VectorC8
-#define STM32_I2C2_EVENT_NUMBER 33
-#define STM32_I2C2_ERROR_NUMBER 34
-
-#define STM32_I2C3_EVENT_HANDLER Vector160
-#define STM32_I2C3_ERROR_HANDLER Vector164
-#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_UP_HANDLER VectorA4
-#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_UP_HANDLER VectorF0
-#define STM32_TIM8_CC_HANDLER VectorF8
-#define STM32_TIM9_HANDLER VectorA0
-#define STM32_TIM10_HANDLER VectorA4 /* Note: same as STM32_TIM1_UP */
-#define STM32_TIM11_HANDLER VectorA8
-#define STM32_TIM12_HANDLER VectorEC
-#define STM32_TIM13_HANDLER VectorF0 /* Note: same as STM32_TIM8_UP */
-#define STM32_TIM14_HANDLER VectorF4
-
-#define STM32_TIM1_UP_NUMBER 25
-#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_UP_NUMBER 44
-#define STM32_TIM8_CC_NUMBER 46
-#define STM32_TIM9_NUMBER 24
-#define STM32_TIM10_NUMBER 25 /* Note: same as STM32_TIM1_UP */
-#define STM32_TIM11_NUMBER 26
-#define STM32_TIM12_NUMBER 43
-#define STM32_TIM13_NUMBER 44 /* Note: same as STM32_TIM8_UP */
-#define STM32_TIM14_NUMBER 45
-
-/*
- * 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_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
-
-/*
- * 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. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief EXTI0 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI0_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI1_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI2 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI2_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI3 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI3_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI4 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI4_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI5..9 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI5_9_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI10..15 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI10_15_PRIORITY 6
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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 ISR names and numbers remapping
+ * @{
+ */
+/*
+ * 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_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
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_EVENT_HANDLER VectorBC
+#define STM32_I2C1_ERROR_HANDLER VectorC0
+#define STM32_I2C1_EVENT_NUMBER 31
+#define STM32_I2C1_ERROR_NUMBER 32
+
+#define STM32_I2C2_EVENT_HANDLER VectorC4
+#define STM32_I2C2_ERROR_HANDLER VectorC8
+#define STM32_I2C2_EVENT_NUMBER 33
+#define STM32_I2C2_ERROR_NUMBER 34
+
+#define STM32_I2C3_EVENT_HANDLER Vector160
+#define STM32_I2C3_ERROR_HANDLER Vector164
+#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_UP_HANDLER VectorA4
+#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_UP_HANDLER VectorF0
+#define STM32_TIM8_CC_HANDLER VectorF8
+#define STM32_TIM9_HANDLER VectorA0
+#define STM32_TIM10_HANDLER VectorA4 /* Note: same as STM32_TIM1_UP */
+#define STM32_TIM11_HANDLER VectorA8
+#define STM32_TIM12_HANDLER VectorEC
+#define STM32_TIM13_HANDLER VectorF0 /* Note: same as STM32_TIM8_UP */
+#define STM32_TIM14_HANDLER VectorF4
+
+#define STM32_TIM1_UP_NUMBER 25
+#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_UP_NUMBER 44
+#define STM32_TIM8_CC_NUMBER 46
+#define STM32_TIM9_NUMBER 24
+#define STM32_TIM10_NUMBER 25 /* Note: same as STM32_TIM1_UP */
+#define STM32_TIM11_NUMBER 26
+#define STM32_TIM12_NUMBER 43
+#define STM32_TIM13_NUMBER 44 /* Note: same as STM32_TIM8_UP */
+#define STM32_TIM14_NUMBER 45
+
+/*
+ * 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_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
+
+/*
+ * 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. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI0_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI1_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI2 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI2_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI3 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI3_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI4 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI4_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI5..9 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI5_9_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI10..15 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI10_15_PRIORITY 6
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32F4xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h
index cc401ce059..2734a14fdf 100644
--- a/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F4xx/stm32_rcc.h
@@ -1,1658 +1,1658 @@
-/*
- 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 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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-
-/**
- * @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 Resets the ADC2 peripheral.
- *
- * @api
- */
-#define rccResetADC2() rccResetAPB2(RCC_APB2RSTR_ADC2RST)
-
-/**
- * @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)
-
-/**
- * @brief Resets the ADC3 peripheral.
- *
- * @api
- */
-#define rccResetADC3() rccResetAPB2(RCC_APB2RSTR_ADC3RST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @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) rccEnableAHB1(RCC_AHB1ENR_OTGHSULPIEN, lp)
-
-/**
- * @brief Disables the OTG_HS peripheral clock.
- *
- * @api
- */
-#define rccDisableOTG_HSULPI() rccDisableAHB1(RCC_AHB1ENR_OTGHSULPIEN)
-/** @} */
-
-/**
- * @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 */
-
-/** @} */
+/*
+ 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 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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+
+/**
+ * @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 Resets the ADC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC2() rccResetAPB2(RCC_APB2RSTR_ADC2RST)
+
+/**
+ * @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)
+
+/**
+ * @brief Resets the ADC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC3() rccResetAPB2(RCC_APB2RSTR_ADC3RST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @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) rccEnableAHB1(RCC_AHB1ENR_OTGHSULPIEN, lp)
+
+/**
+ * @brief Disables the OTG_HS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableOTG_HSULPI() rccDisableAHB1(RCC_AHB1ENR_OTGHSULPIEN)
+/** @} */
+
+/**
+ * @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/STM32/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
index 5072ce7443..bb8a3fb625 100644
--- a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
@@ -1,3174 +1,3174 @@
-/*
- 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 STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-#if defined(STM32F469xx) || defined(STM32F479xx)
-#define STM32F469_479xx
-#define STM32F4XX
-
-#elif defined(STM32F446xx)
-#define STM32F4XX
-
-#elif defined(STM32F439xx) || defined(STM32F429xx)
-#define STM32F429_439xx
-#define STM32F4XX
-
-#elif defined(STM32F437xx) || defined(STM32F427xx)
-#define STM32F427_437xx
-#define STM32F4XX
-
-#elif defined(STM32F413xx)
-#define STM32F413xx
-#define STM32F4XX
-
-#elif defined(STM32F412Cx) || defined(STM32F412Rx) || \
- defined(STM32F412Vx) || defined(STM32F412Zx)
-#define STM32F412xx
-#define STM32F4XX
-
-#elif defined(STM32F411xE)
-#define STM32F411xx
-#define STM32F4XX
-
-#elif defined(STM32F410Cx) || defined(STM32F410Rx) || \
- defined(STM32F410Tx)
-#define STM32F410xx
-#define STM32F4XX
-
-#elif defined(STM32F405xx) || defined(STM32F415xx) || \
- defined(STM32F407xx) || defined(STM32F417xx)
-#define STM32F40_41xxx
-#define STM32F4XX
-
-#elif defined(STM32F401xC) || defined(STM32F401xE)
-#define STM32F401xx
-#define STM32F4XX
-
-#elif defined(STM32F205xx) || defined(STM32F215xx) || \
- defined(STM32F207xx) || defined(STM32F217xx)
-#define STM32F2XX
-
-#else
-#error "STM32F2xx/F4xx 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)
-
-/*===========================================================================*/
-/* STM32F469xx, STM32F479xx. */
-/*===========================================================================*/
-
-#if defined(STM32F469_479xx) || defined(__DOXYGEN__)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI TRUE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#define STM32_HAS_RCC_DCKCFGR2 FALSE
-#define STM32_HAS_RCC_I2SSRC TRUE
-#define STM32_HAS_RCC_I2SPLLSRC FALSE
-#define STM32_HAS_RCC_CK48MSEL TRUE
-#define STM32_RCC_CK48MSEL_USES_I2S FALSE
-#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT
-#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
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ TRUE
-#define STM32_HAS_GPIOK TRUE
-
-#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 | \
- RCC_AHB1ENR_GPIOJEN | \
- RCC_AHB1ENR_GPIOKEN)
-
-/* 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 TRUE
-#define STM32_QUADSPI1_HANDLER Vector1AC
-#define STM32_QUADSPI1_NUMBER 91
-#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_QUADSPI1_DMA_CHN 0x30000000
-
-/* 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 TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-#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(STM32F469_479xx) */
-
-/*===========================================================================*/
-/* STM32F446xx. */
-/*===========================================================================*/
-
-#if defined(STM32F446xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI TRUE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#define STM32_HAS_RCC_DCKCFGR2 TRUE
-#define STM32_HAS_RCC_I2SSRC FALSE
-#define STM32_HAS_RCC_I2SPLLSRC FALSE
-#define STM32_HAS_RCC_CK48MSEL TRUE
-#define STM32_RCC_CK48MSEL_USES_I2S FALSE
-#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_P_CLKOUT
-#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 FALSE
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#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)
-
-/* 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 TRUE
-#define STM32_QUADSPI1_HANDLER Vector1B0
-#define STM32_QUADSPI1_NUMBER 92
-#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_QUADSPI1_DMA_CHN 0x30000000
-
-/* 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 TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX 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 FALSE
-#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 FALSE
-#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 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-#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(STM32F446xx) */
-
-/*===========================================================================*/
-/* STM32F439xx, STM32F429xx, STM32F437xx, STM32F427xx. */
-/*===========================================================================*/
-
-#if defined(STM32F429_439xx) || defined(STM32F427_437xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI TRUE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#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
-#define STM32_HAS_GPIOI TRUE
-#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_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 1
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 3
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 5
-
-#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) */
-
-/*===========================================================================*/
-/* STM32F413xx. */
-/*===========================================================================*/
-
-#if defined(STM32F413xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI FALSE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#define STM32_HAS_RCC_DCKCFGR2 TRUE
-#define STM32_HAS_RCC_I2SSRC FALSE
-#define STM32_HAS_RCC_I2SPLLSRC TRUE
-#define STM32_HAS_RCC_CK48MSEL TRUE
-#define STM32_RCC_CK48MSEL_USES_I2S TRUE
-#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT
-#define STM32_TIMPRE_PRESCALE4 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 TRUE
-#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 FALSE
-
-/* 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
-#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)
-
-/* 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, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_RX_DMA_CHN 0x00000310
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C3_TX_DMA_CHN 0x00630000
-
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_SUPPORTS_FMP TRUE
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
-#define STM32_I2C4_RX_DMA_CHN 0x00001000
-#define STM32_I2C4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1)
-#define STM32_I2C4_TX_DMA_CHN 0x00000020
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_HANDLER Vector1B0
-#define STM32_QUADSPI1_NUMBER 92
-#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_QUADSPI1_DMA_CHN 0x30000000
-
-/* 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 TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SPI1_TX_DMA_CHN 0x00303200
-
-#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 TRUE
-#define STM32_SPI4_I2S_FULLDUPLEX TRUE
-#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
- STM32_DMA_STREAM_ID_MSK(2, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI4_RX_DMA_CHN 0x00045004
-#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 TRUE
-#define STM32_SPI5_I2S_FULLDUPLEX TRUE
-#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, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_SPI5_TX_DMA_CHN 0x07520000
-
-#define STM32_HAS_SPI6 FALSE
-
-/* 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
-
-#define STM32_HAS_LPTIM1 TRUE
-
-/* 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 0x80000000
-
-#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 TRUE
-#define STM32_UART9_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_UART9_RX_DMA_CHN 0x00000000
-#define STM32_UART9_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0)
-#define STM32_UART9_TX_DMA_CHN 0x00000001
-
-#define STM32_HAS_UART10 TRUE
-#define STM32_UART10_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0)
-#define STM32_UART10_RX_DMA_CHN 0x00000005
-#define STM32_UART10_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_UART10_TX_DMA_CHN 0x60000000
-
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-#endif /* defined(STM32F413xx) */
-
-/*===========================================================================*/
-/* STM32F412xx. */
-/*===========================================================================*/
-
-#if defined(STM32F412xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI FALSE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#define STM32_HAS_RCC_DCKCFGR2 TRUE
-#define STM32_HAS_RCC_I2SSRC FALSE
-#define STM32_HAS_RCC_I2SPLLSRC TRUE
-#define STM32_HAS_RCC_CK48MSEL TRUE
-#define STM32_RCC_CK48MSEL_USES_I2S TRUE
-#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT
-#define STM32_TIMPRE_PRESCALE4 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#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 FALSE
-
-/* 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
-#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)
-
-/* 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, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_RX_DMA_CHN 0x00000310
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C3_TX_DMA_CHN 0x00630000
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_HANDLER Vector1B0
-#define STM32_QUADSPI1_NUMBER 92
-#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_QUADSPI1_DMA_CHN 0x30000000
-
-/* 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 TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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 TRUE
-#define STM32_SPI4_I2S_FULLDUPLEX TRUE
-#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
- STM32_DMA_STREAM_ID_MSK(2, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI4_RX_DMA_CHN 0x00045004
-#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 TRUE
-#define STM32_SPI5_I2S_FULLDUPLEX TRUE
-#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, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_SPI5_TX_DMA_CHN 0x07520000
-
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_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_TIM8 FALSE
-#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_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_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-#endif /* defined(STM32F412xx) */
-
-/*===========================================================================*/
-/* STM32F411xx. */
-/*===========================================================================*/
-
-#if defined(STM32F411xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI FALSE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#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_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT
-#define STM32_TIMPRE_PRESCALE4 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#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 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_GPIOG FALSE
-#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_GPIOHEN)
-
-/* 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) |\
- STM32_DMA_STREAM_ID_MSK(1, 1))
-#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, 1) |\
-+ STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_RX_DMA_CHN 0x00000310
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
-+ STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C3_TX_DMA_CHN 0x00630000
-
-#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 TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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 TRUE
-#define STM32_SPI4_I2S_FULLDUPLEX TRUE
-#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 TRUE
-#define STM32_SPI5_I2S_FULLDUPLEX TRUE
-#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 FALSE
-
-/* 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_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_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-
-#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 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 1
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 3
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-#endif /* defined(STM32F411xx) */
-
-/*===========================================================================*/
-/* STM32F410xx. */
-/*===========================================================================*/
-
-#if defined(STM32F410xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI FALSE
-#define STM32_HAS_RCC_PLLI2S FALSE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#define STM32_HAS_RCC_DCKCFGR2 TRUE
-#define STM32_HAS_RCC_I2SSRC FALSE
-#define STM32_HAS_RCC_I2SPLLSRC FALSE
-#define STM32_HAS_RCC_CK48MSEL FALSE
-#define STM32_RCC_CK48MSEL_USES_I2S FALSE
-#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT
-#define STM32_TIMPRE_PRESCALE4 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_ADC3 FALSE
-#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 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* 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 FALSE
-#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 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#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_GPIOHEN)
-
-/* 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 FALSE
-
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0)) |\
- STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_I2C4_RX_DMA_CHN 0x00002007
-#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) |\
- STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_I2C4_TX_DMA_CHN 0x00040020
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00003200
-
-#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_SPI5 TRUE
-#define STM32_SPI5_SUPPORTS_I2S TRUE
-#define STM32_SPI5_I2S_FULLDUPLEX TRUE
-#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_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_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_TIM9 TRUE
-#define STM32_TIM9_IS_32BITS FALSE
-#define STM32_TIM9_CHANNELS 2
-
-#define STM32_HAS_TIM11 TRUE
-#define STM32_TIM11_IS_32BITS FALSE
-#define STM32_TIM11_CHANNELS 1
-
-#define STM32_HAS_TIM2 FALSE
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_RX_DMA_CHN 0x60400000
-#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6)
-#define STM32_USART2_TX_DMA_CHN 0x04000000
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-
-#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 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-#endif /* defined(STM32F410xx) */
-
-/*===========================================================================*/
-/* STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, STM32F205xx, */
-/* STM32F215xx, STM32F207xx, STM32F217xx. */
-/*===========================================================================*/
-
-#if defined(STM32F40_41xxx) || defined(STM32F2XX)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI FALSE
-#define STM32_HAS_RCC_PLLI2S TRUE
-#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.*/
-#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F205xx) || \
- defined(STM32F215xx)
-#define STM32_HAS_ETH FALSE
-#else
-#define STM32_HAS_ETH TRUE
-#define STM32_ETH_HANDLER Vector134
-#define STM32_ETH_NUMBER 61
-#endif
-
-/* 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
-#define STM32_HAS_GPIOI TRUE
-#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 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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 6
-
-#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 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 1
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 3
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 5
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-#define STM32_FSMC_IS_FMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-#endif /* defined(STM32F40_41xxx) || defined(STM32F2XX) */
-
-/*===========================================================================*/
-/* STM32F401xx. */
-/*===========================================================================*/
-
-#if defined(STM32F401xx)
-
-/* Clock tree attributes.*/
-#define STM32_HAS_RCC_PLLSAI FALSE
-#define STM32_HAS_RCC_PLLI2S FALSE
-#define STM32_HAS_RCC_DCKCFGR TRUE
-#define STM32_HAS_RCC_DCKCFGR2 FALSE
-#define STM32_HAS_RCC_I2SSRC FALSE
-#define STM32_HAS_RCC_I2SPLLSRC FALSE
-#define STM32_HAS_RCC_CK48MSEL FALSE
-#define STM32_RCC_CK48MSEL_USES_I2S FALSE
-#define STM32_TIMPRE_PRESCALE4 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#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 FALSE
-
-/* 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 FALSE
-#define STM32_HAS_GPIOG FALSE
-#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)
-
-/* 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 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* 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_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_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-
-#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 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 1
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 3
-#define STM32_HAS_OTG2 FALSE
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-#endif /* defined(STM32F401xx) */
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32F4xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+#if defined(STM32F469xx) || defined(STM32F479xx)
+#define STM32F469_479xx
+#define STM32F4XX
+
+#elif defined(STM32F446xx)
+#define STM32F4XX
+
+#elif defined(STM32F439xx) || defined(STM32F429xx)
+#define STM32F429_439xx
+#define STM32F4XX
+
+#elif defined(STM32F437xx) || defined(STM32F427xx)
+#define STM32F427_437xx
+#define STM32F4XX
+
+#elif defined(STM32F413xx)
+#define STM32F413xx
+#define STM32F4XX
+
+#elif defined(STM32F412Cx) || defined(STM32F412Rx) || \
+ defined(STM32F412Vx) || defined(STM32F412Zx)
+#define STM32F412xx
+#define STM32F4XX
+
+#elif defined(STM32F411xE)
+#define STM32F411xx
+#define STM32F4XX
+
+#elif defined(STM32F410Cx) || defined(STM32F410Rx) || \
+ defined(STM32F410Tx)
+#define STM32F410xx
+#define STM32F4XX
+
+#elif defined(STM32F405xx) || defined(STM32F415xx) || \
+ defined(STM32F407xx) || defined(STM32F417xx)
+#define STM32F40_41xxx
+#define STM32F4XX
+
+#elif defined(STM32F401xC) || defined(STM32F401xE)
+#define STM32F401xx
+#define STM32F4XX
+
+#elif defined(STM32F205xx) || defined(STM32F215xx) || \
+ defined(STM32F207xx) || defined(STM32F217xx)
+#define STM32F2XX
+
+#else
+#error "STM32F2xx/F4xx 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)
+
+/*===========================================================================*/
+/* STM32F469xx, STM32F479xx. */
+/*===========================================================================*/
+
+#if defined(STM32F469_479xx) || defined(__DOXYGEN__)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI TRUE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#define STM32_HAS_RCC_DCKCFGR2 FALSE
+#define STM32_HAS_RCC_I2SSRC TRUE
+#define STM32_HAS_RCC_I2SPLLSRC FALSE
+#define STM32_HAS_RCC_CK48MSEL TRUE
+#define STM32_RCC_CK48MSEL_USES_I2S FALSE
+#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT
+#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
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ TRUE
+#define STM32_HAS_GPIOK TRUE
+
+#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 | \
+ RCC_AHB1ENR_GPIOJEN | \
+ RCC_AHB1ENR_GPIOKEN)
+
+/* 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 TRUE
+#define STM32_QUADSPI1_HANDLER Vector1AC
+#define STM32_QUADSPI1_NUMBER 91
+#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_QUADSPI1_DMA_CHN 0x30000000
+
+/* 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 TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+#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(STM32F469_479xx) */
+
+/*===========================================================================*/
+/* STM32F446xx. */
+/*===========================================================================*/
+
+#if defined(STM32F446xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI TRUE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#define STM32_HAS_RCC_DCKCFGR2 TRUE
+#define STM32_HAS_RCC_I2SSRC FALSE
+#define STM32_HAS_RCC_I2SPLLSRC FALSE
+#define STM32_HAS_RCC_CK48MSEL TRUE
+#define STM32_RCC_CK48MSEL_USES_I2S FALSE
+#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_P_CLKOUT
+#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 FALSE
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#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)
+
+/* 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 TRUE
+#define STM32_QUADSPI1_HANDLER Vector1B0
+#define STM32_QUADSPI1_NUMBER 92
+#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_QUADSPI1_DMA_CHN 0x30000000
+
+/* 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 TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX 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 FALSE
+#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 FALSE
+#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 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+#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(STM32F446xx) */
+
+/*===========================================================================*/
+/* STM32F439xx, STM32F429xx, STM32F437xx, STM32F427xx. */
+/*===========================================================================*/
+
+#if defined(STM32F429_439xx) || defined(STM32F427_437xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI TRUE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#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
+#define STM32_HAS_GPIOI TRUE
+#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_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 1
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 3
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 5
+
+#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) */
+
+/*===========================================================================*/
+/* STM32F413xx. */
+/*===========================================================================*/
+
+#if defined(STM32F413xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI FALSE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#define STM32_HAS_RCC_DCKCFGR2 TRUE
+#define STM32_HAS_RCC_I2SSRC FALSE
+#define STM32_HAS_RCC_I2SPLLSRC TRUE
+#define STM32_HAS_RCC_CK48MSEL TRUE
+#define STM32_RCC_CK48MSEL_USES_I2S TRUE
+#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT
+#define STM32_TIMPRE_PRESCALE4 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 TRUE
+#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 FALSE
+
+/* 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
+#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)
+
+/* 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, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_RX_DMA_CHN 0x00000310
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C3_TX_DMA_CHN 0x00630000
+
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_SUPPORTS_FMP TRUE
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 3)
+#define STM32_I2C4_RX_DMA_CHN 0x00001000
+#define STM32_I2C4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 1)
+#define STM32_I2C4_TX_DMA_CHN 0x00000020
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_HANDLER Vector1B0
+#define STM32_QUADSPI1_NUMBER 92
+#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_QUADSPI1_DMA_CHN 0x30000000
+
+/* 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 TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SPI1_TX_DMA_CHN 0x00303200
+
+#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 TRUE
+#define STM32_SPI4_I2S_FULLDUPLEX TRUE
+#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI4_RX_DMA_CHN 0x00045004
+#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 TRUE
+#define STM32_SPI5_I2S_FULLDUPLEX TRUE
+#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, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SPI5_TX_DMA_CHN 0x07520000
+
+#define STM32_HAS_SPI6 FALSE
+
+/* 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
+
+#define STM32_HAS_LPTIM1 TRUE
+
+/* 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 0x80000000
+
+#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 TRUE
+#define STM32_UART9_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_UART9_RX_DMA_CHN 0x00000000
+#define STM32_UART9_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0)
+#define STM32_UART9_TX_DMA_CHN 0x00000001
+
+#define STM32_HAS_UART10 TRUE
+#define STM32_UART10_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 0)
+#define STM32_UART10_RX_DMA_CHN 0x00000005
+#define STM32_UART10_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_UART10_TX_DMA_CHN 0x60000000
+
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+#endif /* defined(STM32F413xx) */
+
+/*===========================================================================*/
+/* STM32F412xx. */
+/*===========================================================================*/
+
+#if defined(STM32F412xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI FALSE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#define STM32_HAS_RCC_DCKCFGR2 TRUE
+#define STM32_HAS_RCC_I2SSRC FALSE
+#define STM32_HAS_RCC_I2SPLLSRC TRUE
+#define STM32_HAS_RCC_CK48MSEL TRUE
+#define STM32_RCC_CK48MSEL_USES_I2S TRUE
+#define STM32_PLL48CLK_ALTSRC STM32_PLLI2S_Q_CLKOUT
+#define STM32_TIMPRE_PRESCALE4 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#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 FALSE
+
+/* 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
+#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)
+
+/* 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, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_RX_DMA_CHN 0x00000310
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C3_TX_DMA_CHN 0x00630000
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_HANDLER Vector1B0
+#define STM32_QUADSPI1_NUMBER 92
+#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_QUADSPI1_DMA_CHN 0x30000000
+
+/* 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 TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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 TRUE
+#define STM32_SPI4_I2S_FULLDUPLEX TRUE
+#define STM32_SPI4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI4_RX_DMA_CHN 0x00045004
+#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 TRUE
+#define STM32_SPI5_I2S_FULLDUPLEX TRUE
+#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, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SPI5_TX_DMA_CHN 0x07520000
+
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_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_TIM8 FALSE
+#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_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_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+#endif /* defined(STM32F412xx) */
+
+/*===========================================================================*/
+/* STM32F411xx. */
+/*===========================================================================*/
+
+#if defined(STM32F411xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI FALSE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#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_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT
+#define STM32_TIMPRE_PRESCALE4 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#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 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_GPIOG FALSE
+#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_GPIOHEN)
+
+/* 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) |\
+ STM32_DMA_STREAM_ID_MSK(1, 1))
+#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, 1) |\
++ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_RX_DMA_CHN 0x00000310
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
++ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C3_TX_DMA_CHN 0x00630000
+
+#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 TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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 TRUE
+#define STM32_SPI4_I2S_FULLDUPLEX TRUE
+#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 TRUE
+#define STM32_SPI5_I2S_FULLDUPLEX TRUE
+#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 FALSE
+
+/* 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_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_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+
+#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 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 1
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 3
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+#endif /* defined(STM32F411xx) */
+
+/*===========================================================================*/
+/* STM32F410xx. */
+/*===========================================================================*/
+
+#if defined(STM32F410xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI FALSE
+#define STM32_HAS_RCC_PLLI2S FALSE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#define STM32_HAS_RCC_DCKCFGR2 TRUE
+#define STM32_HAS_RCC_I2SSRC FALSE
+#define STM32_HAS_RCC_I2SPLLSRC FALSE
+#define STM32_HAS_RCC_CK48MSEL FALSE
+#define STM32_RCC_CK48MSEL_USES_I2S FALSE
+#define STM32_PLL48CLK_ALTSRC STM32_PLLSAI_Q_CLKOUT
+#define STM32_TIMPRE_PRESCALE4 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_ADC3 FALSE
+#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 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* 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 FALSE
+#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 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#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_GPIOHEN)
+
+/* 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 FALSE
+
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0)) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_I2C4_RX_DMA_CHN 0x00002007
+#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7)) |\
+ STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_I2C4_TX_DMA_CHN 0x00040020
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00003200
+
+#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_SPI5 TRUE
+#define STM32_SPI5_SUPPORTS_I2S TRUE
+#define STM32_SPI5_I2S_FULLDUPLEX TRUE
+#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_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_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_TIM9 TRUE
+#define STM32_TIM9_IS_32BITS FALSE
+#define STM32_TIM9_CHANNELS 2
+
+#define STM32_HAS_TIM11 TRUE
+#define STM32_TIM11_IS_32BITS FALSE
+#define STM32_TIM11_CHANNELS 1
+
+#define STM32_HAS_TIM2 FALSE
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_RX_DMA_CHN 0x60400000
+#define STM32_USART2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 6)
+#define STM32_USART2_TX_DMA_CHN 0x04000000
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+
+#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 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+#endif /* defined(STM32F410xx) */
+
+/*===========================================================================*/
+/* STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx, STM32F205xx, */
+/* STM32F215xx, STM32F207xx, STM32F217xx. */
+/*===========================================================================*/
+
+#if defined(STM32F40_41xxx) || defined(STM32F2XX)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI FALSE
+#define STM32_HAS_RCC_PLLI2S TRUE
+#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.*/
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F205xx) || \
+ defined(STM32F215xx)
+#define STM32_HAS_ETH FALSE
+#else
+#define STM32_HAS_ETH TRUE
+#define STM32_ETH_HANDLER Vector134
+#define STM32_ETH_NUMBER 61
+#endif
+
+/* 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
+#define STM32_HAS_GPIOI TRUE
+#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 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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 6
+
+#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 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 1
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 3
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 5
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+#define STM32_FSMC_IS_FMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+#endif /* defined(STM32F40_41xxx) || defined(STM32F2XX) */
+
+/*===========================================================================*/
+/* STM32F401xx. */
+/*===========================================================================*/
+
+#if defined(STM32F401xx)
+
+/* Clock tree attributes.*/
+#define STM32_HAS_RCC_PLLSAI FALSE
+#define STM32_HAS_RCC_PLLI2S FALSE
+#define STM32_HAS_RCC_DCKCFGR TRUE
+#define STM32_HAS_RCC_DCKCFGR2 FALSE
+#define STM32_HAS_RCC_I2SSRC FALSE
+#define STM32_HAS_RCC_I2SPLLSRC FALSE
+#define STM32_HAS_RCC_CK48MSEL FALSE
+#define STM32_RCC_CK48MSEL_USES_I2S FALSE
+#define STM32_TIMPRE_PRESCALE4 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#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 FALSE
+
+/* 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 FALSE
+#define STM32_HAS_GPIOG FALSE
+#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)
+
+/* 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 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* 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_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_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+
+#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 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 1
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 3
+#define STM32_HAS_OTG2 FALSE
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+#endif /* defined(STM32F401xx) */
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.c b/os/hal/ports/STM32/STM32F7xx/hal_lld.c
index f57e097bc5..52a35a16da 100644
--- a/os/hal/ports/STM32/STM32F7xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.c
@@ -1,318 +1,319 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..3a9245af91 100644
--- a/os/hal/ports/STM32/STM32F7xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.h
@@ -1,2200 +1,2208 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32F7xx/platform.mk b/os/hal/ports/STM32/STM32F7xx/platform.mk
index cf89bb6c5b..f65bc14487 100644
--- a/os/hal/ports/STM32/STM32F7xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F7xx/platform.mk
@@ -1,49 +1,49 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F7xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F7xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F7xx
-
-# 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/I2Cv2/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/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F7xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F7xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32F7xx
+
+# 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/I2Cv2/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/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/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/STM32F7xx/stm32_isr.c b/os/hal/ports/STM32/STM32F7xx/stm32_isr.c
index f895a57264..1fd78d5f4b 100644
--- a/os/hal/ports/STM32/STM32F7xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32F7xx/stm32_isr.c
@@ -1,176 +1,176 @@
-/*
- 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/stm32_isr.c
- * @brief STM32F7xx ISR handler code.
- *
- * @addtogroup STM32F7xx_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. */
-/*===========================================================================*/
-
-#include "stm32_exti0.inc"
-#include "stm32_exti1.inc"
-#include "stm32_exti2.inc"
-#include "stm32_exti3.inc"
-#include "stm32_exti4.inc"
-#include "stm32_exti5_9.inc"
-#include "stm32_exti10_15.inc"
-#include "stm32_exti16.inc"
-#include "stm32_exti17.inc"
-#include "stm32_exti18.inc"
-#include "stm32_exti19.inc"
-#include "stm32_exti20.inc"
-#include "stm32_exti21.inc"
-#include "stm32_exti22.inc"
-#include "stm32_exti23.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart3.inc"
-#include "stm32_uart4.inc"
-#include "stm32_uart5.inc"
-#include "stm32_usart6.inc"
-#include "stm32_uart7.inc"
-#include "stm32_uart8.inc"
-
-#include "stm32_tim1_9_10_11.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim4.inc"
-#include "stm32_tim5.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim8_12_13_14.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_irq_init();
- exti1_irq_init();
- exti2_irq_init();
- exti3_irq_init();
- exti4_irq_init();
- exti5_9_irq_init();
- exti10_15_irq_init();
- exti16_irq_init();
- exti17_irq_init();
- exti18_irq_init();
- exti19_irq_init();
- exti20_irq_init();
- exti21_irq_init();
- exti22_irq_init();
- exti23_irq_init();
-
- tim1_tim9_tim10_tim11_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim4_irq_init();
- tim5_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim8_tim12_tim13_tim14_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_irq_init();
- uart4_irq_init();
- uart5_irq_init();
- usart6_irq_init();
- uart7_irq_init();
- uart8_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_irq_deinit();
- exti1_irq_deinit();
- exti2_irq_deinit();
- exti3_irq_deinit();
- exti4_irq_deinit();
- exti5_9_irq_deinit();
- exti10_15_irq_deinit();
- exti16_irq_deinit();
- exti17_irq_deinit();
- exti18_irq_deinit();
- exti19_irq_deinit();
- exti20_irq_deinit();
- exti21_irq_deinit();
- exti22_irq_deinit();
- exti23_irq_deinit();
-
- tim1_tim9_tim10_tim11_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim4_irq_deinit();
- tim5_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim8_tim12_tim13_tim14_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_irq_deinit();
- uart4_irq_deinit();
- uart5_irq_deinit();
- usart6_irq_deinit();
- uart7_irq_deinit();
- uart8_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32F7xx ISR handler code.
+ *
+ * @addtogroup STM32F7xx_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. */
+/*===========================================================================*/
+
+#include "stm32_exti0.inc"
+#include "stm32_exti1.inc"
+#include "stm32_exti2.inc"
+#include "stm32_exti3.inc"
+#include "stm32_exti4.inc"
+#include "stm32_exti5_9.inc"
+#include "stm32_exti10_15.inc"
+#include "stm32_exti16.inc"
+#include "stm32_exti17.inc"
+#include "stm32_exti18.inc"
+#include "stm32_exti19.inc"
+#include "stm32_exti20.inc"
+#include "stm32_exti21.inc"
+#include "stm32_exti22.inc"
+#include "stm32_exti23.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart3.inc"
+#include "stm32_uart4.inc"
+#include "stm32_uart5.inc"
+#include "stm32_usart6.inc"
+#include "stm32_uart7.inc"
+#include "stm32_uart8.inc"
+
+#include "stm32_tim1_9_10_11.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim4.inc"
+#include "stm32_tim5.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim8_12_13_14.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_irq_init();
+ exti1_irq_init();
+ exti2_irq_init();
+ exti3_irq_init();
+ exti4_irq_init();
+ exti5_9_irq_init();
+ exti10_15_irq_init();
+ exti16_irq_init();
+ exti17_irq_init();
+ exti18_irq_init();
+ exti19_irq_init();
+ exti20_irq_init();
+ exti21_irq_init();
+ exti22_irq_init();
+ exti23_irq_init();
+
+ tim1_tim9_tim10_tim11_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim4_irq_init();
+ tim5_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim8_tim12_tim13_tim14_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_irq_init();
+ uart4_irq_init();
+ uart5_irq_init();
+ usart6_irq_init();
+ uart7_irq_init();
+ uart8_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_irq_deinit();
+ exti1_irq_deinit();
+ exti2_irq_deinit();
+ exti3_irq_deinit();
+ exti4_irq_deinit();
+ exti5_9_irq_deinit();
+ exti10_15_irq_deinit();
+ exti16_irq_deinit();
+ exti17_irq_deinit();
+ exti18_irq_deinit();
+ exti19_irq_deinit();
+ exti20_irq_deinit();
+ exti21_irq_deinit();
+ exti22_irq_deinit();
+ exti23_irq_deinit();
+
+ tim1_tim9_tim10_tim11_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim4_irq_deinit();
+ tim5_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim8_tim12_tim13_tim14_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_irq_deinit();
+ uart4_irq_deinit();
+ uart5_irq_deinit();
+ usart6_irq_deinit();
+ uart7_irq_deinit();
+ uart8_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_isr.h b/os/hal/ports/STM32/STM32F7xx/stm32_isr.h
index 5b9c222f83..1ed43c388a 100644
--- a/os/hal/ports/STM32/STM32F7xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32F7xx/stm32_isr.h
@@ -1,340 +1,340 @@
-/*
- 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/stm32_isr.h
- * @brief STM32F7xx ISR handler header.
- *
- * @addtogroup STM32F7xx_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
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC units.
- */
-#define STM32_ADC_HANDLER Vector88
-
-#define STM32_ADC_NUMBER 18
-
-/*
- * 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 Vector1E0
-#define STM32_CAN3_RX0_HANDLER Vector1E4
-#define STM32_CAN3_RX1_HANDLER Vector1E8
-#define STM32_CAN3_SCE_HANDLER Vector1EC
-
-#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 104
-#define STM32_CAN3_RX0_NUMBER 105
-#define STM32_CAN3_RX1_NUMBER 106
-#define STM32_CAN3_SCE_NUMBER 107
-
-/*
- * DMA units.
- */
-#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_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_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_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
-
-/*
- * 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_EXTI23_HANDLER Vector1B4 /* LPTIM1 */
-
-#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
-#define STM32_EXTI23_NUMBER 93
-
-/*
- * 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_I2C4_EVENT_HANDLER Vector1BC
-#define STM32_I2C4_ERROR_HANDLER Vector1C0
-
-#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
-#define STM32_I2C4_EVENT_NUMBER 95
-#define STM32_I2C4_ERROR_NUMBER 96
-
-/*
- * ETH units.
- */
-#define STM32_ETH_HANDLER Vector134
-
-#define STM32_ETH_NUMBER 61
-
-/*
- * QUADSPI units.
- */
-#define STM32_QUADSPI1_HANDLER Vector1B0
-
-#define STM32_QUADSPI1_NUMBER 92
-
-/*
- * SDMMC units.
- */
-#define STM32_SDMMC1_HANDLER Vector104
-#define STM32_SDMMC2_HANDLER Vector1DC
-
-#define STM32_SDMMC1_NUMBER 49
-#define STM32_SDMMC2_NUMBER 103
-
-/*
- * 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
-
-/*
- * USART/UART 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_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
-
-/*
- * USB/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
-
-/*
- * FSMC units.
- */
-#define STM32_FSMC_HANDLER Vector100
-
-#define STM32_FSMC_NUMBER 48
-
-/*
- * LTDC units.
- */
-#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 units.
- */
-#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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32F7xx ISR handler header.
+ *
+ * @addtogroup STM32F7xx_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
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC units.
+ */
+#define STM32_ADC_HANDLER Vector88
+
+#define STM32_ADC_NUMBER 18
+
+/*
+ * 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 Vector1E0
+#define STM32_CAN3_RX0_HANDLER Vector1E4
+#define STM32_CAN3_RX1_HANDLER Vector1E8
+#define STM32_CAN3_SCE_HANDLER Vector1EC
+
+#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 104
+#define STM32_CAN3_RX0_NUMBER 105
+#define STM32_CAN3_RX1_NUMBER 106
+#define STM32_CAN3_SCE_NUMBER 107
+
+/*
+ * DMA units.
+ */
+#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_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_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_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
+
+/*
+ * 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_EXTI23_HANDLER Vector1B4 /* LPTIM1 */
+
+#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
+#define STM32_EXTI23_NUMBER 93
+
+/*
+ * 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_I2C4_EVENT_HANDLER Vector1BC
+#define STM32_I2C4_ERROR_HANDLER Vector1C0
+
+#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
+#define STM32_I2C4_EVENT_NUMBER 95
+#define STM32_I2C4_ERROR_NUMBER 96
+
+/*
+ * ETH units.
+ */
+#define STM32_ETH_HANDLER Vector134
+
+#define STM32_ETH_NUMBER 61
+
+/*
+ * QUADSPI units.
+ */
+#define STM32_QUADSPI1_HANDLER Vector1B0
+
+#define STM32_QUADSPI1_NUMBER 92
+
+/*
+ * SDMMC units.
+ */
+#define STM32_SDMMC1_HANDLER Vector104
+#define STM32_SDMMC2_HANDLER Vector1DC
+
+#define STM32_SDMMC1_NUMBER 49
+#define STM32_SDMMC2_NUMBER 103
+
+/*
+ * 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
+
+/*
+ * USART/UART 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_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
+
+/*
+ * USB/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
+
+/*
+ * FSMC units.
+ */
+#define STM32_FSMC_HANDLER Vector100
+
+#define STM32_FSMC_NUMBER 48
+
+/*
+ * LTDC units.
+ */
+#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 units.
+ */
+#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/STM32/STM32F7xx/stm32_rcc.h b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h
index a303e04f42..daa5162a2c 100644
--- a/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32F7xx/stm32_rcc.h
@@ -1,1700 +1,1700 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32f7xx.h.
- *
- * @addtogroup STM32F7xx_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
- * @param[in] lp low power enable flag
- *
- * @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 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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-
-/**
- * @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 Resets the ADC2 peripheral.
- *
- * @api
- */
-#define rccResetADC2() rccResetAPB2(RCC_APB2RSTR_ADC2RST)
-
-/**
- * @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)
-
-/**
- * @brief Resets the ADC3 peripheral.
- *
- * @api
- */
-#define rccResetADC3() rccResetAPB2(RCC_APB2RSTR_ADC3RST)
-/** @} */
-
-/**
- * @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
- */
-#define rccEnableBKPSRAM(lp) rccEnableAHB1(RCC_AHB1ENR_BKPSRAMEN, lp)
-
-/**
- * @brief Disables the BKPSRAM peripheral clock.
- *
- * @api
- */
-#define rccDisableBKPSRAM() rccDisableAHB1(RCC_AHB1ENR_BKPSRAMEN)
-/** @} */
-
-/**
- * @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.
- *
- * @api
- */
-#define rccEnableETH(lp) rccEnableAHB1(RCC_AHB1ENR_ETHMACEN | \
- RCC_AHB1ENR_ETHMACTXEN | \
- RCC_AHB1ENR_ETHMACRXEN, lp)
-
-/**
- * @brief Disables the ETH peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @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.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C4(lp) rccEnableAPB1(RCC_APB1ENR_I2C4EN, lp)
-
-/**
- * @brief Disables the I2C4 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C4() rccDisableAPB1(RCC_APB1ENR_I2C4EN)
-
-/**
- * @brief Resets the I2C4 peripheral.
- *
- * @api
- */
-#define rccResetI2C4() rccResetAPB1(RCC_APB1RSTR_I2C4RST)
-/** @} */
-
-/**
- * @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) rccEnableAHB1(RCC_AHB1ENR_OTGHSULPIEN, lp)
-
-/**
- * @brief Disables the OTG_HS peripheral clock.
- *
- * @api
- */
-#define rccDisableOTG_HSULPI() rccDisableAHB1(RCC_AHB1ENR_OTGHSULPIEN)
-/** @} */
-
-/**
- * @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 RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
-/** @} */
-
-/**
- * @name SDMMC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDMMC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp)
-
-/**
- * @brief Disables the SDMMC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC1() rccDisableAPB2(RCC_APB2ENR_SDMMC1EN)
-
-/**
- * @brief Resets the SDMMC1 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST)
-
-/**
- * @brief Enables the SDMMC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC2(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC2EN, lp)
-
-/**
- * @brief Disables the SDMMC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC2() rccDisableAPB2(RCC_APB2ENR_SDMMC2EN)
-
-/**
- * @brief Resets the SDMMC2 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC2() rccResetAPB2(RCC_APB2RSTR_SDMMC2RST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @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 HASH peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRYP peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRYP(lp) rccEnableAHB2(RCC_AHB2ENR_CRYPEN, lp)
-
-/**
- * @brief Disables the CRYP peripheral clock.
- *
- * @api
- */
-#define rccDisableCRYP() rccDisableAHB2(RCC_AHB2ENR_CRYPEN)
-
-/**
- * @brief Resets the CRYP peripheral.
- *
- * @api
- */
-#define rccResetCRYP() rccResetAHB2(RCC_AHB2RSTR_CRYPRST)
-/** @} */
-
-/**
- * @name HASH peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the HASH peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableHASH(lp) rccEnableAHB2(RCC_AHB2ENR_HASHEN, lp)
-
-/**
- * @brief Disables the HASH peripheral clock.
- *
- * @api
- */
-#define rccDisableHASH() rccDisableAHB2(RCC_AHB2ENR_HASHEN)
-
-/**
- * @brief Resets the HASH peripheral.
- *
- * @api
- */
-#define rccResetHASH() rccResetAHB2(RCC_AHB2RSTR_HASHRST)
-/** @} */
-
-/**
- * @name FSMC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FSMC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#if defined(STM32_FSMC_IS_FMC)
- #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
-#else
- #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FSMCEN, lp)
-#endif
-
-/**
- * @brief Disables the FSMC peripheral clock.
- *
- * @api
- */
-#if defined(STM32_FSMC_IS_FMC)
- #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
-#else
- #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FSMCEN)
-#endif
-
-/**
- * @brief Resets the FSMC peripheral.
- *
- * @api
- */
-#if defined(STM32_FSMC_IS_FMC)
- #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
-#else
- #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FSMCRST)
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32f7xx.h.
+ *
+ * @addtogroup STM32F7xx_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
+ * @param[in] lp low power enable flag
+ *
+ * @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 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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+
+/**
+ * @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 Resets the ADC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC2() rccResetAPB2(RCC_APB2RSTR_ADC2RST)
+
+/**
+ * @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)
+
+/**
+ * @brief Resets the ADC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC3() rccResetAPB2(RCC_APB2RSTR_ADC3RST)
+/** @} */
+
+/**
+ * @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
+ */
+#define rccEnableBKPSRAM(lp) rccEnableAHB1(RCC_AHB1ENR_BKPSRAMEN, lp)
+
+/**
+ * @brief Disables the BKPSRAM peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableBKPSRAM() rccDisableAHB1(RCC_AHB1ENR_BKPSRAMEN)
+/** @} */
+
+/**
+ * @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.
+ *
+ * @api
+ */
+#define rccEnableETH(lp) rccEnableAHB1(RCC_AHB1ENR_ETHMACEN | \
+ RCC_AHB1ENR_ETHMACTXEN | \
+ RCC_AHB1ENR_ETHMACRXEN, lp)
+
+/**
+ * @brief Disables the ETH peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @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.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C4(lp) rccEnableAPB1(RCC_APB1ENR_I2C4EN, lp)
+
+/**
+ * @brief Disables the I2C4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C4() rccDisableAPB1(RCC_APB1ENR_I2C4EN)
+
+/**
+ * @brief Resets the I2C4 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C4() rccResetAPB1(RCC_APB1RSTR_I2C4RST)
+/** @} */
+
+/**
+ * @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) rccEnableAHB1(RCC_AHB1ENR_OTGHSULPIEN, lp)
+
+/**
+ * @brief Disables the OTG_HS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableOTG_HSULPI() rccDisableAHB1(RCC_AHB1ENR_OTGHSULPIEN)
+/** @} */
+
+/**
+ * @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 RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
+/** @} */
+
+/**
+ * @name SDMMC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDMMC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp)
+
+/**
+ * @brief Disables the SDMMC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC1() rccDisableAPB2(RCC_APB2ENR_SDMMC1EN)
+
+/**
+ * @brief Resets the SDMMC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST)
+
+/**
+ * @brief Enables the SDMMC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC2(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC2EN, lp)
+
+/**
+ * @brief Disables the SDMMC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC2() rccDisableAPB2(RCC_APB2ENR_SDMMC2EN)
+
+/**
+ * @brief Resets the SDMMC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC2() rccResetAPB2(RCC_APB2RSTR_SDMMC2RST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @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 HASH peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRYP peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRYP(lp) rccEnableAHB2(RCC_AHB2ENR_CRYPEN, lp)
+
+/**
+ * @brief Disables the CRYP peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRYP() rccDisableAHB2(RCC_AHB2ENR_CRYPEN)
+
+/**
+ * @brief Resets the CRYP peripheral.
+ *
+ * @api
+ */
+#define rccResetCRYP() rccResetAHB2(RCC_AHB2RSTR_CRYPRST)
+/** @} */
+
+/**
+ * @name HASH peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the HASH peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableHASH(lp) rccEnableAHB2(RCC_AHB2ENR_HASHEN, lp)
+
+/**
+ * @brief Disables the HASH peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableHASH() rccDisableAHB2(RCC_AHB2ENR_HASHEN)
+
+/**
+ * @brief Resets the HASH peripheral.
+ *
+ * @api
+ */
+#define rccResetHASH() rccResetAHB2(RCC_AHB2RSTR_HASHRST)
+/** @} */
+
+/**
+ * @name FSMC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FSMC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#if defined(STM32_FSMC_IS_FMC)
+ #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
+#else
+ #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FSMCEN, lp)
+#endif
+
+/**
+ * @brief Disables the FSMC peripheral clock.
+ *
+ * @api
+ */
+#if defined(STM32_FSMC_IS_FMC)
+ #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
+#else
+ #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FSMCEN)
+#endif
+
+/**
+ * @brief Resets the FSMC peripheral.
+ *
+ * @api
+ */
+#if defined(STM32_FSMC_IS_FMC)
+ #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
+#else
+ #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FSMCRST)
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h
index e67e7372fb..0928be4e22 100644
--- a/os/hal/ports/STM32/STM32F7xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F7xx/stm32_registry.h
@@ -1,1107 +1,1107 @@
-/*
- 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/stm32_registry.h
- * @brief STM32F7xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32F7xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 128
-#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)
-
-#if defined(STM32F732xx) || defined(STM32F733xx) || defined(STM32F756xx) || \
- defined(STM32F777xx) || defined(STM32F779xx) || defined(__DOXYGEN__)
-#define STM32_HAS_HASH1 TRUE
-#define STM32_HAS_CRYP1 TRUE
-#define STM32_HASH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_HASH1_DMA_CHN 0x20000000
-#define STM32_CRYP1_IN_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6)
-#define STM32_CRYP1_IN_DMA_CHN 0x02000000
-#define STM32_CRYP1_OUT_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5)
-#define STM32_CRYP1_OUT_DMA_CHN 0x00200000
-
-#else /* Devices without cryp nor hash.*/
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-/*===========================================================================*/
-/* STM32F722xx, STM32F723xx, STM32F732xx, STM32F733xx. */
-/*===========================================================================*/
-#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F732xx) || \
- defined(STM32F733xx) || defined(__DOXYGEN__)
-/* ADC attributes.*/
-#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_CAN_MAX_FILTERS 28
-
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* 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 TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 TRUE
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 24
-#define STM32_EXTI_IMR1_MASK 0xFF000000
-
-/* 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
-#define STM32_HAS_GPIOI TRUE
-#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, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_RX_DMA_CHN 0x00000310
-#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 TRUE
-#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_QUADSPI1_DMA_CHN 0x30000000
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_HAS_INTERRUPTS FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000
-
-#define STM32_HAS_SDMMC2 TRUE
-#define STM32_SDC_SDMMC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SDC_SDMMC2_DMA_CHN 0x00B0000B
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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_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_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 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#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_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 8
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* 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
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32F722xx) || defined(STM32F723xx) ||
- defined(STM32F732xx) || defined(STM32F733xx) */
-
-/*===========================================================================*/
-/* STM32F745xx, STM32F746xx, STM32F756xx. */
-/*===========================================================================*/
-#if defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F756xx) || \
- defined(__DOXYGEN__)
-/* ADC attributes.*/
-#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_CAN_MAX_FILTERS 28
-#define STM32_CAN3_MAX_FILTERS 14
-
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 TRUE
-#define STM32_HAS_CAN3 TRUE
-
-/* 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 TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 TRUE
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH TRUE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 24
-#define STM32_EXTI_IMR1_MASK 0xFF000000
-
-/* 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
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ TRUE
-#define STM32_HAS_GPIOK TRUE
-#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 | \
- RCC_AHB1ENR_GPIOJEN | \
- RCC_AHB1ENR_GPIOKEN)
-
-/* 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, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_RX_DMA_CHN 0x00000310
-#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C3_TX_DMA_CHN 0x00030000
-
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
-#define STM32_I2C4_RX_DMA_CHN 0x00000200
-#define STM32_I2C4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C4_TX_DMA_CHN 0x00200000
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
-#define STM32_QUADSPI1_DMA_CHN 0x30000000
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_HAS_INTERRUPTS FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000
-
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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_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_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_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 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#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_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 8
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* 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
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F756xx) */
-
-/*===========================================================================*/
-/* STM32F765xx, STM32F767xx, STM32F769xx, STM32F777xx, STM32F779xx. */
-/*===========================================================================*/
-#if defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || \
- defined(STM32F777xx) || defined(STM32F779xx) || \
- defined(__DOXYGEN__)
-/* ADC attributes.*/
-#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_CAN_MAX_FILTERS 28
-#define STM32_CAN3_MAX_FILTERS 14
-
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 TRUE
-#define STM32_HAS_CAN3 TRUE
-
-/* 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 TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 TRUE
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH TRUE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 24
-#define STM32_EXTI_IMR1_MASK 0xFF000000
-
-/* 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
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ TRUE
-#define STM32_HAS_GPIOK TRUE
-#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 | \
- RCC_AHB1ENR_GPIOJEN | \
- RCC_AHB1ENR_GPIOKEN)
-
-/* 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, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C2_TX_DMA_CHN 0x70080000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_RX_DMA_CHN 0x00000310
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_I2C3_TX_DMA_CHN 0x00030008
-
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 1))
-#define STM32_I2C4_RX_DMA_CHN 0x00000280
-#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C4_TX_DMA_CHN 0x08200000
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_QUADSPI1_DMA_CHN 0x30000B00
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_HAS_INTERRUPTS FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000
-
-#define STM32_HAS_SDMMC2 TRUE
-#define STM32_SDC_SDMMC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SDC_SDMMC2_DMA_CHN 0x00B0000B
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-#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, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI2_RX_DMA_CHN 0x00000090
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_TX_DMA_CHN 0x09000000
-
-#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_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, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI4_TX_DMA_CHN 0x00050940
-
-#define STM32_HAS_SPI5 TRUE
-#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 0x00902000
-#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_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 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#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_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 8
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* 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
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) ||
- defined(STM32F777xx) || defined(STM32F779xx) */
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32F7xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32F7xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
+#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)
+
+#if defined(STM32F732xx) || defined(STM32F733xx) || defined(STM32F756xx) || \
+ defined(STM32F777xx) || defined(STM32F779xx) || defined(__DOXYGEN__)
+#define STM32_HAS_HASH1 TRUE
+#define STM32_HAS_CRYP1 TRUE
+#define STM32_HASH1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_HASH1_DMA_CHN 0x20000000
+#define STM32_CRYP1_IN_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 6)
+#define STM32_CRYP1_IN_DMA_CHN 0x02000000
+#define STM32_CRYP1_OUT_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5)
+#define STM32_CRYP1_OUT_DMA_CHN 0x00200000
+
+#else /* Devices without cryp nor hash.*/
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+/*===========================================================================*/
+/* STM32F722xx, STM32F723xx, STM32F732xx, STM32F733xx. */
+/*===========================================================================*/
+#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F732xx) || \
+ defined(STM32F733xx) || defined(__DOXYGEN__)
+/* ADC attributes.*/
+#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_CAN_MAX_FILTERS 28
+
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* 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 TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+
+#define STM32_HAS_DMA1 TRUE
+#define STM32_HAS_DMA2 TRUE
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 24
+#define STM32_EXTI_IMR1_MASK 0xFF000000
+
+/* 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
+#define STM32_HAS_GPIOI TRUE
+#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, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_RX_DMA_CHN 0x00000310
+#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 TRUE
+#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_QUADSPI1_DMA_CHN 0x30000000
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_HAS_INTERRUPTS FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000
+
+#define STM32_HAS_SDMMC2 TRUE
+#define STM32_SDC_SDMMC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SDC_SDMMC2_DMA_CHN 0x00B0000B
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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_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_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 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#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_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 8
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* 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
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32F722xx) || defined(STM32F723xx) ||
+ defined(STM32F732xx) || defined(STM32F733xx) */
+
+/*===========================================================================*/
+/* STM32F745xx, STM32F746xx, STM32F756xx. */
+/*===========================================================================*/
+#if defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F756xx) || \
+ defined(__DOXYGEN__)
+/* ADC attributes.*/
+#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_CAN_MAX_FILTERS 28
+#define STM32_CAN3_MAX_FILTERS 14
+
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 TRUE
+
+/* 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 TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+
+#define STM32_HAS_DMA1 TRUE
+#define STM32_HAS_DMA2 TRUE
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH TRUE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 24
+#define STM32_EXTI_IMR1_MASK 0xFF000000
+
+/* 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
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ TRUE
+#define STM32_HAS_GPIOK TRUE
+#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 | \
+ RCC_AHB1ENR_GPIOJEN | \
+ RCC_AHB1ENR_GPIOKEN)
+
+/* 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, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_RX_DMA_CHN 0x00000310
+#define STM32_I2C3_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C3_TX_DMA_CHN 0x00030000
+
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 2)
+#define STM32_I2C4_RX_DMA_CHN 0x00000200
+#define STM32_I2C4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C4_TX_DMA_CHN 0x00200000
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 7)
+#define STM32_QUADSPI1_DMA_CHN 0x30000000
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_HAS_INTERRUPTS FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000
+
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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_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_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_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 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#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_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 8
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* 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
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F756xx) */
+
+/*===========================================================================*/
+/* STM32F765xx, STM32F767xx, STM32F769xx, STM32F777xx, STM32F779xx. */
+/*===========================================================================*/
+#if defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || \
+ defined(STM32F777xx) || defined(STM32F779xx) || \
+ defined(__DOXYGEN__)
+/* ADC attributes.*/
+#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_CAN_MAX_FILTERS 28
+#define STM32_CAN3_MAX_FILTERS 14
+
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 TRUE
+
+/* 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 TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+
+#define STM32_HAS_DMA1 TRUE
+#define STM32_HAS_DMA2 TRUE
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH TRUE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 24
+#define STM32_EXTI_IMR1_MASK 0xFF000000
+
+/* 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
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ TRUE
+#define STM32_HAS_GPIOK TRUE
+#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 | \
+ RCC_AHB1ENR_GPIOJEN | \
+ RCC_AHB1ENR_GPIOKEN)
+
+/* 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, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C2_TX_DMA_CHN 0x70080000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_RX_DMA_CHN 0x00000310
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_I2C3_TX_DMA_CHN 0x00030008
+
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 1))
+#define STM32_I2C4_RX_DMA_CHN 0x00000280
+#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C4_TX_DMA_CHN 0x08200000
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_QUADSPI1_DMA_CHN 0x30000B00
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_HAS_INTERRUPTS FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x04004000
+
+#define STM32_HAS_SDMMC2 TRUE
+#define STM32_SDC_SDMMC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 0) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SDC_SDMMC2_DMA_CHN 0x00B0000B
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+#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, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI2_RX_DMA_CHN 0x00000090
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_TX_DMA_CHN 0x09000000
+
+#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_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, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI4_TX_DMA_CHN 0x00050940
+
+#define STM32_HAS_SPI5 TRUE
+#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 0x00902000
+#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_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 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#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_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 8
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* 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
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) ||
+ defined(STM32F777xx) || defined(STM32F779xx) */
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.c b/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.c
index 20af8885e7..22784ecc8a 100644
--- a/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.c
+++ b/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.c
@@ -1,608 +1,608 @@
-/*
- 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 STM32G07/8nxx 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 8U
-#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
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief EFL1 driver identifier.
- */
-EFlashDriver EFLD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/* The descriptor for 64K devices. */
-static const flash_descriptor_t efl_lld_size1[STM32_FLASH_NUMBER_OF_BANKS] = {
- { /* Bank 1. */
- .attributes = FLASH_ATTR_ERASED_IS_ONE |
- FLASH_ATTR_MEMORY_MAPPED |
- FLASH_ATTR_ECC_CAPABLE |
- FLASH_ATTR_ECC_ZERO_LINE_CAPABLE,
- .page_size = STM32_FLASH_LINE_SIZE,
- .sectors_count = STM32_FLASH_SECTORS_TOTAL_64K,
- .sectors = NULL,
- .sectors_size = STM32_FLASH_SECTOR_SIZE_64K,
- .address = (uint8_t *)FLASH_BASE,
- .size = STM32_FLASH_SIZE_64K * STM32_FLASH_SIZE_SCALE
- }
-};
-
-/* The descriptor for 128K devices. */
-static const flash_descriptor_t efl_lld_size2[STM32_FLASH_NUMBER_OF_BANKS] = {
- { /* Bank 1. */
- .attributes = FLASH_ATTR_ERASED_IS_ONE |
- FLASH_ATTR_MEMORY_MAPPED |
- FLASH_ATTR_ECC_CAPABLE |
- FLASH_ATTR_ECC_ZERO_LINE_CAPABLE,
- .page_size = STM32_FLASH_LINE_SIZE,
- .sectors_count = STM32_FLASH_SECTORS_TOTAL_128K,
- .sectors = NULL,
- .sectors_size = STM32_FLASH_SECTOR_SIZE_128K,
- .address = (uint8_t *)FLASH_BASE,
- .size = STM32_FLASH_SIZE_128K * 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
- }
-};
-
-/*===========================================================================*/
-/* 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) {
-
- 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_BSY1) != 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
-#error "Device settings incorrectly configured - single bank mode only supported"
-#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 & (FLASH_SR_FASTERR |
- FLASH_SR_MISERR |
- FLASH_SR_SIZERR)) == 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_PROGERR | 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);
-
- /* Checking for errors after reading.*/
- if ((devp->flash->SR & FLASH_SR_RDERR) != 0U) {
- err = FLASH_ERROR_READ;
- }
-
- /* Ready state again.*/
- devp->state = FLASH_READY;
-
- return err;
-
-}
-
-/**
- * @brief Program operation.
- * @note The device supports ECC, it is only possible to write erased
- * pages once except when writing all zeroes.
- *
- * @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;
-
- union {
- uint32_t w[STM32_FLASH_LINE_SIZE / sizeof (uint32_t)];
- uint8_t b[STM32_FLASH_LINE_SIZE / sizeof (uint8_t)];
- } line;
-
- /* Unwritten bytes are initialized to all ones.*/
- line.w[0] = 0xFFFFFFFFU;
- line.w[1] = 0xFFFFFFFFU;
-
- /* Programming address aligned to flash lines.*/
- address = (volatile uint32_t *)(bank->address +
- (offset & ~STM32_FLASH_LINE_MASK));
-
- /* Copying data inside the prepared line.*/
- do {
- line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
- offset++;
- n--;
- pp++;
- }
- while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
-
- /* Programming line.*/
- address[0] = line.w[0];
- address[1] = line.w[1];
- 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 bank 2 if it is present. Bank 1 is not
- * allowed since it is normally where the primary program is located.
- * Pages on bank 1 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);
-
- 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 page erase.*/
- devp->flash->CR |= FLASH_CR_PER;
-
-#if defined(FLASH_CR_BKER)
- /* If dual bank is active then setup relevant bank. */
- if (stm32_flash_dual_bank(devp)) {
- if (sector < (bank->sectors_count / 2)) {
- /* First bank.*/
- devp->flash->CR &= ~FLASH_CR_BKER;
- }
- else {
- /* Second bank. Adjust sector index. */
- sector -= (bank->sectors_count / 2);
- devp->flash->CR |= FLASH_CR_BKER;
- }
- }
-#endif
-
- /* Mask off the page selection bits.*/
- devp->flash->CR &= ~FLASH_CR_PNB;
-
- /* Set the page selection bits.*/
- devp->flash->CR |= sector << FLASH_CR_PNB_Pos;
-
- /* Start the erase.*/
- devp->flash->CR |= FLASH_CR_STRT;
-
- return FLASH_NO_ERROR;
-}
-
-/**
- * @brief Queries the driver for erase operation progress.
- *
- * @param[in] ip 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_BSY1) == 0U) {
-
- /* Disabling the various erase control bits.*/
- devp->flash->CR &= ~(FLASH_CR_MER1 |
-#if defined(FLASH_CR_MER2)
- FLASH_CR_MER2 |
-#endif
- FLASH_CR_PER);
-
- /* 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 selected 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 */
-
-/** @} */
+/*
+ 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 STM32G07/8nxx 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 8U
+#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
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EFL1 driver identifier.
+ */
+EFlashDriver EFLD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/* The descriptor for 64K devices. */
+static const flash_descriptor_t efl_lld_size1[STM32_FLASH_NUMBER_OF_BANKS] = {
+ { /* Bank 1. */
+ .attributes = FLASH_ATTR_ERASED_IS_ONE |
+ FLASH_ATTR_MEMORY_MAPPED |
+ FLASH_ATTR_ECC_CAPABLE |
+ FLASH_ATTR_ECC_ZERO_LINE_CAPABLE,
+ .page_size = STM32_FLASH_LINE_SIZE,
+ .sectors_count = STM32_FLASH_SECTORS_TOTAL_64K,
+ .sectors = NULL,
+ .sectors_size = STM32_FLASH_SECTOR_SIZE_64K,
+ .address = (uint8_t *)FLASH_BASE,
+ .size = STM32_FLASH_SIZE_64K * STM32_FLASH_SIZE_SCALE
+ }
+};
+
+/* The descriptor for 128K devices. */
+static const flash_descriptor_t efl_lld_size2[STM32_FLASH_NUMBER_OF_BANKS] = {
+ { /* Bank 1. */
+ .attributes = FLASH_ATTR_ERASED_IS_ONE |
+ FLASH_ATTR_MEMORY_MAPPED |
+ FLASH_ATTR_ECC_CAPABLE |
+ FLASH_ATTR_ECC_ZERO_LINE_CAPABLE,
+ .page_size = STM32_FLASH_LINE_SIZE,
+ .sectors_count = STM32_FLASH_SECTORS_TOTAL_128K,
+ .sectors = NULL,
+ .sectors_size = STM32_FLASH_SECTOR_SIZE_128K,
+ .address = (uint8_t *)FLASH_BASE,
+ .size = STM32_FLASH_SIZE_128K * 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
+ }
+};
+
+/*===========================================================================*/
+/* 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) {
+
+ 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_BSY1) != 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
+#error "Device settings incorrectly configured - single bank mode only supported"
+#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 & (FLASH_SR_FASTERR |
+ FLASH_SR_MISERR |
+ FLASH_SR_SIZERR)) == 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_PROGERR | 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);
+
+ /* Checking for errors after reading.*/
+ if ((devp->flash->SR & FLASH_SR_RDERR) != 0U) {
+ err = FLASH_ERROR_READ;
+ }
+
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ return err;
+
+}
+
+/**
+ * @brief Program operation.
+ * @note The device supports ECC, it is only possible to write erased
+ * pages once except when writing all zeroes.
+ *
+ * @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;
+
+ union {
+ uint32_t w[STM32_FLASH_LINE_SIZE / sizeof (uint32_t)];
+ uint8_t b[STM32_FLASH_LINE_SIZE / sizeof (uint8_t)];
+ } line;
+
+ /* Unwritten bytes are initialized to all ones.*/
+ line.w[0] = 0xFFFFFFFFU;
+ line.w[1] = 0xFFFFFFFFU;
+
+ /* Programming address aligned to flash lines.*/
+ address = (volatile uint32_t *)(bank->address +
+ (offset & ~STM32_FLASH_LINE_MASK));
+
+ /* Copying data inside the prepared line.*/
+ do {
+ line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
+ offset++;
+ n--;
+ pp++;
+ }
+ while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
+
+ /* Programming line.*/
+ address[0] = line.w[0];
+ address[1] = line.w[1];
+ 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 bank 2 if it is present. Bank 1 is not
+ * allowed since it is normally where the primary program is located.
+ * Pages on bank 1 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);
+
+ 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 page erase.*/
+ devp->flash->CR |= FLASH_CR_PER;
+
+#if defined(FLASH_CR_BKER)
+ /* If dual bank is active then setup relevant bank. */
+ if (stm32_flash_dual_bank(devp)) {
+ if (sector < (bank->sectors_count / 2)) {
+ /* First bank.*/
+ devp->flash->CR &= ~FLASH_CR_BKER;
+ }
+ else {
+ /* Second bank. Adjust sector index. */
+ sector -= (bank->sectors_count / 2);
+ devp->flash->CR |= FLASH_CR_BKER;
+ }
+ }
+#endif
+
+ /* Mask off the page selection bits.*/
+ devp->flash->CR &= ~FLASH_CR_PNB;
+
+ /* Set the page selection bits.*/
+ devp->flash->CR |= sector << FLASH_CR_PNB_Pos;
+
+ /* Start the erase.*/
+ devp->flash->CR |= FLASH_CR_STRT;
+
+ return FLASH_NO_ERROR;
+}
+
+/**
+ * @brief Queries the driver for erase operation progress.
+ *
+ * @param[in] ip 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_BSY1) == 0U) {
+
+ /* Disabling the various erase control bits.*/
+ devp->flash->CR &= ~(FLASH_CR_MER1 |
+#if defined(FLASH_CR_MER2)
+ FLASH_CR_MER2 |
+#endif
+ FLASH_CR_PER);
+
+ /* 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 selected 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/STM32/STM32G0xx/hal_efl_lld.h b/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.h
index 19f4b83cab..1b647abd22 100644
--- a/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.h
+++ b/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.h
@@ -1,144 +1,144 @@
-/*
- 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 STM32G07/8nxx 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 STM32G0xx 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(STM32G070xx) || defined(STM32G071xx) || \
- defined(STM32G081xx) || \
- defined(__DOXYGEN__)
-
-/* Flash size register. */
-#define STM32_FLASH_SIZE_REGISTER 0x1FFF75E0
-#define STM32_FLASH_SIZE_SCALE 1024U
-
-/*
- * Flash size is organised as 32 or 64 x 2K pages.
- *
- */
-#define STM32_FLASH_SIZE_64K 64U
-#define STM32_FLASH_SIZE_128K 128U
-#define STM32_FLASH_SECTORS_TOTAL_64K 32
-#define STM32_FLASH_SECTORS_TOTAL_128K 64
-
-/* 64K flash.*/
-#define STM32_FLASH_SECTOR_SIZE_64K ((STM32_FLASH_SIZE_64K \
- * STM32_FLASH_SIZE_SCALE) \
- / STM32_FLASH_SECTORS_TOTAL_64K)
-/* 128K flash.*/
-#define STM32_FLASH_SECTOR_SIZE_128K ((STM32_FLASH_SIZE_128K \
- * STM32_FLASH_SIZE_SCALE) \
- / STM32_FLASH_SECTORS_TOTAL_128K)
-
-#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 */
-
-/** @} */
+/*
+ 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 STM32G07/8nxx 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 STM32G0xx 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(STM32G070xx) || defined(STM32G071xx) || \
+ defined(STM32G081xx) || \
+ defined(__DOXYGEN__)
+
+/* Flash size register. */
+#define STM32_FLASH_SIZE_REGISTER 0x1FFF75E0
+#define STM32_FLASH_SIZE_SCALE 1024U
+
+/*
+ * Flash size is organised as 32 or 64 x 2K pages.
+ *
+ */
+#define STM32_FLASH_SIZE_64K 64U
+#define STM32_FLASH_SIZE_128K 128U
+#define STM32_FLASH_SECTORS_TOTAL_64K 32
+#define STM32_FLASH_SECTORS_TOTAL_128K 64
+
+/* 64K flash.*/
+#define STM32_FLASH_SECTOR_SIZE_64K ((STM32_FLASH_SIZE_64K \
+ * STM32_FLASH_SIZE_SCALE) \
+ / STM32_FLASH_SECTORS_TOTAL_64K)
+/* 128K flash.*/
+#define STM32_FLASH_SECTOR_SIZE_128K ((STM32_FLASH_SIZE_128K \
+ * STM32_FLASH_SIZE_SCALE) \
+ / STM32_FLASH_SECTORS_TOTAL_128K)
+
+#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/STM32/STM32G0xx/hal_lld.c b/os/hal/ports/STM32/STM32G0xx/hal_lld.c
index 960cad5c2e..b4befc9cbf 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 ((!FOME_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < 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 */
+
+ /* 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++ < FOME_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..53e07872ce 100644
--- a/os/hal/ports/STM32/STM32G0xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.h
@@ -1,1591 +1,1599 @@
-/*
- 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 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 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
+
+ #if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+ #error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+ #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_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/STM32G0xx/platform.mk b/os/hal/ports/STM32/STM32G0xx/platform.mk
index a40f7cc7f2..4cab52f18c 100644
--- a/os/hal/ports/STM32/STM32G0xx/platform.mk
+++ b/os/hal/ports/STM32/STM32G0xx/platform.mk
@@ -1,44 +1,44 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx
-
-# 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/ADCv5/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx/hal_efl_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G0xx
+
+# 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/ADCv5/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/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/STM32G0xx/stm32_dmamux.h b/os/hal/ports/STM32/STM32G0xx/stm32_dmamux.h
index 38226919f6..8cef754e23 100644
--- a/os/hal/ports/STM32/STM32G0xx/stm32_dmamux.h
+++ b/os/hal/ports/STM32/STM32G0xx/stm32_dmamux.h
@@ -1,131 +1,131 @@
-/*
- 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 STM32G0xx/stm32_dmamux.h
- * @brief STM32G0xx DMAMUX handler header.
- *
- * @addtogroup STM32G0xx_DMAMUX
- * @{
- */
-
-#ifndef STM32_DMAMUX_H
-#define STM32_DMAMUX_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name DMAMUX1 request sources
- * @{
- */
-#define STM32_DMAMUX1_REQ_GEN0 1
-#define STM32_DMAMUX1_REQ_GEN1 2
-#define STM32_DMAMUX1_REQ_GEN2 3
-#define STM32_DMAMUX1_REQ_GEN3 4
-#define STM32_DMAMUX1_ADC1 5
-#define STM32_DMAMUX1_AES_IN 6
-#define STM32_DMAMUX1_AES_OUT 7
-#define STM32_DMAMUX1_DAC1_CH1 8
-#define STM32_DMAMUX1_DAC1_CH2 9
-#define STM32_DMAMUX1_I2C1_RX 10
-#define STM32_DMAMUX1_I2C1_TX 11
-#define STM32_DMAMUX1_I2C2_RX 12
-#define STM32_DMAMUX1_I2C2_TX 13
-#define STM32_DMAMUX1_LPUART1_RX 14
-#define STM32_DMAMUX1_LPUART1_TX 15
-#define STM32_DMAMUX1_SPI1_RX 16
-#define STM32_DMAMUX1_SPI1_TX 17
-#define STM32_DMAMUX1_SPI2_RX 18
-#define STM32_DMAMUX1_SPI2_TX 19
-#define STM32_DMAMUX1_TIM1_CH1 20
-#define STM32_DMAMUX1_TIM1_CH2 21
-#define STM32_DMAMUX1_TIM1_CH3 22
-#define STM32_DMAMUX1_TIM1_CH4 23
-#define STM32_DMAMUX1_TIM1_COM 24
-#define STM32_DMAMUX1_TIM1_UP 25
-#define STM32_DMAMUX1_TIM2_CH1 26
-#define STM32_DMAMUX1_TIM2_CH2 27
-#define STM32_DMAMUX1_TIM2_CH3 28
-#define STM32_DMAMUX1_TIM2_CH4 29
-#define STM32_DMAMUX1_TIM2_TRIG 30
-#define STM32_DMAMUX1_TIM2_UP 31
-#define STM32_DMAMUX1_TIM3_CH1 32
-#define STM32_DMAMUX1_TIM3_CH2 33
-#define STM32_DMAMUX1_TIM3_CH3 34
-#define STM32_DMAMUX1_TIM3_CH4 35
-#define STM32_DMAMUX1_TIM3_TRIG 36
-#define STM32_DMAMUX1_TIM3_UP 37
-#define STM32_DMAMUX1_TIM6_UP 38
-#define STM32_DMAMUX1_TIM7_UP 39
-#define STM32_DMAMUX1_TIM15_CH1 40
-#define STM32_DMAMUX1_TIM15_CH2 41
-#define STM32_DMAMUX1_TIM15_COM 42
-#define STM32_DMAMUX1_TIM15_UP 43
-#define STM32_DMAMUX1_TIM16_CH1 44
-#define STM32_DMAMUX1_TIM16_COM 45
-#define STM32_DMAMUX1_TIM16_UP 46
-#define STM32_DMAMUX1_TIM17_CH1 47
-#define STM32_DMAMUX1_TIM17_COM 48
-#define STM32_DMAMUX1_TIM17_UP 49
-#define STM32_DMAMUX1_USART1_RX 50
-#define STM32_DMAMUX1_USART1_TX 51
-#define STM32_DMAMUX1_USART2_RX 52
-#define STM32_DMAMUX1_USART2_TX 53
-#define STM32_DMAMUX1_USART3_RX 54
-#define STM32_DMAMUX1_USART3_TX 55
-#define STM32_DMAMUX1_USART4_RX 56
-#define STM32_DMAMUX1_USART4_TX 57
-#define STM32_DMAMUX1_UART4_RX STM32_DMAMUX1_USART4_RX /* Legacy. */
-#define STM32_DMAMUX1_UART4_TX STM32_DMAMUX1_USART4_TX /* Legacy. */
-#define STM32_DMAMUX1_UCPD1_RX 58
-#define STM32_DMAMUX1_UCPD1_TX 59
-#define STM32_DMAMUX1_UCPD2_RX 60
-#define STM32_DMAMUX1_UCPD2_TX 61
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMAMUX_H */
-
-/** @} */
+/*
+ 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 STM32G0xx/stm32_dmamux.h
+ * @brief STM32G0xx DMAMUX handler header.
+ *
+ * @addtogroup STM32G0xx_DMAMUX
+ * @{
+ */
+
+#ifndef STM32_DMAMUX_H
+#define STM32_DMAMUX_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name DMAMUX1 request sources
+ * @{
+ */
+#define STM32_DMAMUX1_REQ_GEN0 1
+#define STM32_DMAMUX1_REQ_GEN1 2
+#define STM32_DMAMUX1_REQ_GEN2 3
+#define STM32_DMAMUX1_REQ_GEN3 4
+#define STM32_DMAMUX1_ADC1 5
+#define STM32_DMAMUX1_AES_IN 6
+#define STM32_DMAMUX1_AES_OUT 7
+#define STM32_DMAMUX1_DAC1_CH1 8
+#define STM32_DMAMUX1_DAC1_CH2 9
+#define STM32_DMAMUX1_I2C1_RX 10
+#define STM32_DMAMUX1_I2C1_TX 11
+#define STM32_DMAMUX1_I2C2_RX 12
+#define STM32_DMAMUX1_I2C2_TX 13
+#define STM32_DMAMUX1_LPUART1_RX 14
+#define STM32_DMAMUX1_LPUART1_TX 15
+#define STM32_DMAMUX1_SPI1_RX 16
+#define STM32_DMAMUX1_SPI1_TX 17
+#define STM32_DMAMUX1_SPI2_RX 18
+#define STM32_DMAMUX1_SPI2_TX 19
+#define STM32_DMAMUX1_TIM1_CH1 20
+#define STM32_DMAMUX1_TIM1_CH2 21
+#define STM32_DMAMUX1_TIM1_CH3 22
+#define STM32_DMAMUX1_TIM1_CH4 23
+#define STM32_DMAMUX1_TIM1_COM 24
+#define STM32_DMAMUX1_TIM1_UP 25
+#define STM32_DMAMUX1_TIM2_CH1 26
+#define STM32_DMAMUX1_TIM2_CH2 27
+#define STM32_DMAMUX1_TIM2_CH3 28
+#define STM32_DMAMUX1_TIM2_CH4 29
+#define STM32_DMAMUX1_TIM2_TRIG 30
+#define STM32_DMAMUX1_TIM2_UP 31
+#define STM32_DMAMUX1_TIM3_CH1 32
+#define STM32_DMAMUX1_TIM3_CH2 33
+#define STM32_DMAMUX1_TIM3_CH3 34
+#define STM32_DMAMUX1_TIM3_CH4 35
+#define STM32_DMAMUX1_TIM3_TRIG 36
+#define STM32_DMAMUX1_TIM3_UP 37
+#define STM32_DMAMUX1_TIM6_UP 38
+#define STM32_DMAMUX1_TIM7_UP 39
+#define STM32_DMAMUX1_TIM15_CH1 40
+#define STM32_DMAMUX1_TIM15_CH2 41
+#define STM32_DMAMUX1_TIM15_COM 42
+#define STM32_DMAMUX1_TIM15_UP 43
+#define STM32_DMAMUX1_TIM16_CH1 44
+#define STM32_DMAMUX1_TIM16_COM 45
+#define STM32_DMAMUX1_TIM16_UP 46
+#define STM32_DMAMUX1_TIM17_CH1 47
+#define STM32_DMAMUX1_TIM17_COM 48
+#define STM32_DMAMUX1_TIM17_UP 49
+#define STM32_DMAMUX1_USART1_RX 50
+#define STM32_DMAMUX1_USART1_TX 51
+#define STM32_DMAMUX1_USART2_RX 52
+#define STM32_DMAMUX1_USART2_TX 53
+#define STM32_DMAMUX1_USART3_RX 54
+#define STM32_DMAMUX1_USART3_TX 55
+#define STM32_DMAMUX1_USART4_RX 56
+#define STM32_DMAMUX1_USART4_TX 57
+#define STM32_DMAMUX1_UART4_RX STM32_DMAMUX1_USART4_RX /* Legacy. */
+#define STM32_DMAMUX1_UART4_TX STM32_DMAMUX1_USART4_TX /* Legacy. */
+#define STM32_DMAMUX1_UCPD1_RX 58
+#define STM32_DMAMUX1_UCPD1_TX 59
+#define STM32_DMAMUX1_UCPD2_RX 60
+#define STM32_DMAMUX1_UCPD2_TX 61
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMAMUX_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G0xx/stm32_isr.c b/os/hal/ports/STM32/STM32G0xx/stm32_isr.c
index 131b33a38e..794e8c2025 100644
--- a/os/hal/ports/STM32/STM32G0xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32G0xx/stm32_isr.c
@@ -1,134 +1,134 @@
-/*
- 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/stm32_isr.c
- * @brief STM32G0xx ISR handler code.
- *
- * @addtogroup STM32G0xx_ISR
- * @{
- */
-
-#include "hal.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define exti_serve_irq(pr, channel) { \
- \
- if ((pr) & (1U << (channel))) { \
- _pal_isr_code(channel); \
- } \
-}
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#include "stm32_dma1_ch23.inc"
-#include "stm32_dma1_ch4567.inc"
-
-#include "stm32_exti0_1.inc"
-#include "stm32_exti2_3.inc"
-#include "stm32_exti4_15.inc"
-#include "stm32_exti19-21.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart3_4_lp1.inc"
-
-#include "stm32_tim1.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim14.inc"
-#include "stm32_tim15.inc"
-#include "stm32_tim16.inc"
-#include "stm32_tim17.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_1_irq_init();
- exti2_3_irq_init();
- exti4_15_irq_init();
- exti19_exti21_irq_init();
-
- tim1_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim14_irq_init();
- tim15_irq_init();
- tim16_irq_init();
- tim17_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_usart4_lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_1_irq_deinit();
- exti2_3_irq_deinit();
- exti4_15_irq_deinit();
- exti19_exti21_irq_deinit();
-
- tim1_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim14_irq_deinit();
- tim15_irq_deinit();
- tim16_irq_deinit();
- tim17_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_usart4_lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32G0xx ISR handler code.
+ *
+ * @addtogroup STM32G0xx_ISR
+ * @{
+ */
+
+#include "hal.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define exti_serve_irq(pr, channel) { \
+ \
+ if ((pr) & (1U << (channel))) { \
+ _pal_isr_code(channel); \
+ } \
+}
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#include "stm32_dma1_ch23.inc"
+#include "stm32_dma1_ch4567.inc"
+
+#include "stm32_exti0_1.inc"
+#include "stm32_exti2_3.inc"
+#include "stm32_exti4_15.inc"
+#include "stm32_exti19-21.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart3_4_lp1.inc"
+
+#include "stm32_tim1.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim14.inc"
+#include "stm32_tim15.inc"
+#include "stm32_tim16.inc"
+#include "stm32_tim17.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_1_irq_init();
+ exti2_3_irq_init();
+ exti4_15_irq_init();
+ exti19_exti21_irq_init();
+
+ tim1_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim14_irq_init();
+ tim15_irq_init();
+ tim16_irq_init();
+ tim17_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_usart4_lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_1_irq_deinit();
+ exti2_3_irq_deinit();
+ exti4_15_irq_deinit();
+ exti19_exti21_irq_deinit();
+
+ tim1_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim14_irq_deinit();
+ tim15_irq_deinit();
+ tim16_irq_deinit();
+ tim17_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_usart4_lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G0xx/stm32_isr.h b/os/hal/ports/STM32/STM32G0xx/stm32_isr.h
index 2e833f28bc..2baf0da48d 100644
--- a/os/hal/ports/STM32/STM32G0xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32G0xx/stm32_isr.h
@@ -1,182 +1,182 @@
-/*
- 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/stm32_isr.h
- * @brief STM32G0xx ISR handler header.
- *
- * @addtogroup STM32G0xx_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_TIM14_SUPPRESS_ISR
-#define STM32_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_SUPPRESS_ISR
-
-#define STM32_USART1_SUPPRESS_ISR
-#define STM32_USART2_SUPPRESS_ISR
-#define STM32_USART3_SUPPRESS_ISR
-#define STM32_UART4_SUPPRESS_ISR
-#define STM32_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC unit.
- */
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-
-/*
- * DMA unit.
- */
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH4567_NUMBER 11
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-
-#define STM32_DMA1_CH1_CMASK 0x00000001U
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/*
- * EXTI unit.
- */
-#define STM32_EXTI0_1_HANDLER Vector54
-#define STM32_EXTI2_3_HANDLER Vector58
-#define STM32_EXTI4_15_HANDLER Vector5C
-#define STM32_EXTI16_HANDLER Vector44
-#define STM32_EXTI1921_HANDLER Vector48
-
-#define STM32_EXTI0_1_NUMBER 5
-#define STM32_EXTI2_3_NUMBER 6
-#define STM32_EXTI4_15_NUMBER 7
-#define STM32_EXTI6_NUMBER 1
-#define STM32_EXTI1921_NUMBER 2
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_GLOBAL_HANDLER Vector9C
-#define STM32_I2C2_GLOBAL_HANDLER VectorA0
-
-#define STM32_I2C1_GLOBAL_NUMBER 23
-#define STM32_I2C2_GLOBAL_NUMBER 24
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_UP_HANDLER Vector74
-#define STM32_TIM1_CC_HANDLER Vector78
-#define STM32_TIM2_HANDLER Vector7C
-#define STM32_TIM3_HANDLER Vector80
-#define STM32_TIM6_HANDLER Vector84
-#define STM32_TIM7_HANDLER Vector88
-#define STM32_TIM14_HANDLER Vector8C
-#define STM32_TIM15_HANDLER Vector90
-#define STM32_TIM16_HANDLER Vector94
-#define STM32_TIM17_HANDLER Vector98
-
-#define STM32_TIM1_UP_NUMBER 13
-#define STM32_TIM1_CC_NUMBER 14
-#define STM32_TIM2_NUMBER 15
-#define STM32_TIM3_NUMBER 16
-#define STM32_TIM6_NUMBER 17
-#define STM32_TIM7_NUMBER 18
-#define STM32_TIM14_NUMBER 19
-#define STM32_TIM15_NUMBER 20
-#define STM32_TIM16_NUMBER 21
-#define STM32_TIM17_NUMBER 22
-
-/*
- * USART/UART units.
- */
-#define STM32_USART1_HANDLER VectorAC
-#define STM32_USART2_HANDLER VectorB0
-#define STM32_USART3_4_LP1_HANDLER VectorB4
-
-#define STM32_USART1_NUMBER 27
-#define STM32_USART2_NUMBER 28
-#define STM32_USART3_4_LP1_NUMBER 29
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32G0xx ISR handler header.
+ *
+ * @addtogroup STM32G0xx_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_TIM14_SUPPRESS_ISR
+#define STM32_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_SUPPRESS_ISR
+
+#define STM32_USART1_SUPPRESS_ISR
+#define STM32_USART2_SUPPRESS_ISR
+#define STM32_USART3_SUPPRESS_ISR
+#define STM32_UART4_SUPPRESS_ISR
+#define STM32_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC unit.
+ */
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+
+/*
+ * DMA unit.
+ */
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH4567_NUMBER 11
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+
+#define STM32_DMA1_CH1_CMASK 0x00000001U
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/*
+ * EXTI unit.
+ */
+#define STM32_EXTI0_1_HANDLER Vector54
+#define STM32_EXTI2_3_HANDLER Vector58
+#define STM32_EXTI4_15_HANDLER Vector5C
+#define STM32_EXTI16_HANDLER Vector44
+#define STM32_EXTI1921_HANDLER Vector48
+
+#define STM32_EXTI0_1_NUMBER 5
+#define STM32_EXTI2_3_NUMBER 6
+#define STM32_EXTI4_15_NUMBER 7
+#define STM32_EXTI6_NUMBER 1
+#define STM32_EXTI1921_NUMBER 2
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_GLOBAL_HANDLER Vector9C
+#define STM32_I2C2_GLOBAL_HANDLER VectorA0
+
+#define STM32_I2C1_GLOBAL_NUMBER 23
+#define STM32_I2C2_GLOBAL_NUMBER 24
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_UP_HANDLER Vector74
+#define STM32_TIM1_CC_HANDLER Vector78
+#define STM32_TIM2_HANDLER Vector7C
+#define STM32_TIM3_HANDLER Vector80
+#define STM32_TIM6_HANDLER Vector84
+#define STM32_TIM7_HANDLER Vector88
+#define STM32_TIM14_HANDLER Vector8C
+#define STM32_TIM15_HANDLER Vector90
+#define STM32_TIM16_HANDLER Vector94
+#define STM32_TIM17_HANDLER Vector98
+
+#define STM32_TIM1_UP_NUMBER 13
+#define STM32_TIM1_CC_NUMBER 14
+#define STM32_TIM2_NUMBER 15
+#define STM32_TIM3_NUMBER 16
+#define STM32_TIM6_NUMBER 17
+#define STM32_TIM7_NUMBER 18
+#define STM32_TIM14_NUMBER 19
+#define STM32_TIM15_NUMBER 20
+#define STM32_TIM16_NUMBER 21
+#define STM32_TIM17_NUMBER 22
+
+/*
+ * USART/UART units.
+ */
+#define STM32_USART1_HANDLER VectorAC
+#define STM32_USART2_HANDLER VectorB0
+#define STM32_USART3_4_LP1_HANDLER VectorB4
+
+#define STM32_USART1_NUMBER 27
+#define STM32_USART2_NUMBER 28
+#define STM32_USART3_4_LP1_NUMBER 29
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32G0xx/stm32_rcc.h b/os/hal/ports/STM32/STM32G0xx/stm32_rcc.h
index 3927dea5cb..28c7563664 100644
--- a/os/hal/ports/STM32/STM32G0xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32G0xx/stm32_rcc.h
@@ -1,869 +1,869 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32g0xx.h.
- *
- * @addtogroup STM32G0xx_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 APB bus (R1).
- *
- * @param[in] mask APB R1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPBR1(mask, lp) { \
- RCC->APBENR1 |= (mask); \
- if (lp) \
- RCC->APBSMENR1 |= (mask); \
- else \
- RCC->APBSMENR1 &= ~(mask); \
- (void)RCC->APBSMENR1; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB bus (R1).
- *
- * @param[in] mask APB R1 peripherals mask
- *
- * @api
- */
-#define rccDisableAPBR1(mask) { \
- RCC->APBENR1 &= ~(mask); \
- RCC->APBSMENR1 &= ~(mask); \
- (void)RCC->APBSMENR1; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB bus (R1).
- *
- * @param[in] mask APB R1 peripherals mask
- *
- * @api
- */
-#define rccResetAPBR1(mask) { \
- RCC->APBRSTR1 |= (mask); \
- RCC->APBRSTR1 &= ~(mask); \
- (void)RCC->APBRSTR1; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB bus (R2).
- *
- * @param[in] mask APB R2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPBR2(mask, lp) { \
- RCC->APBENR2 |= (mask); \
- if (lp) \
- RCC->APBSMENR2 |= (mask); \
- else \
- RCC->APBSMENR2 &= ~(mask); \
- (void)RCC->APBSMENR2; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB bus (R2).
- *
- * @param[in] mask APB R2 peripherals mask
- *
- * @api
- */
-#define rccDisableAPBR2(mask) { \
- RCC->APBENR2 &= ~(mask); \
- RCC->APBSMENR2 &= ~(mask); \
- (void)RCC->APBSMENR2; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB bus (R2).
- *
- * @param[in] mask APB R2 peripherals mask
- *
- * @api
- */
-#define rccResetAPBR2(mask) { \
- RCC->APBRSTR2 |= (mask); \
- RCC->APBRSTR2 &= ~(mask); \
- (void)RCC->APBRSTR2; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the IOP bus.
- *
- * @param[in] mask IOP peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableIOP(mask, lp) { \
- RCC->IOPENR |= (mask); \
- if (lp) \
- RCC->IOPSMENR |= (mask); \
- else \
- RCC->IOPSMENR &= ~(mask); \
- (void)RCC->IOPSMENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the IOP bus.
- *
- * @param[in] mask IOP peripherals mask
- *
- * @api
- */
-#define rccDisableIOP(mask) { \
- RCC->IOPENR &= ~(mask); \
- RCC->IOPSMENR &= ~(mask); \
- (void)RCC->IOPSMENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the IOP bus.
- *
- * @param[in] mask IOP peripherals mask
- *
- * @api
- */
-#define rccResetIOP(mask) { \
- RCC->IOPRSTR |= (mask); \
- RCC->IOPRSTR &= ~(mask); \
- (void)RCC->IOPRSTR; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- if (lp) \
- RCC->AHBSMENR |= (mask); \
- else \
- RCC->AHBSMENR &= ~(mask); \
- (void)RCC->AHBSMENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- RCC->AHBSMENR &= ~(mask); \
- (void)RCC->AHBSMENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ADC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC1(lp) rccEnableAPBR2(RCC_APBENR2_ADCEN, lp)
-
-/**
- * @brief Disables the ADC peripheral clock.
- *
- * @api
- */
-#define rccDisableADC1() rccDisableAPBR2(RCC_APBENR2_ADCEN)
-
-/**
- * @brief Resets the ADC peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPBR2(RCC_APBRSTR2_ADCRST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC1(lp) rccEnableAPBR1(RCC_APBENR1_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPBR1(RCC_APBENR1_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPBR1(RCC_APBRSTR1_DAC1RST)
-/** @} */
-
-/**
- * @name DMA peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMA1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- *
- * @api
- */
-#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
-/** @} */
-
-/**
- * @name DMAMUX peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMAMUX peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMAMUX(lp)
-
-/**
- * @brief Disables the DMAMUX peripheral clock.
- *
- * @api
- */
-#define rccDisableDMAMUX()
-
-/**
- * @brief Resets the DMAMUX peripheral.
- *
- * @api
- */
-#define rccResetDMAMUX()
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnablePWRInterface(lp) rccEnableAPBR1(RCC_APBENR1_PWREN, lp)
-
-/**
- * @brief Disables PWR interface clock.
- *
- * @api
- */
-#define rccDisablePWRInterface() rccDisableAPBR1(RCC_APBENR1_PWREN)
-
-/**
- * @brief Resets the PWR interface.
- *
- * @api
- */
-#define rccResetPWRInterface() rccResetAPBR1(RCC_APBRSTR1_PWRRST)
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C1(lp) rccEnableAPBR1(RCC_APBENR1_I2C1EN, lp)
-
-/**
- * @brief Disables the I2C1 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C1() rccDisableAPBR1(RCC_APBENR1_I2C1EN)
-
-/**
- * @brief Resets the I2C1 peripheral.
- *
- * @api
- */
-#define rccResetI2C1() rccResetAPBR1(RCC_APBRSTR1_I2C1RST)
-
-/**
- * @brief Enables the I2C2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C2(lp) rccEnableAPBR1(RCC_APBENR1_I2C2EN, lp)
-
-/**
- * @brief Disables the I2C2 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C2() rccDisableAPBR1(RCC_APBENR1_I2C2EN)
-
-/**
- * @brief Resets the I2C2 peripheral.
- *
- * @api
- */
-#define rccResetI2C2() rccResetAPBR1(RCC_APBRSTR1_I2C2RST)
-/** @} */
-
-/**
- * @name RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB(RCC_AHBENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB(RCC_AHBENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB(RCC_AHBRSTR_RNGRST)
-/** @} */
-
-/**
- * @name SPI peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SPI1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI1(lp) rccEnableAPBR2(RCC_APBENR2_SPI1EN, lp)
-
-/**
- * @brief Disables the SPI1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI1() rccDisableAPBR2(RCC_APBENR2_SPI1EN)
-
-/**
- * @brief Resets the SPI1 peripheral.
- *
- * @api
- */
-#define rccResetSPI1() rccResetAPB(RCC_APBRSTR2_SPI1RST)
-
-/**
- * @brief Enables the SPI2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI2(lp) rccEnableAPBR1(RCC_APBENR1_SPI2EN, lp)
-
-/**
- * @brief Disables the SPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI2() rccDisableAPBR1(RCC_APBENR1_SPI2EN)
-
-/**
- * @brief Resets the SPI2 peripheral.
- *
- * @api
- */
-#define rccResetSPI2() rccResetAPBR1(RCC_APBRSTR1_SPI2RST)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the TIM1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM1(lp) rccEnableAPBR2(RCC_APBENR2_TIM1EN, lp)
-
-/**
- * @brief Disables the TIM1 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM1() rccDisableAPBR2(RCC_APBENR2_TIM1EN)
-
-/**
- * @brief Resets the TIM1 peripheral.
- *
- * @api
- */
-#define rccResetTIM1() rccResetAPBR2(RCC_APBRSTR2_TIM1RST)
-
-/**
- * @brief Enables the TIM2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM2(lp) rccEnableAPBR1(RCC_APBENR1_TIM2EN, lp)
-
-/**
- * @brief Disables the TIM2 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM2() rccDisableAPBR1(RCC_APBENR1_TIM2EN)
-
-/**
- * @brief Resets the TIM2 peripheral.
- *
- * @api
- */
-#define rccResetTIM2() rccResetAPBR1(RCC_APBRSTR1_TIM2RST)
-
-/**
- * @brief Enables the TIM3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM3(lp) rccEnableAPBR1(RCC_APBENR1_TIM3EN, lp)
-
-/**
- * @brief Disables the TIM3 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM3() rccDisableAPBR1(RCC_APBENR1_TIM3EN)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPBR1(RCC_APBRSTR1_TIM3RST)
-
-/**
- * @brief Enables the TIM6 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM6(lp) rccEnableAPBR1(RCC_APBENR1_TIM6EN, lp)
-
-/**
- * @brief Disables the TIM6 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM6() rccDisableAPBR1(RCC_APBENR1_TIM6EN)
-
-/**
- * @brief Resets the TIM6 peripheral.
- *
- * @api
- */
-#define rccResetTIM6() rccResetAPBR1(RCC_APBRSTR1_TIM6RST)
-
-/**
- * @brief Enables the TIM7 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM7(lp) rccEnableAPBR1(RCC_APBENR1_TIM7EN, lp)
-
-/**
- * @brief Disables the TIM7 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM7() rccDisableAPBR1(RCC_APBENR1_TIM7EN)
-
-/**
- * @brief Resets the TIM7 peripheral.
- *
- * @api
- */
-#define rccResetTIM7() rccResetAPBR1(RCC_APBRSTR1_TIM7RST)
-
-/**
- * @brief Enables the TIM14 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM14(lp) rccEnableAPBR2(RCC_APBENR2_TIM14EN, lp)
-
-/**
- * @brief Disables the TIM14 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM14() rccDisableAPBR2(RCC_APBENR2_TIM14EN)
-
-/**
- * @brief Resets the TIM14 peripheral.
- *
- * @api
- */
-#define rccResetTIM14() rccResetAPBR2(RCC_APBRSTR2_TIM14RST)
-
-/**
- * @brief Enables the TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPBR2(RCC_APBENR2_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPBR2(RCC_APBENR2_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPBR2(RCC_APBRSTR2_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB(RCC_APBENR2_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPBR2(RCC_APBENR2_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPBR2(RCC_APBRSTR2_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPBR2(RCC_APBENR2_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPBR2(RCC_APBENR2_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPBR2(RCC_APBRSTR2_TIM17RST)
-/** @} */
-
-/**
- * @name USART/UART peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART1(lp) rccEnableAPBR2(RCC_APBENR2_USART1EN, lp)
-
-/**
- * @brief Disables the USART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART1() rccDisableAPBR2(RCC_APBENR2_USART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetUSART1() rccResetAPBR2(RCC_APBRSTR2_USART1RST)
-
-/**
- * @brief Enables the USART2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART2(lp) rccEnableAPBR1(RCC_APBENR1_USART2EN, lp)
-
-/**
- * @brief Disables the USART2 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART2() rccDisableAPBR1(RCC_APBENR1_USART2EN)
-
-/**
- * @brief Resets the USART2 peripheral.
- *
- * @api
- */
-#define rccResetUSART2() rccResetAPBR1(RCC_APBRSTR1_USART2RST)
-
-/**
- * @brief Enables the USART3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART3(lp) rccEnableAPBR1(RCC_APBENR1_USART3EN, lp)
-
-/**
- * @brief Disables the USART3 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART3() rccDisableAPBR1(RCC_APBENR1_USART3EN)
-
-/**
- * @brief Resets the USART3 peripheral.
- *
- * @api
- */
-#define rccResetUSART3() rccResetAPBR1(RCC_APBRSTR1_USART3RST)
-
-/**
- * @brief Enables the UART4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPBR1(RCC_APBENR1_USART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPBR1(RCC_APBENR1_USART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPBR1(RCC_APBRSTR1_USART4RST)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPBR1(RCC_APBENR1_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPBR1(RCC_APBENR1_LPUART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPBR1(RCC_APBRSTR1_LPUART1RST)
-/** @} */
-
-/**
- * @name CRC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
-
-/**
- * @brief Disables the CRC peripheral clock.
- *
- * @api
- */
-#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
-
-/**
- * @brief Resets the CRC peripheral.
- *
- * @api
- */
-#define rccResetCRC() rccResetAHB(RCC_AHBRSTR_CRCRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32g0xx.h.
+ *
+ * @addtogroup STM32G0xx_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 APB bus (R1).
+ *
+ * @param[in] mask APB R1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPBR1(mask, lp) { \
+ RCC->APBENR1 |= (mask); \
+ if (lp) \
+ RCC->APBSMENR1 |= (mask); \
+ else \
+ RCC->APBSMENR1 &= ~(mask); \
+ (void)RCC->APBSMENR1; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB bus (R1).
+ *
+ * @param[in] mask APB R1 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPBR1(mask) { \
+ RCC->APBENR1 &= ~(mask); \
+ RCC->APBSMENR1 &= ~(mask); \
+ (void)RCC->APBSMENR1; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB bus (R1).
+ *
+ * @param[in] mask APB R1 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPBR1(mask) { \
+ RCC->APBRSTR1 |= (mask); \
+ RCC->APBRSTR1 &= ~(mask); \
+ (void)RCC->APBRSTR1; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB bus (R2).
+ *
+ * @param[in] mask APB R2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPBR2(mask, lp) { \
+ RCC->APBENR2 |= (mask); \
+ if (lp) \
+ RCC->APBSMENR2 |= (mask); \
+ else \
+ RCC->APBSMENR2 &= ~(mask); \
+ (void)RCC->APBSMENR2; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB bus (R2).
+ *
+ * @param[in] mask APB R2 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPBR2(mask) { \
+ RCC->APBENR2 &= ~(mask); \
+ RCC->APBSMENR2 &= ~(mask); \
+ (void)RCC->APBSMENR2; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB bus (R2).
+ *
+ * @param[in] mask APB R2 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPBR2(mask) { \
+ RCC->APBRSTR2 |= (mask); \
+ RCC->APBRSTR2 &= ~(mask); \
+ (void)RCC->APBRSTR2; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the IOP bus.
+ *
+ * @param[in] mask IOP peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableIOP(mask, lp) { \
+ RCC->IOPENR |= (mask); \
+ if (lp) \
+ RCC->IOPSMENR |= (mask); \
+ else \
+ RCC->IOPSMENR &= ~(mask); \
+ (void)RCC->IOPSMENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the IOP bus.
+ *
+ * @param[in] mask IOP peripherals mask
+ *
+ * @api
+ */
+#define rccDisableIOP(mask) { \
+ RCC->IOPENR &= ~(mask); \
+ RCC->IOPSMENR &= ~(mask); \
+ (void)RCC->IOPSMENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the IOP bus.
+ *
+ * @param[in] mask IOP peripherals mask
+ *
+ * @api
+ */
+#define rccResetIOP(mask) { \
+ RCC->IOPRSTR |= (mask); \
+ RCC->IOPRSTR &= ~(mask); \
+ (void)RCC->IOPRSTR; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ if (lp) \
+ RCC->AHBSMENR |= (mask); \
+ else \
+ RCC->AHBSMENR &= ~(mask); \
+ (void)RCC->AHBSMENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ RCC->AHBSMENR &= ~(mask); \
+ (void)RCC->AHBSMENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ADC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC1(lp) rccEnableAPBR2(RCC_APBENR2_ADCEN, lp)
+
+/**
+ * @brief Disables the ADC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC1() rccDisableAPBR2(RCC_APBENR2_ADCEN)
+
+/**
+ * @brief Resets the ADC peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPBR2(RCC_APBRSTR2_ADCRST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC1(lp) rccEnableAPBR1(RCC_APBENR1_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPBR1(RCC_APBENR1_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPBR1(RCC_APBRSTR1_DAC1RST)
+/** @} */
+
+/**
+ * @name DMA peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMA1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA1(lp) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
+/** @} */
+
+/**
+ * @name DMAMUX peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMAMUX peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMAMUX(lp)
+
+/**
+ * @brief Disables the DMAMUX peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMAMUX()
+
+/**
+ * @brief Resets the DMAMUX peripheral.
+ *
+ * @api
+ */
+#define rccResetDMAMUX()
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnablePWRInterface(lp) rccEnableAPBR1(RCC_APBENR1_PWREN, lp)
+
+/**
+ * @brief Disables PWR interface clock.
+ *
+ * @api
+ */
+#define rccDisablePWRInterface() rccDisableAPBR1(RCC_APBENR1_PWREN)
+
+/**
+ * @brief Resets the PWR interface.
+ *
+ * @api
+ */
+#define rccResetPWRInterface() rccResetAPBR1(RCC_APBRSTR1_PWRRST)
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C1(lp) rccEnableAPBR1(RCC_APBENR1_I2C1EN, lp)
+
+/**
+ * @brief Disables the I2C1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C1() rccDisableAPBR1(RCC_APBENR1_I2C1EN)
+
+/**
+ * @brief Resets the I2C1 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C1() rccResetAPBR1(RCC_APBRSTR1_I2C1RST)
+
+/**
+ * @brief Enables the I2C2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C2(lp) rccEnableAPBR1(RCC_APBENR1_I2C2EN, lp)
+
+/**
+ * @brief Disables the I2C2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C2() rccDisableAPBR1(RCC_APBENR1_I2C2EN)
+
+/**
+ * @brief Resets the I2C2 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C2() rccResetAPBR1(RCC_APBRSTR1_I2C2RST)
+/** @} */
+
+/**
+ * @name RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB(RCC_AHBENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB(RCC_AHBENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB(RCC_AHBRSTR_RNGRST)
+/** @} */
+
+/**
+ * @name SPI peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SPI1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI1(lp) rccEnableAPBR2(RCC_APBENR2_SPI1EN, lp)
+
+/**
+ * @brief Disables the SPI1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI1() rccDisableAPBR2(RCC_APBENR2_SPI1EN)
+
+/**
+ * @brief Resets the SPI1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI1() rccResetAPB(RCC_APBRSTR2_SPI1RST)
+
+/**
+ * @brief Enables the SPI2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI2(lp) rccEnableAPBR1(RCC_APBENR1_SPI2EN, lp)
+
+/**
+ * @brief Disables the SPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI2() rccDisableAPBR1(RCC_APBENR1_SPI2EN)
+
+/**
+ * @brief Resets the SPI2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI2() rccResetAPBR1(RCC_APBRSTR1_SPI2RST)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the TIM1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM1(lp) rccEnableAPBR2(RCC_APBENR2_TIM1EN, lp)
+
+/**
+ * @brief Disables the TIM1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM1() rccDisableAPBR2(RCC_APBENR2_TIM1EN)
+
+/**
+ * @brief Resets the TIM1 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM1() rccResetAPBR2(RCC_APBRSTR2_TIM1RST)
+
+/**
+ * @brief Enables the TIM2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM2(lp) rccEnableAPBR1(RCC_APBENR1_TIM2EN, lp)
+
+/**
+ * @brief Disables the TIM2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM2() rccDisableAPBR1(RCC_APBENR1_TIM2EN)
+
+/**
+ * @brief Resets the TIM2 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM2() rccResetAPBR1(RCC_APBRSTR1_TIM2RST)
+
+/**
+ * @brief Enables the TIM3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM3(lp) rccEnableAPBR1(RCC_APBENR1_TIM3EN, lp)
+
+/**
+ * @brief Disables the TIM3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM3() rccDisableAPBR1(RCC_APBENR1_TIM3EN)
+
+/**
+ * @brief Resets the TIM3 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM3() rccResetAPBR1(RCC_APBRSTR1_TIM3RST)
+
+/**
+ * @brief Enables the TIM6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM6(lp) rccEnableAPBR1(RCC_APBENR1_TIM6EN, lp)
+
+/**
+ * @brief Disables the TIM6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM6() rccDisableAPBR1(RCC_APBENR1_TIM6EN)
+
+/**
+ * @brief Resets the TIM6 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM6() rccResetAPBR1(RCC_APBRSTR1_TIM6RST)
+
+/**
+ * @brief Enables the TIM7 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM7(lp) rccEnableAPBR1(RCC_APBENR1_TIM7EN, lp)
+
+/**
+ * @brief Disables the TIM7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM7() rccDisableAPBR1(RCC_APBENR1_TIM7EN)
+
+/**
+ * @brief Resets the TIM7 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM7() rccResetAPBR1(RCC_APBRSTR1_TIM7RST)
+
+/**
+ * @brief Enables the TIM14 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM14(lp) rccEnableAPBR2(RCC_APBENR2_TIM14EN, lp)
+
+/**
+ * @brief Disables the TIM14 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM14() rccDisableAPBR2(RCC_APBENR2_TIM14EN)
+
+/**
+ * @brief Resets the TIM14 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM14() rccResetAPBR2(RCC_APBRSTR2_TIM14RST)
+
+/**
+ * @brief Enables the TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPBR2(RCC_APBENR2_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPBR2(RCC_APBENR2_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPBR2(RCC_APBRSTR2_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB(RCC_APBENR2_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPBR2(RCC_APBENR2_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPBR2(RCC_APBRSTR2_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPBR2(RCC_APBENR2_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPBR2(RCC_APBENR2_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPBR2(RCC_APBRSTR2_TIM17RST)
+/** @} */
+
+/**
+ * @name USART/UART peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART1(lp) rccEnableAPBR2(RCC_APBENR2_USART1EN, lp)
+
+/**
+ * @brief Disables the USART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART1() rccDisableAPBR2(RCC_APBENR2_USART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART1() rccResetAPBR2(RCC_APBRSTR2_USART1RST)
+
+/**
+ * @brief Enables the USART2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART2(lp) rccEnableAPBR1(RCC_APBENR1_USART2EN, lp)
+
+/**
+ * @brief Disables the USART2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART2() rccDisableAPBR1(RCC_APBENR1_USART2EN)
+
+/**
+ * @brief Resets the USART2 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART2() rccResetAPBR1(RCC_APBRSTR1_USART2RST)
+
+/**
+ * @brief Enables the USART3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART3(lp) rccEnableAPBR1(RCC_APBENR1_USART3EN, lp)
+
+/**
+ * @brief Disables the USART3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART3() rccDisableAPBR1(RCC_APBENR1_USART3EN)
+
+/**
+ * @brief Resets the USART3 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART3() rccResetAPBR1(RCC_APBRSTR1_USART3RST)
+
+/**
+ * @brief Enables the UART4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPBR1(RCC_APBENR1_USART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPBR1(RCC_APBENR1_USART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPBR1(RCC_APBRSTR1_USART4RST)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPBR1(RCC_APBENR1_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPBR1(RCC_APBENR1_LPUART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPBR1(RCC_APBRSTR1_LPUART1RST)
+/** @} */
+
+/**
+ * @name CRC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRC(lp) rccEnableAHB(RCC_AHBENR_CRCEN, lp)
+
+/**
+ * @brief Disables the CRC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRC() rccDisableAHB(RCC_AHBENR_CRCEN)
+
+/**
+ * @brief Resets the CRC peripheral.
+ *
+ * @api
+ */
+#define rccResetCRC() rccResetAHB(RCC_AHBRSTR_CRCRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G0xx/stm32_registry.h b/os/hal/ports/STM32/STM32G0xx/stm32_registry.h
index dfccfce654..8d7bc853e4 100644
--- a/os/hal/ports/STM32/STM32G0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32G0xx/stm32_registry.h
@@ -1,455 +1,455 @@
-/*
- 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 STM32G0xx/stm32_registry.h
- * @brief STM32G0xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32G0xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RTC and TAMP attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 20
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_EVENT_RTC_EXTI 19
-#define STM32_RTC_EVENT_TAMP_EXTI 21
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, \
- STM32_IRQ_EXTI1921_PRIORITY); \
-} while (false)
-
- /* Enabling RTC-related EXTI lines.*/
-#define STM32_RTC_ENABLE_ALL_EXTI() do { \
- extiEnableGroup1(EXTI_MASK1(STM32_RTC_EVENT_RTC_EXTI) | \
- EXTI_MASK1(STM32_RTC_EVENT_TAMP_EXTI), \
- EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); \
-} while (false)
-
-/* Clearing EXTI interrupts. */
-#define STM32_RTC_CLEAR_ALL_EXTI() do { \
- extiClearGroup1(EXTI_MASK1(STM32_RTC_EVENT_RTC_EXTI) | \
- EXTI_MASK1(STM32_RTC_EVENT_TAMP_EXTI)); \
-} while (false)
-
-/* Masks used to preserve state of RTC and TAMP register reserved bits. */
-#define STM32_RTC_CR_MASK 0xE7FFFF7F
-#define STM32_RTC_PRER_MASK 0x007F7FFF
-#define STM32_TAMP_CR1_MASK 0x003C0003
-#define STM32_TAMP_CR2_MASK 0x030300FF
-#define STM32_TAMP_FLTCR_MASK 0x000000FF
-#define STM32_TAMP_IER_MASK 0x003C0003
-
-#if defined(STM32G081xx) || defined(__DOXYGEN__)
-#define STM32_HAS_RNG1 TRUE
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 TRUE
-#else
-#define STM32_HAS_RNG1 FALSE
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-/*===========================================================================*/
-/* STM32G070xx. */
-/*===========================================================================*/
-
-#if defined(STM32G070xx) || defined(__DOXYGEN__)
-
-/* Errata attributes.*/
-#define STM32_HAS_TIM1617_ERRATA TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_HAS_CR TRUE
-#define STM32_EXTI_SEPARATE_RF TRUE
-#define STM32_EXTI_HAS_GROUP2 FALSE
-#define STM32_EXTI_NUM_LINES 16
-#define STM32_EXTI_IMR1_MASK 0xFFF80000U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIODEN | \
- RCC_IOPENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* OCTOSPI attributes.*/
-#define STM32_HAS_OCTOSPI1 FALSE
-#define STM32_HAS_OCTOSPI2 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 FALSE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#define STM32_HAS_TIM3 TRUE
-#define STM32_TIM3_IS_32BITS FALSE
-#define STM32_TIM3_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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM2 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_LPUART1 TRUE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC FALSE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI FALSE
-
-#endif /* defined(STM32G070xx) */
-
-/*===========================================================================*/
-/* STM32G071xx STM32G081xx. */
-/*===========================================================================*/
-
-#if defined(STM32G071xx) || defined(STM32G081xx)
-
-/* Errata attributes.*/
-#define STM32_HAS_TIM1617_ERRATA TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_HAS_CR TRUE
-#define STM32_EXTI_SEPARATE_RF TRUE
-#define STM32_EXTI_HAS_GROUP2 FALSE
-#define STM32_EXTI_NUM_LINES 33
-#define STM32_EXTI_IMR1_MASK 0xFFF80000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFFU
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF TRUE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIODEN | \
- RCC_IOPENR_GPIOFEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* OCTOSPI attributes.*/
-#define STM32_HAS_OCTOSPI1 FALSE
-#define STM32_HAS_OCTOSPI2 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 FALSE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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_TIM14 TRUE
-#define STM32_TIM14_IS_32BITS FALSE
-#define STM32_TIM14_CHANNELS 1
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_LPUART1 TRUE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC FALSE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI FALSE
-
-#endif /* defined(STM32G071xx) || defined(STM32G081xx) */
-
-/** @} */
-
-#endif /* STM32_REGISTRY_H */
-
-/** @} */
+/*
+ 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 STM32G0xx/stm32_registry.h
+ * @brief STM32G0xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32G0xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RTC and TAMP attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 20
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_EVENT_RTC_EXTI 19
+#define STM32_RTC_EVENT_TAMP_EXTI 21
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, \
+ STM32_IRQ_EXTI1921_PRIORITY); \
+} while (false)
+
+ /* Enabling RTC-related EXTI lines.*/
+#define STM32_RTC_ENABLE_ALL_EXTI() do { \
+ extiEnableGroup1(EXTI_MASK1(STM32_RTC_EVENT_RTC_EXTI) | \
+ EXTI_MASK1(STM32_RTC_EVENT_TAMP_EXTI), \
+ EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT); \
+} while (false)
+
+/* Clearing EXTI interrupts. */
+#define STM32_RTC_CLEAR_ALL_EXTI() do { \
+ extiClearGroup1(EXTI_MASK1(STM32_RTC_EVENT_RTC_EXTI) | \
+ EXTI_MASK1(STM32_RTC_EVENT_TAMP_EXTI)); \
+} while (false)
+
+/* Masks used to preserve state of RTC and TAMP register reserved bits. */
+#define STM32_RTC_CR_MASK 0xE7FFFF7F
+#define STM32_RTC_PRER_MASK 0x007F7FFF
+#define STM32_TAMP_CR1_MASK 0x003C0003
+#define STM32_TAMP_CR2_MASK 0x030300FF
+#define STM32_TAMP_FLTCR_MASK 0x000000FF
+#define STM32_TAMP_IER_MASK 0x003C0003
+
+#if defined(STM32G081xx) || defined(__DOXYGEN__)
+#define STM32_HAS_RNG1 TRUE
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 TRUE
+#else
+#define STM32_HAS_RNG1 FALSE
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+/*===========================================================================*/
+/* STM32G070xx. */
+/*===========================================================================*/
+
+#if defined(STM32G070xx) || defined(__DOXYGEN__)
+
+/* Errata attributes.*/
+#define STM32_HAS_TIM1617_ERRATA TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_HAS_CR TRUE
+#define STM32_EXTI_SEPARATE_RF TRUE
+#define STM32_EXTI_HAS_GROUP2 FALSE
+#define STM32_EXTI_NUM_LINES 16
+#define STM32_EXTI_IMR1_MASK 0xFFF80000U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIODEN | \
+ RCC_IOPENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* OCTOSPI attributes.*/
+#define STM32_HAS_OCTOSPI1 FALSE
+#define STM32_HAS_OCTOSPI2 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 FALSE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#define STM32_HAS_TIM3 TRUE
+#define STM32_TIM3_IS_32BITS FALSE
+#define STM32_TIM3_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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM2 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_LPUART1 TRUE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC FALSE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI FALSE
+
+#endif /* defined(STM32G070xx) */
+
+/*===========================================================================*/
+/* STM32G071xx STM32G081xx. */
+/*===========================================================================*/
+
+#if defined(STM32G071xx) || defined(STM32G081xx)
+
+/* Errata attributes.*/
+#define STM32_HAS_TIM1617_ERRATA TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_HAS_CR TRUE
+#define STM32_EXTI_SEPARATE_RF TRUE
+#define STM32_EXTI_HAS_GROUP2 FALSE
+#define STM32_EXTI_NUM_LINES 33
+#define STM32_EXTI_IMR1_MASK 0xFFF80000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFFU
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF TRUE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIODEN | \
+ RCC_IOPENR_GPIOFEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* OCTOSPI attributes.*/
+#define STM32_HAS_OCTOSPI1 FALSE
+#define STM32_HAS_OCTOSPI2 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 FALSE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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_TIM14 TRUE
+#define STM32_TIM14_IS_32BITS FALSE
+#define STM32_TIM14_CHANNELS 1
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_LPUART1 TRUE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC FALSE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI FALSE
+
+#endif /* defined(STM32G071xx) || defined(STM32G081xx) */
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G4xx/hal_lld.c b/os/hal/ports/STM32/STM32G4xx/hal_lld.c
index 61d1e8f01b..77b4657e6f 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 ((!FOME_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < 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 */
+
+ /* 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..50bc3a0ba0 100644
--- a/os/hal/ports/STM32/STM32G4xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32G4xx/hal_lld.h
@@ -1,2004 +1,2012 @@
-/*
- 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 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 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
+
+ #if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+ #error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+ #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_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/STM32G4xx/platform.mk b/os/hal/ports/STM32/STM32G4xx/platform.mk
index f1d83a141f..4b3b0db196 100644
--- a/os/hal/ports/STM32/STM32G4xx/platform.mk
+++ b/os/hal/ports/STM32/STM32G4xx/platform.mk
@@ -1,46 +1,46 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx
-
-# 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/ADCv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32G4xx
+
+# 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/ADCv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/FDCANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/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/STM32G4xx/stm32_dmamux.h b/os/hal/ports/STM32/STM32G4xx/stm32_dmamux.h
index f4aec572a0..c8a0ed320e 100644
--- a/os/hal/ports/STM32/STM32G4xx/stm32_dmamux.h
+++ b/os/hal/ports/STM32/STM32G4xx/stm32_dmamux.h
@@ -1,183 +1,183 @@
-/*
- 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 STM32G4xx/stm32_dmamux.h
- * @brief STM32G4xx DMAMUX handler header.
- *
- * @addtogroup STM32G4xx_DMAMUX
- * @{
- */
-
-#ifndef STM32_DMAMUX_H
-#define STM32_DMAMUX_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name DMAMUX1 request sources
- * @{
- */
-#define STM32_DMAMUX1_REQ_GEN0 1
-#define STM32_DMAMUX1_REQ_GEN1 2
-#define STM32_DMAMUX1_REQ_GEN2 3
-#define STM32_DMAMUX1_REQ_GEN3 4
-#define STM32_DMAMUX1_ADC1 5
-#define STM32_DMAMUX1_DAC1_CH1 6
-#define STM32_DMAMUX1_DAC1_CH2 7
-#define STM32_DMAMUX1_TIM6_UP 8
-#define STM32_DMAMUX1_TIM7_UP 9
-#define STM32_DMAMUX1_SPI1_RX 10
-#define STM32_DMAMUX1_SPI1_TX 11
-#define STM32_DMAMUX1_SPI2_RX 12
-#define STM32_DMAMUX1_SPI2_TX 13
-#define STM32_DMAMUX1_SPI3_RX 14
-#define STM32_DMAMUX1_SPI3_TX 15
-#define STM32_DMAMUX1_I2C1_RX 16
-#define STM32_DMAMUX1_I2C1_TX 17
-#define STM32_DMAMUX1_I2C2_RX 18
-#define STM32_DMAMUX1_I2C2_TX 19
-#define STM32_DMAMUX1_I2C3_RX 20
-#define STM32_DMAMUX1_I2C3_TX 21
-#define STM32_DMAMUX1_I2C4_RX 22
-#define STM32_DMAMUX1_I2C4_TX 23
-#define STM32_DMAMUX1_USART1_RX 24
-#define STM32_DMAMUX1_USART1_TX 25
-#define STM32_DMAMUX1_USART2_RX 26
-#define STM32_DMAMUX1_USART2_TX 27
-#define STM32_DMAMUX1_USART3_RX 28
-#define STM32_DMAMUX1_USART3_TX 29
-#define STM32_DMAMUX1_UART4_RX 30
-#define STM32_DMAMUX1_UART4_TX 31
-#define STM32_DMAMUX1_UART5_RX 32
-#define STM32_DMAMUX1_UART5_TX 33
-#define STM32_DMAMUX1_LPUART1_RX 34
-#define STM32_DMAMUX1_LPUART1_TX 35
-#define STM32_DMAMUX1_ADC2 36
-#define STM32_DMAMUX1_ADC3 37
-#define STM32_DMAMUX1_ADC4 38
-#define STM32_DMAMUX1_ADC5 39
-#define STM32_DMAMUX1_QUADSPI 40
-#define STM32_DMAMUX1_DAC2_CH1 41
-#define STM32_DMAMUX1_TIM1_CH1 42
-#define STM32_DMAMUX1_TIM1_CH2 43
-#define STM32_DMAMUX1_TIM1_CH3 44
-#define STM32_DMAMUX1_TIM1_CH4 45
-#define STM32_DMAMUX1_TIM1_UP 46
-#define STM32_DMAMUX1_TIM1_TRIG 47
-#define STM32_DMAMUX1_TIM1_COM 48
-#define STM32_DMAMUX1_TIM8_CH1 49
-#define STM32_DMAMUX1_TIM8_CH2 50
-#define STM32_DMAMUX1_TIM8_CH3 51
-#define STM32_DMAMUX1_TIM8_CH4 52
-#define STM32_DMAMUX1_TIM8_UP 53
-#define STM32_DMAMUX1_TIM8_TRIG 54
-#define STM32_DMAMUX1_TIM8_COM 55
-#define STM32_DMAMUX1_TIM2_CH1 56
-#define STM32_DMAMUX1_TIM2_CH2 57
-#define STM32_DMAMUX1_TIM2_CH3 58
-#define STM32_DMAMUX1_TIM2_CH4 59
-#define STM32_DMAMUX1_TIM2_UP 60
-#define STM32_DMAMUX1_TIM3_CH1 61
-#define STM32_DMAMUX1_TIM3_CH2 62
-#define STM32_DMAMUX1_TIM3_CH3 63
-#define STM32_DMAMUX1_TIM3_CH4 64
-#define STM32_DMAMUX1_TIM3_UP 65
-#define STM32_DMAMUX1_TIM3_TRIG 66
-#define STM32_DMAMUX1_TIM4_CH1 67
-#define STM32_DMAMUX1_TIM4_CH2 68
-#define STM32_DMAMUX1_TIM4_CH3 69
-#define STM32_DMAMUX1_TIM4_CH4 70
-#define STM32_DMAMUX1_TIM4_UP 71
-#define STM32_DMAMUX1_TIM5_CH1 72
-#define STM32_DMAMUX1_TIM5_CH2 73
-#define STM32_DMAMUX1_TIM5_CH3 74
-#define STM32_DMAMUX1_TIM5_CH4 75
-#define STM32_DMAMUX1_TIM5_UP 76
-#define STM32_DMAMUX1_TIM5_TRIG 77
-#define STM32_DMAMUX1_TIM15_CH1 78
-#define STM32_DMAMUX1_TIM15_UP 79
-#define STM32_DMAMUX1_TIM15_TRIG 80
-#define STM32_DMAMUX1_TIM15_COM 81
-#define STM32_DMAMUX1_TIM16_CH1 82
-#define STM32_DMAMUX1_TIM16_UP 83
-#define STM32_DMAMUX1_TIM17_CH1 84
-#define STM32_DMAMUX1_TIM17_UP 85
-#define STM32_DMAMUX1_TIM20_CH1 86
-#define STM32_DMAMUX1_TIM20_CH2 87
-#define STM32_DMAMUX1_TIM20_CH3 88
-#define STM32_DMAMUX1_TIM20_CH4 89
-#define STM32_DMAMUX1_TIM20_UP 90
-#define STM32_DMAMUX1_AES_IN 91
-#define STM32_DMAMUX1_AES_OUT 92
-#define STM32_DMAMUX1_TIM20_TRIG 93
-#define STM32_DMAMUX1_TIM20_COM 94
-#define STM32_DMAMUX1_HRTIM_MASTER 95
-#define STM32_DMAMUX1_HRTIM_TIMA 96
-#define STM32_DMAMUX1_HRTIM_TIMB 97
-#define STM32_DMAMUX1_HRTIM_TIMC 98
-#define STM32_DMAMUX1_HRTIM_TIMD 99
-#define STM32_DMAMUX1_HRTIM_TIME 100
-#define STM32_DMAMUX1_HRTIM_TIMF 101
-#define STM32_DMAMUX1_DAC3_CH1 102
-#define STM32_DMAMUX1_DAC3_CH2 103
-#define STM32_DMAMUX1_DAC4_CH1 104
-#define STM32_DMAMUX1_DAC4_CH2 105
-#define STM32_DMAMUX1_SPI4_RX 106
-#define STM32_DMAMUX1_SPI4_TX 107
-#define STM32_DMAMUX1_SAI1_A 108
-#define STM32_DMAMUX1_SAI1_B 109
-#define STM32_DMAMUX1_FMAC_READ 110
-#define STM32_DMAMUX1_FMAC_WRITE 111
-#define STM32_DMAMUX1_CORDIC_READ 112
-#define STM32_DMAMUX1_CORDIC_WRITE 113
-#define STM32_DMAMUX1_UCPD1_RX 114
-#define STM32_DMAMUX1_UCPD1_TX 115
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMAMUX_H */
-
-/** @} */
+/*
+ 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 STM32G4xx/stm32_dmamux.h
+ * @brief STM32G4xx DMAMUX handler header.
+ *
+ * @addtogroup STM32G4xx_DMAMUX
+ * @{
+ */
+
+#ifndef STM32_DMAMUX_H
+#define STM32_DMAMUX_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name DMAMUX1 request sources
+ * @{
+ */
+#define STM32_DMAMUX1_REQ_GEN0 1
+#define STM32_DMAMUX1_REQ_GEN1 2
+#define STM32_DMAMUX1_REQ_GEN2 3
+#define STM32_DMAMUX1_REQ_GEN3 4
+#define STM32_DMAMUX1_ADC1 5
+#define STM32_DMAMUX1_DAC1_CH1 6
+#define STM32_DMAMUX1_DAC1_CH2 7
+#define STM32_DMAMUX1_TIM6_UP 8
+#define STM32_DMAMUX1_TIM7_UP 9
+#define STM32_DMAMUX1_SPI1_RX 10
+#define STM32_DMAMUX1_SPI1_TX 11
+#define STM32_DMAMUX1_SPI2_RX 12
+#define STM32_DMAMUX1_SPI2_TX 13
+#define STM32_DMAMUX1_SPI3_RX 14
+#define STM32_DMAMUX1_SPI3_TX 15
+#define STM32_DMAMUX1_I2C1_RX 16
+#define STM32_DMAMUX1_I2C1_TX 17
+#define STM32_DMAMUX1_I2C2_RX 18
+#define STM32_DMAMUX1_I2C2_TX 19
+#define STM32_DMAMUX1_I2C3_RX 20
+#define STM32_DMAMUX1_I2C3_TX 21
+#define STM32_DMAMUX1_I2C4_RX 22
+#define STM32_DMAMUX1_I2C4_TX 23
+#define STM32_DMAMUX1_USART1_RX 24
+#define STM32_DMAMUX1_USART1_TX 25
+#define STM32_DMAMUX1_USART2_RX 26
+#define STM32_DMAMUX1_USART2_TX 27
+#define STM32_DMAMUX1_USART3_RX 28
+#define STM32_DMAMUX1_USART3_TX 29
+#define STM32_DMAMUX1_UART4_RX 30
+#define STM32_DMAMUX1_UART4_TX 31
+#define STM32_DMAMUX1_UART5_RX 32
+#define STM32_DMAMUX1_UART5_TX 33
+#define STM32_DMAMUX1_LPUART1_RX 34
+#define STM32_DMAMUX1_LPUART1_TX 35
+#define STM32_DMAMUX1_ADC2 36
+#define STM32_DMAMUX1_ADC3 37
+#define STM32_DMAMUX1_ADC4 38
+#define STM32_DMAMUX1_ADC5 39
+#define STM32_DMAMUX1_QUADSPI 40
+#define STM32_DMAMUX1_DAC2_CH1 41
+#define STM32_DMAMUX1_TIM1_CH1 42
+#define STM32_DMAMUX1_TIM1_CH2 43
+#define STM32_DMAMUX1_TIM1_CH3 44
+#define STM32_DMAMUX1_TIM1_CH4 45
+#define STM32_DMAMUX1_TIM1_UP 46
+#define STM32_DMAMUX1_TIM1_TRIG 47
+#define STM32_DMAMUX1_TIM1_COM 48
+#define STM32_DMAMUX1_TIM8_CH1 49
+#define STM32_DMAMUX1_TIM8_CH2 50
+#define STM32_DMAMUX1_TIM8_CH3 51
+#define STM32_DMAMUX1_TIM8_CH4 52
+#define STM32_DMAMUX1_TIM8_UP 53
+#define STM32_DMAMUX1_TIM8_TRIG 54
+#define STM32_DMAMUX1_TIM8_COM 55
+#define STM32_DMAMUX1_TIM2_CH1 56
+#define STM32_DMAMUX1_TIM2_CH2 57
+#define STM32_DMAMUX1_TIM2_CH3 58
+#define STM32_DMAMUX1_TIM2_CH4 59
+#define STM32_DMAMUX1_TIM2_UP 60
+#define STM32_DMAMUX1_TIM3_CH1 61
+#define STM32_DMAMUX1_TIM3_CH2 62
+#define STM32_DMAMUX1_TIM3_CH3 63
+#define STM32_DMAMUX1_TIM3_CH4 64
+#define STM32_DMAMUX1_TIM3_UP 65
+#define STM32_DMAMUX1_TIM3_TRIG 66
+#define STM32_DMAMUX1_TIM4_CH1 67
+#define STM32_DMAMUX1_TIM4_CH2 68
+#define STM32_DMAMUX1_TIM4_CH3 69
+#define STM32_DMAMUX1_TIM4_CH4 70
+#define STM32_DMAMUX1_TIM4_UP 71
+#define STM32_DMAMUX1_TIM5_CH1 72
+#define STM32_DMAMUX1_TIM5_CH2 73
+#define STM32_DMAMUX1_TIM5_CH3 74
+#define STM32_DMAMUX1_TIM5_CH4 75
+#define STM32_DMAMUX1_TIM5_UP 76
+#define STM32_DMAMUX1_TIM5_TRIG 77
+#define STM32_DMAMUX1_TIM15_CH1 78
+#define STM32_DMAMUX1_TIM15_UP 79
+#define STM32_DMAMUX1_TIM15_TRIG 80
+#define STM32_DMAMUX1_TIM15_COM 81
+#define STM32_DMAMUX1_TIM16_CH1 82
+#define STM32_DMAMUX1_TIM16_UP 83
+#define STM32_DMAMUX1_TIM17_CH1 84
+#define STM32_DMAMUX1_TIM17_UP 85
+#define STM32_DMAMUX1_TIM20_CH1 86
+#define STM32_DMAMUX1_TIM20_CH2 87
+#define STM32_DMAMUX1_TIM20_CH3 88
+#define STM32_DMAMUX1_TIM20_CH4 89
+#define STM32_DMAMUX1_TIM20_UP 90
+#define STM32_DMAMUX1_AES_IN 91
+#define STM32_DMAMUX1_AES_OUT 92
+#define STM32_DMAMUX1_TIM20_TRIG 93
+#define STM32_DMAMUX1_TIM20_COM 94
+#define STM32_DMAMUX1_HRTIM_MASTER 95
+#define STM32_DMAMUX1_HRTIM_TIMA 96
+#define STM32_DMAMUX1_HRTIM_TIMB 97
+#define STM32_DMAMUX1_HRTIM_TIMC 98
+#define STM32_DMAMUX1_HRTIM_TIMD 99
+#define STM32_DMAMUX1_HRTIM_TIME 100
+#define STM32_DMAMUX1_HRTIM_TIMF 101
+#define STM32_DMAMUX1_DAC3_CH1 102
+#define STM32_DMAMUX1_DAC3_CH2 103
+#define STM32_DMAMUX1_DAC4_CH1 104
+#define STM32_DMAMUX1_DAC4_CH2 105
+#define STM32_DMAMUX1_SPI4_RX 106
+#define STM32_DMAMUX1_SPI4_TX 107
+#define STM32_DMAMUX1_SAI1_A 108
+#define STM32_DMAMUX1_SAI1_B 109
+#define STM32_DMAMUX1_FMAC_READ 110
+#define STM32_DMAMUX1_FMAC_WRITE 111
+#define STM32_DMAMUX1_CORDIC_READ 112
+#define STM32_DMAMUX1_CORDIC_WRITE 113
+#define STM32_DMAMUX1_UCPD1_RX 114
+#define STM32_DMAMUX1_UCPD1_TX 115
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMAMUX_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G4xx/stm32_isr.c b/os/hal/ports/STM32/STM32G4xx/stm32_isr.c
index 44138bdbf7..53c0de59e8 100644
--- a/os/hal/ports/STM32/STM32G4xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32G4xx/stm32_isr.c
@@ -1,183 +1,183 @@
-/*
- 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/stm32_isr.c
- * @brief STM32G4xx ISR handler code.
- *
- * @addtogroup STM32G4xx_ISR
- * @{
- */
-
-#include "hal.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define exti_serve_irq(pr, channel) { \
- \
- if ((pr) & (1U << (channel))) { \
- _pal_isr_code(channel); \
- } \
-}
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#include "stm32_exti0.inc"
-#include "stm32_exti1.inc"
-#include "stm32_exti2.inc"
-#include "stm32_exti3.inc"
-#include "stm32_exti4.inc"
-#include "stm32_exti5_9.inc"
-#include "stm32_exti10_15.inc"
-#include "stm32_exti16-40_41.inc"
-#include "stm32_exti17.inc"
-#include "stm32_exti18.inc"
-#include "stm32_exti19.inc"
-#include "stm32_exti20.inc"
-#include "stm32_exti21_22-29.inc"
-#include "stm32_exti30_32.inc"
-#include "stm32_exti33.inc"
-
-#include "stm32_fdcan1.inc"
-#include "stm32_fdcan2.inc"
-#include "stm32_fdcan3.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart3.inc"
-#include "stm32_uart4.inc"
-#include "stm32_uart5.inc"
-#include "stm32_lpuart1.inc"
-
-#include "stm32_tim1_15_16_17.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim4.inc"
-#include "stm32_tim5.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim8.inc"
-#include "stm32_tim20.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_irq_init();
- exti1_irq_init();
- exti2_irq_init();
- exti3_irq_init();
- exti4_irq_init();
- exti5_9_irq_init();
- exti10_15_irq_init();
- exti16_exti40_exti41_irq_init();
- exti17_irq_init();
- exti18_irq_init();
- exti19_irq_init();
- exti21_exti22_exti29_irq_init();
- exti30_32_irq_init();
- exti33_irq_init();
-
- fdcan1_irq_init();
- fdcan2_irq_init();
- fdcan3_irq_init();
-
- tim1_tim15_tim16_tim17_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim4_irq_init();
- tim5_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim8_irq_init();
- tim20_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_irq_init();
- uart4_irq_init();
- uart5_irq_init();
- lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_irq_deinit();
- exti1_irq_deinit();
- exti2_irq_deinit();
- exti3_irq_deinit();
- exti4_irq_deinit();
- exti5_9_irq_deinit();
- exti10_15_irq_deinit();
- exti16_exti40_exti41_irq_deinit();
- exti17_irq_deinit();
- exti18_irq_deinit();
- exti19_irq_deinit();
- exti21_exti22_exti29_irq_deinit();
- exti30_32_irq_deinit();
- exti33_irq_deinit();
-
- fdcan1_irq_deinit();
- fdcan2_irq_deinit();
- fdcan3_irq_deinit();
-
- tim1_tim15_tim16_tim17_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim4_irq_deinit();
- tim5_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim8_irq_deinit();
- tim20_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_irq_deinit();
- uart4_irq_deinit();
- uart5_irq_deinit();
- lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32G4xx ISR handler code.
+ *
+ * @addtogroup STM32G4xx_ISR
+ * @{
+ */
+
+#include "hal.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define exti_serve_irq(pr, channel) { \
+ \
+ if ((pr) & (1U << (channel))) { \
+ _pal_isr_code(channel); \
+ } \
+}
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#include "stm32_exti0.inc"
+#include "stm32_exti1.inc"
+#include "stm32_exti2.inc"
+#include "stm32_exti3.inc"
+#include "stm32_exti4.inc"
+#include "stm32_exti5_9.inc"
+#include "stm32_exti10_15.inc"
+#include "stm32_exti16-40_41.inc"
+#include "stm32_exti17.inc"
+#include "stm32_exti18.inc"
+#include "stm32_exti19.inc"
+#include "stm32_exti20.inc"
+#include "stm32_exti21_22-29.inc"
+#include "stm32_exti30_32.inc"
+#include "stm32_exti33.inc"
+
+#include "stm32_fdcan1.inc"
+#include "stm32_fdcan2.inc"
+#include "stm32_fdcan3.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart3.inc"
+#include "stm32_uart4.inc"
+#include "stm32_uart5.inc"
+#include "stm32_lpuart1.inc"
+
+#include "stm32_tim1_15_16_17.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim4.inc"
+#include "stm32_tim5.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim8.inc"
+#include "stm32_tim20.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_irq_init();
+ exti1_irq_init();
+ exti2_irq_init();
+ exti3_irq_init();
+ exti4_irq_init();
+ exti5_9_irq_init();
+ exti10_15_irq_init();
+ exti16_exti40_exti41_irq_init();
+ exti17_irq_init();
+ exti18_irq_init();
+ exti19_irq_init();
+ exti21_exti22_exti29_irq_init();
+ exti30_32_irq_init();
+ exti33_irq_init();
+
+ fdcan1_irq_init();
+ fdcan2_irq_init();
+ fdcan3_irq_init();
+
+ tim1_tim15_tim16_tim17_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim4_irq_init();
+ tim5_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim8_irq_init();
+ tim20_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_irq_init();
+ uart4_irq_init();
+ uart5_irq_init();
+ lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_irq_deinit();
+ exti1_irq_deinit();
+ exti2_irq_deinit();
+ exti3_irq_deinit();
+ exti4_irq_deinit();
+ exti5_9_irq_deinit();
+ exti10_15_irq_deinit();
+ exti16_exti40_exti41_irq_deinit();
+ exti17_irq_deinit();
+ exti18_irq_deinit();
+ exti19_irq_deinit();
+ exti21_exti22_exti29_irq_deinit();
+ exti30_32_irq_deinit();
+ exti33_irq_deinit();
+
+ fdcan1_irq_deinit();
+ fdcan2_irq_deinit();
+ fdcan3_irq_deinit();
+
+ tim1_tim15_tim16_tim17_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim4_irq_deinit();
+ tim5_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim8_irq_deinit();
+ tim20_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_irq_deinit();
+ uart4_irq_deinit();
+ uart5_irq_deinit();
+ lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G4xx/stm32_isr.h b/os/hal/ports/STM32/STM32G4xx/stm32_isr.h
index 9445758ead..d1dfdd066d 100644
--- a/os/hal/ports/STM32/STM32G4xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32G4xx/stm32_isr.h
@@ -1,298 +1,298 @@
-/*
- 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/stm32_isr.h
- * @brief STM32G4xx ISR handler header.
- *
- * @addtogroup STM32G4xx_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_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_SUPPRESS_ISR
-#define STM32_TIM20_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_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC unit.
- */
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC3_HANDLER VectorFC
-#define STM32_ADC4_HANDLER Vector134
-#define STM32_ADC5_HANDLER Vector138
-
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC3_NUMBER 47
-#define STM32_ADC4_NUMBER 61
-#define STM32_ADC5_NUMBER 62
-
-/*
- * DMA unit.
- */
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#if !defined(STM32G431xx) && !defined(STM32G441xx)
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH8_HANDLER Vector1C0
-#endif
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH6_HANDLER Vector1C4
-#if !defined(STM32G431xx) && !defined(STM32G441xx)
-#define STM32_DMA2_CH7_HANDLER Vector1C8
-#define STM32_DMA2_CH8_HANDLER Vector1CC
-#endif
-
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#if !defined(STM32G431xx) && !defined(STM32G441xx)
-#define STM32_DMA1_CH7_NUMBER 17
-#define STM32_DMA1_CH8_NUMBER 96
-#endif
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-#define STM32_DMA2_CH6_NUMBER 97
-#if !defined(STM32G431xx) && !defined(STM32G441xx)
-#define STM32_DMA2_CH7_NUMBER 98
-#define STM32_DMA2_CH8_NUMBER 99
-#endif
-
-/*
- * 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_EXTI164041_HANDLER Vector44 /* PVD PVM */
-#define STM32_EXTI17_HANDLER VectorE4 /* RTC ALARM */
-#define STM32_EXTI18_HANDLER VectorE8 /* USB WAKEUP */
-#define STM32_EXTI19_HANDLER Vector48 /* RTC TAMP CSS */
-#define STM32_EXTI20_HANDLER Vector4C /* RTC WAKEUP */
-#define STM32_EXTI212229_HANDLER Vector140 /* COMP1..3 */
-#define STM32_EXTI30_32_HANDLER Vector144 /* COMP4..6 */
-#define STM32_EXTI33_HANDLER Vector148 /* COMP7 */
-
-#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_EXTI164041_NUMBER 1
-#define STM32_EXTI17_NUMBER 41
-#define STM32_EXTI18_NUMBER 42
-#define STM32_EXTI19_NUMBER 2
-#define STM32_EXTI20_NUMBER 3
-#define STM32_EXTI212229_NUMBER 64
-#define STM32_EXTI30_32_NUMBER 65
-#define STM32_EXTI33_NUMBER 66
-
-/*
- * FDCAN units.
- */
-#define STM32_FDCAN1_IT0_HANDLER Vector94
-#define STM32_FDCAN1_IT1_HANDLER Vector98
-#define STM32_FDCAN2_IT0_HANDLER Vector198
-#define STM32_FDCAN2_IT1_HANDLER Vector19C
-#define STM32_FDCAN3_IT0_HANDLER Vector1A0
-#define STM32_FDCAN3_IT1_HANDLER Vector1A4
-
-#define STM32_FDCAN1_IT0_NUMBER 21
-#define STM32_FDCAN1_IT1_NUMBER 22
-#define STM32_FDCAN2_IT0_NUMBER 86
-#define STM32_FDCAN2_IT1_NUMBER 87
-#define STM32_FDCAN3_IT0_NUMBER 88
-#define STM32_FDCAN3_IT1_NUMBER 89
-
-/*
- * 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 Vector1B0
-#define STM32_I2C3_ERROR_HANDLER Vector1B4
-#define STM32_I2C4_EVENT_HANDLER Vector188
-#define STM32_I2C4_ERROR_HANDLER Vector18C
-
-#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 92
-#define STM32_I2C3_ERROR_NUMBER 93
-#define STM32_I2C4_EVENT_NUMBER 82
-#define STM32_I2C4_ERROR_NUMBER 83
-
-/*
- * QUADSPI unit.
- */
-#define STM32_QUADSPI1_HANDLER Vector1BC
-#define STM32_QUADSPI1_NUMBER 95
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_BRK_TIM15_HANDLER VectorA0
-#define STM32_TIM1_UP_TIM16_HANDLER VectorA4
-#define STM32_TIM1_TRGCO_TIM17_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_HANDLER VectorEC
-#define STM32_TIM8_UP_HANDLER VectorF0
-#define STM32_TIM8_TRGCO_HANDLER VectorF4
-#define STM32_TIM8_CC_HANDLER VectorF8
-#define STM32_TIM20_BRK_HANDLER Vector174
-#define STM32_TIM20_UP_HANDLER Vector178
-#define STM32_TIM20_TRGCO_HANDLER Vector17C
-#define STM32_TIM20_CC_HANDLER Vector180
-
-#define STM32_TIM1_BRK_TIM15_NUMBER 24
-#define STM32_TIM1_UP_TIM16_NUMBER 25
-#define STM32_TIM1_TRGCO_TIM17_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_NUMBER 43
-#define STM32_TIM8_UP_NUMBER 44
-#define STM32_TIM8_TRGCO_NUMBER 45
-#define STM32_TIM8_CC_NUMBER 46
-#define STM32_TIM20_BRK_NUMBER 77
-#define STM32_TIM20_UP_NUMBER 78
-#define STM32_TIM20_TRGCO_NUMBER 79
-#define STM32_TIM20_CC_NUMBER 80
-
-/*
- * USART/UART 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_LPUART1_HANDLER Vector1AC
-
-#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_LPUART1_NUMBER 91
-
-/*
- * USB units.
- */
-#define STM32_USB1_HP_HANDLER Vector8C
-#define STM32_USB1_LP_HANDLER Vector90
-#define STM32_USB1_HP_NUMBER 19
-#define STM32_USB1_LP_NUMBER 20
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32G4xx ISR handler header.
+ *
+ * @addtogroup STM32G4xx_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_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_SUPPRESS_ISR
+#define STM32_TIM20_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_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC unit.
+ */
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC3_HANDLER VectorFC
+#define STM32_ADC4_HANDLER Vector134
+#define STM32_ADC5_HANDLER Vector138
+
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC3_NUMBER 47
+#define STM32_ADC4_NUMBER 61
+#define STM32_ADC5_NUMBER 62
+
+/*
+ * DMA unit.
+ */
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#if !defined(STM32G431xx) && !defined(STM32G441xx)
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH8_HANDLER Vector1C0
+#endif
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH6_HANDLER Vector1C4
+#if !defined(STM32G431xx) && !defined(STM32G441xx)
+#define STM32_DMA2_CH7_HANDLER Vector1C8
+#define STM32_DMA2_CH8_HANDLER Vector1CC
+#endif
+
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#if !defined(STM32G431xx) && !defined(STM32G441xx)
+#define STM32_DMA1_CH7_NUMBER 17
+#define STM32_DMA1_CH8_NUMBER 96
+#endif
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+#define STM32_DMA2_CH6_NUMBER 97
+#if !defined(STM32G431xx) && !defined(STM32G441xx)
+#define STM32_DMA2_CH7_NUMBER 98
+#define STM32_DMA2_CH8_NUMBER 99
+#endif
+
+/*
+ * 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_EXTI164041_HANDLER Vector44 /* PVD PVM */
+#define STM32_EXTI17_HANDLER VectorE4 /* RTC ALARM */
+#define STM32_EXTI18_HANDLER VectorE8 /* USB WAKEUP */
+#define STM32_EXTI19_HANDLER Vector48 /* RTC TAMP CSS */
+#define STM32_EXTI20_HANDLER Vector4C /* RTC WAKEUP */
+#define STM32_EXTI212229_HANDLER Vector140 /* COMP1..3 */
+#define STM32_EXTI30_32_HANDLER Vector144 /* COMP4..6 */
+#define STM32_EXTI33_HANDLER Vector148 /* COMP7 */
+
+#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_EXTI164041_NUMBER 1
+#define STM32_EXTI17_NUMBER 41
+#define STM32_EXTI18_NUMBER 42
+#define STM32_EXTI19_NUMBER 2
+#define STM32_EXTI20_NUMBER 3
+#define STM32_EXTI212229_NUMBER 64
+#define STM32_EXTI30_32_NUMBER 65
+#define STM32_EXTI33_NUMBER 66
+
+/*
+ * FDCAN units.
+ */
+#define STM32_FDCAN1_IT0_HANDLER Vector94
+#define STM32_FDCAN1_IT1_HANDLER Vector98
+#define STM32_FDCAN2_IT0_HANDLER Vector198
+#define STM32_FDCAN2_IT1_HANDLER Vector19C
+#define STM32_FDCAN3_IT0_HANDLER Vector1A0
+#define STM32_FDCAN3_IT1_HANDLER Vector1A4
+
+#define STM32_FDCAN1_IT0_NUMBER 21
+#define STM32_FDCAN1_IT1_NUMBER 22
+#define STM32_FDCAN2_IT0_NUMBER 86
+#define STM32_FDCAN2_IT1_NUMBER 87
+#define STM32_FDCAN3_IT0_NUMBER 88
+#define STM32_FDCAN3_IT1_NUMBER 89
+
+/*
+ * 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 Vector1B0
+#define STM32_I2C3_ERROR_HANDLER Vector1B4
+#define STM32_I2C4_EVENT_HANDLER Vector188
+#define STM32_I2C4_ERROR_HANDLER Vector18C
+
+#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 92
+#define STM32_I2C3_ERROR_NUMBER 93
+#define STM32_I2C4_EVENT_NUMBER 82
+#define STM32_I2C4_ERROR_NUMBER 83
+
+/*
+ * QUADSPI unit.
+ */
+#define STM32_QUADSPI1_HANDLER Vector1BC
+#define STM32_QUADSPI1_NUMBER 95
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_BRK_TIM15_HANDLER VectorA0
+#define STM32_TIM1_UP_TIM16_HANDLER VectorA4
+#define STM32_TIM1_TRGCO_TIM17_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_HANDLER VectorEC
+#define STM32_TIM8_UP_HANDLER VectorF0
+#define STM32_TIM8_TRGCO_HANDLER VectorF4
+#define STM32_TIM8_CC_HANDLER VectorF8
+#define STM32_TIM20_BRK_HANDLER Vector174
+#define STM32_TIM20_UP_HANDLER Vector178
+#define STM32_TIM20_TRGCO_HANDLER Vector17C
+#define STM32_TIM20_CC_HANDLER Vector180
+
+#define STM32_TIM1_BRK_TIM15_NUMBER 24
+#define STM32_TIM1_UP_TIM16_NUMBER 25
+#define STM32_TIM1_TRGCO_TIM17_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_NUMBER 43
+#define STM32_TIM8_UP_NUMBER 44
+#define STM32_TIM8_TRGCO_NUMBER 45
+#define STM32_TIM8_CC_NUMBER 46
+#define STM32_TIM20_BRK_NUMBER 77
+#define STM32_TIM20_UP_NUMBER 78
+#define STM32_TIM20_TRGCO_NUMBER 79
+#define STM32_TIM20_CC_NUMBER 80
+
+/*
+ * USART/UART 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_LPUART1_HANDLER Vector1AC
+
+#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_LPUART1_NUMBER 91
+
+/*
+ * USB units.
+ */
+#define STM32_USB1_HP_HANDLER Vector8C
+#define STM32_USB1_LP_HANDLER Vector90
+#define STM32_USB1_HP_NUMBER 19
+#define STM32_USB1_LP_NUMBER 20
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32G4xx/stm32_rcc.h b/os/hal/ports/STM32/STM32G4xx/stm32_rcc.h
index 9877f630d4..ba79dd899b 100644
--- a/os/hal/ports/STM32/STM32G4xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32G4xx/stm32_rcc.h
@@ -1,1366 +1,1366 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32g4xx.h.
- *
- * @addtogroup STM32G4xx_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 (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R1(mask, lp) { \
- RCC->APB1ENR1 |= (mask); \
- if (lp) \
- RCC->APB1SMENR1 |= (mask); \
- else \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R1(mask) { \
- RCC->APB1ENR1 &= ~(mask); \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R1(mask) { \
- RCC->APB1RSTR1 |= (mask); \
- RCC->APB1RSTR1 &= ~(mask); \
- (void)RCC->APB1RSTR1; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R2(mask, lp) { \
- RCC->APB1ENR2 |= (mask); \
- if (lp) \
- RCC->APB1SMENR2 |= (mask); \
- else \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R2(mask) { \
- RCC->APB1ENR2 &= ~(mask); \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R2(mask) { \
- RCC->APB1RSTR2 |= (mask); \
- RCC->APB1RSTR2 &= ~(mask); \
- (void)RCC->APB1RSTR2; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB2 bus.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- if (lp) \
- RCC->APB2SMENR |= (mask); \
- else \
- RCC->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->AHB1SMENR |= (mask); \
- else \
- RCC->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB2SMENR |= (mask); \
- else \
- RCC->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB3SMENR |= (mask); \
- else \
- RCC->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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 Enables the ADC1/ADC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC12(lp) rccEnableAHB2(RCC_AHB2ENR_ADC12EN, lp)
-
-/**
- * @brief Disables the ADC1/ADC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC12() rccDisableAHB2(RCC_AHB2ENR_ADC12EN)
-
-/**
- * @brief Resets the ADC1/ADC2 peripheral.
- *
- * @api
- */
-#define rccResetADC12() rccResetAHB2(RCC_AHB2RSTR_ADC12RST)
-
-/**
- * @brief Enables the ADC3/ADC4/ADC5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC345(lp) rccEnableAHB2(RCC_AHB2ENR_ADC345EN, lp)
-
-/**
- * @brief Disables the ADC3/ADC4/ADC5 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC345() rccDisableAHB2(RCC_AHB2ENR_ADC345EN)
-
-/**
- * @brief Resets the ADC3/ADC4/ADC5 peripheral.
- *
- * @api
- */
-#define rccResetADC345() rccResetAHB2(RCC_AHB2RSTR_ADC345RST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC1(lp) rccEnableAHB2(RCC_AHB2ENR_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAHB2(RCC_AHB2ENR_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAHB2(RCC_AHB2RSTR_DAC1RST)
-
-/**
- * @brief Enables the DAC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC2(lp) rccEnableAHB2(RCC_AHB2ENR_DAC2EN, lp)
-
-/**
- * @brief Disables the DAC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC2() rccDisableAHB2(RCC_AHB2ENR_DAC2EN)
-
-/**
- * @brief Resets the DAC2 peripheral.
- *
- * @api
- */
-#define rccResetDAC2() rccResetAHB2(RCC_AHB2RSTR_DAC2RST)
-
-/**
- * @brief Enables the DAC3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC3(lp) rccEnableAHB2(RCC_AHB2ENR_DAC3EN, lp)
-
-/**
- * @brief Disables the DAC3 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC3() rccDisableAHB2(RCC_AHB2ENR_DAC3EN)
-
-/**
- * @brief Resets the DAC3 peripheral.
- *
- * @api
- */
-#define rccResetDAC3() rccResetAHB2(RCC_AHB2RSTR_DAC3RST)
-
-/**
- * @brief Enables the DAC4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC4(lp) rccEnableAHB2(RCC_AHB2ENR_DAC4EN, lp)
-
-/**
- * @brief Disables the DAC4 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC4() rccDisableAHB2(RCC_AHB2ENR_DAC4EN)
-
-/**
- * @brief Resets the DAC4 peripheral.
- *
- * @api
- */
-#define rccResetDAC4() rccResetAHB2(RCC_AHB2RSTR_DAC4RST)
-/** @} */
-
-/**
- * @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 DMAMUX peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMAMUX peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMAMUX(lp) rccEnableAHB1(RCC_AHB1ENR_DMAMUX1EN, lp)
-
-/**
- * @brief Disables the DMAMUX peripheral clock.
- *
- * @api
- */
-#define rccDisableDMAMUX() rccDisableAHB1(RCC_AHB1ENR_DMAMUX1EN)
-
-/**
- * @brief Resets the DMAMUX peripheral.
- *
- * @api
- */
-#define rccResetDMAMUX() rccResetAHB1(RCC_AHB1RSTR_DMAMUX1RST)
-/** @} */
-
-/**
- * @name FDCAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FDCAN peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableFDCAN(lp) rccEnableAPB1R1(RCC_APB1ENR1_FDCANEN, lp)
-
-/**
- * @brief Disables the FDCAN peripheral clock.
- *
- * @api
- */
-#define rccDisableFDCAN() rccDisableAPB1R1(RCC_APB1ENR1_FDCANEN)
-
-/**
- * @brief Resets the FDCAN peripheral.
- *
- * @api
- */
-#define rccResetFDCAN() rccResetAPB1R1(RCC_APB1RSTR1_FDCANRST)
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
-
-/**
- * @brief Disables PWR interface clock.
- *
- * @api
- */
-#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
-
-/**
- * @brief Resets the PWR interface.
- *
- * @api
- */
-#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
-/** @} */
-
-/**
- * @name FDCAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FDCAN1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableFDCAN1(lp) rccEnableAPB1R1(RCC_APB1ENR1_FDCANEN, lp)
-
-/**
- * @brief Disables the FDCAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableFDCAN1() rccDisableAPB1R1(RCC_APB1ENR1_FDCANEN)
-
-/**
- * @brief Resets the FDCAN1 peripheral.
- *
- * @api
- */
-#define rccResetFDCAN1() rccResetAPB1R1(RCC_APB1RSTR1_FDCANRST)
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
-
-/**
- * @brief Disables the I2C1 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
-
-/**
- * @brief Resets the I2C1 peripheral.
- *
- * @api
- */
-#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
-
-/**
- * @brief Enables the I2C2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
-
-/**
- * @brief Disables the I2C2 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
-
-/**
- * @brief Resets the I2C2 peripheral.
- *
- * @api
- */
-#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
-
-/**
- * @brief Enables the I2C3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
-
-/**
- * @brief Disables the I2C3 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
-
-/**
- * @brief Resets the I2C3 peripheral.
- *
- * @api
- */
-#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
-
-/**
- * @brief Enables the I2C4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
-
-/**
- * @brief Disables the I2C4 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
-
-/**
- * @brief Resets the I2C4 peripheral.
- *
- * @api
- */
-#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
-/** @} */
-
-/**
- * @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 RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
-
-/**
- * @brief Disables the SPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
-
-/**
- * @brief Resets the SPI2 peripheral.
- *
- * @api
- */
-#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
-
-/**
- * @brief Enables the SPI3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
-
-/**
- * @brief Disables the SPI3 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
-
-/**
- * @brief Resets the SPI3 peripheral.
- *
- * @api
- */
-#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_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)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
-
-/**
- * @brief Disables the TIM2 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
-
-/**
- * @brief Resets the TIM2 peripheral.
- *
- * @api
- */
-#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
-
-/**
- * @brief Enables the TIM3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
-
-/**
- * @brief Disables the TIM3 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
-
-/**
- * @brief Enables the TIM4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
-
-/**
- * @brief Disables the TIM4 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
-
-/**
- * @brief Resets the TIM4 peripheral.
- *
- * @api
- */
-#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
-
-/**
- * @brief Enables the TIM5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
-
-/**
- * @brief Disables the TIM5 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
-
-/**
- * @brief Resets the TIM5 peripheral.
- *
- * @api
- */
-#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
-
-/**
- * @brief Enables the TIM6 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
-
-/**
- * @brief Disables the TIM6 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
-
-/**
- * @brief Resets the TIM6 peripheral.
- *
- * @api
- */
-#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
-
-/**
- * @brief Enables the TIM7 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
-
-/**
- * @brief Disables the TIM7 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
-
-/**
- * @brief Resets the TIM7 peripheral.
- *
- * @api
- */
-#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-
-/**
- * @brief Enables the TIM20 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM20(lp) rccEnableAPB2(RCC_APB2ENR_TIM20EN, lp)
-
-/**
- * @brief Disables the TIM20 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM20() rccDisableAPB2(RCC_APB2ENR_TIM20EN)
-
-/**
- * @brief Resets the TIM20 peripheral.
- *
- * @api
- */
-#define rccResetTIM20() rccResetAPB2(RCC_APB2RSTR_TIM20RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
-
-/**
- * @brief Disables the USART2 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
-
-/**
- * @brief Resets the USART2 peripheral.
- *
- * @api
- */
-#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
-
-/**
- * @brief Enables the USART3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
-
-/**
- * @brief Disables the USART3 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
-
-/**
- * @brief Resets the USART3 peripheral.
- *
- * @api
- */
-#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
-
-/**
- * @brief Enables the UART4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
-
-/**
- * @brief Enables the UART5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
-
-/**
- * @brief Disables the UART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
-
-/**
- * @brief Resets the UART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBRST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32g4xx.h.
+ *
+ * @addtogroup STM32G4xx_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 (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R1(mask, lp) { \
+ RCC->APB1ENR1 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR1 |= (mask); \
+ else \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R1(mask) { \
+ RCC->APB1ENR1 &= ~(mask); \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R1(mask) { \
+ RCC->APB1RSTR1 |= (mask); \
+ RCC->APB1RSTR1 &= ~(mask); \
+ (void)RCC->APB1RSTR1; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R2(mask, lp) { \
+ RCC->APB1ENR2 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR2 |= (mask); \
+ else \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R2(mask) { \
+ RCC->APB1ENR2 &= ~(mask); \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R2(mask) { \
+ RCC->APB1RSTR2 |= (mask); \
+ RCC->APB1RSTR2 &= ~(mask); \
+ (void)RCC->APB1RSTR2; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB2 bus.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ if (lp) \
+ RCC->APB2SMENR |= (mask); \
+ else \
+ RCC->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR |= (mask); \
+ else \
+ RCC->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR |= (mask); \
+ else \
+ RCC->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR |= (mask); \
+ else \
+ RCC->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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 Enables the ADC1/ADC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC12(lp) rccEnableAHB2(RCC_AHB2ENR_ADC12EN, lp)
+
+/**
+ * @brief Disables the ADC1/ADC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC12() rccDisableAHB2(RCC_AHB2ENR_ADC12EN)
+
+/**
+ * @brief Resets the ADC1/ADC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC12() rccResetAHB2(RCC_AHB2RSTR_ADC12RST)
+
+/**
+ * @brief Enables the ADC3/ADC4/ADC5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC345(lp) rccEnableAHB2(RCC_AHB2ENR_ADC345EN, lp)
+
+/**
+ * @brief Disables the ADC3/ADC4/ADC5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC345() rccDisableAHB2(RCC_AHB2ENR_ADC345EN)
+
+/**
+ * @brief Resets the ADC3/ADC4/ADC5 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC345() rccResetAHB2(RCC_AHB2RSTR_ADC345RST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC1(lp) rccEnableAHB2(RCC_AHB2ENR_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAHB2(RCC_AHB2ENR_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAHB2(RCC_AHB2RSTR_DAC1RST)
+
+/**
+ * @brief Enables the DAC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC2(lp) rccEnableAHB2(RCC_AHB2ENR_DAC2EN, lp)
+
+/**
+ * @brief Disables the DAC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC2() rccDisableAHB2(RCC_AHB2ENR_DAC2EN)
+
+/**
+ * @brief Resets the DAC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC2() rccResetAHB2(RCC_AHB2RSTR_DAC2RST)
+
+/**
+ * @brief Enables the DAC3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC3(lp) rccEnableAHB2(RCC_AHB2ENR_DAC3EN, lp)
+
+/**
+ * @brief Disables the DAC3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC3() rccDisableAHB2(RCC_AHB2ENR_DAC3EN)
+
+/**
+ * @brief Resets the DAC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC3() rccResetAHB2(RCC_AHB2RSTR_DAC3RST)
+
+/**
+ * @brief Enables the DAC4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC4(lp) rccEnableAHB2(RCC_AHB2ENR_DAC4EN, lp)
+
+/**
+ * @brief Disables the DAC4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC4() rccDisableAHB2(RCC_AHB2ENR_DAC4EN)
+
+/**
+ * @brief Resets the DAC4 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC4() rccResetAHB2(RCC_AHB2RSTR_DAC4RST)
+/** @} */
+
+/**
+ * @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 DMAMUX peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMAMUX peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMAMUX(lp) rccEnableAHB1(RCC_AHB1ENR_DMAMUX1EN, lp)
+
+/**
+ * @brief Disables the DMAMUX peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMAMUX() rccDisableAHB1(RCC_AHB1ENR_DMAMUX1EN)
+
+/**
+ * @brief Resets the DMAMUX peripheral.
+ *
+ * @api
+ */
+#define rccResetDMAMUX() rccResetAHB1(RCC_AHB1RSTR_DMAMUX1RST)
+/** @} */
+
+/**
+ * @name FDCAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FDCAN peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableFDCAN(lp) rccEnableAPB1R1(RCC_APB1ENR1_FDCANEN, lp)
+
+/**
+ * @brief Disables the FDCAN peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFDCAN() rccDisableAPB1R1(RCC_APB1ENR1_FDCANEN)
+
+/**
+ * @brief Resets the FDCAN peripheral.
+ *
+ * @api
+ */
+#define rccResetFDCAN() rccResetAPB1R1(RCC_APB1RSTR1_FDCANRST)
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
+
+/**
+ * @brief Disables PWR interface clock.
+ *
+ * @api
+ */
+#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
+
+/**
+ * @brief Resets the PWR interface.
+ *
+ * @api
+ */
+#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
+/** @} */
+
+/**
+ * @name FDCAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FDCAN1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableFDCAN1(lp) rccEnableAPB1R1(RCC_APB1ENR1_FDCANEN, lp)
+
+/**
+ * @brief Disables the FDCAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFDCAN1() rccDisableAPB1R1(RCC_APB1ENR1_FDCANEN)
+
+/**
+ * @brief Resets the FDCAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetFDCAN1() rccResetAPB1R1(RCC_APB1RSTR1_FDCANRST)
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
+
+/**
+ * @brief Disables the I2C1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
+
+/**
+ * @brief Resets the I2C1 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
+
+/**
+ * @brief Enables the I2C2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
+
+/**
+ * @brief Disables the I2C2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
+
+/**
+ * @brief Resets the I2C2 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
+
+/**
+ * @brief Enables the I2C3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
+
+/**
+ * @brief Disables the I2C3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
+
+/**
+ * @brief Resets the I2C3 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
+
+/**
+ * @brief Enables the I2C4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
+
+/**
+ * @brief Disables the I2C4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
+
+/**
+ * @brief Resets the I2C4 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
+/** @} */
+
+/**
+ * @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 RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
+
+/**
+ * @brief Disables the SPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
+
+/**
+ * @brief Resets the SPI2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
+
+/**
+ * @brief Enables the SPI3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
+
+/**
+ * @brief Disables the SPI3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
+
+/**
+ * @brief Resets the SPI3 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_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)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
+
+/**
+ * @brief Disables the TIM2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
+
+/**
+ * @brief Resets the TIM2 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
+
+/**
+ * @brief Enables the TIM3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
+
+/**
+ * @brief Disables the TIM3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
+
+/**
+ * @brief Resets the TIM3 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
+
+/**
+ * @brief Enables the TIM4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
+
+/**
+ * @brief Disables the TIM4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
+
+/**
+ * @brief Resets the TIM4 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
+
+/**
+ * @brief Enables the TIM5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
+
+/**
+ * @brief Disables the TIM5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
+
+/**
+ * @brief Resets the TIM5 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
+
+/**
+ * @brief Enables the TIM6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
+
+/**
+ * @brief Disables the TIM6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
+
+/**
+ * @brief Resets the TIM6 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
+
+/**
+ * @brief Enables the TIM7 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
+
+/**
+ * @brief Disables the TIM7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
+
+/**
+ * @brief Resets the TIM7 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+
+/**
+ * @brief Enables the TIM20 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM20(lp) rccEnableAPB2(RCC_APB2ENR_TIM20EN, lp)
+
+/**
+ * @brief Disables the TIM20 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM20() rccDisableAPB2(RCC_APB2ENR_TIM20EN)
+
+/**
+ * @brief Resets the TIM20 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM20() rccResetAPB2(RCC_APB2RSTR_TIM20RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
+
+/**
+ * @brief Disables the USART2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
+
+/**
+ * @brief Resets the USART2 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
+
+/**
+ * @brief Enables the USART3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
+
+/**
+ * @brief Disables the USART3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
+
+/**
+ * @brief Resets the USART3 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
+
+/**
+ * @brief Enables the UART4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
+
+/**
+ * @brief Enables the UART5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
+
+/**
+ * @brief Disables the UART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
+
+/**
+ * @brief Resets the UART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBRST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32G4xx/stm32_registry.h b/os/hal/ports/STM32/STM32G4xx/stm32_registry.h
index f86ef00141..b9dd413daf 100644
--- a/os/hal/ports/STM32/STM32G4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32G4xx/stm32_registry.h
@@ -1,524 +1,524 @@
-/*
- 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 STM32G4xx/stm32_registry.h
- * @brief STM32G4xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32G4xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 128
-#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 18
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
-} while (false)
-
- /* Enabling RTC-related EXTI lines.*/
-#define STM32_RTC_ENABLE_ALL_EXTI() do { \
- 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); \
-} while (false)
-
-/* Clearing EXTI interrupts. */
-#define STM32_RTC_CLEAR_ALL_EXTI() do { \
- extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | \
- EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | \
- EXTI_MASK1(STM32_RTC_WKUP_EXTI)); \
-} while (false)
-
-/* Masks used to preserve state of RTC and TAMP register reserved bits. */
-#define STM32_RTC_CR_MASK 0xE7FFFF7F
-#define STM32_RTC_PRER_MASK 0x007F7FFF
-#define STM32_TAMP_CR1_MASK 0x003C0007
-#define STM32_TAMP_CR2_MASK 0x07070007
-#define STM32_TAMP_FLTCR_MASK 0x000000FF
-#define STM32_TAMP_IER_MASK 0x003C0007
-
-#if defined(STM32G441xx) || defined(STM32G483xx) || defined(STM32G484xx) || \
- defined(__DOXYGEN__)
-#define STM32_HAS_HASH1 TRUE
-#define STM32_HAS_CRYP1 TRUE
-#else
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-/*===========================================================================*/
-/* STM32G473xx, STM32G4843xx, STM32G474xx, STM32G484xx. */
-/*===========================================================================*/
-
-#if defined(STM32G473xx) || defined(STM32G483xx) || \
- defined(STM32G474xx) || defined(STM32G484xx) || \
- defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 TRUE
-#define STM32_HAS_ADC4 TRUE
-#define STM32_HAS_ADC5 TRUE
-
-/* CAN attributes.*/
-#define STM32_HAS_FDCAN1 TRUE
-#define STM32_HAS_FDCAN2 TRUE
-#define STM32_HAS_FDCAN3 TRUE
-#define STM32_FDCAN_FLS_NBR 28U
-#define STM32_FDCAN_FLE_NBR 8U
-#define STM32_FDCAN_RF0_NBR 3U
-#define STM32_FDCAN_RF1_NBR 3U
-#define STM32_FDCAN_RB_NBR 0U
-#define STM32_FDCAN_TEF_NBR 3U
-#define STM32_FDCAN_TB_NBR 3U
-#define STM32_FDCAN_TM_NBR 0U
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_HAS_DAC2_CH2 FALSE
-#define STM32_HAS_DAC3_CH1 TRUE
-#define STM32_HAS_DAC3_CH2 TRUE
-#define STM32_HAS_DAC4_CH1 TRUE
-#define STM32_HAS_DAC4_CH2 TRUE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 8
-#define STM32_DMA2_NUM_CHANNELS 8
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_HAS_CR FALSE
-#define STM32_EXTI_SEPARATE_RF FALSE
-#define STM32_EXTI_NUM_LINES 44
-#define STM32_EXTI_IMR1_MASK 0x1F840000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF3CU
-
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOFEN | \
- RCC_AHB2ENR_GPIOGEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 TRUE
-#define STM32_HAS_I2C4 TRUE
-
-/* OCTOSPI attributes.*/
-#define STM32_HAS_OCTOSPI1 FALSE
-#define STM32_HAS_OCTOSPI2 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 FALSE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-
-#define STM32_HAS_SPI4 TRUE
-#define STM32_SPI4_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM20 TRUE
-#define STM32_TIM20_IS_32BITS FALSE
-#define STM32_TIM20_CHANNELS 6
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#define STM32_HAS_TIM18 FALSE
-#define STM32_HAS_TIM19 FALSE
-#define STM32_HAS_TIM21 FALSE
-#define STM32_HAS_TIM22 FALSE
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_UART5 TRUE
-#define STM32_HAS_LPUART1 TRUE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* OTG/USB attributes.*/
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI FALSE
-
-#endif /* defined(STM32G474xx) || defined(STM32G484xx) */
-
-/*===========================================================================*/
-/* STM32G431xx, STM32G441xx, STM32G471xx. */
-/*===========================================================================*/
-
-#if defined(STM32G431xx) || defined(STM32G441xx) || \
- defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-#define STM32_HAS_ADC5 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_FDCAN1 TRUE
-#define STM32_HAS_FDCAN2 FALSE
-#define STM32_HAS_FDCAN3 FALSE
-#define STM32_FDCAN_FLS_NBR 28U
-#define STM32_FDCAN_FLE_NBR 8U
-#define STM32_FDCAN_RF0_NBR 3U
-#define STM32_FDCAN_RF1_NBR 3U
-#define STM32_FDCAN_RB_NBR 0U
-#define STM32_FDCAN_TEF_NBR 3U
-#define STM32_FDCAN_TB_NBR 3U
-#define STM32_FDCAN_TM_NBR 0U
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-#define STM32_HAS_DAC3_CH1 TRUE
-#define STM32_HAS_DAC3_CH2 TRUE
-#define STM32_HAS_DAC4_CH1 FALSE
-#define STM32_HAS_DAC4_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 6
-#define STM32_DMA2_NUM_CHANNELS 6
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_HAS_CR FALSE
-#define STM32_EXTI_SEPARATE_RF FALSE
-#define STM32_EXTI_NUM_LINES 44
-#define STM32_EXTI_IMR1_MASK 0x1F840000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF3CU
-
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOFEN | \
- RCC_AHB2ENR_GPIOGEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 TRUE
-#define STM32_HAS_I2C4 FALSE
-
-/* OCTOSPI attributes.*/
-#define STM32_HAS_OCTOSPI1 FALSE
-#define STM32_HAS_OCTOSPI2 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 FALSE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_LPUART1 TRUE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* OTG/USB attributes.*/
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI FALSE
-
-#endif /* defined(STM32G431xx) || defined(STM32G441xx) */
-
-/** @} */
-
-#endif /* STM32_REGISTRY_H */
-
-/** @} */
+/*
+ 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 STM32G4xx/stm32_registry.h
+ * @brief STM32G4xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32G4xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
+#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 18
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
+} while (false)
+
+ /* Enabling RTC-related EXTI lines.*/
+#define STM32_RTC_ENABLE_ALL_EXTI() do { \
+ 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); \
+} while (false)
+
+/* Clearing EXTI interrupts. */
+#define STM32_RTC_CLEAR_ALL_EXTI() do { \
+ extiClearGroup1(EXTI_MASK1(STM32_RTC_ALARM_EXTI) | \
+ EXTI_MASK1(STM32_RTC_TAMP_STAMP_EXTI) | \
+ EXTI_MASK1(STM32_RTC_WKUP_EXTI)); \
+} while (false)
+
+/* Masks used to preserve state of RTC and TAMP register reserved bits. */
+#define STM32_RTC_CR_MASK 0xE7FFFF7F
+#define STM32_RTC_PRER_MASK 0x007F7FFF
+#define STM32_TAMP_CR1_MASK 0x003C0007
+#define STM32_TAMP_CR2_MASK 0x07070007
+#define STM32_TAMP_FLTCR_MASK 0x000000FF
+#define STM32_TAMP_IER_MASK 0x003C0007
+
+#if defined(STM32G441xx) || defined(STM32G483xx) || defined(STM32G484xx) || \
+ defined(__DOXYGEN__)
+#define STM32_HAS_HASH1 TRUE
+#define STM32_HAS_CRYP1 TRUE
+#else
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+/*===========================================================================*/
+/* STM32G473xx, STM32G4843xx, STM32G474xx, STM32G484xx. */
+/*===========================================================================*/
+
+#if defined(STM32G473xx) || defined(STM32G483xx) || \
+ defined(STM32G474xx) || defined(STM32G484xx) || \
+ defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 TRUE
+#define STM32_HAS_ADC4 TRUE
+#define STM32_HAS_ADC5 TRUE
+
+/* CAN attributes.*/
+#define STM32_HAS_FDCAN1 TRUE
+#define STM32_HAS_FDCAN2 TRUE
+#define STM32_HAS_FDCAN3 TRUE
+#define STM32_FDCAN_FLS_NBR 28U
+#define STM32_FDCAN_FLE_NBR 8U
+#define STM32_FDCAN_RF0_NBR 3U
+#define STM32_FDCAN_RF1_NBR 3U
+#define STM32_FDCAN_RB_NBR 0U
+#define STM32_FDCAN_TEF_NBR 3U
+#define STM32_FDCAN_TB_NBR 3U
+#define STM32_FDCAN_TM_NBR 0U
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_HAS_DAC2_CH2 FALSE
+#define STM32_HAS_DAC3_CH1 TRUE
+#define STM32_HAS_DAC3_CH2 TRUE
+#define STM32_HAS_DAC4_CH1 TRUE
+#define STM32_HAS_DAC4_CH2 TRUE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 8
+#define STM32_DMA2_NUM_CHANNELS 8
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_HAS_CR FALSE
+#define STM32_EXTI_SEPARATE_RF FALSE
+#define STM32_EXTI_NUM_LINES 44
+#define STM32_EXTI_IMR1_MASK 0x1F840000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF3CU
+
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOFEN | \
+ RCC_AHB2ENR_GPIOGEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 TRUE
+#define STM32_HAS_I2C4 TRUE
+
+/* OCTOSPI attributes.*/
+#define STM32_HAS_OCTOSPI1 FALSE
+#define STM32_HAS_OCTOSPI2 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 FALSE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM20 TRUE
+#define STM32_TIM20_IS_32BITS FALSE
+#define STM32_TIM20_CHANNELS 6
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#define STM32_HAS_TIM18 FALSE
+#define STM32_HAS_TIM19 FALSE
+#define STM32_HAS_TIM21 FALSE
+#define STM32_HAS_TIM22 FALSE
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_UART5 TRUE
+#define STM32_HAS_LPUART1 TRUE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* OTG/USB attributes.*/
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI FALSE
+
+#endif /* defined(STM32G474xx) || defined(STM32G484xx) */
+
+/*===========================================================================*/
+/* STM32G431xx, STM32G441xx, STM32G471xx. */
+/*===========================================================================*/
+
+#if defined(STM32G431xx) || defined(STM32G441xx) || \
+ defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+#define STM32_HAS_ADC5 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_FDCAN1 TRUE
+#define STM32_HAS_FDCAN2 FALSE
+#define STM32_HAS_FDCAN3 FALSE
+#define STM32_FDCAN_FLS_NBR 28U
+#define STM32_FDCAN_FLE_NBR 8U
+#define STM32_FDCAN_RF0_NBR 3U
+#define STM32_FDCAN_RF1_NBR 3U
+#define STM32_FDCAN_RB_NBR 0U
+#define STM32_FDCAN_TEF_NBR 3U
+#define STM32_FDCAN_TB_NBR 3U
+#define STM32_FDCAN_TM_NBR 0U
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+#define STM32_HAS_DAC3_CH1 TRUE
+#define STM32_HAS_DAC3_CH2 TRUE
+#define STM32_HAS_DAC4_CH1 FALSE
+#define STM32_HAS_DAC4_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 6
+#define STM32_DMA2_NUM_CHANNELS 6
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_HAS_CR FALSE
+#define STM32_EXTI_SEPARATE_RF FALSE
+#define STM32_EXTI_NUM_LINES 44
+#define STM32_EXTI_IMR1_MASK 0x1F840000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF3CU
+
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOFEN | \
+ RCC_AHB2ENR_GPIOGEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 TRUE
+#define STM32_HAS_I2C4 FALSE
+
+/* OCTOSPI attributes.*/
+#define STM32_HAS_OCTOSPI1 FALSE
+#define STM32_HAS_OCTOSPI2 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 FALSE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_LPUART1 TRUE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* OTG/USB attributes.*/
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI FALSE
+
+#endif /* defined(STM32G431xx) || defined(STM32G441xx) */
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.c b/os/hal/ports/STM32/STM32H7xx/hal_lld.c
index 4f1de78e4f..106324aa45 100644
--- a/os/hal/ports/STM32/STM32H7xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.c
@@ -1,439 +1,440 @@
-/*
- 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)
+ && ((RCC->BDCR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..2cc2d57091 100644
--- a/os/hal/ports/STM32/STM32H7xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.h
@@ -1,3072 +1,3080 @@
-/*
- 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 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_CK
+#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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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_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/STM32H7xx/platform.mk b/os/hal/ports/STM32/STM32H7xx/platform.mk
index 830fd82da3..ae9c00572e 100644
--- a/os/hal/ports/STM32/STM32H7xx/platform.mk
+++ b/os/hal/ports/STM32/STM32H7xx/platform.mk
@@ -1,51 +1,51 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32H7xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32H7xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32H7xx
-
-# 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/ADCv4/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/BDMAv1/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/FDCANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/MDMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32H7xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32H7xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32H7xx
+
+# 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/ADCv4/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/BDMAv1/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/FDCANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/MDMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/MACv2/driver.mk
+
+# Shared variables
+ALLCSRC += $(PLATFORMSRC)
+ALLINC += $(PLATFORMINC)
diff --git a/os/hal/ports/STM32/STM32H7xx/stm32_dmamux.h b/os/hal/ports/STM32/STM32H7xx/stm32_dmamux.h
index d870d956da..c93b688b91 100644
--- a/os/hal/ports/STM32/STM32H7xx/stm32_dmamux.h
+++ b/os/hal/ports/STM32/STM32H7xx/stm32_dmamux.h
@@ -1,206 +1,206 @@
-/*
- 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/stm32_dmamux.h
- * @brief STM32H7xx DMAMUX handler header.
- *
- * @addtogroup STM32H7xx_DMAMUX
- * @{
- */
-
-#ifndef STM32_DMAMUX_H
-#define STM32_DMAMUX_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name DMAMUX1 request sources
- * @{
- */
-#define STM32_DMAMUX1_REQ_GEN0 1
-#define STM32_DMAMUX1_REQ_GEN1 2
-#define STM32_DMAMUX1_REQ_GEN2 3
-#define STM32_DMAMUX1_REQ_GEN3 4
-#define STM32_DMAMUX1_REQ_GEN4 5
-#define STM32_DMAMUX1_REQ_GEN5 6
-#define STM32_DMAMUX1_REQ_GEN6 7
-#define STM32_DMAMUX1_REQ_GEN7 8
-#define STM32_DMAMUX1_ADC1 9
-#define STM32_DMAMUX1_ADC2 10
-#define STM32_DMAMUX1_TIM1_CH1 11
-#define STM32_DMAMUX1_TIM1_CH2 12
-#define STM32_DMAMUX1_TIM1_CH3 13
-#define STM32_DMAMUX1_TIM1_CH4 14
-#define STM32_DMAMUX1_TIM1_UP 15
-#define STM32_DMAMUX1_TIM1_TRIG 16
-#define STM32_DMAMUX1_TIM1_COM 17
-#define STM32_DMAMUX1_TIM2_CH1 18
-#define STM32_DMAMUX1_TIM2_CH2 19
-#define STM32_DMAMUX1_TIM2_CH3 20
-#define STM32_DMAMUX1_TIM2_CH4 21
-#define STM32_DMAMUX1_TIM2_UP 22
-#define STM32_DMAMUX1_TIM3_CH1 23
-#define STM32_DMAMUX1_TIM3_CH2 24
-#define STM32_DMAMUX1_TIM3_CH3 25
-#define STM32_DMAMUX1_TIM3_CH4 26
-#define STM32_DMAMUX1_TIM3_UP 27
-#define STM32_DMAMUX1_TIM3_TRIG 28
-#define STM32_DMAMUX1_TIM4_CH1 29
-#define STM32_DMAMUX1_TIM4_CH2 30
-#define STM32_DMAMUX1_TIM4_CH3 31
-#define STM32_DMAMUX1_TIM4_UP 32
-#define STM32_DMAMUX1_I2C1_RX 33
-#define STM32_DMAMUX1_I2C1_TX 34
-#define STM32_DMAMUX1_I2C2_RX 35
-#define STM32_DMAMUX1_I2C2_TX 36
-#define STM32_DMAMUX1_SPI1_RX 37
-#define STM32_DMAMUX1_SPI1_TX 38
-#define STM32_DMAMUX1_SPI2_RX 39
-#define STM32_DMAMUX1_SPI2_TX 40
-#define STM32_DMAMUX1_USART1_RX 41
-#define STM32_DMAMUX1_USART1_TX 42
-#define STM32_DMAMUX1_USART2_RX 43
-#define STM32_DMAMUX1_USART2_TX 44
-#define STM32_DMAMUX1_USART3_RX 45
-#define STM32_DMAMUX1_USART3_TX 46
-#define STM32_DMAMUX1_TIM8_CH1 47
-#define STM32_DMAMUX1_TIM8_CH2 48
-#define STM32_DMAMUX1_TIM8_CH3 49
-#define STM32_DMAMUX1_TIM8_CH4 50
-#define STM32_DMAMUX1_TIM8_UP 51
-#define STM32_DMAMUX1_TIM8_TRIG 52
-#define STM32_DMAMUX1_TIM8_COM 53
-#define STM32_DMAMUX1_RESERVED54 54
-#define STM32_DMAMUX1_TIM5_CH1 55
-#define STM32_DMAMUX1_TIM5_CH2 56
-#define STM32_DMAMUX1_TIM5_CH3 57
-#define STM32_DMAMUX1_TIM5_CH4 58
-#define STM32_DMAMUX1_TIM5_UP 59
-#define STM32_DMAMUX1_TIM5_TRIG 60
-#define STM32_DMAMUX1_SPI3_RX 61
-#define STM32_DMAMUX1_SPI3_TX 62
-#define STM32_DMAMUX1_UART4_RX 63
-#define STM32_DMAMUX1_UART4_TX 64
-#define STM32_DMAMUX1_UART5_RX 65
-#define STM32_DMAMUX1_UART5_TX 66
-#define STM32_DMAMUX1_DAC1_CH1 67 /* Renamed to L4 name.*/
-#define STM32_DMAMUX1_DAC1_CH2 68 /* Renamed to L4 name.*/
-#define STM32_DMAMUX1_TIM6_UP 69
-#define STM32_DMAMUX1_TIM7_UP 70
-#define STM32_DMAMUX1_USART6_RX 71
-#define STM32_DMAMUX1_USART6_TX 72
-#define STM32_DMAMUX1_I2C3_RX 73
-#define STM32_DMAMUX1_I2C3_TX 74
-#define STM32_DMAMUX1_DCMI 75
-#define STM32_DMAMUX1_CRYP_IN 76
-#define STM32_DMAMUX1_CRYP_OUT 77
-#define STM32_DMAMUX1_HASH_IN 78
-#define STM32_DMAMUX1_UART7_RX 79
-#define STM32_DMAMUX1_UART7_TX 80
-#define STM32_DMAMUX1_UART8_RX 81
-#define STM32_DMAMUX1_UART8_TX 82
-#define STM32_DMAMUX1_SPI4_RX 83
-#define STM32_DMAMUX1_SPI4_TX 84
-#define STM32_DMAMUX1_SPI5_RX 85
-#define STM32_DMAMUX1_SPI5_TX 86
-#define STM32_DMAMUX1_SAI1_A 87
-#define STM32_DMAMUX1_SAI1_B 88
-#define STM32_DMAMUX1_SAI2_A 89
-#define STM32_DMAMUX1_SAI2_B 90
-#define STM32_DMAMUX1_SWPMI_RX 91
-#define STM32_DMAMUX1_SQPMI_TX 92
-#define STM32_DMAMUX1_SPDIFRX_DT 93
-#define STM32_DMAMUX1_SPDIFRX_CS 94
-#define STM32_DMAMUX1_HR_REQ1 95
-#define STM32_DMAMUX1_HR_REQ2 96
-#define STM32_DMAMUX1_HR_REQ3 97
-#define STM32_DMAMUX1_HR_REQ4 98
-#define STM32_DMAMUX1_HR_REQ5 99
-#define STM32_DMAMUX1_HR_REQ6 100
-#define STM32_DMAMUX1_DFSDM1_DMA0 101
-#define STM32_DMAMUX1_DFSDM1_DMA1 102
-#define STM32_DMAMUX1_DFSDM1_DMA2 103
-#define STM32_DMAMUX1_DFSDM1_DMA3 104
-#define STM32_DMAMUX1_TIM15_CH1 105
-#define STM32_DMAMUX1_TIM15_UP 106
-#define STM32_DMAMUX1_TIM15_TRIG 107
-#define STM32_DMAMUX1_TIM15_COM 108
-#define STM32_DMAMUX1_TIM16_CH1 109
-#define STM32_DMAMUX1_TIM16_UP 110
-#define STM32_DMAMUX1_TIM17_CH1 111
-#define STM32_DMAMUX1_TIM17_UP 112
-#define STM32_DMAMUX1_SAI3_A 113
-#define STM32_DMAMUX1_SAI3_B 114
-#define STM32_DMAMUX1_ADC3 115
-/** @} */
-
-/**
- * @name DMAMUX2 request sources
- * @{
- */
-#define STM32_DMAMUX2_REQ_GEN0 1
-#define STM32_DMAMUX2_REQ_GEN1 2
-#define STM32_DMAMUX2_REQ_GEN2 3
-#define STM32_DMAMUX2_REQ_GEN3 4
-#define STM32_DMAMUX2_REQ_GEN4 5
-#define STM32_DMAMUX2_REQ_GEN5 6
-#define STM32_DMAMUX2_REQ_GEN6 7
-#define STM32_DMAMUX2_REQ_GEN7 8
-#define STM32_DMAMUX2_LP_UART1_RX 9
-#define STM32_DMAMUX2_LP_UART1_TX 10
-#define STM32_DMAMUX2_SPI6_RX 11
-#define STM32_DMAMUX2_SPI6_TX 12
-#define STM32_DMAMUX2_I2C4_RX 13
-#define STM32_DMAMUX2_I2C4_TX 14
-#define STM32_DMAMUX2_SAI4_A 15
-#define STM32_DMAMUX2_SAI4_B 16
-#define STM32_DMAMUX2_ADC3_REQ 17
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMAMUX_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/stm32_dmamux.h
+ * @brief STM32H7xx DMAMUX handler header.
+ *
+ * @addtogroup STM32H7xx_DMAMUX
+ * @{
+ */
+
+#ifndef STM32_DMAMUX_H
+#define STM32_DMAMUX_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name DMAMUX1 request sources
+ * @{
+ */
+#define STM32_DMAMUX1_REQ_GEN0 1
+#define STM32_DMAMUX1_REQ_GEN1 2
+#define STM32_DMAMUX1_REQ_GEN2 3
+#define STM32_DMAMUX1_REQ_GEN3 4
+#define STM32_DMAMUX1_REQ_GEN4 5
+#define STM32_DMAMUX1_REQ_GEN5 6
+#define STM32_DMAMUX1_REQ_GEN6 7
+#define STM32_DMAMUX1_REQ_GEN7 8
+#define STM32_DMAMUX1_ADC1 9
+#define STM32_DMAMUX1_ADC2 10
+#define STM32_DMAMUX1_TIM1_CH1 11
+#define STM32_DMAMUX1_TIM1_CH2 12
+#define STM32_DMAMUX1_TIM1_CH3 13
+#define STM32_DMAMUX1_TIM1_CH4 14
+#define STM32_DMAMUX1_TIM1_UP 15
+#define STM32_DMAMUX1_TIM1_TRIG 16
+#define STM32_DMAMUX1_TIM1_COM 17
+#define STM32_DMAMUX1_TIM2_CH1 18
+#define STM32_DMAMUX1_TIM2_CH2 19
+#define STM32_DMAMUX1_TIM2_CH3 20
+#define STM32_DMAMUX1_TIM2_CH4 21
+#define STM32_DMAMUX1_TIM2_UP 22
+#define STM32_DMAMUX1_TIM3_CH1 23
+#define STM32_DMAMUX1_TIM3_CH2 24
+#define STM32_DMAMUX1_TIM3_CH3 25
+#define STM32_DMAMUX1_TIM3_CH4 26
+#define STM32_DMAMUX1_TIM3_UP 27
+#define STM32_DMAMUX1_TIM3_TRIG 28
+#define STM32_DMAMUX1_TIM4_CH1 29
+#define STM32_DMAMUX1_TIM4_CH2 30
+#define STM32_DMAMUX1_TIM4_CH3 31
+#define STM32_DMAMUX1_TIM4_UP 32
+#define STM32_DMAMUX1_I2C1_RX 33
+#define STM32_DMAMUX1_I2C1_TX 34
+#define STM32_DMAMUX1_I2C2_RX 35
+#define STM32_DMAMUX1_I2C2_TX 36
+#define STM32_DMAMUX1_SPI1_RX 37
+#define STM32_DMAMUX1_SPI1_TX 38
+#define STM32_DMAMUX1_SPI2_RX 39
+#define STM32_DMAMUX1_SPI2_TX 40
+#define STM32_DMAMUX1_USART1_RX 41
+#define STM32_DMAMUX1_USART1_TX 42
+#define STM32_DMAMUX1_USART2_RX 43
+#define STM32_DMAMUX1_USART2_TX 44
+#define STM32_DMAMUX1_USART3_RX 45
+#define STM32_DMAMUX1_USART3_TX 46
+#define STM32_DMAMUX1_TIM8_CH1 47
+#define STM32_DMAMUX1_TIM8_CH2 48
+#define STM32_DMAMUX1_TIM8_CH3 49
+#define STM32_DMAMUX1_TIM8_CH4 50
+#define STM32_DMAMUX1_TIM8_UP 51
+#define STM32_DMAMUX1_TIM8_TRIG 52
+#define STM32_DMAMUX1_TIM8_COM 53
+#define STM32_DMAMUX1_RESERVED54 54
+#define STM32_DMAMUX1_TIM5_CH1 55
+#define STM32_DMAMUX1_TIM5_CH2 56
+#define STM32_DMAMUX1_TIM5_CH3 57
+#define STM32_DMAMUX1_TIM5_CH4 58
+#define STM32_DMAMUX1_TIM5_UP 59
+#define STM32_DMAMUX1_TIM5_TRIG 60
+#define STM32_DMAMUX1_SPI3_RX 61
+#define STM32_DMAMUX1_SPI3_TX 62
+#define STM32_DMAMUX1_UART4_RX 63
+#define STM32_DMAMUX1_UART4_TX 64
+#define STM32_DMAMUX1_UART5_RX 65
+#define STM32_DMAMUX1_UART5_TX 66
+#define STM32_DMAMUX1_DAC1_CH1 67 /* Renamed to L4 name.*/
+#define STM32_DMAMUX1_DAC1_CH2 68 /* Renamed to L4 name.*/
+#define STM32_DMAMUX1_TIM6_UP 69
+#define STM32_DMAMUX1_TIM7_UP 70
+#define STM32_DMAMUX1_USART6_RX 71
+#define STM32_DMAMUX1_USART6_TX 72
+#define STM32_DMAMUX1_I2C3_RX 73
+#define STM32_DMAMUX1_I2C3_TX 74
+#define STM32_DMAMUX1_DCMI 75
+#define STM32_DMAMUX1_CRYP_IN 76
+#define STM32_DMAMUX1_CRYP_OUT 77
+#define STM32_DMAMUX1_HASH_IN 78
+#define STM32_DMAMUX1_UART7_RX 79
+#define STM32_DMAMUX1_UART7_TX 80
+#define STM32_DMAMUX1_UART8_RX 81
+#define STM32_DMAMUX1_UART8_TX 82
+#define STM32_DMAMUX1_SPI4_RX 83
+#define STM32_DMAMUX1_SPI4_TX 84
+#define STM32_DMAMUX1_SPI5_RX 85
+#define STM32_DMAMUX1_SPI5_TX 86
+#define STM32_DMAMUX1_SAI1_A 87
+#define STM32_DMAMUX1_SAI1_B 88
+#define STM32_DMAMUX1_SAI2_A 89
+#define STM32_DMAMUX1_SAI2_B 90
+#define STM32_DMAMUX1_SWPMI_RX 91
+#define STM32_DMAMUX1_SQPMI_TX 92
+#define STM32_DMAMUX1_SPDIFRX_DT 93
+#define STM32_DMAMUX1_SPDIFRX_CS 94
+#define STM32_DMAMUX1_HR_REQ1 95
+#define STM32_DMAMUX1_HR_REQ2 96
+#define STM32_DMAMUX1_HR_REQ3 97
+#define STM32_DMAMUX1_HR_REQ4 98
+#define STM32_DMAMUX1_HR_REQ5 99
+#define STM32_DMAMUX1_HR_REQ6 100
+#define STM32_DMAMUX1_DFSDM1_DMA0 101
+#define STM32_DMAMUX1_DFSDM1_DMA1 102
+#define STM32_DMAMUX1_DFSDM1_DMA2 103
+#define STM32_DMAMUX1_DFSDM1_DMA3 104
+#define STM32_DMAMUX1_TIM15_CH1 105
+#define STM32_DMAMUX1_TIM15_UP 106
+#define STM32_DMAMUX1_TIM15_TRIG 107
+#define STM32_DMAMUX1_TIM15_COM 108
+#define STM32_DMAMUX1_TIM16_CH1 109
+#define STM32_DMAMUX1_TIM16_UP 110
+#define STM32_DMAMUX1_TIM17_CH1 111
+#define STM32_DMAMUX1_TIM17_UP 112
+#define STM32_DMAMUX1_SAI3_A 113
+#define STM32_DMAMUX1_SAI3_B 114
+#define STM32_DMAMUX1_ADC3 115
+/** @} */
+
+/**
+ * @name DMAMUX2 request sources
+ * @{
+ */
+#define STM32_DMAMUX2_REQ_GEN0 1
+#define STM32_DMAMUX2_REQ_GEN1 2
+#define STM32_DMAMUX2_REQ_GEN2 3
+#define STM32_DMAMUX2_REQ_GEN3 4
+#define STM32_DMAMUX2_REQ_GEN4 5
+#define STM32_DMAMUX2_REQ_GEN5 6
+#define STM32_DMAMUX2_REQ_GEN6 7
+#define STM32_DMAMUX2_REQ_GEN7 8
+#define STM32_DMAMUX2_LP_UART1_RX 9
+#define STM32_DMAMUX2_LP_UART1_TX 10
+#define STM32_DMAMUX2_SPI6_RX 11
+#define STM32_DMAMUX2_SPI6_TX 12
+#define STM32_DMAMUX2_I2C4_RX 13
+#define STM32_DMAMUX2_I2C4_TX 14
+#define STM32_DMAMUX2_SAI4_A 15
+#define STM32_DMAMUX2_SAI4_B 16
+#define STM32_DMAMUX2_ADC3_REQ 17
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMAMUX_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32H7xx/stm32_isr.c b/os/hal/ports/STM32/STM32H7xx/stm32_isr.c
index 8ed4d72fc7..aea191e691 100644
--- a/os/hal/ports/STM32/STM32H7xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32H7xx/stm32_isr.c
@@ -1,198 +1,198 @@
-/*
- 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/stm32_isr.c
- * @brief STM32H7xx ISR handler code.
- *
- * @addtogroup STM32H7xx_ISR
- * @{
- */
-
-#include "hal.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define exti_serve_irq(pr, channel) { \
- \
- if ((pr) & (1U << (channel))) { \
- _pal_isr_code(channel); \
- } \
-}
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#include "stm32_exti0.inc"
-#include "stm32_exti1.inc"
-#include "stm32_exti2.inc"
-#include "stm32_exti3.inc"
-#include "stm32_exti4.inc"
-#include "stm32_exti5_9.inc"
-#include "stm32_exti10_15.inc"
-#include "stm32_exti16.inc"
-#include "stm32_exti17.inc"
-#include "stm32_exti18.inc"
-#include "stm32_exti19.inc"
-#include "stm32_exti20_21.inc"
-
-#include "stm32_fdcan1.inc"
-#include "stm32_fdcan2.inc"
-
-#include "stm32_quadspi1.inc"
-
-#include "stm32_sdmmc1.inc"
-#include "stm32_sdmmc2.inc"
-
-#include
-#include "stm32_usart2.inc"
-#include "stm32_usart3.inc"
-#include "stm32_uart4.inc"
-#include "stm32_uart5.inc"
-#include "stm32_usart6.inc"
-#include "stm32_uart7.inc"
-#include "stm32_uart8.inc"
-#include "stm32_lpuart1.inc"
-
-#include "stm32_tim1.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim4.inc"
-#include "stm32_tim5.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim8_12_13_14.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_irq_init();
- exti1_irq_init();
- exti2_irq_init();
- exti3_irq_init();
- exti4_irq_init();
- exti5_9_irq_init();
- exti10_15_irq_init();
- exti16_irq_init();
- exti17_irq_init();
- exti18_irq_init();
- exti19_irq_init();
- exti20_exti21_irq_init();
-
- fdcan1_irq_init();
- fdcan2_irq_init();
-
- mdma_irq_init();
-
- quadspi1_irq_init();
-
- sdmmc1_irq_init();
- sdmmc2_irq_init();
-
- tim1_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim4_irq_init();
- tim5_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim8_tim12_tim13_tim14_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_irq_init();
- uart4_irq_init();
- uart5_irq_init();
- usart6_irq_init();
- uart7_irq_init();
- uart8_irq_init();
- lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_irq_deinit();
- exti1_irq_deinit();
- exti2_irq_deinit();
- exti3_irq_deinit();
- exti4_irq_deinit();
- exti5_9_irq_deinit();
- exti10_15_irq_deinit();
- exti16_irq_deinit();
- exti17_irq_deinit();
- exti18_irq_deinit();
- exti19_irq_deinit();
- exti20_exti21_irq_deinit();
-
- fdcan1_irq_deinit();
- fdcan2_irq_deinit();
-
- mdma_irq_deinit();
-
- quadspi1_irq_deinit();
-
- sdmmc1_irq_deinit();
- sdmmc2_irq_deinit();
-
- tim1_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim4_irq_deinit();
- tim5_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim8_tim12_tim13_tim14_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_irq_deinit();
- uart4_irq_deinit();
- uart5_irq_deinit();
- usart6_irq_deinit();
- uart7_irq_deinit();
- uart8_irq_deinit();
- lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32H7xx ISR handler code.
+ *
+ * @addtogroup STM32H7xx_ISR
+ * @{
+ */
+
+#include "hal.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define exti_serve_irq(pr, channel) { \
+ \
+ if ((pr) & (1U << (channel))) { \
+ _pal_isr_code(channel); \
+ } \
+}
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#include "stm32_exti0.inc"
+#include "stm32_exti1.inc"
+#include "stm32_exti2.inc"
+#include "stm32_exti3.inc"
+#include "stm32_exti4.inc"
+#include "stm32_exti5_9.inc"
+#include "stm32_exti10_15.inc"
+#include "stm32_exti16.inc"
+#include "stm32_exti17.inc"
+#include "stm32_exti18.inc"
+#include "stm32_exti19.inc"
+#include "stm32_exti20_21.inc"
+
+#include "stm32_fdcan1.inc"
+#include "stm32_fdcan2.inc"
+
+#include "stm32_quadspi1.inc"
+
+#include "stm32_sdmmc1.inc"
+#include "stm32_sdmmc2.inc"
+
+#include
+#include "stm32_usart2.inc"
+#include "stm32_usart3.inc"
+#include "stm32_uart4.inc"
+#include "stm32_uart5.inc"
+#include "stm32_usart6.inc"
+#include "stm32_uart7.inc"
+#include "stm32_uart8.inc"
+#include "stm32_lpuart1.inc"
+
+#include "stm32_tim1.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim4.inc"
+#include "stm32_tim5.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim8_12_13_14.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_irq_init();
+ exti1_irq_init();
+ exti2_irq_init();
+ exti3_irq_init();
+ exti4_irq_init();
+ exti5_9_irq_init();
+ exti10_15_irq_init();
+ exti16_irq_init();
+ exti17_irq_init();
+ exti18_irq_init();
+ exti19_irq_init();
+ exti20_exti21_irq_init();
+
+ fdcan1_irq_init();
+ fdcan2_irq_init();
+
+ mdma_irq_init();
+
+ quadspi1_irq_init();
+
+ sdmmc1_irq_init();
+ sdmmc2_irq_init();
+
+ tim1_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim4_irq_init();
+ tim5_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim8_tim12_tim13_tim14_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_irq_init();
+ uart4_irq_init();
+ uart5_irq_init();
+ usart6_irq_init();
+ uart7_irq_init();
+ uart8_irq_init();
+ lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_irq_deinit();
+ exti1_irq_deinit();
+ exti2_irq_deinit();
+ exti3_irq_deinit();
+ exti4_irq_deinit();
+ exti5_9_irq_deinit();
+ exti10_15_irq_deinit();
+ exti16_irq_deinit();
+ exti17_irq_deinit();
+ exti18_irq_deinit();
+ exti19_irq_deinit();
+ exti20_exti21_irq_deinit();
+
+ fdcan1_irq_deinit();
+ fdcan2_irq_deinit();
+
+ mdma_irq_deinit();
+
+ quadspi1_irq_deinit();
+
+ sdmmc1_irq_deinit();
+ sdmmc2_irq_deinit();
+
+ tim1_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim4_irq_deinit();
+ tim5_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim8_tim12_tim13_tim14_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_irq_deinit();
+ uart4_irq_deinit();
+ uart5_irq_deinit();
+ usart6_irq_deinit();
+ uart7_irq_deinit();
+ uart8_irq_deinit();
+ lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32H7xx/stm32_isr.h b/os/hal/ports/STM32/STM32H7xx/stm32_isr.h
index a51b10a6dc..fe7dfd924d 100644
--- a/os/hal/ports/STM32/STM32H7xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32H7xx/stm32_isr.h
@@ -1,384 +1,384 @@
-/*
- 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/stm32_isr.h
- * @brief STM32H7xx ISR handler header.
- *
- * @addtogroup STM32H7xx_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_TIM12_SUPPRESS_ISR
-#define STM32_TIM13_SUPPRESS_ISR
-#define STM32_TIM14_SUPPRESS_ISR
-#define STM32_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC units.
- */
-#define STM32_ADC12_HANDLER Vector88
-#define STM32_ADC3_HANDLER Vector23C
-
-#define STM32_ADC12_NUMBER 18
-#define STM32_ADC3_NUMBER 127
-
-/*
- * BDMA units.
- */
-#define STM32_BDMA1_CH0_HANDLER Vector244
-#define STM32_BDMA1_CH1_HANDLER Vector248
-#define STM32_BDMA1_CH2_HANDLER Vector24C
-#define STM32_BDMA1_CH3_HANDLER Vector250
-#define STM32_BDMA1_CH4_HANDLER Vector254
-#define STM32_BDMA1_CH5_HANDLER Vector258
-#define STM32_BDMA1_CH6_HANDLER Vector25C
-#define STM32_BDMA1_CH7_HANDLER Vector260
-
-#define STM32_BDMA1_CH0_NUMBER 129
-#define STM32_BDMA1_CH1_NUMBER 130
-#define STM32_BDMA1_CH2_NUMBER 131
-#define STM32_BDMA1_CH3_NUMBER 132
-#define STM32_BDMA1_CH4_NUMBER 133
-#define STM32_BDMA1_CH5_NUMBER 134
-#define STM32_BDMA1_CH6_NUMBER 135
-#define STM32_BDMA1_CH7_NUMBER 136
-
-/*
- * DMA units.
- */
-#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_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_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_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
-
-/*
- * MDMA units.
- */
-#define STM32_MDMA_HANDLER Vector228
-
-#define STM32_MDMA_NUMBER 122
-
-/*
- * ETH units.
- */
-#define STM32_ETH_HANDLER Vector134
-
-#define STM32_ETH_NUMBER 61
-
-/*
- * EXTI units.
- */
-#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 Vector48 /* RTC TAMP CSS */
-#define STM32_EXTI19_HANDLER Vector4C /* RTC WAKEUP */
-#define STM32_EXTI2021_HANDLER Vector264 /* COMP1 COMP2 */
-
-#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 3
-#define STM32_EXTI2021_NUMBER 137
-
-/*
- * FDCAN units.
- */
-#define STM32_FDCAN1_IT0_HANDLER Vector8C
-#define STM32_FDCAN1_IT1_HANDLER Vector94
-#define STM32_FDCAN2_IT0_HANDLER Vector90
-#define STM32_FDCAN2_IT1_HANDLER Vector98
-
-#define STM32_FDCAN1_IT0_NUMBER 19
-#define STM32_FDCAN1_IT1_NUMBER 21
-#define STM32_FDCAN2_IT0_NUMBER 20
-#define STM32_FDCAN2_IT1_NUMBER 22
-
-/*
- * 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_I2C4_EVENT_HANDLER Vector1BC
-#define STM32_I2C4_ERROR_HANDLER Vector1C0
-
-#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
-#define STM32_I2C4_EVENT_NUMBER 95
-#define STM32_I2C4_ERROR_NUMBER 96
-
-/*
- * QUADSPI units.
- */
-#define STM32_QUADSPI1_HANDLER Vector1B0
-
-#define STM32_QUADSPI1_NUMBER 92
-
-/*
- * SDMMC units.
- */
-#define STM32_SDMMC1_HANDLER Vector104
-#define STM32_SDMMC2_HANDLER Vector230
-
-#define STM32_SDMMC1_NUMBER 49
-#define STM32_SDMMC2_NUMBER 124
-
-/*
- * SPI units.
- */
-#define STM32_SPI1_HANDLER VectorCC
-#define STM32_SPI2_HANDLER VectorD0
-#define STM32_SPI3_HANDLER Vector10C
-#define STM32_SPI4_HANDLER Vector190
-#define STM32_SPI5_HANDLER Vector194
-#define STM32_SPI6_HANDLER Vector198
-
-#define STM32_SPI1_NUMBER 35
-#define STM32_SPI2_NUMBER 36
-#define STM32_SPI3_NUMBER 51
-#define STM32_SPI4_NUMBER 84
-#define STM32_SPI5_NUMBER 85
-#define STM32_SPI6_NUMBER 86
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_BRK_HANDLER VectorA0
-#define STM32_TIM1_UP_HANDLER VectorA4
-#define STM32_TIM1_TRGCO_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_TIM15_HANDLER Vector210
-#define STM32_TIM16_HANDLER Vector214
-#define STM32_TIM17_HANDLER Vector218
-
-#define STM32_TIM1_BRK_NUMBER 24
-#define STM32_TIM1_UP_NUMBER 25
-#define STM32_TIM1_TRGCO_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
-#define STM32_TIM15_NUMBER 116
-#define STM32_TIM16_NUMBER 117
-#define STM32_TIM17_NUMBER 118
-
-/*
- * USART/UART 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_LPUART1_HANDLER Vector278
-
-#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_LPUART1_NUMBER 142
-
-/*
- * USB/OTG units.
- */
-#define STM32_OTG1_HANDLER Vector1D4
-#define STM32_OTG1_EP1OUT_HANDLER Vector1C8
-#define STM32_OTG1_EP1IN_HANDLER Vector1CC
-#define STM32_OTG2_HANDLER Vector174
-#define STM32_OTG2_EP1OUT_HANDLER Vector168
-#define STM32_OTG2_EP1IN_HANDLER Vector16C
-
-#define STM32_OTG1_NUMBER 101
-#define STM32_OTG1_EP1OUT_NUMBER 98
-#define STM32_OTG1_EP1IN_NUMBER 99
-#define STM32_OTG2_NUMBER 77
-#define STM32_OTG2_EP1OUT_NUMBER 74
-#define STM32_OTG2_EP1IN_NUMBER 75
-
-/*
- * LTDC units.
- */
-#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 units.
- */
-#define STM32_DMA2D_HANDLER Vector1A8
-
-#define STM32_DMA2D_NUMBER 90
-
-/*
- * FSMC units.
- */
-#define STM32_FSMC_HANDLER Vector100
-
-#define STM32_FSMC_NUMBER 48
-
-/*
- * DCMI units.
- */
-#define STM32_DCMI_HANDLER Vector178
-
-#define STM32_DCMI_NUMBER 78
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32H7xx ISR handler header.
+ *
+ * @addtogroup STM32H7xx_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_TIM12_SUPPRESS_ISR
+#define STM32_TIM13_SUPPRESS_ISR
+#define STM32_TIM14_SUPPRESS_ISR
+#define STM32_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC units.
+ */
+#define STM32_ADC12_HANDLER Vector88
+#define STM32_ADC3_HANDLER Vector23C
+
+#define STM32_ADC12_NUMBER 18
+#define STM32_ADC3_NUMBER 127
+
+/*
+ * BDMA units.
+ */
+#define STM32_BDMA1_CH0_HANDLER Vector244
+#define STM32_BDMA1_CH1_HANDLER Vector248
+#define STM32_BDMA1_CH2_HANDLER Vector24C
+#define STM32_BDMA1_CH3_HANDLER Vector250
+#define STM32_BDMA1_CH4_HANDLER Vector254
+#define STM32_BDMA1_CH5_HANDLER Vector258
+#define STM32_BDMA1_CH6_HANDLER Vector25C
+#define STM32_BDMA1_CH7_HANDLER Vector260
+
+#define STM32_BDMA1_CH0_NUMBER 129
+#define STM32_BDMA1_CH1_NUMBER 130
+#define STM32_BDMA1_CH2_NUMBER 131
+#define STM32_BDMA1_CH3_NUMBER 132
+#define STM32_BDMA1_CH4_NUMBER 133
+#define STM32_BDMA1_CH5_NUMBER 134
+#define STM32_BDMA1_CH6_NUMBER 135
+#define STM32_BDMA1_CH7_NUMBER 136
+
+/*
+ * DMA units.
+ */
+#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_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_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_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
+
+/*
+ * MDMA units.
+ */
+#define STM32_MDMA_HANDLER Vector228
+
+#define STM32_MDMA_NUMBER 122
+
+/*
+ * ETH units.
+ */
+#define STM32_ETH_HANDLER Vector134
+
+#define STM32_ETH_NUMBER 61
+
+/*
+ * EXTI units.
+ */
+#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 Vector48 /* RTC TAMP CSS */
+#define STM32_EXTI19_HANDLER Vector4C /* RTC WAKEUP */
+#define STM32_EXTI2021_HANDLER Vector264 /* COMP1 COMP2 */
+
+#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 3
+#define STM32_EXTI2021_NUMBER 137
+
+/*
+ * FDCAN units.
+ */
+#define STM32_FDCAN1_IT0_HANDLER Vector8C
+#define STM32_FDCAN1_IT1_HANDLER Vector94
+#define STM32_FDCAN2_IT0_HANDLER Vector90
+#define STM32_FDCAN2_IT1_HANDLER Vector98
+
+#define STM32_FDCAN1_IT0_NUMBER 19
+#define STM32_FDCAN1_IT1_NUMBER 21
+#define STM32_FDCAN2_IT0_NUMBER 20
+#define STM32_FDCAN2_IT1_NUMBER 22
+
+/*
+ * 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_I2C4_EVENT_HANDLER Vector1BC
+#define STM32_I2C4_ERROR_HANDLER Vector1C0
+
+#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
+#define STM32_I2C4_EVENT_NUMBER 95
+#define STM32_I2C4_ERROR_NUMBER 96
+
+/*
+ * QUADSPI units.
+ */
+#define STM32_QUADSPI1_HANDLER Vector1B0
+
+#define STM32_QUADSPI1_NUMBER 92
+
+/*
+ * SDMMC units.
+ */
+#define STM32_SDMMC1_HANDLER Vector104
+#define STM32_SDMMC2_HANDLER Vector230
+
+#define STM32_SDMMC1_NUMBER 49
+#define STM32_SDMMC2_NUMBER 124
+
+/*
+ * SPI units.
+ */
+#define STM32_SPI1_HANDLER VectorCC
+#define STM32_SPI2_HANDLER VectorD0
+#define STM32_SPI3_HANDLER Vector10C
+#define STM32_SPI4_HANDLER Vector190
+#define STM32_SPI5_HANDLER Vector194
+#define STM32_SPI6_HANDLER Vector198
+
+#define STM32_SPI1_NUMBER 35
+#define STM32_SPI2_NUMBER 36
+#define STM32_SPI3_NUMBER 51
+#define STM32_SPI4_NUMBER 84
+#define STM32_SPI5_NUMBER 85
+#define STM32_SPI6_NUMBER 86
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_BRK_HANDLER VectorA0
+#define STM32_TIM1_UP_HANDLER VectorA4
+#define STM32_TIM1_TRGCO_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_TIM15_HANDLER Vector210
+#define STM32_TIM16_HANDLER Vector214
+#define STM32_TIM17_HANDLER Vector218
+
+#define STM32_TIM1_BRK_NUMBER 24
+#define STM32_TIM1_UP_NUMBER 25
+#define STM32_TIM1_TRGCO_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
+#define STM32_TIM15_NUMBER 116
+#define STM32_TIM16_NUMBER 117
+#define STM32_TIM17_NUMBER 118
+
+/*
+ * USART/UART 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_LPUART1_HANDLER Vector278
+
+#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_LPUART1_NUMBER 142
+
+/*
+ * USB/OTG units.
+ */
+#define STM32_OTG1_HANDLER Vector1D4
+#define STM32_OTG1_EP1OUT_HANDLER Vector1C8
+#define STM32_OTG1_EP1IN_HANDLER Vector1CC
+#define STM32_OTG2_HANDLER Vector174
+#define STM32_OTG2_EP1OUT_HANDLER Vector168
+#define STM32_OTG2_EP1IN_HANDLER Vector16C
+
+#define STM32_OTG1_NUMBER 101
+#define STM32_OTG1_EP1OUT_NUMBER 98
+#define STM32_OTG1_EP1IN_NUMBER 99
+#define STM32_OTG2_NUMBER 77
+#define STM32_OTG2_EP1OUT_NUMBER 74
+#define STM32_OTG2_EP1IN_NUMBER 75
+
+/*
+ * LTDC units.
+ */
+#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 units.
+ */
+#define STM32_DMA2D_HANDLER Vector1A8
+
+#define STM32_DMA2D_NUMBER 90
+
+/*
+ * FSMC units.
+ */
+#define STM32_FSMC_HANDLER Vector100
+
+#define STM32_FSMC_NUMBER 48
+
+/*
+ * DCMI units.
+ */
+#define STM32_DCMI_HANDLER Vector178
+
+#define STM32_DCMI_NUMBER 78
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32H7xx/stm32_rcc.h b/os/hal/ports/STM32/STM32H7xx/stm32_rcc.h
index 1b78dbb80b..c9ebfb9eda 100644
--- a/os/hal/ports/STM32/STM32H7xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32H7xx/stm32_rcc.h
@@ -1,1907 +1,1907 @@
-/*
- 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 STM32F7xx/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32f7xx.h.
- *
- * @addtogroup STM32F7xx_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, low set
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1L(mask, lp) { \
- RCC->APB1LENR |= (mask); \
- if (lp) \
- RCC->APB1LLPENR |= (mask); \
- else \
- RCC->APB1LLPENR &= ~(mask); \
- (void)RCC->APB1LLPENR; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB1 bus.
- *
- * @param[in] mask APB1 peripherals mask, high set
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1H(mask, lp) { \
- RCC->APB1HENR |= (mask); \
- if (lp) \
- RCC->APB1HLPENR |= (mask); \
- else \
- RCC->APB1HLPENR &= ~(mask); \
- (void)RCC->APB1HLPENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus.
- *
- * @param[in] mask APB1 peripherals mask, low set
- *
- * @api
- */
-#define rccDisableAPB1L(mask) { \
- RCC->APB1LENR &= ~(mask); \
- RCC->APB1LLPENR &= ~(mask); \
- (void)RCC->APB1LLPENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus.
- *
- * @param[in] mask APB1 peripherals mask, high set
- *
- * @api
- */
-#define rccDisableAPB1H(mask) { \
- RCC->APB1HENR &= ~(mask); \
- RCC->APB1HLPENR &= ~(mask); \
- (void)RCC->APB1HLPENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus.
- *
- * @param[in] mask APB1 peripherals mask, low set
- *
- * @api
- */
-#define rccResetAPB1L(mask) { \
- RCC->APB1LRSTR |= (mask); \
- RCC->APB1LRSTR &= ~(mask); \
- (void)RCC->APB1LRSTR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus.
- *
- * @param[in] mask APB1 peripherals mask, high set
- *
- * @api
- */
-#define rccResetAPB1H(mask) { \
- RCC->APB1HRSTR |= (mask); \
- RCC->APB1HRSTR &= ~(mask); \
- (void)RCC->APB1HRSTR; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB2 bus.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @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 APB3 bus.
- *
- * @param[in] mask APB3 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB3(mask, lp) { \
- RCC->APB3ENR |= (mask); \
- if (lp) \
- RCC->APB3LPENR |= (mask); \
- else \
- RCC->APB3LPENR &= ~(mask); \
- (void)RCC->APB3LPENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB3 bus.
- *
- * @param[in] mask APB3 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB3(mask) { \
- RCC->APB3ENR &= ~(mask); \
- RCC->APB3LPENR &= ~(mask); \
- (void)RCC->APB3LPENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB3 bus.
- *
- * @param[in] mask APB2 peripherals mask
- *
- * @api
- */
-#define rccResetAPB3(mask) { \
- RCC->APB3RSTR |= (mask); \
- RCC->APB3RSTR &= ~(mask); \
- (void)RCC->APB3RSTR; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB4 bus.
- *
- * @param[in] mask APB4 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB4(mask, lp) { \
- RCC->APB4ENR |= (mask); \
- if (lp) \
- RCC->APB4LPENR |= (mask); \
- else \
- RCC->APB4LPENR &= ~(mask); \
- (void)RCC->APB4LPENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB4 bus.
- *
- * @param[in] mask APB4 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB4(mask) { \
- RCC->APB4ENR &= ~(mask); \
- RCC->APB4LPENR &= ~(mask); \
- (void)RCC->APB4LPENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB4 bus.
- *
- * @param[in] mask APB4 peripherals mask
- *
- * @api
- */
-#define rccResetAPB4(mask) { \
- RCC->APB4RSTR |= (mask); \
- RCC->APB4RSTR &= ~(mask); \
- (void)RCC->APB4RSTR; \
-}
-
-/**
- * @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 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 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 bus.
- *
- * @param[in] mask AHB3 peripherals mask
- *
- * @api
- */
-#define rccResetAHB3(mask) { \
- RCC->AHB3RSTR |= (mask); \
- RCC->AHB3RSTR &= ~(mask); \
- (void)RCC->AHB3RSTR; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the AHB4 bus.
- *
- * @param[in] mask AHB4 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB4(mask, lp) { \
- RCC->AHB4ENR |= (mask); \
- if (lp) \
- RCC->AHB4LPENR |= (mask); \
- else \
- RCC->AHB4LPENR &= ~(mask); \
- (void)RCC->AHB4LPENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB4 bus.
- *
- * @param[in] mask AHB4 peripherals mask
- *
- * @api
- */
-#define rccDisableAHB4(mask) { \
- RCC->AHB4ENR &= ~(mask); \
- RCC->AHB4LPENR &= ~(mask); \
- (void)RCC->AHB4LPENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB4 bus.
- *
- * @param[in] mask AHB4 peripherals mask
- *
- * @api
- */
-#define rccResetAHB4(mask) { \
- RCC->AHB4RSTR |= (mask); \
- RCC->AHB4RSTR &= ~(mask); \
- (void)RCC->AHB4RSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the ADC1/ADC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC12(lp) rccEnableAHB1(RCC_AHB1ENR_ADC12EN, lp)
-
-/**
- * @brief Disables the ADC1/ADC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC12() rccDisableAHB1(RCC_AHB1ENR_ADC12EN)
-
-/**
- * @brief Resets the ADC1/ADC2 peripheral.
- *
- * @api
- */
-#define rccResetADC12() rccResetAHB1(RCC_AHB1RSTR_ADC12RST)
-
-/**
- * @brief Enables the ADC3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC3(lp) rccEnableAHB4(RCC_AHB4ENR_ADC3EN, lp)
-
-/**
- * @brief Disables the ADC3 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC3() rccDisableAHB4(RCC_AHB4ENR_ADC3EN)
-
-/**
- * @brief Resets the ADC3 peripheral.
- *
- * @api
- */
-#define rccResetADC3() rccResetAHB4(RCC_AHB4RSTR_ADC3RST)
-/** @} */
-
-/**
- * @name CRC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRC(lp) rccEnableAHB4(RCC_AHB4ENR_CRCEN, lp)
-
-/**
- * @brief Disables the CRC peripheral clock.
- *
- * @api
- */
-#define rccDisableCRC() rccDisableAHB4(RCC_AHB4ENR_CRCEN)
-
-/**
- * @brief Resets the CRC peripheral.
- *
- * @api
- */
-#define rccResetCRC() rccResetAHB4(RCC_AHB4RSTR_CRCRST)
-/** @} */
-
-/**
- * @name CRYP peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CRYP peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCRYP(lp) rccEnableAHB2(RCC_AHB2ENR_CRYPEN, lp)
-
-/**
- * @brief Disables the CRYP peripheral clock.
- *
- * @api
- */
-#define rccDisableCRYP() rccDisableAHB2(RCC_AHB2ENR_CRYPEN)
-
-/**
- * @brief Resets the CRYP peripheral.
- *
- * @api
- */
-#define rccResetCRYP() rccResetAHB2(RCC_AHB2RSTR_CRYPRST)
-/** @} */
-
-/**
- * @name HASH peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the HASH peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableHASH(lp) rccEnableAHB2(RCC_AHB2ENR_HASHEN, lp)
-
-/**
- * @brief Disables the HASH peripheral clock.
- *
- * @api
- */
-#define rccDisableHASH() rccDisableAHB2(RCC_AHB2ENR_HASHEN)
-
-/**
- * @brief Resets the HASH peripheral.
- *
- * @api
- */
-#define rccResetHASH() rccResetAHB2(RCC_AHB2RSTR_HASHRST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC1(lp) rccEnableAPB1L(RCC_APB1LENR_DAC12EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPB1L(RCC_APB1LENR_DAC12EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPB1L(RCC_APB1LRSTR_DAC12RST)
-/** @} */
-
-/**
- * @name DMA peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the BDMA1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableBDMA1(lp) rccEnableAHB4(RCC_AHB4ENR_BDMAEN, lp)
-
-/**
- * @brief Disables the BDMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableBDMA1() rccDisableAHB4(RCC_AHB4ENR_BDMAEN)
-
-/**
- * @brief Resets the BDMA1 peripheral.
- *
- * @api
- */
-#define rccResetBDMA1() rccResetAHB4(RCC_AHB4RSTR_BDMARST)
-
-/**
- * @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)
-
-/**
- * @brief Enables the MDMA peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableMDMA(lp) rccEnableAHB3(RCC_AHB3ENR_MDMAEN, lp)
-
-/**
- * @brief Disables the MDMA peripheral clock.
- *
- * @api
- */
-#define rccDisableMDMA() rccDisableAHB3(RCC_AHB3ENR_MDMAEN)
-
-/**
- * @brief Resets the MDMA peripheral.
- *
- * @api
- */
-#define rccResetMDMA() rccResetAHB3(RCC_AHB3ENR_MDMARST)
-/** @} */
-
-/**
- * @name RAM specific RCC operations
- * @{
- */
-/**
- * @brief Enables the BKPRAM clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableBKPRAM(lp) rccEnableAHB4(RCC_AHB4ENR_BKPRAMEN, lp)
-
-/**
- * @brief Disables the BKPRAM clock.
- *
- * @api
- */
-#define rccDisableBKPRAM() rccDisableAHB4(RCC_AHB4ENR_BKPRAMEN)
-
-/**
- * @brief Enables the SRAM1 clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSRAM1(lp) rccEnableAHB2(RCC_AHB2ENR_D2SRAM1EN, lp)
-
-/**
- * @brief Disables the SRAM1 clock.
- *
- * @api
- */
-#define rccDisableSRAM1() rccDisableAHB2(RCC_AHB2ENR_D2SRAM1EN)
-
-/**
- * @brief Enables the SRAM2 clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSRAM2(lp) rccEnableAHB2(RCC_AHB2ENR_D2SRAM2EN, lp)
-
-/**
- * @brief Disables the SRAM2 clock.
- *
- * @api
- */
-#define rccDisableSRAM2() rccDisableAHB2(RCC_AHB2ENR_D2SRAM2EN)
-
-/**
- * @brief Enables the SRAM3 clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSRAM3(lp) rccEnableAHB2(RCC_AHB2ENR_D2SRAM3EN, lp)
-
-/**
- * @brief Disables the SRAM3 clock.
- *
- * @api
- */
-#define rccDisableSRAM3() rccDisableAHB2(RCC_AHB2ENR_D2SRAM3EN)
-/** @} */
-
-/**
- * @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_ETH1MACEN | \
- RCC_AHB1ENR_ETH1TXEN | \
- RCC_AHB1ENR_ETH1RXEN, lp)
-
-/**
- * @brief Disables the ETH peripheral clock.
- *
- * @api
- */
-#define rccDisableETH() rccDisableAHB1(RCC_AHB1ENR_ETH1MACEN | \
- RCC_AHB1ENR_ETH1TXEN | \
- RCC_AHB1ENR_ETH1RXEN)
-
-/**
- * @brief Resets the ETH peripheral.
- *
- * @api
- */
-#define rccResetETH() rccResetAHB1(RCC_AHB1RSTR_ETH1MACRST)
-/** @} */
-
-/**
- * @name FDCAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FDCAN peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableFDCAN(lp) rccEnableAPB1H(RCC_APB1HENR_FDCANEN, lp)
-
-/**
- * @brief Disables the FDCAN peripheral clock.
- *
- * @api
- */
-#define rccDisableFDCAN() rccDisableAPB1H(RCC_APB1HENR_FDCANEN)
-
-/**
- * @brief Resets the FDCAN peripheral.
- *
- * @api
- */
-#define rccResetFDCAN() rccResetAPB1H(RCC_APB1HRSTR_FDCANRST)
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C1(lp) rccEnableAPB1L(RCC_APB1LENR_I2C1EN, lp)
-
-/**
- * @brief Disables the I2C1 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C1() rccDisableAPB1L(RCC_APB1LENR_I2C1EN)
-
-/**
- * @brief Resets the I2C1 peripheral.
- *
- * @api
- */
-#define rccResetI2C1() rccResetAPB1L(RCC_APB1LRSTR_I2C1RST)
-
-/**
- * @brief Enables the I2C2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C2(lp) rccEnableAPB1L(RCC_APB1LENR_I2C2EN, lp)
-
-/**
- * @brief Disables the I2C2 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C2() rccDisableAPB1L(RCC_APB1LENR_I2C2EN)
-
-/**
- * @brief Resets the I2C2 peripheral.
- *
- * @api
- */
-#define rccResetI2C2() rccResetAPB1L(RCC_APB1LRSTR_I2C2RST)
-
-/**
- * @brief Enables the I2C3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C3(lp) rccEnableAPB1L(RCC_APB1LENR_I2C3EN, lp)
-
-/**
- * @brief Disables the I2C3 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C3() rccDisableAPB1L(RCC_APB1LENR_I2C3EN)
-
-/**
- * @brief Resets the I2C3 peripheral.
- *
- * @api
- */
-#define rccResetI2C3() rccResetAPB1L(RCC_APB1LRSTR_I2C3RST)
-
-/**
- * @brief Enables the I2C4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C4(lp) rccEnableAPB4(RCC_APB4ENR_I2C4EN, lp)
-
-/**
- * @brief Disables the I2C4 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C4() rccDisableAPB4(RCC_APB4ENR_I2C4EN)
-
-/**
- * @brief Resets the I2C4 peripheral.
- *
- * @api
- */
-#define rccResetI2C4() rccResetAPB4(RCC_APB4RSTR_I2C4RST)
-/** @} */
-
-/**
- * @name OTG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB1_OTG_HS peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB1_OTG_HS(lp) rccEnableAHB1(RCC_AHB1ENR_USB1OTGHSEN, lp)
-
-/**
- * @brief Disables the USB1_OTG_HS peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB1_OTG_HS() rccDisableAHB1(RCC_AHB1ENR_USB1OTGHSEN)
-
-/**
- * @brief Resets the USB1_OTG_HS peripheral.
- *
- * @api
- */
-#define rccResetUSB1_OTG_HS() rccResetAHB1(RCC_AHB1RSTR_USB1OTGHSRST)
-
-/**
- * @brief Enables the USB1_OTG_HS ULPI peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB1_HSULPI(lp) rccEnableAHB1(RCC_AHB1ENR_USB1OTGHSULPIEN, lp)
-
-/**
- * @brief Disables the USB1_OTG_HS peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB1_HSULPI() rccDisableAHB1(RCC_AHB1ENR_USB1OTGHSULPIEN)
-
-/**
- * @brief Enables the USB2_OTG_FS peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB2_OTG_FS(lp) rccEnableAHB1(RCC_AHB1ENR_USB2OTGFSEN, lp)
-
-/**
- * @brief Disables the USB2_OTG_FS peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB2_OTG_FS() rccDisableAHB1(RCC_AHB1ENR_USB2OTGFSEN)
-
-/**
- * @brief Resets the USB2_OTG_FS peripheral.
- *
- * @api
- */
-#define rccResetUSB2_OTG_FS() rccResetAHB1(RCC_AHB1RSTR_USB2OTGFSRST)
-
-/**
- * @brief Enables the USB2_OTG_HS ULPI peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB2_HSULPI(lp) rccEnableAHB1(RCC_AHB1ENR_USB2OTGHSULPIEN, lp)
-
-/**
- * @brief Disables the USB2_OTG_HS peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB2_HSULPI() rccDisableAHB1(RCC_AHB1ENR_USB2OTGHSULPIEN)
-/** @} */
-
-/**
- * @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 RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
-/** @} */
-
-/**
- * @name SDMMC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDMMC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC1(lp) rccEnableAHB3(RCC_AHB3ENR_SDMMC1EN, lp)
-
-/**
- * @brief Disables the SDMMC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC1() rccDisableAHB3(RCC_AHB3ENR_SDMMC1EN)
-
-/**
- * @brief Resets the SDMMC1 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC1() rccResetAHB3(RCC_AHB3RSTR_SDMMC1RST)
-
-/**
- * @brief Enables the SDMMC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC2(lp) rccEnableAHB2(RCC_AHB2ENR_SDMMC2EN, lp)
-
-/**
- * @brief Disables the SDMMC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC2() rccDisableAHB2(RCC_AHB2ENR_SDMMC2EN)
-
-/**
- * @brief Resets the SDMMC2 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC2() rccResetAHB2(RCC_AHB2RSTR_SDMMC2RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1L(RCC_APB1LENR_SPI2EN, lp)
-
-/**
- * @brief Disables the SPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI2() rccDisableAPB1L(RCC_APB1LENR_SPI2EN)
-
-/**
- * @brief Resets the SPI2 peripheral.
- *
- * @api
- */
-#define rccResetSPI2() rccResetAPB1L(RCC_APB1LRSTR_SPI2RST)
-
-/**
- * @brief Enables the SPI3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI3(lp) rccEnableAPB1L(RCC_APB1LENR_SPI3EN, lp)
-
-/**
- * @brief Disables the SPI3 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI3() rccDisableAPB1L(RCC_APB1LENR_SPI3EN)
-
-/**
- * @brief Resets the SPI3 peripheral.
- *
- * @api
- */
-#define rccResetSPI3() rccResetAPB1L(RCC_APB1LRSTR_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) rccEnableAPB4(RCC_APB4ENR_SPI6EN, lp)
-
-/**
- * @brief Disables the SPI6 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI6() rccDisableAPB4(RCC_APB4ENR_SPI6EN)
-
-/**
- * @brief Resets the SPI6 peripheral.
- *
- * @api
- */
-#define rccResetSPI6() rccResetAPB4(RCC_APB4RSTR_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) rccEnableAPB1L(RCC_APB1LENR_TIM2EN, lp)
-
-/**
- * @brief Disables the TIM2 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM2() rccDisableAPB1L(RCC_APB1LENR_TIM2EN)
-
-/**
- * @brief Resets the TIM2 peripheral.
- *
- * @api
- */
-#define rccResetTIM2() rccResetAPB1L(RCC_APB1LRSTR_TIM2RST)
-
-/**
- * @brief Enables the TIM3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM3(lp) rccEnableAPB1L(RCC_APB1LENR_TIM3EN, lp)
-
-/**
- * @brief Disables the TIM3 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM3() rccDisableAPB1L(RCC_APB1LENR_TIM3EN)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPB1L(RCC_APB1LRSTR_TIM3RST)
-
-/**
- * @brief Enables the TIM4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM4(lp) rccEnableAPB1L(RCC_APB1LENR_TIM4EN, lp)
-
-/**
- * @brief Disables the TIM4 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM4() rccDisableAPB1L(RCC_APB1LENR_TIM4EN)
-
-/**
- * @brief Resets the TIM4 peripheral.
- *
- * @api
- */
-#define rccResetTIM4() rccResetAPB1L(RCC_APB1LRSTR_TIM4RST)
-
-/**
- * @brief Enables the TIM5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM5(lp) rccEnableAPB1L(RCC_APB1LENR_TIM5EN, lp)
-
-/**
- * @brief Disables the TIM5 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM5() rccDisableAPB1L(RCC_APB1LENR_TIM5EN)
-
-/**
- * @brief Resets the TIM5 peripheral.
- *
- * @api
- */
-#define rccResetTIM5() rccResetAPB1L(RCC_APB1LRSTR_TIM5RST)
-
-/**
- * @brief Enables the TIM6 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM6(lp) rccEnableAPB1L(RCC_APB1LENR_TIM6EN, lp)
-
-/**
- * @brief Disables the TIM6 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM6() rccDisableAPB1L(RCC_APB1LENR_TIM6EN)
-
-/**
- * @brief Resets the TIM6 peripheral.
- *
- * @api
- */
-#define rccResetTIM6() rccResetAPB1L(RCC_APB1LRSTR_TIM6RST)
-
-/**
- * @brief Enables the TIM7 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM7(lp) rccEnableAPB1L(RCC_APB1LENR_TIM7EN, lp)
-
-/**
- * @brief Disables the TIM7 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM7() rccDisableAPB1L(RCC_APB1LENR_TIM7EN)
-
-/**
- * @brief Resets the TIM7 peripheral.
- *
- * @api
- */
-#define rccResetTIM7() rccResetAPB1L(RCC_APB1LRSTR_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 TIM12 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM12(lp) rccEnableAPB1L(RCC_APB1LENR_TIM12EN, lp)
-
-/**
- * @brief Disables the TIM12 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM12() rccDisableAPB1L(RCC_APB1LENR_TIM12EN)
-
-/**
- * @brief Resets the TIM12 peripheral.
- *
- * @api
- */
-#define rccResetTIM12() rccResetAPB1L(RCC_APB1LRSTR_TIM12RST)
-
-/**
- * @brief Enables the TIM13 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM13(lp) rccEnableAPB1L(RCC_APB1LENR_TIM13EN, lp)
-
-/**
- * @brief Disables the TIM13 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM13() rccDisableAPB1L(RCC_APB1LENR_TIM13EN)
-
-/**
- * @brief Resets the TIM13 peripheral.
- *
- * @api
- */
-#define rccResetTIM13() rccResetAPB1L(RCC_APB1LRSTR_TIM13RST)
-
-/**
- * @brief Enables the TIM14 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM14(lp) rccEnableAPB1L(RCC_APB1LENR_TIM14EN, lp)
-
-/**
- * @brief Disables the TIM14 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM14() rccDisableAPB1L(RCC_APB1LENR_TIM14EN)
-
-/**
- * @brief Resets the TIM14 peripheral.
- *
- * @api
- */
-#define rccResetTIM14() rccResetAPB1L(RCC_APB1LRSTR_TIM14RST)
-
-/**
- * @brief Enables the TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1L(RCC_APB1LENR_USART2EN, lp)
-
-/**
- * @brief Disables the USART2 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART2() rccDisableAPB1L(RCC_APB1LENR_USART2EN)
-
-/**
- * @brief Resets the USART2 peripheral.
- *
- * @api
- */
-#define rccResetUSART2() rccResetAPB1L(RCC_APB1LRSTR_USART2RST)
-
-/**
- * @brief Enables the USART3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART3(lp) rccEnableAPB1L(RCC_APB1LENR_USART3EN, lp)
-
-/**
- * @brief Disables the USART3 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART3() rccDisableAPB1L(RCC_APB1LENR_USART3EN)
-
-/**
- * @brief Resets the USART3 peripheral.
- *
- * @api
- */
-#define rccResetUSART3() rccResetAPB1L(RCC_APB1LRSTR_USART3RST)
-
-/**
- * @brief Enables the UART4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPB1L(RCC_APB1LENR_UART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1L(RCC_APB1LENR_UART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1L(RCC_APB1LRSTR_UART4RST)
-
-/**
- * @brief Enables the UART5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1L(RCC_APB1LENR_UART5EN, lp)
-
-/**
- * @brief Disables the UART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1L(RCC_APB1LENR_UART5EN)
-
-/**
- * @brief Resets the UART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1L(RCC_APB1LRSTR_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) rccEnableAPB1L(RCC_APB1LENR_UART7EN, lp)
-
-/**
- * @brief Disables the UART7 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART7() rccDisableAPB1L(RCC_APB1LENR_UART7EN)
-
-/**
- * @brief Resets the UART7 peripheral.
- *
- * @api
- */
-#define rccResetUART7() rccResetAPB1L(RCC_APB1LRSTR_UART7RST)
-
-/**
- * @brief Enables the UART8 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART8(lp) rccEnableAPB1L(RCC_APB1LENR_UART8EN, lp)
-
-/**
- * @brief Disables the UART8 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART8() rccDisableAPB1L(RCC_APB1LENR_UART8EN)
-
-/**
- * @brief Resets the UART8 peripheral.
- *
- * @api
- */
-#define rccResetUART8() rccResetAPB1L(RCC_APB1LRSTR_UART8RST)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPB4(RCC_APB4ENR_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPB4(RCC_APB4ENR_LPUART1EN)
-
-/**
- * @brief Resets the LPUART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPB4(RCC_APB4RSTR_LPUART1RST)
-/** @} */
-
-/**
- * @name LTDC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the LTDC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLTDC(lp) rccEnableAPB3(RCC_APB3ENR_LTDCEN, lp)
-
-/**
- * @brief Disables the LTDC peripheral clock.
-. *
- * @api
- */
-#define rccDisableLTDC() rccDisableAPB3(RCC_APB3ENR_LTDCEN)
-
-/**
- * @brief Resets the LTDC peripheral.
- *
- * @api
- */
-#define rccResetLTDC() rccResetAPB3(RCC_APB3RSTR_LTDCRST)
-
-/**
- * @name DMA2D peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMA2D peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA2D(lp) rccEnableAHB3(RCC_AHB3ENR_DMA2DEN, lp)
-
-/**
- * @brief Disables the DMA2D peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA2D() rccDisableAHB3(RCC_AHB3ENR_DMA2DEN)
-
-/**
- * @brief Resets the DMA2D peripheral.
- *
- * @api
- */
-#define rccResetDMA2D() rccResetAHB3(RCC_AHB3RSTR_DMA2DRST)
-/** @} */
-
-/**
- * @name FSMC peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FSMC peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#if defined(STM32_FSMC_IS_FMC)
- #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
-#else
- #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FSMCEN, lp)
-#endif
-
-/**
- * @brief Disables the FSMC peripheral clock.
- *
- * @api
- */
-#if defined(STM32_FSMC_IS_FMC)
- #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
-#else
- #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FSMCEN)
-#endif
-
-/**
- * @brief Resets the FSMC peripheral.
- *
- * @api
- */
-#if defined(STM32_FSMC_IS_FMC)
- #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
-#else
- #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FSMCRST)
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_H */
-
-/** @} */
+/*
+ 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 STM32F7xx/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32f7xx.h.
+ *
+ * @addtogroup STM32F7xx_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, low set
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1L(mask, lp) { \
+ RCC->APB1LENR |= (mask); \
+ if (lp) \
+ RCC->APB1LLPENR |= (mask); \
+ else \
+ RCC->APB1LLPENR &= ~(mask); \
+ (void)RCC->APB1LLPENR; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB1 bus.
+ *
+ * @param[in] mask APB1 peripherals mask, high set
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1H(mask, lp) { \
+ RCC->APB1HENR |= (mask); \
+ if (lp) \
+ RCC->APB1HLPENR |= (mask); \
+ else \
+ RCC->APB1HLPENR &= ~(mask); \
+ (void)RCC->APB1HLPENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus.
+ *
+ * @param[in] mask APB1 peripherals mask, low set
+ *
+ * @api
+ */
+#define rccDisableAPB1L(mask) { \
+ RCC->APB1LENR &= ~(mask); \
+ RCC->APB1LLPENR &= ~(mask); \
+ (void)RCC->APB1LLPENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus.
+ *
+ * @param[in] mask APB1 peripherals mask, high set
+ *
+ * @api
+ */
+#define rccDisableAPB1H(mask) { \
+ RCC->APB1HENR &= ~(mask); \
+ RCC->APB1HLPENR &= ~(mask); \
+ (void)RCC->APB1HLPENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus.
+ *
+ * @param[in] mask APB1 peripherals mask, low set
+ *
+ * @api
+ */
+#define rccResetAPB1L(mask) { \
+ RCC->APB1LRSTR |= (mask); \
+ RCC->APB1LRSTR &= ~(mask); \
+ (void)RCC->APB1LRSTR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus.
+ *
+ * @param[in] mask APB1 peripherals mask, high set
+ *
+ * @api
+ */
+#define rccResetAPB1H(mask) { \
+ RCC->APB1HRSTR |= (mask); \
+ RCC->APB1HRSTR &= ~(mask); \
+ (void)RCC->APB1HRSTR; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB2 bus.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @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 APB3 bus.
+ *
+ * @param[in] mask APB3 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB3(mask, lp) { \
+ RCC->APB3ENR |= (mask); \
+ if (lp) \
+ RCC->APB3LPENR |= (mask); \
+ else \
+ RCC->APB3LPENR &= ~(mask); \
+ (void)RCC->APB3LPENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB3 bus.
+ *
+ * @param[in] mask APB3 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB3(mask) { \
+ RCC->APB3ENR &= ~(mask); \
+ RCC->APB3LPENR &= ~(mask); \
+ (void)RCC->APB3LPENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB3 bus.
+ *
+ * @param[in] mask APB2 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB3(mask) { \
+ RCC->APB3RSTR |= (mask); \
+ RCC->APB3RSTR &= ~(mask); \
+ (void)RCC->APB3RSTR; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB4 bus.
+ *
+ * @param[in] mask APB4 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB4(mask, lp) { \
+ RCC->APB4ENR |= (mask); \
+ if (lp) \
+ RCC->APB4LPENR |= (mask); \
+ else \
+ RCC->APB4LPENR &= ~(mask); \
+ (void)RCC->APB4LPENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB4 bus.
+ *
+ * @param[in] mask APB4 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB4(mask) { \
+ RCC->APB4ENR &= ~(mask); \
+ RCC->APB4LPENR &= ~(mask); \
+ (void)RCC->APB4LPENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB4 bus.
+ *
+ * @param[in] mask APB4 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB4(mask) { \
+ RCC->APB4RSTR |= (mask); \
+ RCC->APB4RSTR &= ~(mask); \
+ (void)RCC->APB4RSTR; \
+}
+
+/**
+ * @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 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 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 bus.
+ *
+ * @param[in] mask AHB3 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB3(mask) { \
+ RCC->AHB3RSTR |= (mask); \
+ RCC->AHB3RSTR &= ~(mask); \
+ (void)RCC->AHB3RSTR; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the AHB4 bus.
+ *
+ * @param[in] mask AHB4 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB4(mask, lp) { \
+ RCC->AHB4ENR |= (mask); \
+ if (lp) \
+ RCC->AHB4LPENR |= (mask); \
+ else \
+ RCC->AHB4LPENR &= ~(mask); \
+ (void)RCC->AHB4LPENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB4 bus.
+ *
+ * @param[in] mask AHB4 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB4(mask) { \
+ RCC->AHB4ENR &= ~(mask); \
+ RCC->AHB4LPENR &= ~(mask); \
+ (void)RCC->AHB4LPENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB4 bus.
+ *
+ * @param[in] mask AHB4 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB4(mask) { \
+ RCC->AHB4RSTR |= (mask); \
+ RCC->AHB4RSTR &= ~(mask); \
+ (void)RCC->AHB4RSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the ADC1/ADC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC12(lp) rccEnableAHB1(RCC_AHB1ENR_ADC12EN, lp)
+
+/**
+ * @brief Disables the ADC1/ADC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC12() rccDisableAHB1(RCC_AHB1ENR_ADC12EN)
+
+/**
+ * @brief Resets the ADC1/ADC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC12() rccResetAHB1(RCC_AHB1RSTR_ADC12RST)
+
+/**
+ * @brief Enables the ADC3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC3(lp) rccEnableAHB4(RCC_AHB4ENR_ADC3EN, lp)
+
+/**
+ * @brief Disables the ADC3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC3() rccDisableAHB4(RCC_AHB4ENR_ADC3EN)
+
+/**
+ * @brief Resets the ADC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC3() rccResetAHB4(RCC_AHB4RSTR_ADC3RST)
+/** @} */
+
+/**
+ * @name CRC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRC(lp) rccEnableAHB4(RCC_AHB4ENR_CRCEN, lp)
+
+/**
+ * @brief Disables the CRC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRC() rccDisableAHB4(RCC_AHB4ENR_CRCEN)
+
+/**
+ * @brief Resets the CRC peripheral.
+ *
+ * @api
+ */
+#define rccResetCRC() rccResetAHB4(RCC_AHB4RSTR_CRCRST)
+/** @} */
+
+/**
+ * @name CRYP peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CRYP peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCRYP(lp) rccEnableAHB2(RCC_AHB2ENR_CRYPEN, lp)
+
+/**
+ * @brief Disables the CRYP peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCRYP() rccDisableAHB2(RCC_AHB2ENR_CRYPEN)
+
+/**
+ * @brief Resets the CRYP peripheral.
+ *
+ * @api
+ */
+#define rccResetCRYP() rccResetAHB2(RCC_AHB2RSTR_CRYPRST)
+/** @} */
+
+/**
+ * @name HASH peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the HASH peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableHASH(lp) rccEnableAHB2(RCC_AHB2ENR_HASHEN, lp)
+
+/**
+ * @brief Disables the HASH peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableHASH() rccDisableAHB2(RCC_AHB2ENR_HASHEN)
+
+/**
+ * @brief Resets the HASH peripheral.
+ *
+ * @api
+ */
+#define rccResetHASH() rccResetAHB2(RCC_AHB2RSTR_HASHRST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC1(lp) rccEnableAPB1L(RCC_APB1LENR_DAC12EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPB1L(RCC_APB1LENR_DAC12EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPB1L(RCC_APB1LRSTR_DAC12RST)
+/** @} */
+
+/**
+ * @name DMA peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the BDMA1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableBDMA1(lp) rccEnableAHB4(RCC_AHB4ENR_BDMAEN, lp)
+
+/**
+ * @brief Disables the BDMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableBDMA1() rccDisableAHB4(RCC_AHB4ENR_BDMAEN)
+
+/**
+ * @brief Resets the BDMA1 peripheral.
+ *
+ * @api
+ */
+#define rccResetBDMA1() rccResetAHB4(RCC_AHB4RSTR_BDMARST)
+
+/**
+ * @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)
+
+/**
+ * @brief Enables the MDMA peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableMDMA(lp) rccEnableAHB3(RCC_AHB3ENR_MDMAEN, lp)
+
+/**
+ * @brief Disables the MDMA peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableMDMA() rccDisableAHB3(RCC_AHB3ENR_MDMAEN)
+
+/**
+ * @brief Resets the MDMA peripheral.
+ *
+ * @api
+ */
+#define rccResetMDMA() rccResetAHB3(RCC_AHB3ENR_MDMARST)
+/** @} */
+
+/**
+ * @name RAM specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the BKPRAM clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableBKPRAM(lp) rccEnableAHB4(RCC_AHB4ENR_BKPRAMEN, lp)
+
+/**
+ * @brief Disables the BKPRAM clock.
+ *
+ * @api
+ */
+#define rccDisableBKPRAM() rccDisableAHB4(RCC_AHB4ENR_BKPRAMEN)
+
+/**
+ * @brief Enables the SRAM1 clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSRAM1(lp) rccEnableAHB2(RCC_AHB2ENR_D2SRAM1EN, lp)
+
+/**
+ * @brief Disables the SRAM1 clock.
+ *
+ * @api
+ */
+#define rccDisableSRAM1() rccDisableAHB2(RCC_AHB2ENR_D2SRAM1EN)
+
+/**
+ * @brief Enables the SRAM2 clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSRAM2(lp) rccEnableAHB2(RCC_AHB2ENR_D2SRAM2EN, lp)
+
+/**
+ * @brief Disables the SRAM2 clock.
+ *
+ * @api
+ */
+#define rccDisableSRAM2() rccDisableAHB2(RCC_AHB2ENR_D2SRAM2EN)
+
+/**
+ * @brief Enables the SRAM3 clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSRAM3(lp) rccEnableAHB2(RCC_AHB2ENR_D2SRAM3EN, lp)
+
+/**
+ * @brief Disables the SRAM3 clock.
+ *
+ * @api
+ */
+#define rccDisableSRAM3() rccDisableAHB2(RCC_AHB2ENR_D2SRAM3EN)
+/** @} */
+
+/**
+ * @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_ETH1MACEN | \
+ RCC_AHB1ENR_ETH1TXEN | \
+ RCC_AHB1ENR_ETH1RXEN, lp)
+
+/**
+ * @brief Disables the ETH peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableETH() rccDisableAHB1(RCC_AHB1ENR_ETH1MACEN | \
+ RCC_AHB1ENR_ETH1TXEN | \
+ RCC_AHB1ENR_ETH1RXEN)
+
+/**
+ * @brief Resets the ETH peripheral.
+ *
+ * @api
+ */
+#define rccResetETH() rccResetAHB1(RCC_AHB1RSTR_ETH1MACRST)
+/** @} */
+
+/**
+ * @name FDCAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FDCAN peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableFDCAN(lp) rccEnableAPB1H(RCC_APB1HENR_FDCANEN, lp)
+
+/**
+ * @brief Disables the FDCAN peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFDCAN() rccDisableAPB1H(RCC_APB1HENR_FDCANEN)
+
+/**
+ * @brief Resets the FDCAN peripheral.
+ *
+ * @api
+ */
+#define rccResetFDCAN() rccResetAPB1H(RCC_APB1HRSTR_FDCANRST)
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C1(lp) rccEnableAPB1L(RCC_APB1LENR_I2C1EN, lp)
+
+/**
+ * @brief Disables the I2C1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C1() rccDisableAPB1L(RCC_APB1LENR_I2C1EN)
+
+/**
+ * @brief Resets the I2C1 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C1() rccResetAPB1L(RCC_APB1LRSTR_I2C1RST)
+
+/**
+ * @brief Enables the I2C2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C2(lp) rccEnableAPB1L(RCC_APB1LENR_I2C2EN, lp)
+
+/**
+ * @brief Disables the I2C2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C2() rccDisableAPB1L(RCC_APB1LENR_I2C2EN)
+
+/**
+ * @brief Resets the I2C2 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C2() rccResetAPB1L(RCC_APB1LRSTR_I2C2RST)
+
+/**
+ * @brief Enables the I2C3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C3(lp) rccEnableAPB1L(RCC_APB1LENR_I2C3EN, lp)
+
+/**
+ * @brief Disables the I2C3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C3() rccDisableAPB1L(RCC_APB1LENR_I2C3EN)
+
+/**
+ * @brief Resets the I2C3 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C3() rccResetAPB1L(RCC_APB1LRSTR_I2C3RST)
+
+/**
+ * @brief Enables the I2C4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C4(lp) rccEnableAPB4(RCC_APB4ENR_I2C4EN, lp)
+
+/**
+ * @brief Disables the I2C4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C4() rccDisableAPB4(RCC_APB4ENR_I2C4EN)
+
+/**
+ * @brief Resets the I2C4 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C4() rccResetAPB4(RCC_APB4RSTR_I2C4RST)
+/** @} */
+
+/**
+ * @name OTG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB1_OTG_HS peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB1_OTG_HS(lp) rccEnableAHB1(RCC_AHB1ENR_USB1OTGHSEN, lp)
+
+/**
+ * @brief Disables the USB1_OTG_HS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB1_OTG_HS() rccDisableAHB1(RCC_AHB1ENR_USB1OTGHSEN)
+
+/**
+ * @brief Resets the USB1_OTG_HS peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB1_OTG_HS() rccResetAHB1(RCC_AHB1RSTR_USB1OTGHSRST)
+
+/**
+ * @brief Enables the USB1_OTG_HS ULPI peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB1_HSULPI(lp) rccEnableAHB1(RCC_AHB1ENR_USB1OTGHSULPIEN, lp)
+
+/**
+ * @brief Disables the USB1_OTG_HS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB1_HSULPI() rccDisableAHB1(RCC_AHB1ENR_USB1OTGHSULPIEN)
+
+/**
+ * @brief Enables the USB2_OTG_FS peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB2_OTG_FS(lp) rccEnableAHB1(RCC_AHB1ENR_USB2OTGFSEN, lp)
+
+/**
+ * @brief Disables the USB2_OTG_FS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB2_OTG_FS() rccDisableAHB1(RCC_AHB1ENR_USB2OTGFSEN)
+
+/**
+ * @brief Resets the USB2_OTG_FS peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB2_OTG_FS() rccResetAHB1(RCC_AHB1RSTR_USB2OTGFSRST)
+
+/**
+ * @brief Enables the USB2_OTG_HS ULPI peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB2_HSULPI(lp) rccEnableAHB1(RCC_AHB1ENR_USB2OTGHSULPIEN, lp)
+
+/**
+ * @brief Disables the USB2_OTG_HS peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB2_HSULPI() rccDisableAHB1(RCC_AHB1ENR_USB2OTGHSULPIEN)
+/** @} */
+
+/**
+ * @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 RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
+/** @} */
+
+/**
+ * @name SDMMC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDMMC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC1(lp) rccEnableAHB3(RCC_AHB3ENR_SDMMC1EN, lp)
+
+/**
+ * @brief Disables the SDMMC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC1() rccDisableAHB3(RCC_AHB3ENR_SDMMC1EN)
+
+/**
+ * @brief Resets the SDMMC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC1() rccResetAHB3(RCC_AHB3RSTR_SDMMC1RST)
+
+/**
+ * @brief Enables the SDMMC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC2(lp) rccEnableAHB2(RCC_AHB2ENR_SDMMC2EN, lp)
+
+/**
+ * @brief Disables the SDMMC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC2() rccDisableAHB2(RCC_AHB2ENR_SDMMC2EN)
+
+/**
+ * @brief Resets the SDMMC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC2() rccResetAHB2(RCC_AHB2RSTR_SDMMC2RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1L(RCC_APB1LENR_SPI2EN, lp)
+
+/**
+ * @brief Disables the SPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI2() rccDisableAPB1L(RCC_APB1LENR_SPI2EN)
+
+/**
+ * @brief Resets the SPI2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI2() rccResetAPB1L(RCC_APB1LRSTR_SPI2RST)
+
+/**
+ * @brief Enables the SPI3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI3(lp) rccEnableAPB1L(RCC_APB1LENR_SPI3EN, lp)
+
+/**
+ * @brief Disables the SPI3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI3() rccDisableAPB1L(RCC_APB1LENR_SPI3EN)
+
+/**
+ * @brief Resets the SPI3 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI3() rccResetAPB1L(RCC_APB1LRSTR_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) rccEnableAPB4(RCC_APB4ENR_SPI6EN, lp)
+
+/**
+ * @brief Disables the SPI6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI6() rccDisableAPB4(RCC_APB4ENR_SPI6EN)
+
+/**
+ * @brief Resets the SPI6 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI6() rccResetAPB4(RCC_APB4RSTR_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) rccEnableAPB1L(RCC_APB1LENR_TIM2EN, lp)
+
+/**
+ * @brief Disables the TIM2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM2() rccDisableAPB1L(RCC_APB1LENR_TIM2EN)
+
+/**
+ * @brief Resets the TIM2 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM2() rccResetAPB1L(RCC_APB1LRSTR_TIM2RST)
+
+/**
+ * @brief Enables the TIM3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM3(lp) rccEnableAPB1L(RCC_APB1LENR_TIM3EN, lp)
+
+/**
+ * @brief Disables the TIM3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM3() rccDisableAPB1L(RCC_APB1LENR_TIM3EN)
+
+/**
+ * @brief Resets the TIM3 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM3() rccResetAPB1L(RCC_APB1LRSTR_TIM3RST)
+
+/**
+ * @brief Enables the TIM4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM4(lp) rccEnableAPB1L(RCC_APB1LENR_TIM4EN, lp)
+
+/**
+ * @brief Disables the TIM4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM4() rccDisableAPB1L(RCC_APB1LENR_TIM4EN)
+
+/**
+ * @brief Resets the TIM4 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM4() rccResetAPB1L(RCC_APB1LRSTR_TIM4RST)
+
+/**
+ * @brief Enables the TIM5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM5(lp) rccEnableAPB1L(RCC_APB1LENR_TIM5EN, lp)
+
+/**
+ * @brief Disables the TIM5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM5() rccDisableAPB1L(RCC_APB1LENR_TIM5EN)
+
+/**
+ * @brief Resets the TIM5 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM5() rccResetAPB1L(RCC_APB1LRSTR_TIM5RST)
+
+/**
+ * @brief Enables the TIM6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM6(lp) rccEnableAPB1L(RCC_APB1LENR_TIM6EN, lp)
+
+/**
+ * @brief Disables the TIM6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM6() rccDisableAPB1L(RCC_APB1LENR_TIM6EN)
+
+/**
+ * @brief Resets the TIM6 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM6() rccResetAPB1L(RCC_APB1LRSTR_TIM6RST)
+
+/**
+ * @brief Enables the TIM7 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM7(lp) rccEnableAPB1L(RCC_APB1LENR_TIM7EN, lp)
+
+/**
+ * @brief Disables the TIM7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM7() rccDisableAPB1L(RCC_APB1LENR_TIM7EN)
+
+/**
+ * @brief Resets the TIM7 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM7() rccResetAPB1L(RCC_APB1LRSTR_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 TIM12 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM12(lp) rccEnableAPB1L(RCC_APB1LENR_TIM12EN, lp)
+
+/**
+ * @brief Disables the TIM12 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM12() rccDisableAPB1L(RCC_APB1LENR_TIM12EN)
+
+/**
+ * @brief Resets the TIM12 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM12() rccResetAPB1L(RCC_APB1LRSTR_TIM12RST)
+
+/**
+ * @brief Enables the TIM13 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM13(lp) rccEnableAPB1L(RCC_APB1LENR_TIM13EN, lp)
+
+/**
+ * @brief Disables the TIM13 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM13() rccDisableAPB1L(RCC_APB1LENR_TIM13EN)
+
+/**
+ * @brief Resets the TIM13 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM13() rccResetAPB1L(RCC_APB1LRSTR_TIM13RST)
+
+/**
+ * @brief Enables the TIM14 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM14(lp) rccEnableAPB1L(RCC_APB1LENR_TIM14EN, lp)
+
+/**
+ * @brief Disables the TIM14 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM14() rccDisableAPB1L(RCC_APB1LENR_TIM14EN)
+
+/**
+ * @brief Resets the TIM14 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM14() rccResetAPB1L(RCC_APB1LRSTR_TIM14RST)
+
+/**
+ * @brief Enables the TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1L(RCC_APB1LENR_USART2EN, lp)
+
+/**
+ * @brief Disables the USART2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART2() rccDisableAPB1L(RCC_APB1LENR_USART2EN)
+
+/**
+ * @brief Resets the USART2 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART2() rccResetAPB1L(RCC_APB1LRSTR_USART2RST)
+
+/**
+ * @brief Enables the USART3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART3(lp) rccEnableAPB1L(RCC_APB1LENR_USART3EN, lp)
+
+/**
+ * @brief Disables the USART3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART3() rccDisableAPB1L(RCC_APB1LENR_USART3EN)
+
+/**
+ * @brief Resets the USART3 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART3() rccResetAPB1L(RCC_APB1LRSTR_USART3RST)
+
+/**
+ * @brief Enables the UART4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPB1L(RCC_APB1LENR_UART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1L(RCC_APB1LENR_UART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1L(RCC_APB1LRSTR_UART4RST)
+
+/**
+ * @brief Enables the UART5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1L(RCC_APB1LENR_UART5EN, lp)
+
+/**
+ * @brief Disables the UART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1L(RCC_APB1LENR_UART5EN)
+
+/**
+ * @brief Resets the UART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1L(RCC_APB1LRSTR_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) rccEnableAPB1L(RCC_APB1LENR_UART7EN, lp)
+
+/**
+ * @brief Disables the UART7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART7() rccDisableAPB1L(RCC_APB1LENR_UART7EN)
+
+/**
+ * @brief Resets the UART7 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART7() rccResetAPB1L(RCC_APB1LRSTR_UART7RST)
+
+/**
+ * @brief Enables the UART8 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART8(lp) rccEnableAPB1L(RCC_APB1LENR_UART8EN, lp)
+
+/**
+ * @brief Disables the UART8 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART8() rccDisableAPB1L(RCC_APB1LENR_UART8EN)
+
+/**
+ * @brief Resets the UART8 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART8() rccResetAPB1L(RCC_APB1LRSTR_UART8RST)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPB4(RCC_APB4ENR_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPB4(RCC_APB4ENR_LPUART1EN)
+
+/**
+ * @brief Resets the LPUART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPB4(RCC_APB4RSTR_LPUART1RST)
+/** @} */
+
+/**
+ * @name LTDC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the LTDC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLTDC(lp) rccEnableAPB3(RCC_APB3ENR_LTDCEN, lp)
+
+/**
+ * @brief Disables the LTDC peripheral clock.
+. *
+ * @api
+ */
+#define rccDisableLTDC() rccDisableAPB3(RCC_APB3ENR_LTDCEN)
+
+/**
+ * @brief Resets the LTDC peripheral.
+ *
+ * @api
+ */
+#define rccResetLTDC() rccResetAPB3(RCC_APB3RSTR_LTDCRST)
+
+/**
+ * @name DMA2D peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMA2D peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA2D(lp) rccEnableAHB3(RCC_AHB3ENR_DMA2DEN, lp)
+
+/**
+ * @brief Disables the DMA2D peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA2D() rccDisableAHB3(RCC_AHB3ENR_DMA2DEN)
+
+/**
+ * @brief Resets the DMA2D peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA2D() rccResetAHB3(RCC_AHB3RSTR_DMA2DRST)
+/** @} */
+
+/**
+ * @name FSMC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FSMC peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#if defined(STM32_FSMC_IS_FMC)
+ #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
+#else
+ #define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FSMCEN, lp)
+#endif
+
+/**
+ * @brief Disables the FSMC peripheral clock.
+ *
+ * @api
+ */
+#if defined(STM32_FSMC_IS_FMC)
+ #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
+#else
+ #define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FSMCEN)
+#endif
+
+/**
+ * @brief Resets the FSMC peripheral.
+ *
+ * @api
+ */
+#if defined(STM32_FSMC_IS_FMC)
+ #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
+#else
+ #define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FSMCRST)
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32H7xx/stm32_registry.h b/os/hal/ports/STM32/STM32H7xx/stm32_registry.h
index f102679ced..1e7e7e2428 100644
--- a/os/hal/ports/STM32/STM32H7xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32H7xx/stm32_registry.h
@@ -1,558 +1,558 @@
-/*
- 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/stm32_registry.h
- * @brief STM32H7xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/* Cores.*/
-#if defined(STM32H750xx) || defined(STM32H742xx) || \
- defined(STM32H743xx) || defined(STM32H753xx)
-#define STM32_HAS_M7 TRUE
-#define STM32_HAS_M4 FALSE
-#else
-#define STM32_HAS_M7 TRUE
-#define STM32_HAS_M4 TRUE
-#endif
-
-/**
- * @name STM32H7xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* I2C attributes.*/
-#define STM32_I2C4_USE_BDMA TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 128
-#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 18
-#define STM32_RTC_WKUP_EXTI 19
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
-} while (false)
-
-/*===========================================================================*/
-/* STM32H730xx, STM32H750xx, STM32H7B0xx, STM32H733xx, STM32H735xx, */
-/* STM32H753xx, STM32H7B3xx, STM32H755xx, STM32H757xx */
-/*===========================================================================*/
-
-#if defined(STM32H730xx) || defined(STM32H750xx) || \
- defined(STM32H7B0xx) || defined(STM32H733xx) || \
- defined(STM32H735xx) || defined(STM32H753xx) || \
- defined(STM32H7B3xx) || defined(STM32H755xx) || \
- defined(STM32H757xx) || \
- defined(__DOXYGEN__)
-
-/* HASH attributes.*/
-#define STM32_HAS_HASH1 TRUE
-
-/* CRYP attributes.*/
-#define STM32_HAS_CRYP1 TRUE
-
-#else
-
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-
-#endif
-
-/*===========================================================================*/
-/* STM32H743xx, STM32H753xx, STM32H745xx, STM32H755xx, STM32H747xx, */
-/* STM32H757xx. */
-/*===========================================================================*/
-#if defined(STM32H743xx) || defined(STM32H753xx) || \
- defined(STM32H745xx) || defined(STM32H755xx) || \
- defined(STM32H747xx) || defined(STM32H757xx) || \
- defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 TRUE
-#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_FDCAN1 TRUE
-#define STM32_HAS_FDCAN2 TRUE
-#define STM32_HAS_FDCAN3 FALSE
-#define STM32_FDCAN_FLS_NBR 64U
-#define STM32_FDCAN_FLE_NBR 64U
-#define STM32_FDCAN_RF0_NBR 48U
-#define STM32_FDCAN_RF1_NBR 48U
-#define STM32_FDCAN_RB_NBR 0U
-#define STM32_FDCAN_TEF_NBR 0U
-#define STM32_FDCAN_TB_NBR 32U
-#define STM32_FDCAN_TM_NBR 0U
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* BDMA attributes.*/
-#define STM32_HAS_BDMA1 TRUE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 TRUE
-
-/* MDMA attributes.*/
-#define STM32_HAS_MDMA1 TRUE
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH TRUE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_ENHANCED
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ TRUE
-#define STM32_HAS_GPIOK TRUE
-#define STM32_GPIO_EN_MASK (RCC_AHB4ENR_GPIOAEN | \
- RCC_AHB4ENR_GPIOBEN | \
- RCC_AHB4ENR_GPIOCEN | \
- RCC_AHB4ENR_GPIODEN | \
- RCC_AHB4ENR_GPIOEEN | \
- RCC_AHB4ENR_GPIOFEN | \
- RCC_AHB4ENR_GPIOGEN | \
- RCC_AHB4ENR_GPIOHEN | \
- RCC_AHB4ENR_GPIOIEN | \
- RCC_AHB4ENR_GPIOJEN | \
- RCC_AHB4ENR_GPIOKEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 TRUE
-#define STM32_HAS_I2C4 TRUE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_HAS_QUADSPI2 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_HAS_SDMMC2 TRUE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-
-#define STM32_HAS_SPI4 TRUE
-#define STM32_SPI4_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI5 TRUE
-#define STM32_SPI5_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI6 TRUE
-#define STM32_SPI6_SUPPORTS_I2S FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#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_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 FALSE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 FALSE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_UART5 TRUE
-#define STM32_HAS_USART6 TRUE
-#define STM32_HAS_UART7 TRUE
-#define STM32_HAS_UART8 TRUE
-#define STM32_HAS_LPUART1 TRUE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 8
-
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 8
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* 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
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI TRUE
-
-#endif /* defined(STM32H743xx) || defined(STM32H753xx) */
-/** @} */
-
-/*===========================================================================*/
-/* STM32H750xx. */
-/*===========================================================================*/
-#if defined(STM32H750xx) || \
- defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 FALSE
-#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_FDCAN1 TRUE
-#define STM32_HAS_FDCAN2 TRUE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* BDMA attributes.*/
-#define STM32_HAS_BDMA1 TRUE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 TRUE
-
-/* MDMA attributes.*/
-#define STM32_HAS_MDMA1 TRUE
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH TRUE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_ENHANCED
-#define STM32_EXTI_NUM_LINES 34
-#define STM32_EXTI_IMR1_MASK 0x1F800000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
-
-/* 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
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ TRUE
-#define STM32_HAS_GPIOK TRUE
-#define STM32_GPIO_EN_MASK (RCC_AHB4ENR_GPIOAEN | \
- RCC_AHB4ENR_GPIOBEN | \
- RCC_AHB4ENR_GPIOCEN | \
- RCC_AHB4ENR_GPIODEN | \
- RCC_AHB4ENR_GPIOEEN | \
- RCC_AHB4ENR_GPIOFEN | \
- RCC_AHB4ENR_GPIOGEN | \
- RCC_AHB4ENR_GPIOHEN | \
- RCC_AHB4ENR_GPIOIEN | \
- RCC_AHB4ENR_GPIOJEN | \
- RCC_AHB4ENR_GPIOKEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 TRUE
-#define STM32_HAS_I2C4 TRUE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_HAS_QUADSPI2 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_HAS_SDMMC2 TRUE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S TRUE
-#define STM32_SPI1_I2S_FULLDUPLEX TRUE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX TRUE
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX TRUE
-
-#define STM32_HAS_SPI4 TRUE
-#define STM32_SPI4_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI5 TRUE
-#define STM32_SPI5_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI6 TRUE
-#define STM32_SPI6_SUPPORTS_I2S FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#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_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 FALSE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 1
-
-#define STM32_HAS_TIM17 FALSE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 1
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_UART5 TRUE
-#define STM32_HAS_USART6 TRUE
-#define STM32_HAS_UART7 TRUE
-#define STM32_HAS_UART8 TRUE
-#define STM32_HAS_LPUART1 TRUE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 8
-
-#define STM32_HAS_OTG2 TRUE
-#define STM32_OTG2_ENDPOINTS 8
-
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* 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
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI TRUE
-
-#endif /* defined(STM32H750xx) */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32H7xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/* Cores.*/
+#if defined(STM32H750xx) || defined(STM32H742xx) || \
+ defined(STM32H743xx) || defined(STM32H753xx)
+#define STM32_HAS_M7 TRUE
+#define STM32_HAS_M4 FALSE
+#else
+#define STM32_HAS_M7 TRUE
+#define STM32_HAS_M4 TRUE
+#endif
+
+/**
+ * @name STM32H7xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* I2C attributes.*/
+#define STM32_I2C4_USE_BDMA TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
+#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 18
+#define STM32_RTC_WKUP_EXTI 19
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI17_PRIORITY); \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+} while (false)
+
+/*===========================================================================*/
+/* STM32H730xx, STM32H750xx, STM32H7B0xx, STM32H733xx, STM32H735xx, */
+/* STM32H753xx, STM32H7B3xx, STM32H755xx, STM32H757xx */
+/*===========================================================================*/
+
+#if defined(STM32H730xx) || defined(STM32H750xx) || \
+ defined(STM32H7B0xx) || defined(STM32H733xx) || \
+ defined(STM32H735xx) || defined(STM32H753xx) || \
+ defined(STM32H7B3xx) || defined(STM32H755xx) || \
+ defined(STM32H757xx) || \
+ defined(__DOXYGEN__)
+
+/* HASH attributes.*/
+#define STM32_HAS_HASH1 TRUE
+
+/* CRYP attributes.*/
+#define STM32_HAS_CRYP1 TRUE
+
+#else
+
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+
+#endif
+
+/*===========================================================================*/
+/* STM32H743xx, STM32H753xx, STM32H745xx, STM32H755xx, STM32H747xx, */
+/* STM32H757xx. */
+/*===========================================================================*/
+#if defined(STM32H743xx) || defined(STM32H753xx) || \
+ defined(STM32H745xx) || defined(STM32H755xx) || \
+ defined(STM32H747xx) || defined(STM32H757xx) || \
+ defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 TRUE
+#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_FDCAN1 TRUE
+#define STM32_HAS_FDCAN2 TRUE
+#define STM32_HAS_FDCAN3 FALSE
+#define STM32_FDCAN_FLS_NBR 64U
+#define STM32_FDCAN_FLE_NBR 64U
+#define STM32_FDCAN_RF0_NBR 48U
+#define STM32_FDCAN_RF1_NBR 48U
+#define STM32_FDCAN_RB_NBR 0U
+#define STM32_FDCAN_TEF_NBR 0U
+#define STM32_FDCAN_TB_NBR 32U
+#define STM32_FDCAN_TM_NBR 0U
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* BDMA attributes.*/
+#define STM32_HAS_BDMA1 TRUE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+
+#define STM32_HAS_DMA1 TRUE
+#define STM32_HAS_DMA2 TRUE
+
+/* MDMA attributes.*/
+#define STM32_HAS_MDMA1 TRUE
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH TRUE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_ENHANCED
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ TRUE
+#define STM32_HAS_GPIOK TRUE
+#define STM32_GPIO_EN_MASK (RCC_AHB4ENR_GPIOAEN | \
+ RCC_AHB4ENR_GPIOBEN | \
+ RCC_AHB4ENR_GPIOCEN | \
+ RCC_AHB4ENR_GPIODEN | \
+ RCC_AHB4ENR_GPIOEEN | \
+ RCC_AHB4ENR_GPIOFEN | \
+ RCC_AHB4ENR_GPIOGEN | \
+ RCC_AHB4ENR_GPIOHEN | \
+ RCC_AHB4ENR_GPIOIEN | \
+ RCC_AHB4ENR_GPIOJEN | \
+ RCC_AHB4ENR_GPIOKEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 TRUE
+#define STM32_HAS_I2C4 TRUE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_HAS_QUADSPI2 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_HAS_SDMMC2 TRUE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI5 TRUE
+#define STM32_SPI5_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI6 TRUE
+#define STM32_SPI6_SUPPORTS_I2S FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#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_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 FALSE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 FALSE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_UART5 TRUE
+#define STM32_HAS_USART6 TRUE
+#define STM32_HAS_UART7 TRUE
+#define STM32_HAS_UART8 TRUE
+#define STM32_HAS_LPUART1 TRUE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 8
+
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 8
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* 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
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI TRUE
+
+#endif /* defined(STM32H743xx) || defined(STM32H753xx) */
+/** @} */
+
+/*===========================================================================*/
+/* STM32H750xx. */
+/*===========================================================================*/
+#if defined(STM32H750xx) || \
+ defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 FALSE
+#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_FDCAN1 TRUE
+#define STM32_HAS_FDCAN2 TRUE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* BDMA attributes.*/
+#define STM32_HAS_BDMA1 TRUE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+
+#define STM32_HAS_DMA1 TRUE
+#define STM32_HAS_DMA2 TRUE
+
+/* MDMA attributes.*/
+#define STM32_HAS_MDMA1 TRUE
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH TRUE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_ENHANCED
+#define STM32_EXTI_NUM_LINES 34
+#define STM32_EXTI_IMR1_MASK 0x1F800000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFFFCU
+
+/* 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
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ TRUE
+#define STM32_HAS_GPIOK TRUE
+#define STM32_GPIO_EN_MASK (RCC_AHB4ENR_GPIOAEN | \
+ RCC_AHB4ENR_GPIOBEN | \
+ RCC_AHB4ENR_GPIOCEN | \
+ RCC_AHB4ENR_GPIODEN | \
+ RCC_AHB4ENR_GPIOEEN | \
+ RCC_AHB4ENR_GPIOFEN | \
+ RCC_AHB4ENR_GPIOGEN | \
+ RCC_AHB4ENR_GPIOHEN | \
+ RCC_AHB4ENR_GPIOIEN | \
+ RCC_AHB4ENR_GPIOJEN | \
+ RCC_AHB4ENR_GPIOKEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 TRUE
+#define STM32_HAS_I2C4 TRUE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_HAS_QUADSPI2 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_HAS_SDMMC2 TRUE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S TRUE
+#define STM32_SPI1_I2S_FULLDUPLEX TRUE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX TRUE
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX TRUE
+
+#define STM32_HAS_SPI4 TRUE
+#define STM32_SPI4_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI5 TRUE
+#define STM32_SPI5_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI6 TRUE
+#define STM32_SPI6_SUPPORTS_I2S FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#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_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 FALSE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 1
+
+#define STM32_HAS_TIM17 FALSE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 1
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_UART5 TRUE
+#define STM32_HAS_USART6 TRUE
+#define STM32_HAS_UART7 TRUE
+#define STM32_HAS_UART8 TRUE
+#define STM32_HAS_LPUART1 TRUE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 8
+
+#define STM32_HAS_OTG2 TRUE
+#define STM32_OTG2_ENDPOINTS 8
+
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* 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
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI TRUE
+
+#endif /* defined(STM32H750xx) */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.c b/os/hal/ports/STM32/STM32L0xx/hal_lld.c
index 43ab11bf96..d26f261cfc 100644
--- a/os/hal/ports/STM32/STM32L0xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.c
@@ -1,269 +1,270 @@
-/*
- 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)
+ && ((RCC->CSR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..15307f0b35 100644
--- a/os/hal/ports/STM32/STM32L0xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.h
@@ -1,1253 +1,1262 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32L0xx/platform.mk b/os/hal/ports/STM32/STM32L0xx/platform.mk
index 208d410149..2e48dad746 100644
--- a/os/hal/ports/STM32/STM32L0xx/platform.mk
+++ b/os/hal/ports/STM32/STM32L0xx/platform.mk
@@ -1,45 +1,45 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx
-
-# 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/ADCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/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/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx
+
+# 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/ADCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/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/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/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/STM32L0xx/stm32_isr.c b/os/hal/ports/STM32/STM32L0xx/stm32_isr.c
index e8417a192d..d7dfc96699 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_isr.c
@@ -1,125 +1,125 @@
-/*
- 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/stm32_isr.c
- * @brief STM32L0xx ISR handler code.
- *
- * @addtogroup SRM32L0xx_ISR
- * @{
- */
-
-#include "hal.h"
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-#define exti_serve_irq(pr, channel) { \
- \
- if ((pr) & (1U << (channel))) { \
- _pal_isr_code(channel); \
- } \
-}
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#include "stm32_dma1_ch23.inc"
-#include "stm32_dma1_ch4567.inc"
-
-#include "stm32_exti0_1.inc"
-#include "stm32_exti2_3.inc"
-#include "stm32_exti4_15.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart4_5.inc"
-#include "stm32_lpuart1.inc"
-
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim21.inc"
-#include "stm32_tim22.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_1_irq_init();
- exti2_3_irq_init();
- exti4_15_irq_init();
-
- tim2_irq_init();
- tim3_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim21_irq_init();
- tim22_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart4_usart5_irq_init();
- lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_1_irq_deinit();
- exti2_3_irq_deinit();
- exti4_15_irq_deinit();
-
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim21_irq_deinit();
- tim22_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart4_usart5_irq_deinit();
- lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32L0xx ISR handler code.
+ *
+ * @addtogroup SRM32L0xx_ISR
+ * @{
+ */
+
+#include "hal.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+#define exti_serve_irq(pr, channel) { \
+ \
+ if ((pr) & (1U << (channel))) { \
+ _pal_isr_code(channel); \
+ } \
+}
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#include "stm32_dma1_ch23.inc"
+#include "stm32_dma1_ch4567.inc"
+
+#include "stm32_exti0_1.inc"
+#include "stm32_exti2_3.inc"
+#include "stm32_exti4_15.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart4_5.inc"
+#include "stm32_lpuart1.inc"
+
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim21.inc"
+#include "stm32_tim22.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_1_irq_init();
+ exti2_3_irq_init();
+ exti4_15_irq_init();
+
+ tim2_irq_init();
+ tim3_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim21_irq_init();
+ tim22_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart4_usart5_irq_init();
+ lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_1_irq_deinit();
+ exti2_3_irq_deinit();
+ exti4_15_irq_deinit();
+
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim21_irq_deinit();
+ tim22_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart4_usart5_irq_deinit();
+ lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L0xx/stm32_isr.h b/os/hal/ports/STM32/STM32L0xx/stm32_isr.h
index fc31e0ab78..3a332634fb 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_isr.h
@@ -1,182 +1,182 @@
-/*
- 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/stm32_isr.h
- * @brief STM32L0xx ISR handler header.
- *
- * @addtogroup STM32L0xx_ISR
- * @{
- */
-
-#ifndef STM32_ISR_H
-#define STM32_ISR_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name ISRs suppressed in standard drivers
- * @{
- */
-#define STM32_TIM2_SUPPRESS_ISR
-#define STM32_TIM3_SUPPRESS_ISR
-#define STM32_TIM6_SUPPRESS_ISR
-#define STM32_TIM7_SUPPRESS_ISR
-#define STM32_TIM21_SUPPRESS_ISR
-#define STM32_TIM22_SUPPRESS_ISR
-
-#define STM32_USART1_SUPPRESS_ISR
-#define STM32_USART2_SUPPRESS_ISR
-#define STM32_UART4_SUPPRESS_ISR
-#define STM32_UART5_SUPPRESS_ISR
-#define STM32_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC unit.
- */
-#define STM32_ADC1_HANDLER Vector70
-#define STM32_ADC1_NUMBER 12
-
-/*
- * DMA unit.
- */
-#define STM32_DMA1_CH1_HANDLER Vector64
-#define STM32_DMA1_CH23_HANDLER Vector68
-#define STM32_DMA1_CH4567_HANDLER Vector6C
-#define STM32_DMA1_CH1_NUMBER 9
-#define STM32_DMA1_CH23_NUMBER 10
-#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
-#define STM32_DMA1_CH4567_NUMBER 11
-#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
-#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
-
-#define STM32_DMA1_CH2_CMASK 0x00000006U
-#define STM32_DMA1_CH3_CMASK 0x00000006U
-#define STM32_DMA1_CH4_CMASK 0x00000078U
-#define STM32_DMA1_CH5_CMASK 0x00000078U
-#define STM32_DMA1_CH6_CMASK 0x00000078U
-#define STM32_DMA1_CH7_CMASK 0x00000078U
-
-/*
- * EXTI unit.
- */
-#define STM32_EXTI0_1_HANDLER Vector54
-#define STM32_EXTI2_3_HANDLER Vector58
-#define STM32_EXTI4_15_HANDLER Vector5C
-#define STM32_EXTI16_HANDLER Vector44
-#define STM32_EXTI171920_HANDLER Vector48
-#define STM32_EXTI2122_HANDLER Vector70
-
-#define STM32_EXTI0_1_NUMBER 5
-#define STM32_EXTI2_3_NUMBER 6
-#define STM32_EXTI4_15_NUMBER 7
-#define STM32_EXTI16_NUMBER 1
-#define STM32_EXTI171920_NUMBER 2
-#define STM32_EXTI2122_NUMBER 12
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_GLOBAL_HANDLER Vector9C
-#define STM32_I2C2_GLOBAL_HANDLER VectorA0
-#define STM32_I2C3_GLOBAL_HANDLER Vector94
-
-#define STM32_I2C1_GLOBAL_NUMBER 23
-#define STM32_I2C2_GLOBAL_NUMBER 24
-#define STM32_I2C3_GLOBAL_NUMBER 21
-
-/*
- * TIM units.
- */
-#define STM32_TIM2_HANDLER Vector7C
-#define STM32_TIM3_HANDLER Vector80
-#define STM32_TIM6_HANDLER Vector84
-#define STM32_TIM7_HANDLER Vector88
-#define STM32_TIM21_HANDLER Vector90
-#define STM32_TIM22_HANDLER Vector98
-
-#define STM32_TIM2_NUMBER 15
-#define STM32_TIM3_NUMBER 16
-#define STM32_TIM6_NUMBER 17
-#define STM32_TIM7_NUMBER 18
-#define STM32_TIM21_NUMBER 20
-#define STM32_TIM22_NUMBER 22
-
-/*
- * USART/UART units.
- */
-#define STM32_USART1_HANDLER VectorAC
-#define STM32_USART2_HANDLER VectorB0
-#define STM32_USART4_5_HANDLER Vector78
-#define STM32_LPUART1_HANDLER VectorB4
-
-#define STM32_USART1_NUMBER 27
-#define STM32_USART2_NUMBER 28
-#define STM32_USART4_5_NUMBER 14
-#define STM32_LPUART1_NUMBER 29
-
-/*
- * USB units.
- */
-#define STM32_USB1_LP_HANDLER VectorBC
-#define STM32_USB1_HP_HANDLER VectorBC
-
-#define STM32_USB1_LP_NUMBER 31
-#define STM32_USB1_HP_NUMBER 31
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32L0xx ISR handler header.
+ *
+ * @addtogroup STM32L0xx_ISR
+ * @{
+ */
+
+#ifndef STM32_ISR_H
+#define STM32_ISR_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name ISRs suppressed in standard drivers
+ * @{
+ */
+#define STM32_TIM2_SUPPRESS_ISR
+#define STM32_TIM3_SUPPRESS_ISR
+#define STM32_TIM6_SUPPRESS_ISR
+#define STM32_TIM7_SUPPRESS_ISR
+#define STM32_TIM21_SUPPRESS_ISR
+#define STM32_TIM22_SUPPRESS_ISR
+
+#define STM32_USART1_SUPPRESS_ISR
+#define STM32_USART2_SUPPRESS_ISR
+#define STM32_UART4_SUPPRESS_ISR
+#define STM32_UART5_SUPPRESS_ISR
+#define STM32_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC unit.
+ */
+#define STM32_ADC1_HANDLER Vector70
+#define STM32_ADC1_NUMBER 12
+
+/*
+ * DMA unit.
+ */
+#define STM32_DMA1_CH1_HANDLER Vector64
+#define STM32_DMA1_CH23_HANDLER Vector68
+#define STM32_DMA1_CH4567_HANDLER Vector6C
+#define STM32_DMA1_CH1_NUMBER 9
+#define STM32_DMA1_CH23_NUMBER 10
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH4567_NUMBER 11
+#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER
+#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER
+
+#define STM32_DMA1_CH2_CMASK 0x00000006U
+#define STM32_DMA1_CH3_CMASK 0x00000006U
+#define STM32_DMA1_CH4_CMASK 0x00000078U
+#define STM32_DMA1_CH5_CMASK 0x00000078U
+#define STM32_DMA1_CH6_CMASK 0x00000078U
+#define STM32_DMA1_CH7_CMASK 0x00000078U
+
+/*
+ * EXTI unit.
+ */
+#define STM32_EXTI0_1_HANDLER Vector54
+#define STM32_EXTI2_3_HANDLER Vector58
+#define STM32_EXTI4_15_HANDLER Vector5C
+#define STM32_EXTI16_HANDLER Vector44
+#define STM32_EXTI171920_HANDLER Vector48
+#define STM32_EXTI2122_HANDLER Vector70
+
+#define STM32_EXTI0_1_NUMBER 5
+#define STM32_EXTI2_3_NUMBER 6
+#define STM32_EXTI4_15_NUMBER 7
+#define STM32_EXTI16_NUMBER 1
+#define STM32_EXTI171920_NUMBER 2
+#define STM32_EXTI2122_NUMBER 12
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_GLOBAL_HANDLER Vector9C
+#define STM32_I2C2_GLOBAL_HANDLER VectorA0
+#define STM32_I2C3_GLOBAL_HANDLER Vector94
+
+#define STM32_I2C1_GLOBAL_NUMBER 23
+#define STM32_I2C2_GLOBAL_NUMBER 24
+#define STM32_I2C3_GLOBAL_NUMBER 21
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM2_HANDLER Vector7C
+#define STM32_TIM3_HANDLER Vector80
+#define STM32_TIM6_HANDLER Vector84
+#define STM32_TIM7_HANDLER Vector88
+#define STM32_TIM21_HANDLER Vector90
+#define STM32_TIM22_HANDLER Vector98
+
+#define STM32_TIM2_NUMBER 15
+#define STM32_TIM3_NUMBER 16
+#define STM32_TIM6_NUMBER 17
+#define STM32_TIM7_NUMBER 18
+#define STM32_TIM21_NUMBER 20
+#define STM32_TIM22_NUMBER 22
+
+/*
+ * USART/UART units.
+ */
+#define STM32_USART1_HANDLER VectorAC
+#define STM32_USART2_HANDLER VectorB0
+#define STM32_USART4_5_HANDLER Vector78
+#define STM32_LPUART1_HANDLER VectorB4
+
+#define STM32_USART1_NUMBER 27
+#define STM32_USART2_NUMBER 28
+#define STM32_USART4_5_NUMBER 14
+#define STM32_LPUART1_NUMBER 29
+
+/*
+ * USB units.
+ */
+#define STM32_USB1_LP_HANDLER VectorBC
+#define STM32_USB1_HP_HANDLER VectorBC
+
+#define STM32_USB1_LP_NUMBER 31
+#define STM32_USB1_HP_NUMBER 31
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32L0xx/stm32_rcc.h b/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h
index 696ae64cf2..644d40a61c 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h
@@ -1,819 +1,819 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32l0xx.h.
- *
- * @addtogroup STM32L1xx_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->APB1SMENR |= (mask); \
- else \
- RCC->APB1SMENR &= ~(mask); \
- (void)RCC->APB1SMENR; \
-}
-
-/**
- * @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->APB1SMENR &= ~(mask); \
- (void)RCC->APB1SMENR; \
-}
-
-/**
- * @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
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- if (lp) \
- RCC->APB2SMENR |= (mask); \
- else \
- RCC->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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 AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- if (lp) \
- RCC->AHBSMENR |= (mask); \
- else \
- RCC->AHBSMENR &= ~(mask); \
- (void)RCC->AHBSMENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- RCC->AHBSMENR &= ~(mask); \
- (void)RCC->AHBSMENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the IOP bus.
- *
- * @param[in] mask IOP peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableIOP(mask, lp) { \
- RCC->IOPENR |= (mask); \
- if (lp) \
- RCC->IOPSMENR |= (mask); \
- else \
- RCC->IOPSMENR &= ~(mask); \
- (void)RCC->IOPSMENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the IOP bus.
- *
- * @param[in] mask IOP peripherals mask
- *
- * @api
- */
-#define rccDisableIOP(mask) { \
- RCC->IOPENR &= ~(mask); \
- RCC->IOPSMENR &= ~(mask); \
- (void)RCC->IOPSMENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the IOP bus.
- *
- * @param[in] mask IOP peripherals mask
- *
- * @api
- */
-#define rccResetIOP(mask) { \
- RCC->IOPRSTR |= (mask); \
- RCC->IOPRSTR &= ~(mask); \
- (void)RCC->IOPRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-/** @} */
-
-/**
- * @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) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- *
- * @api
- */
-#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
-/** @} */
-
-/**
- * @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 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)
-/** @} */
-
-/**
- * @name RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB(RCC_AHBENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB(RCC_AHBENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB(RCC_AHBRSTR_RNGRST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @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 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 TIM21 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM21(lp) rccEnableAPB2(RCC_APB2ENR_TIM21EN, lp)
-
-/**
- * @brief Disables the TIM21 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM21() rccDisableAPB2(RCC_APB2ENR_TIM21EN)
-
-/**
- * @brief Resets the TIM21 peripheral.
- *
- * @api
- */
-#define rccResetTIM21() rccResetAPB2(RCC_APB2RSTR_TIM21RST)
-
-/**
- * @brief Enables the TIM22 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM22(lp) rccEnableAPB2(RCC_APB2ENR_TIM22EN, lp)
-
-/**
- * @brief Disables the TIM22 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM22() rccDisableAPB2(RCC_APB2ENR_TIM22EN)
-
-/**
- * @brief Resets the TIM22 peripheral.
- *
- * @api
- */
-#define rccResetTIM22() rccResetAPB2(RCC_APB2RSTR_TIM22RST)
-/** @} */
-
-/**
- * @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_USART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1(RCC_APB1ENR_USART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1(RCC_APB1ENR_USART4EN)
-
-/**
- * @brief Enables the UART5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_USART5EN, lp)
-
-/**
- * @brief Disables the UART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1(RCC_APB1ENR_USART5EN)
-
-/**
- * @brief Resets the UART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1(RCC_APB1ENR_USART5EN)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPB1(RCC_APB1ENR_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPB1(RCC_APB1ENR_LPUART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPB1(RCC_APB1RSTR_LPUART1RST)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32l0xx.h.
+ *
+ * @addtogroup STM32L1xx_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->APB1SMENR |= (mask); \
+ else \
+ RCC->APB1SMENR &= ~(mask); \
+ (void)RCC->APB1SMENR; \
+}
+
+/**
+ * @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->APB1SMENR &= ~(mask); \
+ (void)RCC->APB1SMENR; \
+}
+
+/**
+ * @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
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ if (lp) \
+ RCC->APB2SMENR |= (mask); \
+ else \
+ RCC->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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 AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ if (lp) \
+ RCC->AHBSMENR |= (mask); \
+ else \
+ RCC->AHBSMENR &= ~(mask); \
+ (void)RCC->AHBSMENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ RCC->AHBSMENR &= ~(mask); \
+ (void)RCC->AHBSMENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the IOP bus.
+ *
+ * @param[in] mask IOP peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableIOP(mask, lp) { \
+ RCC->IOPENR |= (mask); \
+ if (lp) \
+ RCC->IOPSMENR |= (mask); \
+ else \
+ RCC->IOPSMENR &= ~(mask); \
+ (void)RCC->IOPSMENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the IOP bus.
+ *
+ * @param[in] mask IOP peripherals mask
+ *
+ * @api
+ */
+#define rccDisableIOP(mask) { \
+ RCC->IOPENR &= ~(mask); \
+ RCC->IOPSMENR &= ~(mask); \
+ (void)RCC->IOPSMENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the IOP bus.
+ *
+ * @param[in] mask IOP peripherals mask
+ *
+ * @api
+ */
+#define rccResetIOP(mask) { \
+ RCC->IOPRSTR |= (mask); \
+ RCC->IOPRSTR &= ~(mask); \
+ (void)RCC->IOPRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+/** @} */
+
+/**
+ * @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) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
+/** @} */
+
+/**
+ * @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 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)
+/** @} */
+
+/**
+ * @name RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB(RCC_AHBENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB(RCC_AHBENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB(RCC_AHBRSTR_RNGRST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @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 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 TIM21 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM21(lp) rccEnableAPB2(RCC_APB2ENR_TIM21EN, lp)
+
+/**
+ * @brief Disables the TIM21 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM21() rccDisableAPB2(RCC_APB2ENR_TIM21EN)
+
+/**
+ * @brief Resets the TIM21 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM21() rccResetAPB2(RCC_APB2RSTR_TIM21RST)
+
+/**
+ * @brief Enables the TIM22 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM22(lp) rccEnableAPB2(RCC_APB2ENR_TIM22EN, lp)
+
+/**
+ * @brief Disables the TIM22 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM22() rccDisableAPB2(RCC_APB2ENR_TIM22EN)
+
+/**
+ * @brief Resets the TIM22 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM22() rccResetAPB2(RCC_APB2RSTR_TIM22RST)
+/** @} */
+
+/**
+ * @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_USART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1(RCC_APB1ENR_USART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1(RCC_APB1ENR_USART4EN)
+
+/**
+ * @brief Enables the UART5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1(RCC_APB1ENR_USART5EN, lp)
+
+/**
+ * @brief Disables the UART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1(RCC_APB1ENR_USART5EN)
+
+/**
+ * @brief Resets the UART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1(RCC_APB1ENR_USART5EN)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPB1(RCC_APB1ENR_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPB1(RCC_APB1ENR_LPUART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPB1(RCC_APB1RSTR_LPUART1RST)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
index 7784ffc4c4..067b07d0fa 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
@@ -1,1220 +1,1220 @@
-/*
- 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/stm32_registry.h
- * @brief STM32L0xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32L0xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 20
-#define STM32_RTC_COMMON_HANDLER Vector48
-#define STM32_RTC_COMMON_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() \
- nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_PRIORITY)
-
-/*===========================================================================*/
-/* STM32L011xx. */
-/*===========================================================================*/
-#if defined(STM32L011xx) || defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER TRUE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 5
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0xFF840000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH FALSE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x06000600
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00600060
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_SPI1_RX_DMA_CHN 0x00000010
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00000100
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM21 TRUE
-#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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_TIM22 FALSE
-
-/* USART attributes.*/
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00440000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x04004000
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART1 FALSE
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32L031xx. */
-/*===========================================================================*/
-#elif defined(STM32L031xx)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER TRUE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0xFF840000U
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x06000600
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00600060
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_SPI1_RX_DMA_CHN 0x00000010
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00000100
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM21 TRUE
-#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 2
-
-#define STM32_HAS_TIM22 TRUE
-#define STM32_TIM22_IS_32BITS FALSE
-#define STM32_TIM22_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM6 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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
-
-/* USART attributes.*/
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00440000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x04004000
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART1 FALSE
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32L051xx, STM32L061xx. */
-/*===========================================================================*/
-#elif defined(STM32L051xx) || defined(STM32L061xx)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER TRUE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0xFF840000U
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIODEN | \
- RCC_IOPENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x06000600
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00600060
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00070000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00007000
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_SPI1_RX_DMA_CHN 0x00000010
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00000100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_RX_DMA_CHN 0x00202000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_SPI2_TX_DMA_CHN 0x02020000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM21 TRUE
-#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 2
-
-#define STM32_HAS_TIM22 TRUE
-#define STM32_TIM22_IS_32BITS FALSE
-#define STM32_TIM22_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00030300
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00003030
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00440000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x04004000
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-
-/*===========================================================================*/
-/* STM32L052xx, STM32L062xx, STM32L053xx, STM32L063xx. */
-/*===========================================================================*/
-#elif defined(STM32L052xx) || defined(STM32L062xx) || \
- defined(STM32L053xx) || defined(STM32L063xx)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER TRUE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_DAC1_CH1_DMA_CHN 0x00000090
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 TRUE
-#define STM32_HAS_DAC2_CH2 TRUE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0xFF840000U
-
-/* 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 FALSE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIODEN | \
- RCC_IOPENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x06000600
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00600060
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00070000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00007000
-
-#define STM32_HAS_I2C3 FALSE
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_SPI1_RX_DMA_CHN 0x00000010
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00000100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_RX_DMA_CHN 0x00202000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_SPI2_TX_DMA_CHN 0x02020000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM21 TRUE
-#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 2
-
-#define STM32_HAS_TIM22 TRUE
-#define STM32_TIM22_IS_32BITS FALSE
-#define STM32_TIM22_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00030300
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00003030
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00440000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x04004000
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32L071xx. */
-/*===========================================================================*/
-#elif defined(STM32L071xx)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER TRUE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_DAC1_CH1_DMA_CHN 0x00000090
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_DAC1_CH2_DMA_CHN 0x0000F000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0xFF840000U
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIODEN | \
- RCC_IOPENR_GPIOEEN | \
- RCC_IOPENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x06000600
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00600060
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00070000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00007000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C3_RX_DMA_CHN 0x00E0E000
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C3_TX_DMA_CHN 0x0E0E0000
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_SPI1_RX_DMA_CHN 0x00000010
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00000100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_RX_DMA_CHN 0x00202000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_SPI2_TX_DMA_CHN 0x02020000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM3 TRUE
-#define STM32_TIM3_IS_32BITS FALSE
-#define STM32_TIM3_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_TIM21 TRUE
-#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 2
-
-#define STM32_HAS_TIM22 TRUE
-#define STM32_TIM22_IS_32BITS FALSE
-#define STM32_TIM22_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00030300
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00003030
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00440000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x04004000
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_UART4_RX_DMA_CHN 0x00C000C0
-#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_UART4_TX_DMA_CHN 0x0C000C00
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_UART5_RX_DMA_CHN 0x00D000D0
-#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_UART5_TX_DMA_CHN 0x0D000D00
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/*===========================================================================*/
-/* STM32L072xx, STM32L073xx. */
-/*===========================================================================*/
-#elif defined(STM32L072xx) || defined(STM32L073xx)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC_SUPPORTS_PRESCALER TRUE
-#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_DAC1_CH1_DMA_CHN 0x00000090
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_DAC1_CH2_DMA_CHN 0x0000F000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 0
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 23
-#define STM32_EXTI_IMR1_MASK 0xFF840000U
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
- RCC_IOPENR_GPIOBEN | \
- RCC_IOPENR_GPIOCEN | \
- RCC_IOPENR_GPIODEN | \
- RCC_IOPENR_GPIOEEN | \
- RCC_IOPENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_I2C1_RX_DMA_CHN 0x06000600
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C1_TX_DMA_CHN 0x00600060
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
-#define STM32_I2C2_RX_DMA_CHN 0x00070000
-#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
-#define STM32_I2C2_TX_DMA_CHN 0x00007000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C3_RX_DMA_CHN 0x00E0E000
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_I2C3_TX_DMA_CHN 0x0E0E0000
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_SPI1_RX_DMA_CHN 0x00000010
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_SPI1_TX_DMA_CHN 0x00000100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_SPI2_RX_DMA_CHN 0x00202000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_SPI2_TX_DMA_CHN 0x02020000
-
-#define STM32_HAS_SPI3 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#define STM32_TIM2_CHANNELS 4
-
-#define STM32_HAS_TIM3 TRUE
-#define STM32_TIM3_IS_32BITS FALSE
-#define STM32_TIM3_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_TIM21 TRUE
-#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 2
-
-#define STM32_HAS_TIM22 TRUE
-#define STM32_TIM22_IS_32BITS FALSE
-#define STM32_TIM22_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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
-
-/* USART attributes.*/
-#define STM32_HAS_USART1 TRUE
-#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_USART1_RX_DMA_CHN 0x00030300
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_USART1_TX_DMA_CHN 0x00003030
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00440000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x04004000
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_UART4_RX_DMA_CHN 0x00C000C0
-#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_UART4_TX_DMA_CHN 0x0C000C00
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_UART5_RX_DMA_CHN 0x00D000D0
-#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_UART5_TX_DMA_CHN 0x0D000D00
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#else
-#error "STM32L0xx device not specified"
-#endif
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32L0xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32L0xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 20
+#define STM32_RTC_COMMON_HANDLER Vector48
+#define STM32_RTC_COMMON_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() \
+ nvicEnableVector(STM32_RTC_COMMON_NUMBER, STM32_IRQ_EXTI17_20_PRIORITY)
+
+/*===========================================================================*/
+/* STM32L011xx. */
+/*===========================================================================*/
+#if defined(STM32L011xx) || defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 5
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0xFF840000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH FALSE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x06000600
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00600060
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_SPI1_RX_DMA_CHN 0x00000010
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00000100
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM21 TRUE
+#define STM32_TIM21_IS_32BITS FALSE
+#define STM32_TIM21_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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_TIM22 FALSE
+
+/* USART attributes.*/
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00440000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x04004000
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART1 FALSE
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32L031xx. */
+/*===========================================================================*/
+#elif defined(STM32L031xx)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0xFF840000U
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x06000600
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00600060
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_SPI1_RX_DMA_CHN 0x00000010
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00000100
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM21 TRUE
+#define STM32_TIM21_IS_32BITS FALSE
+#define STM32_TIM21_CHANNELS 2
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM6 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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
+
+/* USART attributes.*/
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00440000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x04004000
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART1 FALSE
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32L051xx, STM32L061xx. */
+/*===========================================================================*/
+#elif defined(STM32L051xx) || defined(STM32L061xx)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 FALSE
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0xFF840000U
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIODEN | \
+ RCC_IOPENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x06000600
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00600060
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00070000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00007000
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_SPI1_RX_DMA_CHN 0x00000010
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00000100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_RX_DMA_CHN 0x00202000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_SPI2_TX_DMA_CHN 0x02020000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM21 TRUE
+#define STM32_TIM21_IS_32BITS FALSE
+#define STM32_TIM21_CHANNELS 2
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00030300
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00003030
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00440000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x04004000
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+
+/*===========================================================================*/
+/* STM32L052xx, STM32L062xx, STM32L053xx, STM32L063xx. */
+/*===========================================================================*/
+#elif defined(STM32L052xx) || defined(STM32L062xx) || \
+ defined(STM32L053xx) || defined(STM32L063xx)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_DAC1_CH1_DMA_CHN 0x00000090
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 TRUE
+#define STM32_HAS_DAC2_CH2 TRUE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0xFF840000U
+
+/* 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 FALSE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIODEN | \
+ RCC_IOPENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x06000600
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00600060
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00070000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00007000
+
+#define STM32_HAS_I2C3 FALSE
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_SPI1_RX_DMA_CHN 0x00000010
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00000100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_RX_DMA_CHN 0x00202000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_SPI2_TX_DMA_CHN 0x02020000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM21 TRUE
+#define STM32_TIM21_IS_32BITS FALSE
+#define STM32_TIM21_CHANNELS 2
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00030300
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00003030
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00440000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x04004000
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32L071xx. */
+/*===========================================================================*/
+#elif defined(STM32L071xx)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_DAC1_CH1_DMA_CHN 0x00000090
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_DAC1_CH2_DMA_CHN 0x0000F000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0xFF840000U
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIODEN | \
+ RCC_IOPENR_GPIOEEN | \
+ RCC_IOPENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x06000600
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00600060
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00070000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00007000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C3_RX_DMA_CHN 0x00E0E000
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C3_TX_DMA_CHN 0x0E0E0000
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_SPI1_RX_DMA_CHN 0x00000010
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00000100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_RX_DMA_CHN 0x00202000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_SPI2_TX_DMA_CHN 0x02020000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM3 TRUE
+#define STM32_TIM3_IS_32BITS FALSE
+#define STM32_TIM3_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_TIM21 TRUE
+#define STM32_TIM21_IS_32BITS FALSE
+#define STM32_TIM21_CHANNELS 2
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00030300
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00003030
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00440000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x04004000
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_UART4_RX_DMA_CHN 0x00C000C0
+#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_UART4_TX_DMA_CHN 0x0C000C00
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_UART5_RX_DMA_CHN 0x00D000D0
+#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_UART5_TX_DMA_CHN 0x0D000D00
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/*===========================================================================*/
+/* STM32L072xx, STM32L073xx. */
+/*===========================================================================*/
+#elif defined(STM32L072xx) || defined(STM32L073xx)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_DAC1_CH1_DMA_CHN 0x00000090
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_DAC1_CH2_DMA_CHN 0x0000F000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 0
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR1_MASK 0xFF840000U
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_IOPENR_GPIOAEN | \
+ RCC_IOPENR_GPIOBEN | \
+ RCC_IOPENR_GPIOCEN | \
+ RCC_IOPENR_GPIODEN | \
+ RCC_IOPENR_GPIOEEN | \
+ RCC_IOPENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_I2C1_RX_DMA_CHN 0x06000600
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C1_TX_DMA_CHN 0x00600060
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 5)
+#define STM32_I2C2_RX_DMA_CHN 0x00070000
+#define STM32_I2C2_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(1, 4)
+#define STM32_I2C2_TX_DMA_CHN 0x00007000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C3_RX_DMA_CHN 0x00E0E000
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_I2C3_TX_DMA_CHN 0x0E0E0000
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_SPI1_RX_DMA_CHN 0x00000010
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_SPI1_TX_DMA_CHN 0x00000100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_SPI2_RX_DMA_CHN 0x00202000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_SPI2_TX_DMA_CHN 0x02020000
+
+#define STM32_HAS_SPI3 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#define STM32_TIM2_CHANNELS 4
+
+#define STM32_HAS_TIM3 TRUE
+#define STM32_TIM3_IS_32BITS FALSE
+#define STM32_TIM3_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_TIM21 TRUE
+#define STM32_TIM21_IS_32BITS FALSE
+#define STM32_TIM21_CHANNELS 2
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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
+
+/* USART attributes.*/
+#define STM32_HAS_USART1 TRUE
+#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_USART1_RX_DMA_CHN 0x00030300
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_USART1_TX_DMA_CHN 0x00003030
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00440000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x04004000
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_UART4_RX_DMA_CHN 0x00C000C0
+#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_UART4_TX_DMA_CHN 0x0C000C00
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART5_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_UART5_RX_DMA_CHN 0x00D000D0
+#define STM32_UART5_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_UART5_TX_DMA_CHN 0x0D000D00
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#else
+#error "STM32L0xx device not specified"
+#endif
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c b/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
index 913f974f19..b61a73d206 100644
--- a/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
+++ b/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
@@ -1,294 +1,294 @@
-/*
- 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_adc_lld.c
- * @brief STM32L1xx ADC subsystem low level driver source.
- *
- * @addtogroup ADC
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief ADC1 driver identifier.*/
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-ADCDriver ADCD1;
-#endif
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief ADC DMA ISR service routine.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- * @param[in] flags pre-shifted content of the ISR register
- */
-static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
-
- /* DMA errors handling.*/
- if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
- /* DMA, this could help only if the DMA tries to access an unmapped
- address space or violates alignment rules.*/
- _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
- }
- else {
- /* It is possible that the conversion group has already be reset by the
- ADC error handler, in this case this interrupt is spurious.*/
- if (adcp->grpp != NULL) {
- if ((flags & STM32_DMA_ISR_TCIF) != 0) {
- /* Transfer complete processing.*/
- _adc_isr_full_code(adcp);
- }
- else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
- /* Half transfer processing.*/
- _adc_isr_half_code(adcp);
- }
- }
- }
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
-/**
- * @brief ADC interrupt handler.
- *
- * @isr
- */
-OSAL_IRQ_HANDLER(Vector88) {
- uint32_t sr;
-
- OSAL_IRQ_PROLOGUE();
-
- sr = ADC1->SR;
- ADC1->SR = 0;
- /* Note, an overflow may occur after the conversion ended before the driver
- is able to stop the ADC, this is why the DMA channel is checked too.*/
- if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
- /* ADC overflow condition, this could happen only if the DMA is unable
- to read data fast enough.*/
- if (ADCD1.grpp != NULL)
- _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
- }
- /* CHTODO: Add here analog watchdog handling.*/
-
- OSAL_IRQ_EPILOGUE();
-}
-#endif
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level ADC driver initialization.
- *
- * @notapi
- */
-void adc_lld_init(void) {
-
-#if STM32_ADC_USE_ADC1
- /* Driver initialization.*/
- adcObjectInit(&ADCD1);
- ADCD1.adc = ADC1;
- ADCD1.dmastp = NULL;
- ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
- STM32_DMA_CR_DIR_P2M |
- STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
- STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
- STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
-#endif
-
- /* The shared vector is initialized on driver initialization and never
- disabled.*/
- nvicEnableVector(ADC1_IRQn, STM32_ADC_IRQ_PRIORITY);
-}
-
-/**
- * @brief Configures and activates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start(ADCDriver *adcp) {
-
- /* If in stopped state then enables the ADC and DMA clocks.*/
- if (adcp->state == ADC_STOP) {
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp) {
- adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1),
- STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
- (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
- (void *)adcp);
- osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
-
- dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
- rccEnableADC1(true);
- }
-#endif /* STM32_ADC_USE_ADC1 */
-
- ADC->CCR = (ADC->CCR & ADC_CCR_TSVREFE) | (STM32_ADC_ADCPRE << 16);
-
- /* ADC initial setup, starting the analog part here in order to reduce
- the latency when starting a conversion.*/
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
- adcp->adc->CR2 = ADC_CR2_ADON;
- }
-}
-
-/**
- * @brief Deactivates the ADC peripheral.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop(ADCDriver *adcp) {
-
- /* If in ready state then disables the ADC clock and analog part.*/
- if (adcp->state == ADC_READY) {
- dmaStreamFreeI(adcp->dmastp);
- adcp->dmastp = NULL;
-
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
-
-#if STM32_ADC_USE_ADC1
- if (&ADCD1 == adcp)
- rccDisableADC1();
-#endif
- }
-}
-
-/**
- * @brief Starts an ADC conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_start_conversion(ADCDriver *adcp) {
- uint32_t mode;
- uint32_t cr2;
- const ADCConversionGroup *grpp = adcp->grpp;
-
- /* DMA setup.*/
- mode = adcp->dmamode;
- if (grpp->circular) {
- mode |= STM32_DMA_CR_CIRC;
- if (adcp->depth > 1) {
- /* If circular buffer depth > 1, then the half transfer interrupt
- is enabled in order to allow streaming processing.*/
- mode |= STM32_DMA_CR_HTIE;
- }
- }
- dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
- dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
- (uint32_t)adcp->depth);
- dmaStreamSetMode(adcp->dmastp, mode);
- dmaStreamEnable(adcp->dmastp);
-
- /* ADC setup.*/
- adcp->adc->SR = 0;
- adcp->adc->SMPR1 = grpp->smpr1;
- adcp->adc->SMPR2 = grpp->smpr2;
- adcp->adc->SMPR3 = grpp->smpr3;
- adcp->adc->SQR1 = grpp->sqr1;
- adcp->adc->SQR2 = grpp->sqr2;
- adcp->adc->SQR3 = grpp->sqr3;
- adcp->adc->SQR4 = grpp->sqr4;
- adcp->adc->SQR5 = grpp->sqr5;
-
- /* ADC configuration and start.*/
- adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;
-
- /* Enforcing the mandatory bits in CR2.*/
- cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON;
-
- /* The start method is different dependign if HW or SW triggered, the
- start is performed using the method specified in the CR2 configuration.*/
- if ((cr2 & ADC_CR2_SWSTART) != 0) {
- /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/
- adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART;
-
- /* Finally enabling ADC_CR2_SWSTART.*/
- adcp->adc->CR2 = (cr2 | ADC_CR2_CONT);
- }
- else
- adcp->adc->CR2 = cr2;
-}
-
-/**
- * @brief Stops an ongoing conversion.
- *
- * @param[in] adcp pointer to the @p ADCDriver object
- *
- * @notapi
- */
-void adc_lld_stop_conversion(ADCDriver *adcp) {
-
- dmaStreamDisable(adcp->dmastp);
- adcp->adc->CR1 = 0;
- adcp->adc->CR2 = 0;
- adcp->adc->CR2 = ADC_CR2_ADON;
-}
-
-/**
- * @brief Enables the TSVREFE bit.
- * @details The TSVREFE bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- */
-void adcSTM32EnableTSVREFE(void) {
-
- ADC->CCR |= ADC_CCR_TSVREFE;
-}
-
-/**
- * @brief Disables the TSVREFE bit.
- * @details The TSVREFE bit is required in order to sample the internal
- * temperature sensor and internal reference voltage.
- * @note This is an STM32-only functionality.
- */
-void adcSTM32DisableTSVREFE(void) {
-
- ADC->CCR &= ~ADC_CCR_TSVREFE;
-}
-
-#endif /* HAL_USE_ADC */
-
-/** @} */
+/*
+ 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_adc_lld.c
+ * @brief STM32L1xx ADC subsystem low level driver source.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/** @brief ADC1 driver identifier.*/
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+ADCDriver ADCD1;
+#endif
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC DMA ISR service routine.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ * @param[in] flags pre-shifted content of the ISR register
+ */
+static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) {
+
+ /* DMA errors handling.*/
+ if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
+ /* DMA, this could help only if the DMA tries to access an unmapped
+ address space or violates alignment rules.*/
+ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
+ }
+ else {
+ /* It is possible that the conversion group has already be reset by the
+ ADC error handler, in this case this interrupt is spurious.*/
+ if (adcp->grpp != NULL) {
+ if ((flags & STM32_DMA_ISR_TCIF) != 0) {
+ /* Transfer complete processing.*/
+ _adc_isr_full_code(adcp);
+ }
+ else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
+ /* Half transfer processing.*/
+ _adc_isr_half_code(adcp);
+ }
+ }
+ }
+}
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 || defined(__DOXYGEN__)
+/**
+ * @brief ADC interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(Vector88) {
+ uint32_t sr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ sr = ADC1->SR;
+ ADC1->SR = 0;
+ /* Note, an overflow may occur after the conversion ended before the driver
+ is able to stop the ADC, this is why the DMA channel is checked too.*/
+ if ((sr & ADC_SR_OVR) && (dmaStreamGetTransactionSize(ADCD1.dmastp) > 0)) {
+ /* ADC overflow condition, this could happen only if the DMA is unable
+ to read data fast enough.*/
+ if (ADCD1.grpp != NULL)
+ _adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
+ }
+ /* CHTODO: Add here analog watchdog handling.*/
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level ADC driver initialization.
+ *
+ * @notapi
+ */
+void adc_lld_init(void) {
+
+#if STM32_ADC_USE_ADC1
+ /* Driver initialization.*/
+ adcObjectInit(&ADCD1);
+ ADCD1.adc = ADC1;
+ ADCD1.dmastp = NULL;
+ ADCD1.dmamode = STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) |
+ STM32_DMA_CR_DIR_P2M |
+ STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD |
+ STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE |
+ STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE;
+#endif
+
+ /* The shared vector is initialized on driver initialization and never
+ disabled.*/
+ nvicEnableVector(ADC1_IRQn, STM32_ADC_IRQ_PRIORITY);
+}
+
+/**
+ * @brief Configures and activates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start(ADCDriver *adcp) {
+
+ /* If in stopped state then enables the ADC and DMA clocks.*/
+ if (adcp->state == ADC_STOP) {
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp) {
+ adcp->dmastp = dmaStreamAllocI(STM32_DMA_STREAM_ID(1, 1),
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(adcp->dmastp != NULL, "unable to allocate stream");
+
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+ rccEnableADC1(true);
+ }
+#endif /* STM32_ADC_USE_ADC1 */
+
+ ADC->CCR = (ADC->CCR & ADC_CCR_TSVREFE) | (STM32_ADC_ADCPRE << 16);
+
+ /* ADC initial setup, starting the analog part here in order to reduce
+ the latency when starting a conversion.*/
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+ adcp->adc->CR2 = ADC_CR2_ADON;
+ }
+}
+
+/**
+ * @brief Deactivates the ADC peripheral.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop(ADCDriver *adcp) {
+
+ /* If in ready state then disables the ADC clock and analog part.*/
+ if (adcp->state == ADC_READY) {
+ dmaStreamFreeI(adcp->dmastp);
+ adcp->dmastp = NULL;
+
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp)
+ rccDisableADC1();
+#endif
+ }
+}
+
+/**
+ * @brief Starts an ADC conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_start_conversion(ADCDriver *adcp) {
+ uint32_t mode;
+ uint32_t cr2;
+ const ADCConversionGroup *grpp = adcp->grpp;
+
+ /* DMA setup.*/
+ mode = adcp->dmamode;
+ if (grpp->circular) {
+ mode |= STM32_DMA_CR_CIRC;
+ if (adcp->depth > 1) {
+ /* If circular buffer depth > 1, then the half transfer interrupt
+ is enabled in order to allow streaming processing.*/
+ mode |= STM32_DMA_CR_HTIE;
+ }
+ }
+ dmaStreamSetMemory0(adcp->dmastp, adcp->samples);
+ dmaStreamSetTransactionSize(adcp->dmastp, (uint32_t)grpp->num_channels *
+ (uint32_t)adcp->depth);
+ dmaStreamSetMode(adcp->dmastp, mode);
+ dmaStreamEnable(adcp->dmastp);
+
+ /* ADC setup.*/
+ adcp->adc->SR = 0;
+ adcp->adc->SMPR1 = grpp->smpr1;
+ adcp->adc->SMPR2 = grpp->smpr2;
+ adcp->adc->SMPR3 = grpp->smpr3;
+ adcp->adc->SQR1 = grpp->sqr1;
+ adcp->adc->SQR2 = grpp->sqr2;
+ adcp->adc->SQR3 = grpp->sqr3;
+ adcp->adc->SQR4 = grpp->sqr4;
+ adcp->adc->SQR5 = grpp->sqr5;
+
+ /* ADC configuration and start.*/
+ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN;
+
+ /* Enforcing the mandatory bits in CR2.*/
+ cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON;
+
+ /* The start method is different dependign if HW or SW triggered, the
+ start is performed using the method specified in the CR2 configuration.*/
+ if ((cr2 & ADC_CR2_SWSTART) != 0) {
+ /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/
+ adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART;
+
+ /* Finally enabling ADC_CR2_SWSTART.*/
+ adcp->adc->CR2 = (cr2 | ADC_CR2_CONT);
+ }
+ else
+ adcp->adc->CR2 = cr2;
+}
+
+/**
+ * @brief Stops an ongoing conversion.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object
+ *
+ * @notapi
+ */
+void adc_lld_stop_conversion(ADCDriver *adcp) {
+
+ dmaStreamDisable(adcp->dmastp);
+ adcp->adc->CR1 = 0;
+ adcp->adc->CR2 = 0;
+ adcp->adc->CR2 = ADC_CR2_ADON;
+}
+
+/**
+ * @brief Enables the TSVREFE bit.
+ * @details The TSVREFE bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ */
+void adcSTM32EnableTSVREFE(void) {
+
+ ADC->CCR |= ADC_CCR_TSVREFE;
+}
+
+/**
+ * @brief Disables the TSVREFE bit.
+ * @details The TSVREFE bit is required in order to sample the internal
+ * temperature sensor and internal reference voltage.
+ * @note This is an STM32-only functionality.
+ */
+void adcSTM32DisableTSVREFE(void) {
+
+ ADC->CCR &= ~ADC_CCR_TSVREFE;
+}
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.h b/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.h
index 31f8679bac..091e06f968 100644
--- a/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.h
+++ b/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.h
@@ -1,383 +1,383 @@
-/*
- 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_adc_lld.h
- * @brief STM32L1xx ADC subsystem low level driver header.
- *
- * @addtogroup ADC
- * @{
- */
-
-#ifndef HAL_ADC_LLD_H
-#define HAL_ADC_LLD_H
-
-#if HAL_USE_ADC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name Triggers selection
- * @{
- */
-#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */
-/** @} */
-
-/**
- * @name ADC clock divider settings
- * @{
- */
-#define ADC_CCR_ADCPRE_DIV1 0
-#define ADC_CCR_ADCPRE_DIV2 1
-#define ADC_CCR_ADCPRE_DIV4 2
-/** @} */
-
-/**
- * @name Available analog channels
- * @{
- */
-#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
-#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
-#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
-#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
-#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
-#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
-#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
-#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
-#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
-#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
-#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
-#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
-#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
-#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
-#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
-#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
-#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
-#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
-#define ADC_CHANNEL_IN18 18 /**< @brief External analog input 18. */
-#define ADC_CHANNEL_IN19 19 /**< @brief External analog input 19. */
-#define ADC_CHANNEL_IN20 20 /**< @brief External analog input 20. */
-#define ADC_CHANNEL_IN21 21 /**< @brief External analog input 21. */
-#define ADC_CHANNEL_IN22 22 /**< @brief External analog input 22. */
-#define ADC_CHANNEL_IN23 23 /**< @brief External analog input 23. */
-#define ADC_CHANNEL_IN24 24 /**< @brief External analog input 24. */
-#define ADC_CHANNEL_IN25 25 /**< @brief External analog input 25. */
-/** @} */
-
-/**
- * @name Sampling rates
- * @{
- */
-#define ADC_SAMPLE_4 0 /**< @brief 4 cycles sampling time. */
-#define ADC_SAMPLE_9 1 /**< @brief 9 cycles sampling time. */
-#define ADC_SAMPLE_16 2 /**< @brief 16 cycles sampling time. */
-#define ADC_SAMPLE_24 3 /**< @brief 24 cycles sampling time. */
-#define ADC_SAMPLE_48 4 /**< @brief 48 cycles sampling time. */
-#define ADC_SAMPLE_96 5 /**< @brief 96 cycles sampling time. */
-#define ADC_SAMPLE_192 6 /**< @brief 192 cycles sampling time. */
-#define ADC_SAMPLE_384 7 /**< @brief 384 cycles sampling time. */
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief ADC1 driver enable switch.
- * @details If set to @p TRUE the support for ADC1 is included.
- * @note The default is @p TRUE.
- */
-#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
-#define STM32_ADC_USE_ADC1 FALSE
-#endif
-
-/**
- * @brief ADC common clock divider.
- * @note This setting is influenced by the VDDA voltage and other
- * external conditions, please refer to the STM32L15x datasheet
- * for more info.
- * See section 6.3.15 "12-bit ADC characteristics".
- */
-#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__)
-#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV1
-#endif
-
-/**
- * @brief ADC1 DMA priority (0..3|lowest..highest).
- */
-#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_PRIORITY 2
-#endif
-
-/**
- * @brief ADC interrupt priority level setting.
- */
-#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_IRQ_PRIORITY 5
-#endif
-
-/**
- * @brief ADC1 DMA interrupt priority level setting.
- */
-#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
-#endif
-
-/** @} */
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
-#error "ADC1 not present in the selected device"
-#endif
-
-#if !STM32_ADC_USE_ADC1
-#error "ADC driver activated but no ADC peripheral assigned"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
-#error "Invalid IRQ priority assigned to ADC1 DMA"
-#endif
-
-#if STM32_ADC_USE_ADC1 && \
- !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
-#error "Invalid DMA priority assigned to ADC1"
-#endif
-
-#if !defined(STM32_DMA_REQUIRED)
-#define STM32_DMA_REQUIRED
-#endif
-
-/**
- * * @brief ADC frequency.
- * */
-/* ADC clock related settings and checks.*/
-#if STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV1
-#define STM32_ADCCLK STM32_HSICLK
-#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV2
-#define STM32_ADCCLK (STM32_HSICLK / 2)
-#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV4
-#define STM32_ADCCLK (STM32_HSICLK / 4)
-#else
-#error "invalid STM32_ADC_ADCPRE value specified"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/**
- * @brief ADC sample data type.
- */
-typedef uint16_t adcsample_t;
-
-/**
- * @brief Channels number in a conversion group.
- */
-typedef uint16_t adc_channels_num_t;
-
-/**
- * @brief Possible ADC failure causes.
- * @note Error codes are architecture dependent and should not relied
- * upon.
- */
-typedef enum {
- ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
- ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */
-} adcerror_t;
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the ADC driver structure.
- */
-#define adc_lld_driver_fields \
- /* Pointer to the ADCx registers block.*/ \
- ADC_TypeDef *adc; \
- /* Pointer to associated DMA channel.*/ \
- const stm32_dma_stream_t *dmastp; \
- /* DMA mode bit mask.*/ \
- uint32_t dmamode
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_config_fields \
- /* Dummy configuration, it is not needed.*/ \
- uint32_t dummy
-
-/**
- * @brief Low level fields of the ADC configuration structure.
- */
-#define adc_lld_configuration_group_fields \
- /* ADC CR1 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
- uint32_t cr1; \
- /* ADC CR2 register initialization data. \
- NOTE: All the required bits must be defined into this field except \
- @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
- enforced inside the driver.*/ \
- uint32_t cr2; \
- /* ADC SMPR1 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 20...25.*/ \
- uint32_t smpr1; \
- /* ADC SMPR2 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 10...19.*/ \
- uint32_t smpr2; \
- /* ADC SMPR3 register initialization data. \
- NOTE: In this field must be specified the sample times for channels \
- 0...9.*/ \
- uint32_t smpr3; \
- /* ADC SQR1 register initialization data. \
- NOTE: Conversion group sequence 25...27 + sequence length.*/ \
- uint32_t sqr1; \
- /* ADC SQR2 register initialization data. \
- NOTE: Conversion group sequence 19...24.*/ \
- uint32_t sqr2; \
- /* ADC SQR3 register initialization data. \
- NOTE: Conversion group sequence 13...18.*/ \
- uint32_t sqr3; \
- /* ADC SQR3 register initialization data. \
- NOTE: Conversion group sequence 7...12.*/ \
- uint32_t sqr4; \
- /* ADC SQR3 register initialization data. \
- NOTE: Conversion group sequence 1...6.*/ \
- uint32_t sqr5
-
-/**
- * @name Sequences building helper macros
- * @{
- */
-/**
- * @brief Number of channels in a conversion sequence.
- */
-#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
-
-#define ADC_SQR5_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
-#define ADC_SQR5_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
-#define ADC_SQR5_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
-#define ADC_SQR5_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
-#define ADC_SQR5_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
-#define ADC_SQR5_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
-
-#define ADC_SQR4_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
-#define ADC_SQR4_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
-#define ADC_SQR4_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
-#define ADC_SQR4_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
-#define ADC_SQR4_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
-#define ADC_SQR4_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
-
-#define ADC_SQR3_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
-#define ADC_SQR3_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
-#define ADC_SQR3_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
-#define ADC_SQR3_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
-#define ADC_SQR3_SQ17_N(n) ((n) << 20) /**< @brief 17th channel in seq.*/
-#define ADC_SQR3_SQ18_N(n) ((n) << 25) /**< @brief 18th channel in seq.*/
-
-#define ADC_SQR2_SQ19_N(n) ((n) << 0) /**< @brief 19th channel in seq.*/
-#define ADC_SQR2_SQ20_N(n) ((n) << 5) /**< @brief 20th channel in seq.*/
-#define ADC_SQR2_SQ21_N(n) ((n) << 10) /**< @brief 21th channel in seq.*/
-#define ADC_SQR2_SQ22_N(n) ((n) << 15) /**< @brief 22th channel in seq.*/
-#define ADC_SQR2_SQ23_N(n) ((n) << 20) /**< @brief 23th channel in seq.*/
-#define ADC_SQR2_SQ24_N(n) ((n) << 25) /**< @brief 24th channel in seq.*/
-
-#define ADC_SQR1_SQ25_N(n) ((n) << 0) /**< @brief 25th channel in seq.*/
-#define ADC_SQR1_SQ26_N(n) ((n) << 5) /**< @brief 26th channel in seq.*/
-#define ADC_SQR1_SQ27_N(n) ((n) << 10) /**< @brief 27th channel in seq.*/
-/** @} */
-
-/**
- * @name Sampling rate settings helper macros
- * @{
- */
-#define ADC_SMPR3_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
-#define ADC_SMPR3_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
-#define ADC_SMPR3_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
-#define ADC_SMPR3_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
-#define ADC_SMPR3_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
-#define ADC_SMPR3_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
-#define ADC_SMPR3_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
-#define ADC_SMPR3_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
-#define ADC_SMPR3_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
-#define ADC_SMPR3_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
-
-#define ADC_SMPR2_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
-#define ADC_SMPR2_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
-#define ADC_SMPR2_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
-#define ADC_SMPR2_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
-#define ADC_SMPR2_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
-#define ADC_SMPR2_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
-#define ADC_SMPR2_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
- sampling time. */
-#define ADC_SMPR2_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
- sampling time. */
-#define ADC_SMPR2_SMP_AN18(n) ((n) << 24) /**< @brief AN18 sampling time. */
-#define ADC_SMPR2_SMP_AN19(n) ((n) << 27) /**< @brief AN19 sampling time. */
-
-#define ADC_SMPR1_SMP_AN20(n) ((n) << 0) /**< @brief AN20 sampling time. */
-#define ADC_SMPR1_SMP_AN21(n) ((n) << 3) /**< @brief AN21 sampling time. */
-#define ADC_SMPR1_SMP_AN22(n) ((n) << 6) /**< @brief AN22 sampling time. */
-#define ADC_SMPR1_SMP_AN23(n) ((n) << 9) /**< @brief AN23 sampling time. */
-#define ADC_SMPR1_SMP_AN24(n) ((n) << 12) /**< @brief AN24 sampling time. */
-#define ADC_SMPR1_SMP_AN25(n) ((n) << 15) /**< @brief AN25 sampling time. */
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
-extern ADCDriver ADCD1;
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- void adc_lld_init(void);
- void adc_lld_start(ADCDriver *adcp);
- void adc_lld_stop(ADCDriver *adcp);
- void adc_lld_start_conversion(ADCDriver *adcp);
- void adc_lld_stop_conversion(ADCDriver *adcp);
- void adcSTM32EnableTSVREFE(void);
- void adcSTM32DisableTSVREFE(void);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HAL_USE_ADC */
-
-#endif /* HAL_ADC_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_adc_lld.h
+ * @brief STM32L1xx ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef HAL_ADC_LLD_H
+#define HAL_ADC_LLD_H
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Triggers selection
+ * @{
+ */
+#define ADC_CR2_EXTSEL_SRC(n) ((n) << 24) /**< @brief Trigger source. */
+/** @} */
+
+/**
+ * @name ADC clock divider settings
+ * @{
+ */
+#define ADC_CCR_ADCPRE_DIV1 0
+#define ADC_CCR_ADCPRE_DIV2 1
+#define ADC_CCR_ADCPRE_DIV4 2
+/** @} */
+
+/**
+ * @name Available analog channels
+ * @{
+ */
+#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
+#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
+#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
+#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
+#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
+#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
+#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
+#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
+#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
+#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
+#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
+#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
+#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
+#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
+#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
+#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
+#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
+#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
+#define ADC_CHANNEL_IN18 18 /**< @brief External analog input 18. */
+#define ADC_CHANNEL_IN19 19 /**< @brief External analog input 19. */
+#define ADC_CHANNEL_IN20 20 /**< @brief External analog input 20. */
+#define ADC_CHANNEL_IN21 21 /**< @brief External analog input 21. */
+#define ADC_CHANNEL_IN22 22 /**< @brief External analog input 22. */
+#define ADC_CHANNEL_IN23 23 /**< @brief External analog input 23. */
+#define ADC_CHANNEL_IN24 24 /**< @brief External analog input 24. */
+#define ADC_CHANNEL_IN25 25 /**< @brief External analog input 25. */
+/** @} */
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#define ADC_SAMPLE_4 0 /**< @brief 4 cycles sampling time. */
+#define ADC_SAMPLE_9 1 /**< @brief 9 cycles sampling time. */
+#define ADC_SAMPLE_16 2 /**< @brief 16 cycles sampling time. */
+#define ADC_SAMPLE_24 3 /**< @brief 24 cycles sampling time. */
+#define ADC_SAMPLE_48 4 /**< @brief 48 cycles sampling time. */
+#define ADC_SAMPLE_96 5 /**< @brief 96 cycles sampling time. */
+#define ADC_SAMPLE_192 6 /**< @brief 192 cycles sampling time. */
+#define ADC_SAMPLE_384 7 /**< @brief 384 cycles sampling time. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief ADC1 driver enable switch.
+ * @details If set to @p TRUE the support for ADC1 is included.
+ * @note The default is @p TRUE.
+ */
+#if !defined(STM32_ADC_USE_ADC1) || defined(__DOXYGEN__)
+#define STM32_ADC_USE_ADC1 FALSE
+#endif
+
+/**
+ * @brief ADC common clock divider.
+ * @note This setting is influenced by the VDDA voltage and other
+ * external conditions, please refer to the STM32L15x datasheet
+ * for more info.
+ * See section 6.3.15 "12-bit ADC characteristics".
+ */
+#if !defined(STM32_ADC_ADCPRE) || defined(__DOXYGEN__)
+#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV1
+#endif
+
+/**
+ * @brief ADC1 DMA priority (0..3|lowest..highest).
+ */
+#if !defined(STM32_ADC_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#endif
+
+/**
+ * @brief ADC interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_IRQ_PRIORITY 5
+#endif
+
+/**
+ * @brief ADC1 DMA interrupt priority level setting.
+ */
+#if !defined(STM32_ADC_ADC1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !STM32_HAS_ADC1
+#error "ADC1 not present in the selected device"
+#endif
+
+#if !STM32_ADC_USE_ADC1
+#error "ADC driver activated but no ADC peripheral assigned"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !OSAL_IRQ_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_IRQ_PRIORITY)
+#error "Invalid IRQ priority assigned to ADC1 DMA"
+#endif
+
+#if STM32_ADC_USE_ADC1 && \
+ !STM32_DMA_IS_VALID_PRIORITY(STM32_ADC_ADC1_DMA_PRIORITY)
+#error "Invalid DMA priority assigned to ADC1"
+#endif
+
+#if !defined(STM32_DMA_REQUIRED)
+#define STM32_DMA_REQUIRED
+#endif
+
+/**
+ * * @brief ADC frequency.
+ * */
+/* ADC clock related settings and checks.*/
+#if STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV1
+#define STM32_ADCCLK STM32_HSICLK
+#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV2
+#define STM32_ADCCLK (STM32_HSICLK / 2)
+#elif STM32_ADC_ADCPRE == ADC_CCR_ADCPRE_DIV4
+#define STM32_ADCCLK (STM32_HSICLK / 4)
+#else
+#error "invalid STM32_ADC_ADCPRE value specified"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief ADC sample data type.
+ */
+typedef uint16_t adcsample_t;
+
+/**
+ * @brief Channels number in a conversion group.
+ */
+typedef uint16_t adc_channels_num_t;
+
+/**
+ * @brief Possible ADC failure causes.
+ * @note Error codes are architecture dependent and should not relied
+ * upon.
+ */
+typedef enum {
+ ADC_ERR_DMAFAILURE = 0, /**< DMA operations failure. */
+ ADC_ERR_OVERFLOW = 1 /**< ADC overflow condition. */
+} adcerror_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the ADC driver structure.
+ */
+#define adc_lld_driver_fields \
+ /* Pointer to the ADCx registers block.*/ \
+ ADC_TypeDef *adc; \
+ /* Pointer to associated DMA channel.*/ \
+ const stm32_dma_stream_t *dmastp; \
+ /* DMA mode bit mask.*/ \
+ uint32_t dmamode
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_config_fields \
+ /* Dummy configuration, it is not needed.*/ \
+ uint32_t dummy
+
+/**
+ * @brief Low level fields of the ADC configuration structure.
+ */
+#define adc_lld_configuration_group_fields \
+ /* ADC CR1 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR1_SCAN that is enforced inside the driver.*/ \
+ uint32_t cr1; \
+ /* ADC CR2 register initialization data. \
+ NOTE: All the required bits must be defined into this field except \
+ @p ADC_CR2_DMA, @p ADC_CR2_CONT and @p ADC_CR2_ADON that are \
+ enforced inside the driver.*/ \
+ uint32_t cr2; \
+ /* ADC SMPR1 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 20...25.*/ \
+ uint32_t smpr1; \
+ /* ADC SMPR2 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 10...19.*/ \
+ uint32_t smpr2; \
+ /* ADC SMPR3 register initialization data. \
+ NOTE: In this field must be specified the sample times for channels \
+ 0...9.*/ \
+ uint32_t smpr3; \
+ /* ADC SQR1 register initialization data. \
+ NOTE: Conversion group sequence 25...27 + sequence length.*/ \
+ uint32_t sqr1; \
+ /* ADC SQR2 register initialization data. \
+ NOTE: Conversion group sequence 19...24.*/ \
+ uint32_t sqr2; \
+ /* ADC SQR3 register initialization data. \
+ NOTE: Conversion group sequence 13...18.*/ \
+ uint32_t sqr3; \
+ /* ADC SQR3 register initialization data. \
+ NOTE: Conversion group sequence 7...12.*/ \
+ uint32_t sqr4; \
+ /* ADC SQR3 register initialization data. \
+ NOTE: Conversion group sequence 1...6.*/ \
+ uint32_t sqr5
+
+/**
+ * @name Sequences building helper macros
+ * @{
+ */
+/**
+ * @brief Number of channels in a conversion sequence.
+ */
+#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
+
+#define ADC_SQR5_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
+#define ADC_SQR5_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
+#define ADC_SQR5_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
+#define ADC_SQR5_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
+#define ADC_SQR5_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
+#define ADC_SQR5_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
+
+#define ADC_SQR4_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
+#define ADC_SQR4_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
+#define ADC_SQR4_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
+#define ADC_SQR4_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
+#define ADC_SQR4_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
+#define ADC_SQR4_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
+
+#define ADC_SQR3_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
+#define ADC_SQR3_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
+#define ADC_SQR3_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
+#define ADC_SQR3_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
+#define ADC_SQR3_SQ17_N(n) ((n) << 20) /**< @brief 17th channel in seq.*/
+#define ADC_SQR3_SQ18_N(n) ((n) << 25) /**< @brief 18th channel in seq.*/
+
+#define ADC_SQR2_SQ19_N(n) ((n) << 0) /**< @brief 19th channel in seq.*/
+#define ADC_SQR2_SQ20_N(n) ((n) << 5) /**< @brief 20th channel in seq.*/
+#define ADC_SQR2_SQ21_N(n) ((n) << 10) /**< @brief 21th channel in seq.*/
+#define ADC_SQR2_SQ22_N(n) ((n) << 15) /**< @brief 22th channel in seq.*/
+#define ADC_SQR2_SQ23_N(n) ((n) << 20) /**< @brief 23th channel in seq.*/
+#define ADC_SQR2_SQ24_N(n) ((n) << 25) /**< @brief 24th channel in seq.*/
+
+#define ADC_SQR1_SQ25_N(n) ((n) << 0) /**< @brief 25th channel in seq.*/
+#define ADC_SQR1_SQ26_N(n) ((n) << 5) /**< @brief 26th channel in seq.*/
+#define ADC_SQR1_SQ27_N(n) ((n) << 10) /**< @brief 27th channel in seq.*/
+/** @} */
+
+/**
+ * @name Sampling rate settings helper macros
+ * @{
+ */
+#define ADC_SMPR3_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
+#define ADC_SMPR3_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
+#define ADC_SMPR3_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
+#define ADC_SMPR3_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
+#define ADC_SMPR3_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
+#define ADC_SMPR3_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
+#define ADC_SMPR3_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
+#define ADC_SMPR3_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
+#define ADC_SMPR3_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
+#define ADC_SMPR3_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
+
+#define ADC_SMPR2_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
+#define ADC_SMPR2_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
+#define ADC_SMPR2_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
+#define ADC_SMPR2_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
+#define ADC_SMPR2_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
+#define ADC_SMPR2_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
+#define ADC_SMPR2_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
+ sampling time. */
+#define ADC_SMPR2_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
+ sampling time. */
+#define ADC_SMPR2_SMP_AN18(n) ((n) << 24) /**< @brief AN18 sampling time. */
+#define ADC_SMPR2_SMP_AN19(n) ((n) << 27) /**< @brief AN19 sampling time. */
+
+#define ADC_SMPR1_SMP_AN20(n) ((n) << 0) /**< @brief AN20 sampling time. */
+#define ADC_SMPR1_SMP_AN21(n) ((n) << 3) /**< @brief AN21 sampling time. */
+#define ADC_SMPR1_SMP_AN22(n) ((n) << 6) /**< @brief AN22 sampling time. */
+#define ADC_SMPR1_SMP_AN23(n) ((n) << 9) /**< @brief AN23 sampling time. */
+#define ADC_SMPR1_SMP_AN24(n) ((n) << 12) /**< @brief AN24 sampling time. */
+#define ADC_SMPR1_SMP_AN25(n) ((n) << 15) /**< @brief AN25 sampling time. */
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if STM32_ADC_USE_ADC1 && !defined(__DOXYGEN__)
+extern ADCDriver ADCD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void adc_lld_init(void);
+ void adc_lld_start(ADCDriver *adcp);
+ void adc_lld_stop(ADCDriver *adcp);
+ void adc_lld_start_conversion(ADCDriver *adcp);
+ void adc_lld_stop_conversion(ADCDriver *adcp);
+ void adcSTM32EnableTSVREFE(void);
+ void adcSTM32DisableTSVREFE(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* HAL_ADC_LLD_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L1xx/hal_lld.c b/os/hal/ports/STM32/STM32L1xx/hal_lld.c
index 9731411837..10e34bc295 100644
--- a/os/hal/ports/STM32/STM32L1xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32L1xx/hal_lld.c
@@ -1,244 +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 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)
+ && ((RCC->CSR & STM32_RTCSEL_MASK) != FOME_STM32_LSE_WAIT_MAX_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..20ca952f99 100644
--- a/os/hal/ports/STM32/STM32L1xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L1xx/hal_lld.h
@@ -1,882 +1,891 @@
-/*
- 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
+
+#if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+#error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+#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/STM32L1xx/platform.dox b/os/hal/ports/STM32/STM32L1xx/platform.dox
index 801ed83a36..09dc6742e5 100644
--- a/os/hal/ports/STM32/STM32L1xx/platform.dox
+++ b/os/hal/ports/STM32/STM32L1xx/platform.dox
@@ -1,315 +1,315 @@
-/*
- 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 STM32L1xx_DRIVERS STM32L1xx Drivers
- * @details This section describes all the supported drivers on the STM32L1xx
- * platform and the implementation details of the single drivers.
- *
- * @ingroup platforms
- */
-
-/**
- * @defgroup STM32L1xx_HAL STM32L1xx Initialization Support
- * @details The STM32L1xx HAL support is responsible for system initialization.
- *
- * @section stm32l1xx_hal_1 Supported HW resources
- * - PLL1.
- * - RCC.
- * - Flash.
- * .
- * @section stm32l1xx_hal_2 STM32L1xx HAL driver implementation features
- * - PLL startup and stabilization.
- * - Clock tree initialization.
- * - Clock source selection.
- * - Flash wait states initialization based on the selected clock options.
- * - SYSTICK initialization based on current clock and kernel required rate.
- * - DMA support initialization.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_ADC STM32L1xx ADC Support
- * @details The STM32L1xx ADC driver supports the ADC peripherals using DMA
- * channels for maximum performance.
- *
- * @section stm32l1xx_adc_1 Supported HW resources
- * - ADC1.
- * - DMA1.
- * .
- * @section stm32l1xx_adc_2 STM32L1xx ADC driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Streaming conversion using DMA for maximum performance.
- * - Programmable ADC interrupt priority level.
- * - Programmable DMA bus priority for each DMA channel.
- * - Programmable DMA interrupt priority for each DMA channel.
- * - DMA and ADC errors detection.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_EXT STM32L1xx EXT Support
- * @details The STM32L1xx EXT driver uses the EXTI peripheral.
- *
- * @section stm32l1xx_ext_1 Supported HW resources
- * - EXTI.
- * .
- * @section stm32l1xx_ext_2 STM32L1xx EXT driver implementation features
- * - Each EXTI channel can be independently enabled and programmed.
- * - Programmable EXTI interrupts priority level.
- * - Capability to work as event sources (WFE) rather than interrupt sources.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_GPT STM32L1xx GPT Support
- * @details The STM32L1xx GPT driver uses the TIMx peripherals.
- *
- * @section stm32l1xx_gpt_1 Supported HW resources
- * - TIM2.
- * - TIM3.
- * - TIM4.
- * .
- * @section stm32l1xx_gpt_2 STM32L1xx GPT driver implementation features
- * - Each timer can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable TIMx interrupts priority level.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_ICU STM32L1xx ICU Support
- * @details The STM32L1xx ICU driver uses the TIMx peripherals.
- *
- * @section stm32l1xx_icu_1 Supported HW resources
- * - TIM2.
- * - TIM3.
- * - TIM4.
- * .
- * @section stm32l1xx_icu_2 STM32L1xx ICU driver implementation features
- * - Each timer can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable TIMx interrupts priority level.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_PAL STM32L1xx PAL Support
- * @details The STM32L1xx PAL driver uses the GPIO peripherals.
- *
- * @section stm32l1xx_pal_1 Supported HW resources
- * - GPIOA.
- * - GPIOB.
- * - GPIOC.
- * - GPIOD.
- * - GPIOE.
- * - GPIOH.
- * .
- * @section stm32l1xx_pal_2 STM32L1xx PAL driver implementation features
- * The PAL driver implementation fully supports the following hardware
- * capabilities:
- * - 16 bits wide ports.
- * - Atomic set/reset functions.
- * - Atomic set+reset function (atomic bus operations).
- * - Output latched regardless of the pad setting.
- * - Direct read of input pads regardless of the pad setting.
- * .
- * @section stm32l1xx_pal_3 Supported PAL setup modes
- * The STM32L1xx PAL driver supports the following I/O modes:
- * - @p PAL_MODE_RESET.
- * - @p PAL_MODE_UNCONNECTED.
- * - @p PAL_MODE_INPUT.
- * - @p PAL_MODE_INPUT_PULLUP.
- * - @p PAL_MODE_INPUT_PULLDOWN.
- * - @p PAL_MODE_INPUT_ANALOG.
- * - @p PAL_MODE_OUTPUT_PUSHPULL.
- * - @p PAL_MODE_OUTPUT_OPENDRAIN.
- * - @p PAL_MODE_ALTERNATE (non standard).
- * .
- * Any attempt to setup an invalid mode is ignored.
- *
- * @section stm32l1xx_pal_4 Suboptimal behavior
- * The STM32L1xx GPIO is less than optimal in several areas, the limitations
- * should be taken in account while using the PAL driver:
- * - Pad/port toggling operations are not atomic.
- * - Pad/group mode setup is not atomic.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_PWM STM32L1xx PWM Support
- * @details The STM32L1xx PWM driver uses the TIMx peripherals.
- *
- * @section stm32l1xx_pwm_1 Supported HW resources
- * - TIM1.
- * - TIM2.
- * - TIM3.
- * - TIM4.
- * .
- * @section stm32l1xx_pwm_2 STM32L1xx PWM driver implementation features
- * - Each timer can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Four independent PWM channels per timer.
- * - Programmable TIMx interrupts priority level.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support
- * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a
- * buffered, interrupt driven, implementation.
- *
- * @section stm32l1xx_serial_1 Supported HW resources
- * The serial driver can support any of the following hardware resources:
- * - USART1.
- * - USART2.
- * - USART3 (where present).
- * - UART4 (where present).
- * - UART5 (where present).
- * .
- * @section stm32l1xx_serial_2 STM32L1xx Serial driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Each UART/USART can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Fully interrupt driven.
- * - Programmable priority levels for each UART/USART.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_SPI STM32L1xx SPI Support
- * @details The SPI driver supports the STM32L1xx SPI peripherals using DMA
- * channels for maximum performance.
- *
- * @section stm32l1xx_spi_1 Supported HW resources
- * - SPI1.
- * - SPI2.
- * - SPI3 (where present).
- * - DMA1.
- * - DMA2 (where present).
- * .
- * @section stm32l1xx_spi_2 STM32L1xx SPI driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Each SPI can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable interrupt priority levels for each SPI.
- * - DMA is used for receiving and transmitting.
- * - Programmable DMA bus priority for each DMA channel.
- * - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_UART STM32L1xx UART Support
- * @details The UART driver supports the STM32L1xx USART peripherals using DMA
- * channels for maximum performance.
- *
- * @section stm32l1xx_uart_1 Supported HW resources
- * The UART driver can support any of the following hardware resources:
- * - USART1.
- * - USART2.
- * - USART3 (where present).
- * - DMA1.
- * .
- * @section stm32l1xx_uart_2 STM32L1xx UART driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Each UART/USART can be independently enabled and programmed. Unused
- * peripherals are left in low power mode.
- * - Programmable interrupt priority levels for each UART/USART.
- * - DMA is used for receiving and transmitting.
- * - Programmable DMA bus priority for each DMA channel.
- * - Programmable DMA interrupt priority for each DMA channel.
- * - Programmable DMA error hook.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_USB STM32L1xx USB Support
- * @details The USB driver supports the STM32L1xx USB peripheral.
- *
- * @section stm32l1xx_usb_1 Supported HW resources
- * The USB driver can support any of the following hardware resources:
- * - USB.
- * .
- * @section stm32l1xx_usb_2 STM32L1xx USB driver implementation features
- * - Clock stop for reduced power usage when the driver is in stop state.
- * - Programmable interrupt priority levels.
- * - Each endpoint programmable in Control, Bulk and Interrupt modes.
- * .
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_PLATFORM_DRIVERS STM32L1xx Platform Drivers
- * @details Platform support drivers. Platform drivers do not implement HAL
- * standard driver templates, their role is to support platform
- * specific functionalities.
- *
- * @ingroup STM32L1xx_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_DMA STM32L1xx DMA Support
- * @details This DMA helper driver is used by the other drivers in order to
- * access the shared DMA resources in a consistent way.
- *
- * @section stm32l1xx_dma_1 Supported HW resources
- * The DMA driver can support any of the following hardware resources:
- * - DMA1.
- * .
- * @section stm32l1xx_dma_2 STM32L1xx DMA driver implementation features
- * - Exports helper functions/macros to the other drivers that share the
- * DMA resource.
- * - Automatic DMA clock stop when not in use by any driver.
- * - DMA streams and interrupt vectors sharing among multiple drivers.
- * .
- * @ingroup STM32L1xx_PLATFORM_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_ISR STM32L1xx ISR Support
- * @details This ISR helper driver is used by the other drivers in order to
- * map ISR names to physical vector names.
- *
- * @ingroup STM32L1xx_PLATFORM_DRIVERS
- */
-
-/**
- * @defgroup STM32L1xx_RCC STM32L1xx RCC Support
- * @details This RCC helper driver is used by the other drivers in order to
- * access the shared RCC resources in a consistent way.
- *
- * @section stm32f1xx_rcc_1 Supported HW resources
- * - RCC.
- * .
- * @section stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features
- * - Peripherals reset.
- * - Peripherals clock enable.
- * - Peripherals clock disable.
- * .
- * @ingroup STM32L1xx_PLATFORM_DRIVERS
- */
+/*
+ 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 STM32L1xx_DRIVERS STM32L1xx Drivers
+ * @details This section describes all the supported drivers on the STM32L1xx
+ * platform and the implementation details of the single drivers.
+ *
+ * @ingroup platforms
+ */
+
+/**
+ * @defgroup STM32L1xx_HAL STM32L1xx Initialization Support
+ * @details The STM32L1xx HAL support is responsible for system initialization.
+ *
+ * @section stm32l1xx_hal_1 Supported HW resources
+ * - PLL1.
+ * - RCC.
+ * - Flash.
+ * .
+ * @section stm32l1xx_hal_2 STM32L1xx HAL driver implementation features
+ * - PLL startup and stabilization.
+ * - Clock tree initialization.
+ * - Clock source selection.
+ * - Flash wait states initialization based on the selected clock options.
+ * - SYSTICK initialization based on current clock and kernel required rate.
+ * - DMA support initialization.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_ADC STM32L1xx ADC Support
+ * @details The STM32L1xx ADC driver supports the ADC peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32l1xx_adc_1 Supported HW resources
+ * - ADC1.
+ * - DMA1.
+ * .
+ * @section stm32l1xx_adc_2 STM32L1xx ADC driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Streaming conversion using DMA for maximum performance.
+ * - Programmable ADC interrupt priority level.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - DMA and ADC errors detection.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_EXT STM32L1xx EXT Support
+ * @details The STM32L1xx EXT driver uses the EXTI peripheral.
+ *
+ * @section stm32l1xx_ext_1 Supported HW resources
+ * - EXTI.
+ * .
+ * @section stm32l1xx_ext_2 STM32L1xx EXT driver implementation features
+ * - Each EXTI channel can be independently enabled and programmed.
+ * - Programmable EXTI interrupts priority level.
+ * - Capability to work as event sources (WFE) rather than interrupt sources.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_GPT STM32L1xx GPT Support
+ * @details The STM32L1xx GPT driver uses the TIMx peripherals.
+ *
+ * @section stm32l1xx_gpt_1 Supported HW resources
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * .
+ * @section stm32l1xx_gpt_2 STM32L1xx GPT driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_ICU STM32L1xx ICU Support
+ * @details The STM32L1xx ICU driver uses the TIMx peripherals.
+ *
+ * @section stm32l1xx_icu_1 Supported HW resources
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * .
+ * @section stm32l1xx_icu_2 STM32L1xx ICU driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_PAL STM32L1xx PAL Support
+ * @details The STM32L1xx PAL driver uses the GPIO peripherals.
+ *
+ * @section stm32l1xx_pal_1 Supported HW resources
+ * - GPIOA.
+ * - GPIOB.
+ * - GPIOC.
+ * - GPIOD.
+ * - GPIOE.
+ * - GPIOH.
+ * .
+ * @section stm32l1xx_pal_2 STM32L1xx PAL driver implementation features
+ * The PAL driver implementation fully supports the following hardware
+ * capabilities:
+ * - 16 bits wide ports.
+ * - Atomic set/reset functions.
+ * - Atomic set+reset function (atomic bus operations).
+ * - Output latched regardless of the pad setting.
+ * - Direct read of input pads regardless of the pad setting.
+ * .
+ * @section stm32l1xx_pal_3 Supported PAL setup modes
+ * The STM32L1xx PAL driver supports the following I/O modes:
+ * - @p PAL_MODE_RESET.
+ * - @p PAL_MODE_UNCONNECTED.
+ * - @p PAL_MODE_INPUT.
+ * - @p PAL_MODE_INPUT_PULLUP.
+ * - @p PAL_MODE_INPUT_PULLDOWN.
+ * - @p PAL_MODE_INPUT_ANALOG.
+ * - @p PAL_MODE_OUTPUT_PUSHPULL.
+ * - @p PAL_MODE_OUTPUT_OPENDRAIN.
+ * - @p PAL_MODE_ALTERNATE (non standard).
+ * .
+ * Any attempt to setup an invalid mode is ignored.
+ *
+ * @section stm32l1xx_pal_4 Suboptimal behavior
+ * The STM32L1xx GPIO is less than optimal in several areas, the limitations
+ * should be taken in account while using the PAL driver:
+ * - Pad/port toggling operations are not atomic.
+ * - Pad/group mode setup is not atomic.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_PWM STM32L1xx PWM Support
+ * @details The STM32L1xx PWM driver uses the TIMx peripherals.
+ *
+ * @section stm32l1xx_pwm_1 Supported HW resources
+ * - TIM1.
+ * - TIM2.
+ * - TIM3.
+ * - TIM4.
+ * .
+ * @section stm32l1xx_pwm_2 STM32L1xx PWM driver implementation features
+ * - Each timer can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Four independent PWM channels per timer.
+ * - Programmable TIMx interrupts priority level.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_SERIAL STM32L1xx Serial Support
+ * @details The STM32L1xx Serial driver uses the USART/UART peripherals in a
+ * buffered, interrupt driven, implementation.
+ *
+ * @section stm32l1xx_serial_1 Supported HW resources
+ * The serial driver can support any of the following hardware resources:
+ * - USART1.
+ * - USART2.
+ * - USART3 (where present).
+ * - UART4 (where present).
+ * - UART5 (where present).
+ * .
+ * @section stm32l1xx_serial_2 STM32L1xx Serial driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each UART/USART can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Fully interrupt driven.
+ * - Programmable priority levels for each UART/USART.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_SPI STM32L1xx SPI Support
+ * @details The SPI driver supports the STM32L1xx SPI peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32l1xx_spi_1 Supported HW resources
+ * - SPI1.
+ * - SPI2.
+ * - SPI3 (where present).
+ * - DMA1.
+ * - DMA2 (where present).
+ * .
+ * @section stm32l1xx_spi_2 STM32L1xx SPI driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each SPI can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each SPI.
+ * - DMA is used for receiving and transmitting.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_UART STM32L1xx UART Support
+ * @details The UART driver supports the STM32L1xx USART peripherals using DMA
+ * channels for maximum performance.
+ *
+ * @section stm32l1xx_uart_1 Supported HW resources
+ * The UART driver can support any of the following hardware resources:
+ * - USART1.
+ * - USART2.
+ * - USART3 (where present).
+ * - DMA1.
+ * .
+ * @section stm32l1xx_uart_2 STM32L1xx UART driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Each UART/USART can be independently enabled and programmed. Unused
+ * peripherals are left in low power mode.
+ * - Programmable interrupt priority levels for each UART/USART.
+ * - DMA is used for receiving and transmitting.
+ * - Programmable DMA bus priority for each DMA channel.
+ * - Programmable DMA interrupt priority for each DMA channel.
+ * - Programmable DMA error hook.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_USB STM32L1xx USB Support
+ * @details The USB driver supports the STM32L1xx USB peripheral.
+ *
+ * @section stm32l1xx_usb_1 Supported HW resources
+ * The USB driver can support any of the following hardware resources:
+ * - USB.
+ * .
+ * @section stm32l1xx_usb_2 STM32L1xx USB driver implementation features
+ * - Clock stop for reduced power usage when the driver is in stop state.
+ * - Programmable interrupt priority levels.
+ * - Each endpoint programmable in Control, Bulk and Interrupt modes.
+ * .
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_PLATFORM_DRIVERS STM32L1xx Platform Drivers
+ * @details Platform support drivers. Platform drivers do not implement HAL
+ * standard driver templates, their role is to support platform
+ * specific functionalities.
+ *
+ * @ingroup STM32L1xx_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_DMA STM32L1xx DMA Support
+ * @details This DMA helper driver is used by the other drivers in order to
+ * access the shared DMA resources in a consistent way.
+ *
+ * @section stm32l1xx_dma_1 Supported HW resources
+ * The DMA driver can support any of the following hardware resources:
+ * - DMA1.
+ * .
+ * @section stm32l1xx_dma_2 STM32L1xx DMA driver implementation features
+ * - Exports helper functions/macros to the other drivers that share the
+ * DMA resource.
+ * - Automatic DMA clock stop when not in use by any driver.
+ * - DMA streams and interrupt vectors sharing among multiple drivers.
+ * .
+ * @ingroup STM32L1xx_PLATFORM_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_ISR STM32L1xx ISR Support
+ * @details This ISR helper driver is used by the other drivers in order to
+ * map ISR names to physical vector names.
+ *
+ * @ingroup STM32L1xx_PLATFORM_DRIVERS
+ */
+
+/**
+ * @defgroup STM32L1xx_RCC STM32L1xx RCC Support
+ * @details This RCC helper driver is used by the other drivers in order to
+ * access the shared RCC resources in a consistent way.
+ *
+ * @section stm32f1xx_rcc_1 Supported HW resources
+ * - RCC.
+ * .
+ * @section stm32l1xx_rcc_2 STM32L1xx RCC driver implementation features
+ * - Peripherals reset.
+ * - Peripherals clock enable.
+ * - Peripherals clock disable.
+ * .
+ * @ingroup STM32L1xx_PLATFORM_DRIVERS
+ */
diff --git a/os/hal/ports/STM32/STM32L1xx/platform.mk b/os/hal/ports/STM32/STM32L1xx/platform.mk
index 43e7d1b0a2..7510bac105 100644
--- a/os/hal/ports/STM32/STM32L1xx/platform.mk
+++ b/os/hal/ports/STM32/STM32L1xx/platform.mk
@@ -1,46 +1,46 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx
-
-# 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"))
-
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
-endif
-else
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
-endif
-
-# Drivers compatible with the platform.
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/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/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx
+
+# 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"))
+
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
+endif
+else
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32L1xx/hal_adc_lld.c
+endif
+
+# Drivers compatible with the platform.
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/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/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/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/USBv1/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/STM32L1xx/stm32_isr.c b/os/hal/ports/STM32/STM32L1xx/stm32_isr.c
index d6353c3471..0f2f7c8c87 100644
--- a/os/hal/ports/STM32/STM32L1xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32L1xx/stm32_isr.c
@@ -1,255 +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 STM32L1xx/stm32_isr.c
- * @brief STM32L1xx ISR handler code.
- *
- * @addtogroup STM32L1xx_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
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32L1xx ISR handler code.
+ *
+ * @addtogroup STM32L1xx_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/STM32/STM32L1xx/stm32_isr.h b/os/hal/ports/STM32/STM32L1xx/stm32_isr.h
index c29cd144f0..6919a12174 100644
--- a/os/hal/ports/STM32/STM32L1xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32L1xx/stm32_isr.h
@@ -1,230 +1,230 @@
-/*
- 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/stm32_isr.h
- * @brief STM32L1xx ISR handler header.
- *
- * @addtogroup STM32L1xx_ISR
- * @{
- */
-
-#ifndef STM32_ISR_H
-#define STM32_ISR_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name ISR names and numbers remapping
- * @{
- */
-/*
- * I2C units.
- */
-#define STM32_I2C1_EVENT_HANDLER VectorBC
-#define STM32_I2C1_ERROR_HANDLER VectorC0
-#define STM32_I2C1_EVENT_NUMBER 31
-#define STM32_I2C1_ERROR_NUMBER 32
-
-#define STM32_I2C2_EVENT_HANDLER VectorC4
-#define STM32_I2C2_ERROR_HANDLER VectorC8
-#define STM32_I2C2_EVENT_NUMBER 33
-#define STM32_I2C2_ERROR_NUMBER 34
-
-/*
- * TIM units.
- */
-#define STM32_TIM2_HANDLER VectorB0
-#define STM32_TIM3_HANDLER VectorB4
-#define STM32_TIM4_HANDLER VectorB8
-#define STM32_TIM5_HANDLER VectorF8
-#define STM32_TIM6_HANDLER VectorEC
-#define STM32_TIM7_HANDLER VectorF0
-#define STM32_TIM9_HANDLER VectorA4
-#define STM32_TIM10_HANDLER VectorA8
-#define STM32_TIM11_HANDLER VectorAC
-
-#define STM32_TIM2_NUMBER 28
-#define STM32_TIM3_NUMBER 29
-#define STM32_TIM4_NUMBER 30
-#define STM32_TIM5_NUMBER 46
-#define STM32_TIM6_NUMBER 43
-#define STM32_TIM7_NUMBER 44
-#define STM32_TIM9_NUMBER 25
-#define STM32_TIM10_NUMBER 26
-#define STM32_TIM11_NUMBER 27
-
-/*
- * USART units.
- */
-#define STM32_USART1_HANDLER VectorD4
-#define STM32_USART2_HANDLER VectorD8
-#define STM32_USART3_HANDLER VectorDC
-#define STM32_UART4_HANDLER Vector100
-#define STM32_UART5_HANDLER Vector104
-
-#define STM32_USART1_NUMBER 37
-#define STM32_USART2_NUMBER 38
-#define STM32_USART3_NUMBER 39
-#define STM32_UART4_NUMBER 48
-#define STM32_UART5_NUMBER 49
-/*
- * USB units.
- */
-#define STM32_USB1_HP_HANDLER Vector8C
-#define STM32_USB1_LP_HANDLER Vector90
-
-#define STM32_USB1_HP_NUMBER 19
-#define STM32_USB1_LP_NUMBER 20
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/**
- * @name Configuration options
- * @{
- */
-/**
- * @brief EXTI0 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI0_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI1 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI1_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI2 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI2_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI3 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI3_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI4 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI4_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI9..5 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI5_9_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI15..10 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI10_15_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI16 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI16_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI17 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI17_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI18 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI18_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI19 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI19_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI20 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI20_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI20_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI21..22 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI21_22_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI21_22_PRIORITY 6
-#endif
-
-/**
- * @brief EXTI23 interrupt priority level setting.
- */
-#if !defined(STM32_IRQ_EXTI23_PRIORITY) || defined(__DOXYGEN__)
-#define STM32_IRQ_EXTI23_PRIORITY 6
-#endif
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32L1xx ISR handler header.
+ *
+ * @addtogroup STM32L1xx_ISR
+ * @{
+ */
+
+#ifndef STM32_ISR_H
+#define STM32_ISR_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name ISR names and numbers remapping
+ * @{
+ */
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_EVENT_HANDLER VectorBC
+#define STM32_I2C1_ERROR_HANDLER VectorC0
+#define STM32_I2C1_EVENT_NUMBER 31
+#define STM32_I2C1_ERROR_NUMBER 32
+
+#define STM32_I2C2_EVENT_HANDLER VectorC4
+#define STM32_I2C2_ERROR_HANDLER VectorC8
+#define STM32_I2C2_EVENT_NUMBER 33
+#define STM32_I2C2_ERROR_NUMBER 34
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM2_HANDLER VectorB0
+#define STM32_TIM3_HANDLER VectorB4
+#define STM32_TIM4_HANDLER VectorB8
+#define STM32_TIM5_HANDLER VectorF8
+#define STM32_TIM6_HANDLER VectorEC
+#define STM32_TIM7_HANDLER VectorF0
+#define STM32_TIM9_HANDLER VectorA4
+#define STM32_TIM10_HANDLER VectorA8
+#define STM32_TIM11_HANDLER VectorAC
+
+#define STM32_TIM2_NUMBER 28
+#define STM32_TIM3_NUMBER 29
+#define STM32_TIM4_NUMBER 30
+#define STM32_TIM5_NUMBER 46
+#define STM32_TIM6_NUMBER 43
+#define STM32_TIM7_NUMBER 44
+#define STM32_TIM9_NUMBER 25
+#define STM32_TIM10_NUMBER 26
+#define STM32_TIM11_NUMBER 27
+
+/*
+ * USART units.
+ */
+#define STM32_USART1_HANDLER VectorD4
+#define STM32_USART2_HANDLER VectorD8
+#define STM32_USART3_HANDLER VectorDC
+#define STM32_UART4_HANDLER Vector100
+#define STM32_UART5_HANDLER Vector104
+
+#define STM32_USART1_NUMBER 37
+#define STM32_USART2_NUMBER 38
+#define STM32_USART3_NUMBER 39
+#define STM32_UART4_NUMBER 48
+#define STM32_UART5_NUMBER 49
+/*
+ * USB units.
+ */
+#define STM32_USB1_HP_HANDLER Vector8C
+#define STM32_USB1_LP_HANDLER Vector90
+
+#define STM32_USB1_HP_NUMBER 19
+#define STM32_USB1_LP_NUMBER 20
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI0_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI0_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI1 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI1_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI1_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI2 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI2_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI2_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI3 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI3_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI3_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI4 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI4_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI4_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI9..5 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI5_9_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI5_9_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI15..10 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI10_15_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI10_15_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI16 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI16_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI16_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI17 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI17_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI17_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI18 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI18_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI18_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI19 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI19_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI19_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI20 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI20_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI20_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI21..22 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI21_22_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI21_22_PRIORITY 6
+#endif
+
+/**
+ * @brief EXTI23 interrupt priority level setting.
+ */
+#if !defined(STM32_IRQ_EXTI23_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_IRQ_EXTI23_PRIORITY 6
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32L1xx/stm32_rcc.h b/os/hal/ports/STM32/STM32L1xx/stm32_rcc.h
index 11cbe332c2..5c0d318d22 100644
--- a/os/hal/ports/STM32/STM32L1xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L1xx/stm32_rcc.h
@@ -1,795 +1,795 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32l1xx.h.
- *
- * @addtogroup STM32L1xx_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
- * @param[in] lp low power enable flag
- *
- * @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 AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAHB(mask, lp) { \
- RCC->AHBENR |= (mask); \
- if (lp) \
- RCC->AHBLPENR |= (mask); \
- else \
- RCC->AHBLPENR &= ~(mask); \
- (void)RCC->AHBLPENR; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccDisableAHB(mask) { \
- RCC->AHBENR &= ~(mask); \
- RCC->AHBLPENR &= ~(mask); \
- (void)RCC->AHBLPENR; \
-}
-
-/**
- * @brief Resets one or more peripheral on the AHB bus.
- *
- * @param[in] mask AHB peripherals mask
- *
- * @api
- */
-#define rccResetAHB(mask) { \
- RCC->AHBRSTR |= (mask); \
- RCC->AHBRSTR &= ~(mask); \
- (void)RCC->AHBRSTR; \
-}
-/** @} */
-
-/**
- * @name ADC peripherals specific RCC operations
- * @{
- */
-/**
- * @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 Resets the ADC1 peripheral.
- *
- * @api
- */
-#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
-/** @} */
-
-/**
- * @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) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
-
-/**
- * @brief Disables the DMA1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
-
-/**
- * @brief Resets the DMA1 peripheral.
- *
- * @api
- */
-#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
-
-/**
- * @brief Enables the DMA2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
-
-/**
- * @brief Disables the DMA2 peripheral clock.
- *
- * @api
- */
-#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
-
-/**
- * @brief Resets the DMA2 peripheral.
- *
- * @api
- */
-#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
-/** @} */
-
-/**
- * @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 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)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @name TIM peripherals specific RCC operations
- * @{
- */
-/**
- * @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 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 TIM10 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)
-
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32l1xx.h.
+ *
+ * @addtogroup STM32L1xx_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
+ * @param[in] lp low power enable flag
+ *
+ * @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 AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAHB(mask, lp) { \
+ RCC->AHBENR |= (mask); \
+ if (lp) \
+ RCC->AHBLPENR |= (mask); \
+ else \
+ RCC->AHBLPENR &= ~(mask); \
+ (void)RCC->AHBLPENR; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAHB(mask) { \
+ RCC->AHBENR &= ~(mask); \
+ RCC->AHBLPENR &= ~(mask); \
+ (void)RCC->AHBLPENR; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the AHB bus.
+ *
+ * @param[in] mask AHB peripherals mask
+ *
+ * @api
+ */
+#define rccResetAHB(mask) { \
+ RCC->AHBRSTR |= (mask); \
+ RCC->AHBRSTR &= ~(mask); \
+ (void)RCC->AHBRSTR; \
+}
+/** @} */
+
+/**
+ * @name ADC peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @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 Resets the ADC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC1() rccResetAPB2(RCC_APB2RSTR_ADC1RST)
+/** @} */
+
+/**
+ * @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) rccEnableAHB(RCC_AHBENR_DMA1EN, lp)
+
+/**
+ * @brief Disables the DMA1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA1() rccDisableAHB(RCC_AHBENR_DMA1EN)
+
+/**
+ * @brief Resets the DMA1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA1() rccResetAHB(RCC_AHBRSTR_DMA1RST)
+
+/**
+ * @brief Enables the DMA2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMA2(lp) rccEnableAHB(RCC_AHBENR_DMA2EN, lp)
+
+/**
+ * @brief Disables the DMA2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMA2() rccDisableAHB(RCC_AHBENR_DMA2EN)
+
+/**
+ * @brief Resets the DMA2 peripheral.
+ *
+ * @api
+ */
+#define rccResetDMA2() rccResetAHB(RCC_AHBRSTR_DMA2RST)
+/** @} */
+
+/**
+ * @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 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)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @name TIM peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @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 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 TIM10 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)
+
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1(RCC_APB1ENR_USBEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1(RCC_APB1ENR_USBEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1(RCC_APB1RSTR_USBRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L1xx/stm32_registry.h b/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
index d227aa1e34..8e0b28525d 100644
--- a/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
@@ -1,377 +1,377 @@
-/*
- 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/stm32_registry.h
- * @brief STM32L1xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
-#define STM32L1XX_PROD_CAT 1
-
-#elif defined(STM32L100xBA) || defined(STM32L151xBA) || defined(STM32L152xBA)
-#define STM32L1XX_PROD_CAT 2
-
-#elif defined(STM32L100xC) || defined(STM32L151xC) || \
- defined(STM32L151xCA) || defined(STM32L152xC) || \
- defined(STM32L152xCA) || defined(STM32L162xC) || \
- defined(STM32L162xCA)
-#define STM32L1XX_PROD_CAT 3
-
-#elif defined(STM32L151xD) || defined(STM32L152xD) || \
- defined(STM32L162xD)
-#define STM32L1XX_PROD_CAT 4
-
-#elif defined(STM32L151xE) || defined (STM32L152xE) || \
- defined(STM32L162xE)
-#define STM32L1XX_PROD_CAT 5
-
-#elif defined(STM32L151xDX) || defined (STM32L152xDX) || \
- defined(STM32L162xDX)
-#define STM32L1XX_PROD_CAT 6
-
-#else
-#error "STM32L1xx device not specified"
-#endif
-
-#if defined(STM32L100xB) || defined(STM32L100xBA) || defined(STM32L100xC)
-#define STM32L1XX_VALUE_LINE TRUE
-#else
-#define STM32L1XX_VALUE_LINE FALSE
-#endif
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32L1xx capabilities
- * @{
- */
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-
-#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
- defined(__DOXYGEN__)
-#define STM32_DMA2_NUM_CHANNELS 0
-#else
-#define STM32_DMA2_NUM_CHANNELS 5
-#define STM32_DMA2_CH1_HANDLER Vector108
-#define STM32_DMA2_CH2_HANDLER Vector10C
-#define STM32_DMA2_CH3_HANDLER Vector110
-#define STM32_DMA2_CH4_HANDLER Vector114
-#define STM32_DMA2_CH5_HANDLER Vector118
-#define STM32_DMA2_CH1_NUMBER 50
-#define STM32_DMA2_CH2_NUMBER 51
-#define STM32_DMA2_CH3_NUMBER 52
-#define STM32_DMA2_CH4_NUMBER 53
-#define STM32_DMA2_CH5_NUMBER 54
-#endif
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
- defined(__DOXYGEN__)
-#define STM32_EXTI_NUM_LINES 23
-#else
-#define STM32_EXTI_NUM_LINES 24
-#endif
-#define STM32_EXTI_IMR1_MASK 0x00000000U
-
-#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
- (STM32L1XX_PROD_CAT == 3) || defined(__DOXYGEN__)
-#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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOHEN)
-#else
-#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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
- RCC_AHBENR_GPIOBEN | \
- RCC_AHBENR_GPIOCEN | \
- RCC_AHBENR_GPIODEN | \
- RCC_AHBENR_GPIOEEN | \
- RCC_AHBENR_GPIOFEN | \
- RCC_AHBENR_GPIOGEN | \
- RCC_AHBENR_GPIOHEN)
-#endif
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_I2C3 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#if (STM32L1XX_PROD_CAT == 1) || defined(__DOXYGEN__)
-#define STM32_RTC_HAS_SUBSECONDS FALSE
-#else
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#endif
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#if STM32L1XX_VALUE_LINE || defined(__DOXYGEN__)
-#define STM32_RTC_STORAGE_SIZE 20
-#elif (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2)
-#define STM32_RTC_STORAGE_SIZE 80
-#else
-#define STM32_RTC_STORAGE_SIZE 128
-#endif
-#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 3
-#define STM32_RTC_WKUP_NUMBER 1
-#define STM32_RTC_ALARM_NUMBER 2
-#define STM32_RTC_ALARM_EXTI 17
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
-} while (false)
-
-/* SDIO attributes.*/
-#define STM32_HAS_SDIO TRUE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S TRUE
-#define STM32_SPI2_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-
-#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
- defined(__DOXYGEN__)
-#define STM32_HAS_SPI3 FALSE
-#else
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S TRUE
-#define STM32_SPI3_I2S_FULLDUPLEX FALSE
-#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#endif
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS FALSE
-#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
-
-#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
- defined(__DOXYGEN__)
-#define STM32_HAS_TIM5 FALSE
-#else
-#define STM32_HAS_TIM5 TRUE
-#define STM32_TIM5_IS_32BITS TRUE
-#define STM32_TIM5_CHANNELS 4
-#endif
-
-#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_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 2
-
-#define STM32_HAS_TIM11 TRUE
-#define STM32_TIM11_IS_32BITS FALSE
-#define STM32_TIM11_CHANNELS 2
-
-#define STM32_HAS_TIM1 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 FALSE
-#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
-#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
-#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
-#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
-
-#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
- (STM32L1XX_PROD_CAT == 3) || defined(__DOXYGEN__)
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#else
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
-#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
-#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
-#endif
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-#define STM32_HAS_LPUART1 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
-#define STM32_USB_PMA_SIZE 512
-#define STM32_USB_HAS_BCDR FALSE
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED FALSE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE FALSE
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32L1xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
+#define STM32L1XX_PROD_CAT 1
+
+#elif defined(STM32L100xBA) || defined(STM32L151xBA) || defined(STM32L152xBA)
+#define STM32L1XX_PROD_CAT 2
+
+#elif defined(STM32L100xC) || defined(STM32L151xC) || \
+ defined(STM32L151xCA) || defined(STM32L152xC) || \
+ defined(STM32L152xCA) || defined(STM32L162xC) || \
+ defined(STM32L162xCA)
+#define STM32L1XX_PROD_CAT 3
+
+#elif defined(STM32L151xD) || defined(STM32L152xD) || \
+ defined(STM32L162xD)
+#define STM32L1XX_PROD_CAT 4
+
+#elif defined(STM32L151xE) || defined (STM32L152xE) || \
+ defined(STM32L162xE)
+#define STM32L1XX_PROD_CAT 5
+
+#elif defined(STM32L151xDX) || defined (STM32L152xDX) || \
+ defined(STM32L162xDX)
+#define STM32L1XX_PROD_CAT 6
+
+#else
+#error "STM32L1xx device not specified"
+#endif
+
+#if defined(STM32L100xB) || defined(STM32L100xBA) || defined(STM32L100xC)
+#define STM32L1XX_VALUE_LINE TRUE
+#else
+#define STM32L1XX_VALUE_LINE FALSE
+#endif
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32L1xx capabilities
+ * @{
+ */
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA FALSE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+
+#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
+ defined(__DOXYGEN__)
+#define STM32_DMA2_NUM_CHANNELS 0
+#else
+#define STM32_DMA2_NUM_CHANNELS 5
+#define STM32_DMA2_CH1_HANDLER Vector108
+#define STM32_DMA2_CH2_HANDLER Vector10C
+#define STM32_DMA2_CH3_HANDLER Vector110
+#define STM32_DMA2_CH4_HANDLER Vector114
+#define STM32_DMA2_CH5_HANDLER Vector118
+#define STM32_DMA2_CH1_NUMBER 50
+#define STM32_DMA2_CH2_NUMBER 51
+#define STM32_DMA2_CH3_NUMBER 52
+#define STM32_DMA2_CH4_NUMBER 53
+#define STM32_DMA2_CH5_NUMBER 54
+#endif
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
+ defined(__DOXYGEN__)
+#define STM32_EXTI_NUM_LINES 23
+#else
+#define STM32_EXTI_NUM_LINES 24
+#endif
+#define STM32_EXTI_IMR1_MASK 0x00000000U
+
+#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
+ (STM32L1XX_PROD_CAT == 3) || defined(__DOXYGEN__)
+#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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOHEN)
+#else
+#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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHBENR_GPIOAEN | \
+ RCC_AHBENR_GPIOBEN | \
+ RCC_AHBENR_GPIOCEN | \
+ RCC_AHBENR_GPIODEN | \
+ RCC_AHBENR_GPIOEEN | \
+ RCC_AHBENR_GPIOFEN | \
+ RCC_AHBENR_GPIOGEN | \
+ RCC_AHBENR_GPIOHEN)
+#endif
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_I2C3 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#if (STM32L1XX_PROD_CAT == 1) || defined(__DOXYGEN__)
+#define STM32_RTC_HAS_SUBSECONDS FALSE
+#else
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#endif
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#if STM32L1XX_VALUE_LINE || defined(__DOXYGEN__)
+#define STM32_RTC_STORAGE_SIZE 20
+#elif (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2)
+#define STM32_RTC_STORAGE_SIZE 80
+#else
+#define STM32_RTC_STORAGE_SIZE 128
+#endif
+#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 3
+#define STM32_RTC_WKUP_NUMBER 1
+#define STM32_RTC_ALARM_NUMBER 2
+#define STM32_RTC_ALARM_EXTI 17
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
+} while (false)
+
+/* SDIO attributes.*/
+#define STM32_HAS_SDIO TRUE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S TRUE
+#define STM32_SPI2_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+
+#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
+ defined(__DOXYGEN__)
+#define STM32_HAS_SPI3 FALSE
+#else
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S TRUE
+#define STM32_SPI3_I2S_FULLDUPLEX FALSE
+#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#endif
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 4
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS FALSE
+#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
+
+#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
+ defined(__DOXYGEN__)
+#define STM32_HAS_TIM5 FALSE
+#else
+#define STM32_HAS_TIM5 TRUE
+#define STM32_TIM5_IS_32BITS TRUE
+#define STM32_TIM5_CHANNELS 4
+#endif
+
+#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_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 2
+
+#define STM32_HAS_TIM11 TRUE
+#define STM32_TIM11_IS_32BITS FALSE
+#define STM32_TIM11_CHANNELS 2
+
+#define STM32_HAS_TIM1 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 FALSE
+#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_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
+#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
+#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
+
+#if (STM32L1XX_PROD_CAT == 1) || (STM32L1XX_PROD_CAT == 2) || \
+ (STM32L1XX_PROD_CAT == 3) || defined(__DOXYGEN__)
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#else
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3)
+#define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5)
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2)
+#define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1)
+#endif
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+#define STM32_HAS_LPUART1 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 FALSE
+#define STM32_USB_PMA_SIZE 512
+#define STM32_USB_HAS_BCDR FALSE
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED FALSE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE FALSE
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx+/hal_lld.c b/os/hal/ports/STM32/STM32L4xx+/hal_lld.c
index 6a6d6de997..f29d5e6705 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 ((!FOME_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < FOME_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 ? 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 */
+
+ /* 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..78877b61ea 100644
--- a/os/hal/ports/STM32/STM32L4xx+/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L4xx+/hal_lld.h
@@ -1,2614 +1,2622 @@
-/*
- 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 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 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
+
+ #if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+ #error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+ #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_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+/platform.mk b/os/hal/ports/STM32/STM32L4xx+/platform.mk
index 2ad09d7288..9d9e5ae0fe 100644
--- a/os/hal/ports/STM32/STM32L4xx+/platform.mk
+++ b/os/hal/ports/STM32/STM32L4xx+/platform.mk
@@ -1,49 +1,49 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+/hal_efl_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+
-
-# 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/ADCv3/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/DMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+/hal_efl_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx+
+
+# 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/ADCv3/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/DMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/OCTOSPIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/OTGv1/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/STM32L4xx+/stm32_dmamux.h b/os/hal/ports/STM32/STM32L4xx+/stm32_dmamux.h
index a7889be365..8b8482127f 100644
--- a/os/hal/ports/STM32/STM32L4xx+/stm32_dmamux.h
+++ b/os/hal/ports/STM32/STM32L4xx+/stm32_dmamux.h
@@ -1,161 +1,161 @@
-/*
- 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+/stm32_dmamux.h
- * @brief STM32L4xx+ DMAMUX handler header.
- *
- * @addtogroup STM32L4xxp_DMAMUX
- * @{
- */
-
-#ifndef STM32_DMAMUX_H
-#define STM32_DMAMUX_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name DMAMUX1 request sources
- * @{
- */
-#define STM32_DMAMUX1_REQ_GEN0 1
-#define STM32_DMAMUX1_REQ_GEN1 2
-#define STM32_DMAMUX1_REQ_GEN2 3
-#define STM32_DMAMUX1_REQ_GEN3 4
-#define STM32_DMAMUX1_ADC1 5
-#define STM32_DMAMUX1_DAC1_CH1 6
-#define STM32_DMAMUX1_DAC1_CH2 7
-#define STM32_DMAMUX1_TIM6_UP 8
-#define STM32_DMAMUX1_TIM7_UP 9
-#define STM32_DMAMUX1_SPI1_RX 10
-#define STM32_DMAMUX1_SPI1_TX 11
-#define STM32_DMAMUX1_SPI2_RX 12
-#define STM32_DMAMUX1_SPI2_TX 13
-#define STM32_DMAMUX1_SPI3_RX 14
-#define STM32_DMAMUX1_SPI3_TX 15
-#define STM32_DMAMUX1_I2C1_RX 16
-#define STM32_DMAMUX1_I2C1_TX 17
-#define STM32_DMAMUX1_I2C2_RX 18
-#define STM32_DMAMUX1_I2C2_TX 19
-#define STM32_DMAMUX1_I2C3_RX 20
-#define STM32_DMAMUX1_I2C3_TX 21
-#define STM32_DMAMUX1_I2C4_RX 22
-#define STM32_DMAMUX1_I2C4_TX 23
-#define STM32_DMAMUX1_USART1_RX 24
-#define STM32_DMAMUX1_USART1_TX 25
-#define STM32_DMAMUX1_USART2_RX 26
-#define STM32_DMAMUX1_USART2_TX 27
-#define STM32_DMAMUX1_USART3_RX 28
-#define STM32_DMAMUX1_USART3_TX 29
-#define STM32_DMAMUX1_UART4_RX 30
-#define STM32_DMAMUX1_UART4_TX 31
-#define STM32_DMAMUX1_UART5_RX 32
-#define STM32_DMAMUX1_UART5_TX 33
-#define STM32_DMAMUX1_LPUART1_RX 34
-#define STM32_DMAMUX1_LPUART1_TX 35
-#define STM32_DMAMUX1_SAI1_A 36
-#define STM32_DMAMUX1_SAI1_B 37
-#define STM32_DMAMUX1_SAI2_A 38
-#define STM32_DMAMUX1_SAI2_B 39
-#define STM32_DMAMUX1_OCTOSPI1 40
-#define STM32_DMAMUX1_OCTOSPI2 41
-#define STM32_DMAMUX1_TIM1_CH1 42
-#define STM32_DMAMUX1_TIM1_CH2 43
-#define STM32_DMAMUX1_TIM1_CH3 44
-#define STM32_DMAMUX1_TIM1_CH4 45
-#define STM32_DMAMUX1_TIM1_UP 46
-#define STM32_DMAMUX1_TIM1_TRIG 47
-#define STM32_DMAMUX1_TIM1_COM 48
-#define STM32_DMAMUX1_TIM8_CH1 49
-#define STM32_DMAMUX1_TIM8_CH2 50
-#define STM32_DMAMUX1_TIM8_CH3 51
-#define STM32_DMAMUX1_TIM8_CH4 52
-#define STM32_DMAMUX1_TIM8_UP 53
-#define STM32_DMAMUX1_TIM8_TRIG 54
-#define STM32_DMAMUX1_TIM8_COM 55
-#define STM32_DMAMUX1_TIM2_CH1 56
-#define STM32_DMAMUX1_TIM2_CH2 57
-#define STM32_DMAMUX1_TIM2_CH3 58
-#define STM32_DMAMUX1_TIM2_CH4 59
-#define STM32_DMAMUX1_TIM2_UP 60
-#define STM32_DMAMUX1_TIM3_CH1 61
-#define STM32_DMAMUX1_TIM3_CH2 62
-#define STM32_DMAMUX1_TIM3_CH3 63
-#define STM32_DMAMUX1_TIM3_CH4 64
-#define STM32_DMAMUX1_TIM3_UP 65
-#define STM32_DMAMUX1_TIM3_TRIG 66
-#define STM32_DMAMUX1_TIM4_CH1 67
-#define STM32_DMAMUX1_TIM4_CH2 68
-#define STM32_DMAMUX1_TIM4_CH3 69
-#define STM32_DMAMUX1_TIM4_CH4 70
-#define STM32_DMAMUX1_TIM4_UP 71
-#define STM32_DMAMUX1_TIM5_CH1 72
-#define STM32_DMAMUX1_TIM5_CH2 73
-#define STM32_DMAMUX1_TIM5_CH3 74
-#define STM32_DMAMUX1_TIM5_CH4 75
-#define STM32_DMAMUX1_TIM5_UP 76
-#define STM32_DMAMUX1_TIM5_TRIG 77
-#define STM32_DMAMUX1_TIM15_CH1 78
-#define STM32_DMAMUX1_TIM15_UP 79
-#define STM32_DMAMUX1_TIM15_TRIG 80
-#define STM32_DMAMUX1_TIM15_COM 81
-#define STM32_DMAMUX1_TIM16_CH1 82
-#define STM32_DMAMUX1_TIM16_UP 83
-#define STM32_DMAMUX1_TIM17_CH1 84
-#define STM32_DMAMUX1_TIM17_UP 85
-#define STM32_DMAMUX1_DFSDM1_FLT0 86
-#define STM32_DMAMUX1_DFSDM1_FLT1 87
-#define STM32_DMAMUX1_DFSDM1_FLT2 88
-#define STM32_DMAMUX1_DFSDM1_FLT3 89
-#define STM32_DMAMUX1_DCMI 90
-#define STM32_DMAMUX1_AES_IN 91
-#define STM32_DMAMUX1_AES_OUT 92
-#define STM32_DMAMUX1_HASH_IN 93
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMAMUX_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+/stm32_dmamux.h
+ * @brief STM32L4xx+ DMAMUX handler header.
+ *
+ * @addtogroup STM32L4xxp_DMAMUX
+ * @{
+ */
+
+#ifndef STM32_DMAMUX_H
+#define STM32_DMAMUX_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name DMAMUX1 request sources
+ * @{
+ */
+#define STM32_DMAMUX1_REQ_GEN0 1
+#define STM32_DMAMUX1_REQ_GEN1 2
+#define STM32_DMAMUX1_REQ_GEN2 3
+#define STM32_DMAMUX1_REQ_GEN3 4
+#define STM32_DMAMUX1_ADC1 5
+#define STM32_DMAMUX1_DAC1_CH1 6
+#define STM32_DMAMUX1_DAC1_CH2 7
+#define STM32_DMAMUX1_TIM6_UP 8
+#define STM32_DMAMUX1_TIM7_UP 9
+#define STM32_DMAMUX1_SPI1_RX 10
+#define STM32_DMAMUX1_SPI1_TX 11
+#define STM32_DMAMUX1_SPI2_RX 12
+#define STM32_DMAMUX1_SPI2_TX 13
+#define STM32_DMAMUX1_SPI3_RX 14
+#define STM32_DMAMUX1_SPI3_TX 15
+#define STM32_DMAMUX1_I2C1_RX 16
+#define STM32_DMAMUX1_I2C1_TX 17
+#define STM32_DMAMUX1_I2C2_RX 18
+#define STM32_DMAMUX1_I2C2_TX 19
+#define STM32_DMAMUX1_I2C3_RX 20
+#define STM32_DMAMUX1_I2C3_TX 21
+#define STM32_DMAMUX1_I2C4_RX 22
+#define STM32_DMAMUX1_I2C4_TX 23
+#define STM32_DMAMUX1_USART1_RX 24
+#define STM32_DMAMUX1_USART1_TX 25
+#define STM32_DMAMUX1_USART2_RX 26
+#define STM32_DMAMUX1_USART2_TX 27
+#define STM32_DMAMUX1_USART3_RX 28
+#define STM32_DMAMUX1_USART3_TX 29
+#define STM32_DMAMUX1_UART4_RX 30
+#define STM32_DMAMUX1_UART4_TX 31
+#define STM32_DMAMUX1_UART5_RX 32
+#define STM32_DMAMUX1_UART5_TX 33
+#define STM32_DMAMUX1_LPUART1_RX 34
+#define STM32_DMAMUX1_LPUART1_TX 35
+#define STM32_DMAMUX1_SAI1_A 36
+#define STM32_DMAMUX1_SAI1_B 37
+#define STM32_DMAMUX1_SAI2_A 38
+#define STM32_DMAMUX1_SAI2_B 39
+#define STM32_DMAMUX1_OCTOSPI1 40
+#define STM32_DMAMUX1_OCTOSPI2 41
+#define STM32_DMAMUX1_TIM1_CH1 42
+#define STM32_DMAMUX1_TIM1_CH2 43
+#define STM32_DMAMUX1_TIM1_CH3 44
+#define STM32_DMAMUX1_TIM1_CH4 45
+#define STM32_DMAMUX1_TIM1_UP 46
+#define STM32_DMAMUX1_TIM1_TRIG 47
+#define STM32_DMAMUX1_TIM1_COM 48
+#define STM32_DMAMUX1_TIM8_CH1 49
+#define STM32_DMAMUX1_TIM8_CH2 50
+#define STM32_DMAMUX1_TIM8_CH3 51
+#define STM32_DMAMUX1_TIM8_CH4 52
+#define STM32_DMAMUX1_TIM8_UP 53
+#define STM32_DMAMUX1_TIM8_TRIG 54
+#define STM32_DMAMUX1_TIM8_COM 55
+#define STM32_DMAMUX1_TIM2_CH1 56
+#define STM32_DMAMUX1_TIM2_CH2 57
+#define STM32_DMAMUX1_TIM2_CH3 58
+#define STM32_DMAMUX1_TIM2_CH4 59
+#define STM32_DMAMUX1_TIM2_UP 60
+#define STM32_DMAMUX1_TIM3_CH1 61
+#define STM32_DMAMUX1_TIM3_CH2 62
+#define STM32_DMAMUX1_TIM3_CH3 63
+#define STM32_DMAMUX1_TIM3_CH4 64
+#define STM32_DMAMUX1_TIM3_UP 65
+#define STM32_DMAMUX1_TIM3_TRIG 66
+#define STM32_DMAMUX1_TIM4_CH1 67
+#define STM32_DMAMUX1_TIM4_CH2 68
+#define STM32_DMAMUX1_TIM4_CH3 69
+#define STM32_DMAMUX1_TIM4_CH4 70
+#define STM32_DMAMUX1_TIM4_UP 71
+#define STM32_DMAMUX1_TIM5_CH1 72
+#define STM32_DMAMUX1_TIM5_CH2 73
+#define STM32_DMAMUX1_TIM5_CH3 74
+#define STM32_DMAMUX1_TIM5_CH4 75
+#define STM32_DMAMUX1_TIM5_UP 76
+#define STM32_DMAMUX1_TIM5_TRIG 77
+#define STM32_DMAMUX1_TIM15_CH1 78
+#define STM32_DMAMUX1_TIM15_UP 79
+#define STM32_DMAMUX1_TIM15_TRIG 80
+#define STM32_DMAMUX1_TIM15_COM 81
+#define STM32_DMAMUX1_TIM16_CH1 82
+#define STM32_DMAMUX1_TIM16_UP 83
+#define STM32_DMAMUX1_TIM17_CH1 84
+#define STM32_DMAMUX1_TIM17_UP 85
+#define STM32_DMAMUX1_DFSDM1_FLT0 86
+#define STM32_DMAMUX1_DFSDM1_FLT1 87
+#define STM32_DMAMUX1_DFSDM1_FLT2 88
+#define STM32_DMAMUX1_DFSDM1_FLT3 89
+#define STM32_DMAMUX1_DCMI 90
+#define STM32_DMAMUX1_AES_IN 91
+#define STM32_DMAMUX1_AES_OUT 92
+#define STM32_DMAMUX1_HASH_IN 93
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMAMUX_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx+/stm32_isr.c b/os/hal/ports/STM32/STM32L4xx+/stm32_isr.c
index e36ca8db0e..8423676183 100644
--- a/os/hal/ports/STM32/STM32L4xx+/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32L4xx+/stm32_isr.c
@@ -1,165 +1,165 @@
-/*
- 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+/stm32_isr.c
- * @brief STM32L4xx+ ISR handler code.
- *
- * @addtogroup STM32L4xxp_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. */
-/*===========================================================================*/
-
-#include "stm32_exti0.inc"
-#include "stm32_exti1.inc"
-#include "stm32_exti2.inc"
-#include "stm32_exti3.inc"
-#include "stm32_exti4.inc"
-#include "stm32_exti5_9.inc"
-#include "stm32_exti10_15.inc"
-#include "stm32_exti16-35_38.inc"
-#include "stm32_exti18.inc"
-#include "stm32_exti19.inc"
-#include "stm32_exti20.inc"
-#include "stm32_exti21_22.inc"
-
-#include "stm32_sdmmc1.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart3.inc"
-#include "stm32_uart4.inc"
-#include "stm32_uart5.inc"
-#include "stm32_lpuart1.inc"
-
-#include "stm32_tim1_15_16_17.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim4.inc"
-#include "stm32_tim5.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim8.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_irq_init();
- exti1_irq_init();
- exti2_irq_init();
- exti3_irq_init();
- exti4_irq_init();
- exti5_9_irq_init();
- exti10_15_irq_init();
- exti16_exti35_38_irq_init();
- exti18_irq_init();
- exti19_irq_init();
- exti21_22_irq_init();
-
- sdmmc1_irq_init();
-
- tim1_tim15_tim16_tim17_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim4_irq_init();
- tim5_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim8_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_irq_init();
- uart4_irq_init();
- uart5_irq_init();
- lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_irq_deinit();
- exti1_irq_deinit();
- exti2_irq_deinit();
- exti3_irq_deinit();
- exti4_irq_deinit();
- exti5_9_irq_deinit();
- exti10_15_irq_deinit();
- exti16_exti35_38_irq_deinit();
- exti18_irq_deinit();
- exti19_irq_deinit();
- exti21_22_irq_deinit();
-
- sdmmc1_irq_deinit();
-
- tim1_tim15_tim16_tim17_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim4_irq_deinit();
- tim5_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim8_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_irq_deinit();
- uart4_irq_deinit();
- uart5_irq_deinit();
- lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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+/stm32_isr.c
+ * @brief STM32L4xx+ ISR handler code.
+ *
+ * @addtogroup STM32L4xxp_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. */
+/*===========================================================================*/
+
+#include "stm32_exti0.inc"
+#include "stm32_exti1.inc"
+#include "stm32_exti2.inc"
+#include "stm32_exti3.inc"
+#include "stm32_exti4.inc"
+#include "stm32_exti5_9.inc"
+#include "stm32_exti10_15.inc"
+#include "stm32_exti16-35_38.inc"
+#include "stm32_exti18.inc"
+#include "stm32_exti19.inc"
+#include "stm32_exti20.inc"
+#include "stm32_exti21_22.inc"
+
+#include "stm32_sdmmc1.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart3.inc"
+#include "stm32_uart4.inc"
+#include "stm32_uart5.inc"
+#include "stm32_lpuart1.inc"
+
+#include "stm32_tim1_15_16_17.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim4.inc"
+#include "stm32_tim5.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim8.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_irq_init();
+ exti1_irq_init();
+ exti2_irq_init();
+ exti3_irq_init();
+ exti4_irq_init();
+ exti5_9_irq_init();
+ exti10_15_irq_init();
+ exti16_exti35_38_irq_init();
+ exti18_irq_init();
+ exti19_irq_init();
+ exti21_22_irq_init();
+
+ sdmmc1_irq_init();
+
+ tim1_tim15_tim16_tim17_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim4_irq_init();
+ tim5_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim8_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_irq_init();
+ uart4_irq_init();
+ uart5_irq_init();
+ lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_irq_deinit();
+ exti1_irq_deinit();
+ exti2_irq_deinit();
+ exti3_irq_deinit();
+ exti4_irq_deinit();
+ exti5_9_irq_deinit();
+ exti10_15_irq_deinit();
+ exti16_exti35_38_irq_deinit();
+ exti18_irq_deinit();
+ exti19_irq_deinit();
+ exti21_22_irq_deinit();
+
+ sdmmc1_irq_deinit();
+
+ tim1_tim15_tim16_tim17_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim4_irq_deinit();
+ tim5_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim8_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_irq_deinit();
+ uart4_irq_deinit();
+ uart5_irq_deinit();
+ lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx+/stm32_isr.h b/os/hal/ports/STM32/STM32L4xx+/stm32_isr.h
index 9e25c86891..cfc357e559 100644
--- a/os/hal/ports/STM32/STM32L4xx+/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32L4xx+/stm32_isr.h
@@ -1,290 +1,290 @@
-/*
- 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+/stm32_isr.h
- * @brief STM32L4xx+ ISR handler header.
- *
- * @addtogroup STM32L4xxp_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_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC unit.
- */
-#define STM32_ADC1_HANDLER Vector88
-
-#define STM32_ADC1_NUMBER 18
-
-/*
- * CAN unit.
- */
-#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_CAN1_TX_NUMBER 19
-#define STM32_CAN1_RX0_NUMBER 20
-#define STM32_CAN1_RX1_NUMBER 21
-#define STM32_CAN1_SCE_NUMBER 22
-
-/*
- * DMA unit.
- */
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH6_HANDLER Vector150
-#define STM32_DMA2_CH7_HANDLER Vector154
-
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-#define STM32_DMA2_CH6_NUMBER 68
-#define STM32_DMA2_CH7_NUMBER 69
-
-/*
- * 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_EXTI1635_38_HANDLER Vector44 /* PVD PVM1 PVM4 */
-#define STM32_EXTI18_HANDLER VectorE4 /* RTC ALARM */
-#define STM32_EXTI19_HANDLER Vector48 /* RTC TAMP CSS */
-#define STM32_EXTI20_HANDLER Vector4C /* RTC WAKEUP */
-#define STM32_EXTI21_22_HANDLER Vector140 /* COMP1..2 */
-
-#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_EXTI1635_38_NUMBER 1
-#define STM32_EXTI18_NUMBER 41
-#define STM32_EXTI19_NUMBER 2
-#define STM32_EXTI20_NUMBER 3
-#define STM32_EXTI21_22_NUMBER 64
-
-/*
- * 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_I2C4_ERROR_HANDLER Vector18C
-#define STM32_I2C4_EVENT_HANDLER Vector190
-
-#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
-#define STM32_I2C4_ERROR_NUMBER 83
-#define STM32_I2C4_EVENT_NUMBER 84
-
-
-/*
- * OCTOSPI unit.
- */
-#define STM32_OCTOSPI1_HANDLER Vector15C
-#define STM32_OCTOSPI2_HANDLER Vector170
-
-#define STM32_OCTOSPI1_NUMBER 71
-#define STM32_OCTOSPI2_NUMBER 76
-
-/*
- * SDMMC unit.
- */
-#define STM32_SDMMC1_HANDLER Vector104
-
-#define STM32_SDMMC1_NUMBER 49
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_BRK_TIM15_HANDLER VectorA0
-#define STM32_TIM1_UP_TIM16_HANDLER VectorA4
-#define STM32_TIM1_TRGCO_TIM17_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_HANDLER VectorEC
-#define STM32_TIM8_UP_HANDLER VectorF0
-#define STM32_TIM8_TRGCO_HANDLER VectorF4
-#define STM32_TIM8_CC_HANDLER VectorF8
-
-#define STM32_TIM1_BRK_TIM15_NUMBER 24
-#define STM32_TIM1_UP_TIM16_NUMBER 25
-#define STM32_TIM1_TRGCO_TIM17_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_NUMBER 43
-#define STM32_TIM8_UP_NUMBER 44
-#define STM32_TIM8_TRGCO_NUMBER 45
-#define STM32_TIM8_CC_NUMBER 46
-
-/*
- * USART/UART 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_LPUART1_HANDLER Vector158
-
-#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_LPUART1_NUMBER 70
-
-/*
- * USB/OTG units.
- */
-#define STM32_OTG1_HANDLER Vector14C
-
-#define STM32_OTG1_NUMBER 67
-
-/*
- * DMA2D unit.
- */
-#define STM32_DMA2D_HANDLER Vector1A8
-
-#define STM32_DMA2D_NUMBER 90
-
-/*
- * FSMC unit.
- */
-#define STM32_FSMC_HANDLER Vector100
-
-#define STM32_FSMC_NUMBER 48
-
-/*
- * DCMI unit.
- */
-#define STM32_DCMI_HANDLER Vector14C
-
-#define STM32_DCMI_NUMBER 85
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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+/stm32_isr.h
+ * @brief STM32L4xx+ ISR handler header.
+ *
+ * @addtogroup STM32L4xxp_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_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC unit.
+ */
+#define STM32_ADC1_HANDLER Vector88
+
+#define STM32_ADC1_NUMBER 18
+
+/*
+ * CAN unit.
+ */
+#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_CAN1_TX_NUMBER 19
+#define STM32_CAN1_RX0_NUMBER 20
+#define STM32_CAN1_RX1_NUMBER 21
+#define STM32_CAN1_SCE_NUMBER 22
+
+/*
+ * DMA unit.
+ */
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH6_HANDLER Vector150
+#define STM32_DMA2_CH7_HANDLER Vector154
+
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+#define STM32_DMA2_CH6_NUMBER 68
+#define STM32_DMA2_CH7_NUMBER 69
+
+/*
+ * 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_EXTI1635_38_HANDLER Vector44 /* PVD PVM1 PVM4 */
+#define STM32_EXTI18_HANDLER VectorE4 /* RTC ALARM */
+#define STM32_EXTI19_HANDLER Vector48 /* RTC TAMP CSS */
+#define STM32_EXTI20_HANDLER Vector4C /* RTC WAKEUP */
+#define STM32_EXTI21_22_HANDLER Vector140 /* COMP1..2 */
+
+#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_EXTI1635_38_NUMBER 1
+#define STM32_EXTI18_NUMBER 41
+#define STM32_EXTI19_NUMBER 2
+#define STM32_EXTI20_NUMBER 3
+#define STM32_EXTI21_22_NUMBER 64
+
+/*
+ * 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_I2C4_ERROR_HANDLER Vector18C
+#define STM32_I2C4_EVENT_HANDLER Vector190
+
+#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
+#define STM32_I2C4_ERROR_NUMBER 83
+#define STM32_I2C4_EVENT_NUMBER 84
+
+
+/*
+ * OCTOSPI unit.
+ */
+#define STM32_OCTOSPI1_HANDLER Vector15C
+#define STM32_OCTOSPI2_HANDLER Vector170
+
+#define STM32_OCTOSPI1_NUMBER 71
+#define STM32_OCTOSPI2_NUMBER 76
+
+/*
+ * SDMMC unit.
+ */
+#define STM32_SDMMC1_HANDLER Vector104
+
+#define STM32_SDMMC1_NUMBER 49
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_BRK_TIM15_HANDLER VectorA0
+#define STM32_TIM1_UP_TIM16_HANDLER VectorA4
+#define STM32_TIM1_TRGCO_TIM17_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_HANDLER VectorEC
+#define STM32_TIM8_UP_HANDLER VectorF0
+#define STM32_TIM8_TRGCO_HANDLER VectorF4
+#define STM32_TIM8_CC_HANDLER VectorF8
+
+#define STM32_TIM1_BRK_TIM15_NUMBER 24
+#define STM32_TIM1_UP_TIM16_NUMBER 25
+#define STM32_TIM1_TRGCO_TIM17_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_NUMBER 43
+#define STM32_TIM8_UP_NUMBER 44
+#define STM32_TIM8_TRGCO_NUMBER 45
+#define STM32_TIM8_CC_NUMBER 46
+
+/*
+ * USART/UART 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_LPUART1_HANDLER Vector158
+
+#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_LPUART1_NUMBER 70
+
+/*
+ * USB/OTG units.
+ */
+#define STM32_OTG1_HANDLER Vector14C
+
+#define STM32_OTG1_NUMBER 67
+
+/*
+ * DMA2D unit.
+ */
+#define STM32_DMA2D_HANDLER Vector1A8
+
+#define STM32_DMA2D_NUMBER 90
+
+/*
+ * FSMC unit.
+ */
+#define STM32_FSMC_HANDLER Vector100
+
+#define STM32_FSMC_NUMBER 48
+
+/*
+ * DCMI unit.
+ */
+#define STM32_DCMI_HANDLER Vector14C
+
+#define STM32_DCMI_NUMBER 85
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32L4xx+/stm32_rcc.h b/os/hal/ports/STM32/STM32L4xx+/stm32_rcc.h
index a7c238aa65..92b38f3f1d 100644
--- a/os/hal/ports/STM32/STM32L4xx+/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L4xx+/stm32_rcc.h
@@ -1,1358 +1,1358 @@
-/*
- 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+/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32l4xx.h.
- *
- * @addtogroup STM32L4xx_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 (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R1(mask, lp) { \
- RCC->APB1ENR1 |= (mask); \
- if (lp) \
- RCC->APB1SMENR1 |= (mask); \
- else \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R1(mask) { \
- RCC->APB1ENR1 &= ~(mask); \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R1(mask) { \
- RCC->APB1RSTR1 |= (mask); \
- RCC->APB1RSTR1 &= ~(mask); \
- (void)RCC->APB1RSTR1; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R2(mask, lp) { \
- RCC->APB1ENR2 |= (mask); \
- if (lp) \
- RCC->APB1SMENR2 |= (mask); \
- else \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R2(mask) { \
- RCC->APB1ENR2 &= ~(mask); \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R2(mask) { \
- RCC->APB1RSTR2 |= (mask); \
- RCC->APB1RSTR2 &= ~(mask); \
- (void)RCC->APB1RSTR2; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB2 bus.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- if (lp) \
- RCC->APB2SMENR |= (mask); \
- else \
- RCC->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->AHB1SMENR |= (mask); \
- else \
- RCC->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB2SMENR |= (mask); \
- else \
- RCC->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB3SMENR |= (mask); \
- else \
- RCC->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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 Enables the ADC1/ADC2/ADC3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC123(lp) rccEnableAHB2(RCC_AHB2ENR_ADCEN, lp)
-
-/**
- * @brief Disables the ADC1/ADC2/ADC3 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC123() rccDisableAHB2(RCC_AHB2ENR_ADCEN)
-
-/**
- * @brief Resets the ADC1/ADC2/ADC3 peripheral.
- *
- * @api
- */
-#define rccResetADC123() rccResetAHB2(RCC_AHB2RSTR_ADCRST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC1(lp) rccEnableAPB1R1(RCC_APB1ENR1_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPB1R1(RCC_APB1ENR1_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPB1R1(RCC_APB1RSTR1_DAC1RST)
-/** @} */
-
-/**
- * @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 DMAMUX peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMAMUX peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMAMUX(lp) rccEnableAHB1(RCC_AHB1ENR_DMAMUX1EN, lp)
-
-/**
- * @brief Disables the DMAMUX peripheral clock.
- *
- * @api
- */
-#define rccDisableDMAMUX() rccDisableAHB1(RCC_AHB1ENR_DMAMUX1EN)
-
-/**
- * @brief Resets the DMAMUX peripheral.
- *
- * @api
- */
-#define rccResetDMAMUX() rccResetAHB1(RCC_AHB1RSTR_DMAMUX1RST)
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
-
-/**
- * @brief Disables PWR interface clock.
- *
- * @api
- */
-#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
-
-/**
- * @brief Resets the PWR interface.
- *
- * @api
- */
-#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
-/** @} */
-
-/**
- * @name CAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CAN1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN1(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN1EN, lp)
-
-/**
- * @brief Disables the CAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN1() rccDisableAPB1R1(RCC_APB1ENR1_CAN1EN)
-
-/**
- * @brief Resets the CAN1 peripheral.
- *
- * @api
- */
-#define rccResetCAN1() rccResetAPB1R1(RCC_APB1RSTR1_CAN1RST)
-
-/**
- * @brief Enables the CAN2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN2(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN2EN, lp)
-
-/**
- * @brief Disables the CAN2 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN2() rccDisableAPB1R1(RCC_APB1ENR1_CAN2EN)
-
-/**
- * @brief Resets the CAN2 peripheral.
- *
- * @api
- */
-#define rccResetCAN2() rccResetAPB1R1(RCC_APB1RSTR1_CAN2RST)
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
-
-/**
- * @brief Disables the I2C1 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
-
-/**
- * @brief Resets the I2C1 peripheral.
- *
- * @api
- */
-#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
-
-/**
- * @brief Enables the I2C2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
-
-/**
- * @brief Disables the I2C2 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
-
-/**
- * @brief Resets the I2C2 peripheral.
- *
- * @api
- */
-#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
-
-/**
- * @brief Enables the I2C3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
-
-/**
- * @brief Disables the I2C3 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
-
-/**
- * @brief Resets the I2C3 peripheral.
- *
- * @api
- */
-#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
-
-/**
- * @brief Enables the I2C4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
-
-/**
- * @brief Disables the I2C4 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
-
-/**
- * @brief Resets the I2C4 peripheral.
- *
- * @api
- */
-#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @name OCTOSPI peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the OCTOSPI1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableOCTOSPI1(lp) rccEnableAHB3(RCC_AHB3ENR_OSPI1EN, lp)
-
-/**
- * @brief Disables the OCTOSPI1 peripheral clock.
- *
- * @api
- */
-#define rccDisableOCTOSPI1() rccDisableAHB3(RCC_AHB3ENR_OSPI1EN)
-
-/**
- * @brief Resets the OCTOSPI1 peripheral.
- *
- * @api
- */
-#define rccResetOCTOSPI1() rccResetAHB3(RCC_AHB3RSTR_OSPI1RST)
-
-/**
- * @brief Enables the OCTOSPI2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableOCTOSPI2(lp) rccEnableAHB3(RCC_AHB3ENR_OSPI2EN, lp)
-
-/**
- * @brief Disables the OCTOSPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableOCTOSPI2() rccDisableAHB3(RCC_AHB3ENR_OSPI2EN)
-
-/**
- * @brief Resets the OCTOSPI1 peripheral.
- *
- * @api
- */
-#define rccResetOCTOSPI2() rccResetAHB3(RCC_AHB3RSTR_OSPI2RST)
-/** @} */
-
-/**
- * @name RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
-/** @} */
-
-/**
- * @name SDMMC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDMMC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC1(lp) rccEnableAHB2(RCC_AHB2ENR_SDMMC1EN, lp)
-
-/**
- * @brief Disables the SDMMC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC1() rccDisableAHB2(RCC_AHB2ENR_SDMMC1EN)
-
-/**
- * @brief Resets the SDMMC1 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC1() rccResetAHB2(RCC_AHB2RSTR_SDMMC1RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
-
-/**
- * @brief Disables the SPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
-
-/**
- * @brief Resets the SPI2 peripheral.
- *
- * @api
- */
-#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
-
-/**
- * @brief Enables the SPI3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
-
-/**
- * @brief Disables the SPI3 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
-
-/**
- * @brief Resets the SPI3 peripheral.
- *
- * @api
- */
-#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_SPI3RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
-
-/**
- * @brief Disables the TIM2 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
-
-/**
- * @brief Resets the TIM2 peripheral.
- *
- * @api
- */
-#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
-
-/**
- * @brief Enables the TIM3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
-
-/**
- * @brief Disables the TIM3 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
-
-/**
- * @brief Enables the TIM4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
-
-/**
- * @brief Disables the TIM4 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
-
-/**
- * @brief Resets the TIM4 peripheral.
- *
- * @api
- */
-#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
-
-/**
- * @brief Enables the TIM5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
-
-/**
- * @brief Disables the TIM5 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
-
-/**
- * @brief Resets the TIM5 peripheral.
- *
- * @api
- */
-#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
-
-/**
- * @brief Enables the TIM6 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
-
-/**
- * @brief Disables the TIM6 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
-
-/**
- * @brief Resets the TIM6 peripheral.
- *
- * @api
- */
-#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
-
-/**
- * @brief Enables the TIM7 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
-
-/**
- * @brief Disables the TIM7 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
-
-/**
- * @brief Resets the TIM7 peripheral.
- *
- * @api
- */
-#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
-
-/**
- * @brief Disables the USART2 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
-
-/**
- * @brief Resets the USART2 peripheral.
- *
- * @api
- */
-#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
-
-/**
- * @brief Enables the USART3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
-
-/**
- * @brief Disables the USART3 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
-
-/**
- * @brief Resets the USART3 peripheral.
- *
- * @api
- */
-#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
-
-/**
- * @brief Enables the UART4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
-
-/**
- * @brief Enables the UART5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
-
-/**
- * @brief Disables the UART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
-
-/**
- * @brief Resets the UART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBFSEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBFSEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBFSRST)
-/** @} */
-
-/**
- * @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
- */
-#define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
-
-/**
- * @brief Disables the FSMC peripheral clock.
- *
- * @api
- */
-#define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
-
-/**
- * @brief Resets the FSMC peripheral.
- *
- * @api
- */
-#define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
-/** @} */
-
-/**
- * @name DCMI peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DCMI peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDCMI(lp) rccEnableAHB2(RCC_AHB2ENR_DCMIEN, lp)
-
-/**
- * @brief Disables the DCMI peripheral clock.
-+ *
-+ * @api
- */
-#define rccDisableDCMI() rccDisableAHB2(RCC_AHB2ENR_DCMIEN)
-
-/**
- * @brief Resets the DCMI peripheral.
- *
- * @api
- */
-#define rccResetDCMI() rccResetAHB2(RCC_AHB2RSTR_DCMIRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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+/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32l4xx.h.
+ *
+ * @addtogroup STM32L4xx_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 (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R1(mask, lp) { \
+ RCC->APB1ENR1 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR1 |= (mask); \
+ else \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R1(mask) { \
+ RCC->APB1ENR1 &= ~(mask); \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R1(mask) { \
+ RCC->APB1RSTR1 |= (mask); \
+ RCC->APB1RSTR1 &= ~(mask); \
+ (void)RCC->APB1RSTR1; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R2(mask, lp) { \
+ RCC->APB1ENR2 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR2 |= (mask); \
+ else \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R2(mask) { \
+ RCC->APB1ENR2 &= ~(mask); \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R2(mask) { \
+ RCC->APB1RSTR2 |= (mask); \
+ RCC->APB1RSTR2 &= ~(mask); \
+ (void)RCC->APB1RSTR2; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB2 bus.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ if (lp) \
+ RCC->APB2SMENR |= (mask); \
+ else \
+ RCC->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR |= (mask); \
+ else \
+ RCC->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR |= (mask); \
+ else \
+ RCC->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR |= (mask); \
+ else \
+ RCC->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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 Enables the ADC1/ADC2/ADC3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC123(lp) rccEnableAHB2(RCC_AHB2ENR_ADCEN, lp)
+
+/**
+ * @brief Disables the ADC1/ADC2/ADC3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC123() rccDisableAHB2(RCC_AHB2ENR_ADCEN)
+
+/**
+ * @brief Resets the ADC1/ADC2/ADC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC123() rccResetAHB2(RCC_AHB2RSTR_ADCRST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC1(lp) rccEnableAPB1R1(RCC_APB1ENR1_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPB1R1(RCC_APB1ENR1_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPB1R1(RCC_APB1RSTR1_DAC1RST)
+/** @} */
+
+/**
+ * @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 DMAMUX peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMAMUX peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMAMUX(lp) rccEnableAHB1(RCC_AHB1ENR_DMAMUX1EN, lp)
+
+/**
+ * @brief Disables the DMAMUX peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMAMUX() rccDisableAHB1(RCC_AHB1ENR_DMAMUX1EN)
+
+/**
+ * @brief Resets the DMAMUX peripheral.
+ *
+ * @api
+ */
+#define rccResetDMAMUX() rccResetAHB1(RCC_AHB1RSTR_DMAMUX1RST)
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
+
+/**
+ * @brief Disables PWR interface clock.
+ *
+ * @api
+ */
+#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
+
+/**
+ * @brief Resets the PWR interface.
+ *
+ * @api
+ */
+#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
+/** @} */
+
+/**
+ * @name CAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CAN1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN1(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN1EN, lp)
+
+/**
+ * @brief Disables the CAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN1() rccDisableAPB1R1(RCC_APB1ENR1_CAN1EN)
+
+/**
+ * @brief Resets the CAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN1() rccResetAPB1R1(RCC_APB1RSTR1_CAN1RST)
+
+/**
+ * @brief Enables the CAN2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN2(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN2EN, lp)
+
+/**
+ * @brief Disables the CAN2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN2() rccDisableAPB1R1(RCC_APB1ENR1_CAN2EN)
+
+/**
+ * @brief Resets the CAN2 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN2() rccResetAPB1R1(RCC_APB1RSTR1_CAN2RST)
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
+
+/**
+ * @brief Disables the I2C1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
+
+/**
+ * @brief Resets the I2C1 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
+
+/**
+ * @brief Enables the I2C2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
+
+/**
+ * @brief Disables the I2C2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
+
+/**
+ * @brief Resets the I2C2 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
+
+/**
+ * @brief Enables the I2C3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
+
+/**
+ * @brief Disables the I2C3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
+
+/**
+ * @brief Resets the I2C3 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
+
+/**
+ * @brief Enables the I2C4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
+
+/**
+ * @brief Disables the I2C4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
+
+/**
+ * @brief Resets the I2C4 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @name OCTOSPI peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the OCTOSPI1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableOCTOSPI1(lp) rccEnableAHB3(RCC_AHB3ENR_OSPI1EN, lp)
+
+/**
+ * @brief Disables the OCTOSPI1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableOCTOSPI1() rccDisableAHB3(RCC_AHB3ENR_OSPI1EN)
+
+/**
+ * @brief Resets the OCTOSPI1 peripheral.
+ *
+ * @api
+ */
+#define rccResetOCTOSPI1() rccResetAHB3(RCC_AHB3RSTR_OSPI1RST)
+
+/**
+ * @brief Enables the OCTOSPI2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableOCTOSPI2(lp) rccEnableAHB3(RCC_AHB3ENR_OSPI2EN, lp)
+
+/**
+ * @brief Disables the OCTOSPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableOCTOSPI2() rccDisableAHB3(RCC_AHB3ENR_OSPI2EN)
+
+/**
+ * @brief Resets the OCTOSPI1 peripheral.
+ *
+ * @api
+ */
+#define rccResetOCTOSPI2() rccResetAHB3(RCC_AHB3RSTR_OSPI2RST)
+/** @} */
+
+/**
+ * @name RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
+/** @} */
+
+/**
+ * @name SDMMC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDMMC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC1(lp) rccEnableAHB2(RCC_AHB2ENR_SDMMC1EN, lp)
+
+/**
+ * @brief Disables the SDMMC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC1() rccDisableAHB2(RCC_AHB2ENR_SDMMC1EN)
+
+/**
+ * @brief Resets the SDMMC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC1() rccResetAHB2(RCC_AHB2RSTR_SDMMC1RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
+
+/**
+ * @brief Disables the SPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
+
+/**
+ * @brief Resets the SPI2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
+
+/**
+ * @brief Enables the SPI3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
+
+/**
+ * @brief Disables the SPI3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
+
+/**
+ * @brief Resets the SPI3 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_SPI3RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
+
+/**
+ * @brief Disables the TIM2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
+
+/**
+ * @brief Resets the TIM2 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
+
+/**
+ * @brief Enables the TIM3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
+
+/**
+ * @brief Disables the TIM3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
+
+/**
+ * @brief Resets the TIM3 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
+
+/**
+ * @brief Enables the TIM4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
+
+/**
+ * @brief Disables the TIM4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
+
+/**
+ * @brief Resets the TIM4 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
+
+/**
+ * @brief Enables the TIM5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
+
+/**
+ * @brief Disables the TIM5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
+
+/**
+ * @brief Resets the TIM5 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
+
+/**
+ * @brief Enables the TIM6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
+
+/**
+ * @brief Disables the TIM6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
+
+/**
+ * @brief Resets the TIM6 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
+
+/**
+ * @brief Enables the TIM7 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
+
+/**
+ * @brief Disables the TIM7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
+
+/**
+ * @brief Resets the TIM7 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
+
+/**
+ * @brief Disables the USART2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
+
+/**
+ * @brief Resets the USART2 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
+
+/**
+ * @brief Enables the USART3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
+
+/**
+ * @brief Disables the USART3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
+
+/**
+ * @brief Resets the USART3 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
+
+/**
+ * @brief Enables the UART4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
+
+/**
+ * @brief Enables the UART5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
+
+/**
+ * @brief Disables the UART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
+
+/**
+ * @brief Resets the UART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBFSEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBFSEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBFSRST)
+/** @} */
+
+/**
+ * @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
+ */
+#define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
+
+/**
+ * @brief Disables the FSMC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
+
+/**
+ * @brief Resets the FSMC peripheral.
+ *
+ * @api
+ */
+#define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
+/** @} */
+
+/**
+ * @name DCMI peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DCMI peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDCMI(lp) rccEnableAHB2(RCC_AHB2ENR_DCMIEN, lp)
+
+/**
+ * @brief Disables the DCMI peripheral clock.
++ *
++ * @api
+ */
+#define rccDisableDCMI() rccDisableAHB2(RCC_AHB2ENR_DCMIEN)
+
+/**
+ * @brief Resets the DCMI peripheral.
+ *
+ * @api
+ */
+#define rccResetDCMI() rccResetAHB2(RCC_AHB2RSTR_DCMIRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h
index 88673699c7..124f335173 100644
--- a/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L4xx+/stm32_registry.h
@@ -1,282 +1,282 @@
-/*
- 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+/stm32_registry.h
- * @brief STM32L4xx+ capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32L4xx+ capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 128
-#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 18
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
-} while (false)
-
-#if defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) || \
- defined(__DOXYGEN__)
-#define STM32_HAS_HASH1 TRUE
-#define STM32_HAS_CRYP1 TRUE
-#else
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-/* I2C attributes.*/
-#define STM32_I2C4_USE_BDMA FALSE
-
-/*===========================================================================*/
-/* STM32L4yyxx+. */
-/*===========================================================================*/
-
-#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || \
- defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) || \
- defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_CAN_MAX_FILTERS 14
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 7
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 41
-#define STM32_EXTI_IMR1_MASK 0xFF820000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOFEN | \
- RCC_AHB2ENR_GPIOGEN | \
- RCC_AHB2ENR_GPIOHEN | \
- RCC_AHB2ENR_GPIOIEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 TRUE
-#define STM32_HAS_I2C4 TRUE
-
-/* OCTOSPI attributes.*/
-#define STM32_HAS_OCTOSPI1 TRUE
-#define STM32_HAS_OCTOSPI2 TRUE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 2
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 2
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_UART5 TRUE
-#define STM32_HAS_LPUART1 TRUE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* 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 FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI TRUE
-
-#endif /* defined(STM32L4R5xx) || defined(STM32L4R7xx) ||
- defined(STM32L4R9xx) || defined(STM32L4S5xx) ||
- defined(STM32L4S7xx) || defined(STM32L4S9xx) */
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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+/stm32_registry.h
+ * @brief STM32L4xx+ capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32L4xx+ capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
+#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 18
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
+} while (false)
+
+#if defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) || \
+ defined(__DOXYGEN__)
+#define STM32_HAS_HASH1 TRUE
+#define STM32_HAS_CRYP1 TRUE
+#else
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+/* I2C attributes.*/
+#define STM32_I2C4_USE_BDMA FALSE
+
+/*===========================================================================*/
+/* STM32L4yyxx+. */
+/*===========================================================================*/
+
+#if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || \
+ defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) || \
+ defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_CAN_MAX_FILTERS 14
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 7
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 41
+#define STM32_EXTI_IMR1_MASK 0xFF820000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOFEN | \
+ RCC_AHB2ENR_GPIOGEN | \
+ RCC_AHB2ENR_GPIOHEN | \
+ RCC_AHB2ENR_GPIOIEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 TRUE
+#define STM32_HAS_I2C4 TRUE
+
+/* OCTOSPI attributes.*/
+#define STM32_HAS_OCTOSPI1 TRUE
+#define STM32_HAS_OCTOSPI2 TRUE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 2
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 2
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_UART5 TRUE
+#define STM32_HAS_LPUART1 TRUE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* 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 FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI TRUE
+
+#endif /* defined(STM32L4R5xx) || defined(STM32L4R7xx) ||
+ defined(STM32L4R9xx) || defined(STM32L4S5xx) ||
+ defined(STM32L4S7xx) || defined(STM32L4S9xx) */
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c b/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
index 6ea46f8b14..7c534e7629 100644
--- a/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
+++ b/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
@@ -1,542 +1,542 @@
-/*
- 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 hal_efl_lld.c
- * @brief STM32L4xx 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_SECTOR_SIZE 2048U
-#define STM32_FLASH_LINE_SIZE 8U
-#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
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/**
- * @brief EFL1 driver identifier.
- */
-EFlashDriver EFLD1;
-
-/*===========================================================================*/
-/* Driver local variables and types. */
-/*===========================================================================*/
-
-static const flash_descriptor_t efl_lld_descriptor = {
- .attributes = FLASH_ATTR_ERASED_IS_ONE |
- FLASH_ATTR_MEMORY_MAPPED |
- FLASH_ATTR_ECC_CAPABLE |
- FLASH_ATTR_ECC_ZERO_LINE_CAPABLE,
- .page_size = STM32_FLASH_LINE_SIZE,
- .sectors_count = STM32_FLASH_NUMBER_OF_BANKS *
- STM32_FLASH_SECTORS_PER_BANK,
- .sectors = NULL,
- .sectors_size = STM32_FLASH_SECTOR_SIZE,
- .address = (uint8_t *)0x08000000U,
- .size = STM32_FLASH_NUMBER_OF_BANKS *
- STM32_FLASH_SECTORS_PER_BANK *
- STM32_FLASH_SECTOR_SIZE
-};
-
-/*===========================================================================*/
-/* 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) {
-
- 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 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 & (FLASH_SR_FASTERR |
- FLASH_SR_MISERR |
- FLASH_SR_SIZERR)) == 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_PROGERR | 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;
-}
-
-/**
- * @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.
- *
- * @notapi
- */
-const flash_descriptor_t *efl_lld_get_descriptor(void *instance) {
-
- (void)instance;
-
- return &efl_lld_descriptor;
-}
-
-/**
- * @brief Read operation.
- *
- * @param[in] ip pointer to a @p EFlashDriver instance
- * @param[in] offset flash offset
- * @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));
- osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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_READY 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_descriptor.address + offset, n);
-
- /* Checking for errors after reading.*/
- if ((devp->flash->SR & FLASH_SR_RDERR) != 0U) {
- err = FLASH_ERROR_READ;
- }
-
- /* Ready state again.*/
- devp->state = FLASH_READY;
-
- return err;
-
-}
-
-/**
- * @brief Program operation.
- * @note The device supports ECC, it is only possible to write erased
- * pages once except when writing all zeroes.
- *
- * @param[in] ip pointer to a @p EFlashDriver instance
- * @param[in] offset flash offset
- * @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;
- flash_error_t err = FLASH_NO_ERROR;
-
- osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
- osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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;
-
- union {
- uint32_t w[STM32_FLASH_LINE_SIZE / sizeof (uint32_t)];
- uint8_t b[STM32_FLASH_LINE_SIZE / sizeof (uint8_t)];
- } line;
-
- /* Unwritten bytes are initialized to all ones.*/
- line.w[0] = 0xFFFFFFFFU;
- line.w[1] = 0xFFFFFFFFU;
-
- /* Programming address aligned to flash lines.*/
- address = (volatile uint32_t *)(efl_lld_descriptor.address +
- (offset & ~STM32_FLASH_LINE_MASK));
-
- /* Copying data inside the prepared line.*/
- do {
- line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
- offset++;
- n--;
- pp++;
- }
- while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
-
- /* Programming line.*/
- address[0] = line.w[0];
- address[1] = line.w[1];
- 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 bank 2 if it is present. Bank 1 is not
- * touched because it is where the program is running on.
- * Pages on bank 1 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;
- }
-
- /* FLASH_PGM state while the operation is performed.*/
- devp->state = FLASH_ERASE;
-
- /* Clearing error status bits.*/
- stm32_flash_clear_status(devp);
-
-#if defined(FLASH_CR_MER2)
- devp->flash->CR |= FLASH_CR_MER2;
- devp->flash->CR |= FLASH_CR_STRT;
-#endif
-
- return FLASH_NO_ERROR;
-}
-
-/**
- * @brief Starts an sector erase operation.
- *
- * @param[in] ip pointer to a @p EFlashDriver instance
- * @param[in] sector sector to be erased
- * @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;
-
- osalDbgCheck(instance != NULL);
- osalDbgCheck(sector < efl_lld_descriptor.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 page erase.*/
- devp->flash->CR |= FLASH_CR_PER;
-
-#if defined(FLASH_CR_BKER)
- /* Bank selection.*/
- if (sector < STM32_FLASH_SECTORS_PER_BANK) {
- /* First bank.*/
- devp->flash->CR &= ~FLASH_CR_BKER;
- }
- else {
- /* Second bank.*/
- devp->flash->CR |= FLASH_CR_BKER;
- }
-#endif
-
- /* Mask off the page selection bits.*/
- devp->flash->CR &= ~FLASH_CR_PNB;
-
- /* Set the page selection bits.*/
- devp->flash->CR |= sector << FLASH_CR_PNB_Pos;
-
- /* Start the erase.*/
- devp->flash->CR |= FLASH_CR_STRT;
-
- return FLASH_NO_ERROR;
-}
-
-/**
- * @brief Queries the driver for erase operation progress.
- *
- * @param[in] ip 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_MER1 |
-#if defined(FLASH_CR_MER2)
- FLASH_CR_MER2 |
-#endif
- FLASH_CR_PER);
-
- /* 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;
- flash_error_t err = FLASH_NO_ERROR;
- unsigned i;
-
- osalDbgCheck(instance != NULL);
- osalDbgCheck(sector < efl_lld_descriptor.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.*/
- address = (uint32_t *)(efl_lld_descriptor.address +
- flashGetSectorOffset(getBaseFlash(devp), sector));
-
- /* FLASH_READY state while the operation is performed.*/
- devp->state = FLASH_READ;
-
- /* Scanning the sector space.*/
- for (i = 0U; i < STM32_FLASH_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 */
-
-/** @} */
+/*
+ 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 hal_efl_lld.c
+ * @brief STM32L4xx 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_SECTOR_SIZE 2048U
+#define STM32_FLASH_LINE_SIZE 8U
+#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
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EFL1 driver identifier.
+ */
+EFlashDriver EFLD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+static const flash_descriptor_t efl_lld_descriptor = {
+ .attributes = FLASH_ATTR_ERASED_IS_ONE |
+ FLASH_ATTR_MEMORY_MAPPED |
+ FLASH_ATTR_ECC_CAPABLE |
+ FLASH_ATTR_ECC_ZERO_LINE_CAPABLE,
+ .page_size = STM32_FLASH_LINE_SIZE,
+ .sectors_count = STM32_FLASH_NUMBER_OF_BANKS *
+ STM32_FLASH_SECTORS_PER_BANK,
+ .sectors = NULL,
+ .sectors_size = STM32_FLASH_SECTOR_SIZE,
+ .address = (uint8_t *)0x08000000U,
+ .size = STM32_FLASH_NUMBER_OF_BANKS *
+ STM32_FLASH_SECTORS_PER_BANK *
+ STM32_FLASH_SECTOR_SIZE
+};
+
+/*===========================================================================*/
+/* 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) {
+
+ 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 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 & (FLASH_SR_FASTERR |
+ FLASH_SR_MISERR |
+ FLASH_SR_SIZERR)) == 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_PROGERR | 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;
+}
+
+/**
+ * @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.
+ *
+ * @notapi
+ */
+const flash_descriptor_t *efl_lld_get_descriptor(void *instance) {
+
+ (void)instance;
+
+ return &efl_lld_descriptor;
+}
+
+/**
+ * @brief Read operation.
+ *
+ * @param[in] ip pointer to a @p EFlashDriver instance
+ * @param[in] offset flash offset
+ * @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));
+ osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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_READY 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_descriptor.address + offset, n);
+
+ /* Checking for errors after reading.*/
+ if ((devp->flash->SR & FLASH_SR_RDERR) != 0U) {
+ err = FLASH_ERROR_READ;
+ }
+
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ return err;
+
+}
+
+/**
+ * @brief Program operation.
+ * @note The device supports ECC, it is only possible to write erased
+ * pages once except when writing all zeroes.
+ *
+ * @param[in] ip pointer to a @p EFlashDriver instance
+ * @param[in] offset flash offset
+ * @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;
+ flash_error_t err = FLASH_NO_ERROR;
+
+ osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
+ osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.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;
+
+ union {
+ uint32_t w[STM32_FLASH_LINE_SIZE / sizeof (uint32_t)];
+ uint8_t b[STM32_FLASH_LINE_SIZE / sizeof (uint8_t)];
+ } line;
+
+ /* Unwritten bytes are initialized to all ones.*/
+ line.w[0] = 0xFFFFFFFFU;
+ line.w[1] = 0xFFFFFFFFU;
+
+ /* Programming address aligned to flash lines.*/
+ address = (volatile uint32_t *)(efl_lld_descriptor.address +
+ (offset & ~STM32_FLASH_LINE_MASK));
+
+ /* Copying data inside the prepared line.*/
+ do {
+ line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
+ offset++;
+ n--;
+ pp++;
+ }
+ while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
+
+ /* Programming line.*/
+ address[0] = line.w[0];
+ address[1] = line.w[1];
+ 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 bank 2 if it is present. Bank 1 is not
+ * touched because it is where the program is running on.
+ * Pages on bank 1 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;
+ }
+
+ /* FLASH_PGM state while the operation is performed.*/
+ devp->state = FLASH_ERASE;
+
+ /* Clearing error status bits.*/
+ stm32_flash_clear_status(devp);
+
+#if defined(FLASH_CR_MER2)
+ devp->flash->CR |= FLASH_CR_MER2;
+ devp->flash->CR |= FLASH_CR_STRT;
+#endif
+
+ return FLASH_NO_ERROR;
+}
+
+/**
+ * @brief Starts an sector erase operation.
+ *
+ * @param[in] ip pointer to a @p EFlashDriver instance
+ * @param[in] sector sector to be erased
+ * @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;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgCheck(sector < efl_lld_descriptor.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 page erase.*/
+ devp->flash->CR |= FLASH_CR_PER;
+
+#if defined(FLASH_CR_BKER)
+ /* Bank selection.*/
+ if (sector < STM32_FLASH_SECTORS_PER_BANK) {
+ /* First bank.*/
+ devp->flash->CR &= ~FLASH_CR_BKER;
+ }
+ else {
+ /* Second bank.*/
+ devp->flash->CR |= FLASH_CR_BKER;
+ }
+#endif
+
+ /* Mask off the page selection bits.*/
+ devp->flash->CR &= ~FLASH_CR_PNB;
+
+ /* Set the page selection bits.*/
+ devp->flash->CR |= sector << FLASH_CR_PNB_Pos;
+
+ /* Start the erase.*/
+ devp->flash->CR |= FLASH_CR_STRT;
+
+ return FLASH_NO_ERROR;
+}
+
+/**
+ * @brief Queries the driver for erase operation progress.
+ *
+ * @param[in] ip 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_MER1 |
+#if defined(FLASH_CR_MER2)
+ FLASH_CR_MER2 |
+#endif
+ FLASH_CR_PER);
+
+ /* 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;
+ flash_error_t err = FLASH_NO_ERROR;
+ unsigned i;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgCheck(sector < efl_lld_descriptor.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.*/
+ address = (uint32_t *)(efl_lld_descriptor.address +
+ flashGetSectorOffset(getBaseFlash(devp), sector));
+
+ /* FLASH_READY state while the operation is performed.*/
+ devp->state = FLASH_READ;
+
+ /* Scanning the sector space.*/
+ for (i = 0U; i < STM32_FLASH_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/STM32/STM32L4xx/hal_efl_lld.h b/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.h
index 774e8ae457..5ee31c5b68 100644
--- a/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.h
+++ b/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.h
@@ -1,116 +1,116 @@
-/*
- 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 hal_efl_lld.h
- * @brief STM32L4xx 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 STM32L4xx 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(STM32_FLASH_NUMBER_OF_BANKS)
-#error "STM32_FLASH_NUMBER_OF_BANKS not defined in registry"
-#endif
-
-#if !defined(STM32_FLASH_SECTORS_PER_BANK)
-#error "STM32_FLASH_SECTORS_PER_BANK not defined in registry"
-#endif
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/**
- * @brief Low level fields of the embedded flash driver structure.
- */
-#define efl_lld_driver_fields \
- /* Flash registers.*/ \
- FLASH_TypeDef *flash
-
-/**
- * @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 */
-
-/** @} */
+/*
+ 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 hal_efl_lld.h
+ * @brief STM32L4xx 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 STM32L4xx 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(STM32_FLASH_NUMBER_OF_BANKS)
+#error "STM32_FLASH_NUMBER_OF_BANKS not defined in registry"
+#endif
+
+#if !defined(STM32_FLASH_SECTORS_PER_BANK)
+#error "STM32_FLASH_SECTORS_PER_BANK not defined in registry"
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level fields of the embedded flash driver structure.
+ */
+#define efl_lld_driver_fields \
+ /* Flash registers.*/ \
+ FLASH_TypeDef *flash
+
+/**
+ * @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/STM32/STM32L4xx/hal_lld.c b/os/hal/ports/STM32/STM32L4xx/hal_lld.c
index 4e3fc566b2..012337cf56 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 ((!FOME_STM32_LSE_WAIT_MAX || rusefiLseCounter++ < FOME_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 ? 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 */
+
+ /* 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..3d34317470 100644
--- a/os/hal/ports/STM32/STM32L4xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.h
@@ -1,2368 +1,2376 @@
-/*
- 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 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 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
+
+ #if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+ #error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+ #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_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/STM32L4xx/platform.mk b/os/hal/ports/STM32/STM32L4xx/platform.mk
index 5426ea32f6..9b1569ca94 100644
--- a/os/hal/ports/STM32/STM32L4xx/platform.mk
+++ b/os/hal/ports/STM32/STM32L4xx/platform.mk
@@ -1,49 +1,49 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx
-
-# 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/ADCv3/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/DMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/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/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx
+
+# 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/ADCv3/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/DMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/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/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/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/STM32L4xx/platform_l432.mk b/os/hal/ports/STM32/STM32L4xx/platform_l432.mk
index 960c70fa15..f3282c5e5d 100644
--- a/os/hal/ports/STM32/STM32L4xx/platform_l432.mk
+++ b/os/hal/ports/STM32/STM32L4xx/platform_l432.mk
@@ -1,48 +1,48 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx
-
-# 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/ADCv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx/hal_efl_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L4xx
+
+# 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/ADCv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/CANv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv3/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RNGv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SDMMCv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/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/STM32L4xx/stm32_isr.c b/os/hal/ports/STM32/STM32L4xx/stm32_isr.c
index 291a6c2871..68ab519f9e 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_isr.c
@@ -1,159 +1,159 @@
-/*
- 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/stm32_isr.c
- * @brief STM32L4xx ISR handler code.
- *
- * @addtogroup STM32L4xx_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. */
-/*===========================================================================*/
-
-#include "stm32_exti0.inc"
-#include "stm32_exti1.inc"
-#include "stm32_exti2.inc"
-#include "stm32_exti3.inc"
-#include "stm32_exti4.inc"
-#include "stm32_exti5_9.inc"
-#include "stm32_exti10_15.inc"
-#include "stm32_exti16-35_38.inc"
-#include "stm32_exti18.inc"
-#include "stm32_exti19.inc"
-#include "stm32_exti20.inc"
-#include "stm32_exti21_22.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart3.inc"
-#include "stm32_uart4.inc"
-#include "stm32_uart5.inc"
-#include "stm32_lpuart1.inc"
-
-#include "stm32_tim1_15_16_17.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim4.inc"
-#include "stm32_tim5.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim8.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_irq_init();
- exti1_irq_init();
- exti2_irq_init();
- exti3_irq_init();
- exti4_irq_init();
- exti5_9_irq_init();
- exti10_15_irq_init();
- exti16_exti35_38_irq_init();
- exti18_irq_init();
- exti19_irq_init();
- exti21_22_irq_init();
-
- tim1_tim15_tim16_tim17_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim4_irq_init();
- tim5_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim8_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_irq_init();
- uart4_irq_init();
- uart5_irq_init();
- lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_irq_deinit();
- exti1_irq_deinit();
- exti2_irq_deinit();
- exti3_irq_deinit();
- exti4_irq_deinit();
- exti5_9_irq_deinit();
- exti10_15_irq_deinit();
- exti16_exti35_38_irq_deinit();
- exti18_irq_deinit();
- exti19_irq_deinit();
- exti21_22_irq_deinit();
-
- tim1_tim15_tim16_tim17_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim4_irq_deinit();
- tim5_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim8_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_irq_deinit();
- uart4_irq_deinit();
- uart5_irq_deinit();
- lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32L4xx ISR handler code.
+ *
+ * @addtogroup STM32L4xx_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. */
+/*===========================================================================*/
+
+#include "stm32_exti0.inc"
+#include "stm32_exti1.inc"
+#include "stm32_exti2.inc"
+#include "stm32_exti3.inc"
+#include "stm32_exti4.inc"
+#include "stm32_exti5_9.inc"
+#include "stm32_exti10_15.inc"
+#include "stm32_exti16-35_38.inc"
+#include "stm32_exti18.inc"
+#include "stm32_exti19.inc"
+#include "stm32_exti20.inc"
+#include "stm32_exti21_22.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart3.inc"
+#include "stm32_uart4.inc"
+#include "stm32_uart5.inc"
+#include "stm32_lpuart1.inc"
+
+#include "stm32_tim1_15_16_17.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim4.inc"
+#include "stm32_tim5.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim8.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_irq_init();
+ exti1_irq_init();
+ exti2_irq_init();
+ exti3_irq_init();
+ exti4_irq_init();
+ exti5_9_irq_init();
+ exti10_15_irq_init();
+ exti16_exti35_38_irq_init();
+ exti18_irq_init();
+ exti19_irq_init();
+ exti21_22_irq_init();
+
+ tim1_tim15_tim16_tim17_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim4_irq_init();
+ tim5_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim8_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_irq_init();
+ uart4_irq_init();
+ uart5_irq_init();
+ lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_irq_deinit();
+ exti1_irq_deinit();
+ exti2_irq_deinit();
+ exti3_irq_deinit();
+ exti4_irq_deinit();
+ exti5_9_irq_deinit();
+ exti10_15_irq_deinit();
+ exti16_exti35_38_irq_deinit();
+ exti18_irq_deinit();
+ exti19_irq_deinit();
+ exti21_22_irq_deinit();
+
+ tim1_tim15_tim16_tim17_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim4_irq_deinit();
+ tim5_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim8_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_irq_deinit();
+ uart4_irq_deinit();
+ uart5_irq_deinit();
+ lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_isr.h b/os/hal/ports/STM32/STM32L4xx/stm32_isr.h
index f4a629435f..9230352d91 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_isr.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.
-*/
-
-/**
- * @file STM32L4xx/stm32_isr.h
- * @brief STM32L4xx ISR handler header.
- *
- * @addtogroup SRM32L4xx_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_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC unit.
- */
-#define STM32_ADC1_HANDLER Vector88
-#define STM32_ADC2_HANDLER Vector88
-#define STM32_ADC3_HANDLER VectorFC
-
-#define STM32_ADC1_NUMBER 18
-#define STM32_ADC2_NUMBER 18
-#define STM32_ADC3_NUMBER 47
-
-/*
- * CAN unit.
- */
-#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 Vector198
-#define STM32_CAN2_RX0_HANDLER Vector19C
-#define STM32_CAN2_RX1_HANDLER Vector1A0
-#define STM32_CAN2_SCE_HANDLER Vector1A4
-
-#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 86
-#define STM32_CAN2_RX0_NUMBER 87
-#define STM32_CAN2_RX1_NUMBER 88
-#define STM32_CAN2_SCE_NUMBER 89
-
-/*
- * DMA unit.
- */
-#define STM32_DMA1_CH1_HANDLER Vector6C
-#define STM32_DMA1_CH2_HANDLER Vector70
-#define STM32_DMA1_CH3_HANDLER Vector74
-#define STM32_DMA1_CH4_HANDLER Vector78
-#define STM32_DMA1_CH5_HANDLER Vector7C
-#define STM32_DMA1_CH6_HANDLER Vector80
-#define STM32_DMA1_CH7_HANDLER Vector84
-#define STM32_DMA2_CH1_HANDLER Vector120
-#define STM32_DMA2_CH2_HANDLER Vector124
-#define STM32_DMA2_CH3_HANDLER Vector128
-#define STM32_DMA2_CH4_HANDLER Vector12C
-#define STM32_DMA2_CH5_HANDLER Vector130
-#define STM32_DMA2_CH6_HANDLER Vector150
-#define STM32_DMA2_CH7_HANDLER Vector154
-
-#define STM32_DMA1_CH1_NUMBER 11
-#define STM32_DMA1_CH2_NUMBER 12
-#define STM32_DMA1_CH3_NUMBER 13
-#define STM32_DMA1_CH4_NUMBER 14
-#define STM32_DMA1_CH5_NUMBER 15
-#define STM32_DMA1_CH6_NUMBER 16
-#define STM32_DMA1_CH7_NUMBER 17
-#define STM32_DMA2_CH1_NUMBER 56
-#define STM32_DMA2_CH2_NUMBER 57
-#define STM32_DMA2_CH3_NUMBER 58
-#define STM32_DMA2_CH4_NUMBER 59
-#define STM32_DMA2_CH5_NUMBER 60
-#define STM32_DMA2_CH6_NUMBER 68
-#define STM32_DMA2_CH7_NUMBER 69
-
-/*
- * 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_EXTI1635_38_HANDLER Vector44 /* PVD PVM1 PVM4 */
-#define STM32_EXTI18_HANDLER VectorE4 /* RTC ALARM */
-#define STM32_EXTI19_HANDLER Vector48 /* RTC TAMP CSS */
-#define STM32_EXTI20_HANDLER Vector4C /* RTC WAKEUP */
-#define STM32_EXTI21_22_HANDLER Vector140 /* COMP1..2 */
-
-#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_EXTI1635_38_NUMBER 1
-#define STM32_EXTI18_NUMBER 41
-#define STM32_EXTI19_NUMBER 2
-#define STM32_EXTI20_NUMBER 3
-#define STM32_EXTI21_22_NUMBER 64
-
-/*
- * 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_I2C4_EVENT_HANDLER Vector18C
-#define STM32_I2C4_ERROR_HANDLER Vector190
-
-#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
-#define STM32_I2C4_EVENT_NUMBER 83
-#define STM32_I2C4_ERROR_NUMBER 84
-
-/*
- * QUADSPI unit.
- */
-#define STM32_QUADSPI1_HANDLER Vector15C
-
-#define STM32_QUADSPI1_NUMBER 71
-
-/*
- * SDMMC unit.
- */
-#define STM32_SDMMC1_HANDLER Vector104
-
-#define STM32_SDMMC1_NUMBER 49
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_BRK_TIM15_HANDLER VectorA0
-#define STM32_TIM1_UP_TIM16_HANDLER VectorA4
-#define STM32_TIM1_TRGCO_TIM17_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_HANDLER VectorEC
-#define STM32_TIM8_UP_HANDLER VectorF0
-#define STM32_TIM8_TRGCO_HANDLER VectorF4
-#define STM32_TIM8_CC_HANDLER VectorF8
-
-#define STM32_TIM1_BRK_TIM15_NUMBER 24
-#define STM32_TIM1_UP_TIM16_NUMBER 25
-#define STM32_TIM1_TRGCO_TIM17_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_NUMBER 43
-#define STM32_TIM8_UP_NUMBER 44
-#define STM32_TIM8_TRGCO_NUMBER 45
-#define STM32_TIM8_CC_NUMBER 46
-
-/*
- * USART/UART 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_LPUART1_HANDLER Vector158
-
-#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_LPUART1_NUMBER 70
-
-/*
- * USB/OTG units.
- */
-#define STM32_USB1_HP_HANDLER Vector14C
-#define STM32_USB1_LP_HANDLER Vector14C
-#define STM32_OTG1_HANDLER Vector14C
-
-#define STM32_USB1_HP_NUMBER 67
-#define STM32_USB1_LP_NUMBER 67
-#define STM32_OTG1_NUMBER 67
-
-/*
- * DMA2D unit.
- */
-#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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32L4xx ISR handler header.
+ *
+ * @addtogroup SRM32L4xx_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_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC unit.
+ */
+#define STM32_ADC1_HANDLER Vector88
+#define STM32_ADC2_HANDLER Vector88
+#define STM32_ADC3_HANDLER VectorFC
+
+#define STM32_ADC1_NUMBER 18
+#define STM32_ADC2_NUMBER 18
+#define STM32_ADC3_NUMBER 47
+
+/*
+ * CAN unit.
+ */
+#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 Vector198
+#define STM32_CAN2_RX0_HANDLER Vector19C
+#define STM32_CAN2_RX1_HANDLER Vector1A0
+#define STM32_CAN2_SCE_HANDLER Vector1A4
+
+#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 86
+#define STM32_CAN2_RX0_NUMBER 87
+#define STM32_CAN2_RX1_NUMBER 88
+#define STM32_CAN2_SCE_NUMBER 89
+
+/*
+ * DMA unit.
+ */
+#define STM32_DMA1_CH1_HANDLER Vector6C
+#define STM32_DMA1_CH2_HANDLER Vector70
+#define STM32_DMA1_CH3_HANDLER Vector74
+#define STM32_DMA1_CH4_HANDLER Vector78
+#define STM32_DMA1_CH5_HANDLER Vector7C
+#define STM32_DMA1_CH6_HANDLER Vector80
+#define STM32_DMA1_CH7_HANDLER Vector84
+#define STM32_DMA2_CH1_HANDLER Vector120
+#define STM32_DMA2_CH2_HANDLER Vector124
+#define STM32_DMA2_CH3_HANDLER Vector128
+#define STM32_DMA2_CH4_HANDLER Vector12C
+#define STM32_DMA2_CH5_HANDLER Vector130
+#define STM32_DMA2_CH6_HANDLER Vector150
+#define STM32_DMA2_CH7_HANDLER Vector154
+
+#define STM32_DMA1_CH1_NUMBER 11
+#define STM32_DMA1_CH2_NUMBER 12
+#define STM32_DMA1_CH3_NUMBER 13
+#define STM32_DMA1_CH4_NUMBER 14
+#define STM32_DMA1_CH5_NUMBER 15
+#define STM32_DMA1_CH6_NUMBER 16
+#define STM32_DMA1_CH7_NUMBER 17
+#define STM32_DMA2_CH1_NUMBER 56
+#define STM32_DMA2_CH2_NUMBER 57
+#define STM32_DMA2_CH3_NUMBER 58
+#define STM32_DMA2_CH4_NUMBER 59
+#define STM32_DMA2_CH5_NUMBER 60
+#define STM32_DMA2_CH6_NUMBER 68
+#define STM32_DMA2_CH7_NUMBER 69
+
+/*
+ * 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_EXTI1635_38_HANDLER Vector44 /* PVD PVM1 PVM4 */
+#define STM32_EXTI18_HANDLER VectorE4 /* RTC ALARM */
+#define STM32_EXTI19_HANDLER Vector48 /* RTC TAMP CSS */
+#define STM32_EXTI20_HANDLER Vector4C /* RTC WAKEUP */
+#define STM32_EXTI21_22_HANDLER Vector140 /* COMP1..2 */
+
+#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_EXTI1635_38_NUMBER 1
+#define STM32_EXTI18_NUMBER 41
+#define STM32_EXTI19_NUMBER 2
+#define STM32_EXTI20_NUMBER 3
+#define STM32_EXTI21_22_NUMBER 64
+
+/*
+ * 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_I2C4_EVENT_HANDLER Vector18C
+#define STM32_I2C4_ERROR_HANDLER Vector190
+
+#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
+#define STM32_I2C4_EVENT_NUMBER 83
+#define STM32_I2C4_ERROR_NUMBER 84
+
+/*
+ * QUADSPI unit.
+ */
+#define STM32_QUADSPI1_HANDLER Vector15C
+
+#define STM32_QUADSPI1_NUMBER 71
+
+/*
+ * SDMMC unit.
+ */
+#define STM32_SDMMC1_HANDLER Vector104
+
+#define STM32_SDMMC1_NUMBER 49
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_BRK_TIM15_HANDLER VectorA0
+#define STM32_TIM1_UP_TIM16_HANDLER VectorA4
+#define STM32_TIM1_TRGCO_TIM17_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_HANDLER VectorEC
+#define STM32_TIM8_UP_HANDLER VectorF0
+#define STM32_TIM8_TRGCO_HANDLER VectorF4
+#define STM32_TIM8_CC_HANDLER VectorF8
+
+#define STM32_TIM1_BRK_TIM15_NUMBER 24
+#define STM32_TIM1_UP_TIM16_NUMBER 25
+#define STM32_TIM1_TRGCO_TIM17_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_NUMBER 43
+#define STM32_TIM8_UP_NUMBER 44
+#define STM32_TIM8_TRGCO_NUMBER 45
+#define STM32_TIM8_CC_NUMBER 46
+
+/*
+ * USART/UART 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_LPUART1_HANDLER Vector158
+
+#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_LPUART1_NUMBER 70
+
+/*
+ * USB/OTG units.
+ */
+#define STM32_USB1_HP_HANDLER Vector14C
+#define STM32_USB1_LP_HANDLER Vector14C
+#define STM32_OTG1_HANDLER Vector14C
+
+#define STM32_USB1_HP_NUMBER 67
+#define STM32_USB1_LP_NUMBER 67
+#define STM32_OTG1_NUMBER 67
+
+/*
+ * DMA2D unit.
+ */
+#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/STM32/STM32L4xx/stm32_rcc.h b/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h
index de3acfae65..5a18b91bbe 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_rcc.h
@@ -1,1279 +1,1279 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32l4xx.h.
- *
- * @addtogroup STM32L4xx_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 (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R1(mask, lp) { \
- RCC->APB1ENR1 |= (mask); \
- if (lp) \
- RCC->APB1SMENR1 |= (mask); \
- else \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R1(mask) { \
- RCC->APB1ENR1 &= ~(mask); \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R1(mask) { \
- RCC->APB1RSTR1 |= (mask); \
- RCC->APB1RSTR1 &= ~(mask); \
- (void)RCC->APB1RSTR1; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R2(mask, lp) { \
- RCC->APB1ENR2 |= (mask); \
- if (lp) \
- RCC->APB1SMENR2 |= (mask); \
- else \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R2(mask) { \
- RCC->APB1ENR2 &= ~(mask); \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R2(mask) { \
- RCC->APB1RSTR2 |= (mask); \
- RCC->APB1RSTR2 &= ~(mask); \
- (void)RCC->APB1RSTR2; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB2 bus.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- if (lp) \
- RCC->APB2SMENR |= (mask); \
- else \
- RCC->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->AHB1SMENR |= (mask); \
- else \
- RCC->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB2SMENR |= (mask); \
- else \
- RCC->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB3SMENR |= (mask); \
- else \
- RCC->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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 Enables the ADC1/ADC2/ADC3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC123(lp) rccEnableAHB2(RCC_AHB2ENR_ADCEN, lp)
-
-/**
- * @brief Disables the ADC1/ADC2/ADC3 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC123() rccDisableAHB2(RCC_AHB2ENR_ADCEN)
-
-/**
- * @brief Resets the ADC1/ADC2/ADC3 peripheral.
- *
- * @api
- */
-#define rccResetADC123() rccResetAHB2(RCC_AHB2RSTR_ADCRST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC1(lp) rccEnableAPB1R1(RCC_APB1ENR1_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPB1R1(RCC_APB1ENR1_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPB1R1(RCC_APB1RSTR1_DAC1RST)
-/** @} */
-
-/**
- * @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 PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
-
-/**
- * @brief Disables PWR interface clock.
- *
- * @api
- */
-#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
-
-/**
- * @brief Resets the PWR interface.
- *
- * @api
- */
-#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
-/** @} */
-
-/**
- * @name CAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the CAN1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN1(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN1EN, lp)
-
-/**
- * @brief Disables the CAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN1() rccDisableAPB1R1(RCC_APB1ENR1_CAN1EN)
-
-/**
- * @brief Resets the CAN1 peripheral.
- *
- * @api
- */
-#define rccResetCAN1() rccResetAPB1R1(RCC_APB1RSTR1_CAN1RST)
-
-/**
- * @brief Enables the CAN2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableCAN2(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN2EN, lp)
-
-/**
- * @brief Disables the CAN2 peripheral clock.
- *
- * @api
- */
-#define rccDisableCAN2() rccDisableAPB1R1(RCC_APB1ENR1_CAN2EN)
-
-/**
- * @brief Resets the CAN2 peripheral.
- *
- * @api
- */
-#define rccResetCAN2() rccResetAPB1R1(RCC_APB1RSTR1_CAN2RST)
-/** @} */
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
-
-/**
- * @brief Disables the I2C1 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
-
-/**
- * @brief Resets the I2C1 peripheral.
- *
- * @api
- */
-#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
-
-/**
- * @brief Enables the I2C2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
-
-/**
- * @brief Disables the I2C2 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
-
-/**
- * @brief Resets the I2C2 peripheral.
- *
- * @api
- */
-#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
-
-/**
- * @brief Enables the I2C3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
-
-/**
- * @brief Disables the I2C3 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
-
-/**
- * @brief Resets the I2C3 peripheral.
- *
- * @api
- */
-#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
-
-/**
- * @brief Enables the I2C4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
-
-/**
- * @brief Disables the I2C4 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
-
-/**
- * @brief Resets the I2C4 peripheral.
- *
- * @api
- */
-#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
-/** @} */
-
-/**
- * @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)
-/** @} */
-
-/**
- * @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 RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
-/** @} */
-
-/**
- * @name SDMMC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDMMC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp)
-
-/**
- * @brief Disables the SDMMC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC1() rccDisableAPB2(RCC_APB2ENR_SDMMC1EN)
-
-/**
- * @brief Resets the SDMMC1 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
-
-/**
- * @brief Disables the SPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
-
-/**
- * @brief Resets the SPI2 peripheral.
- *
- * @api
- */
-#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
-
-/**
- * @brief Enables the SPI3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
-
-/**
- * @brief Disables the SPI3 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
-
-/**
- * @brief Resets the SPI3 peripheral.
- *
- * @api
- */
-#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_SPI3RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
-
-/**
- * @brief Disables the TIM2 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
-
-/**
- * @brief Resets the TIM2 peripheral.
- *
- * @api
- */
-#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
-
-/**
- * @brief Enables the TIM3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
-
-/**
- * @brief Disables the TIM3 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
-
-/**
- * @brief Enables the TIM4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
-
-/**
- * @brief Disables the TIM4 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
-
-/**
- * @brief Resets the TIM4 peripheral.
- *
- * @api
- */
-#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
-
-/**
- * @brief Enables the TIM5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
-
-/**
- * @brief Disables the TIM5 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
-
-/**
- * @brief Resets the TIM5 peripheral.
- *
- * @api
- */
-#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
-
-/**
- * @brief Enables the TIM6 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
-
-/**
- * @brief Disables the TIM6 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
-
-/**
- * @brief Resets the TIM6 peripheral.
- *
- * @api
- */
-#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
-
-/**
- * @brief Enables the TIM7 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
-
-/**
- * @brief Disables the TIM7 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
-
-/**
- * @brief Resets the TIM7 peripheral.
- *
- * @api
- */
-#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
-
-/**
- * @brief Disables the USART2 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
-
-/**
- * @brief Resets the USART2 peripheral.
- *
- * @api
- */
-#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
-
-/**
- * @brief Enables the USART3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
-
-/**
- * @brief Disables the USART3 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
-
-/**
- * @brief Resets the USART3 peripheral.
- *
- * @api
- */
-#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
-
-/**
- * @brief Enables the UART4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
-
-/**
- * @brief Enables the UART5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
-
-/**
- * @brief Disables the UART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
-
-/**
- * @brief Resets the UART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBFSEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBFSEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBFSRST)
-/** @} */
-
-/**
- * @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
- */
-#define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
-
-/**
- * @brief Disables the FSMC peripheral clock.
- *
- * @api
- */
-#define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
-
-/**
- * @brief Resets the FSMC peripheral.
- *
- * @api
- */
-#define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32l4xx.h.
+ *
+ * @addtogroup STM32L4xx_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 (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R1(mask, lp) { \
+ RCC->APB1ENR1 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR1 |= (mask); \
+ else \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R1(mask) { \
+ RCC->APB1ENR1 &= ~(mask); \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R1(mask) { \
+ RCC->APB1RSTR1 |= (mask); \
+ RCC->APB1RSTR1 &= ~(mask); \
+ (void)RCC->APB1RSTR1; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R2(mask, lp) { \
+ RCC->APB1ENR2 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR2 |= (mask); \
+ else \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R2(mask) { \
+ RCC->APB1ENR2 &= ~(mask); \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R2(mask) { \
+ RCC->APB1RSTR2 |= (mask); \
+ RCC->APB1RSTR2 &= ~(mask); \
+ (void)RCC->APB1RSTR2; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB2 bus.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ if (lp) \
+ RCC->APB2SMENR |= (mask); \
+ else \
+ RCC->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR |= (mask); \
+ else \
+ RCC->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR |= (mask); \
+ else \
+ RCC->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR |= (mask); \
+ else \
+ RCC->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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 Enables the ADC1/ADC2/ADC3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC123(lp) rccEnableAHB2(RCC_AHB2ENR_ADCEN, lp)
+
+/**
+ * @brief Disables the ADC1/ADC2/ADC3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC123() rccDisableAHB2(RCC_AHB2ENR_ADCEN)
+
+/**
+ * @brief Resets the ADC1/ADC2/ADC3 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC123() rccResetAHB2(RCC_AHB2RSTR_ADCRST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC1(lp) rccEnableAPB1R1(RCC_APB1ENR1_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPB1R1(RCC_APB1ENR1_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPB1R1(RCC_APB1RSTR1_DAC1RST)
+/** @} */
+
+/**
+ * @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 PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
+
+/**
+ * @brief Disables PWR interface clock.
+ *
+ * @api
+ */
+#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
+
+/**
+ * @brief Resets the PWR interface.
+ *
+ * @api
+ */
+#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
+/** @} */
+
+/**
+ * @name CAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the CAN1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN1(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN1EN, lp)
+
+/**
+ * @brief Disables the CAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN1() rccDisableAPB1R1(RCC_APB1ENR1_CAN1EN)
+
+/**
+ * @brief Resets the CAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN1() rccResetAPB1R1(RCC_APB1RSTR1_CAN1RST)
+
+/**
+ * @brief Enables the CAN2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableCAN2(lp) rccEnableAPB1R1(RCC_APB1ENR1_CAN2EN, lp)
+
+/**
+ * @brief Disables the CAN2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableCAN2() rccDisableAPB1R1(RCC_APB1ENR1_CAN2EN)
+
+/**
+ * @brief Resets the CAN2 peripheral.
+ *
+ * @api
+ */
+#define rccResetCAN2() rccResetAPB1R1(RCC_APB1RSTR1_CAN2RST)
+/** @} */
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
+
+/**
+ * @brief Disables the I2C1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
+
+/**
+ * @brief Resets the I2C1 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
+
+/**
+ * @brief Enables the I2C2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
+
+/**
+ * @brief Disables the I2C2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
+
+/**
+ * @brief Resets the I2C2 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
+
+/**
+ * @brief Enables the I2C3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
+
+/**
+ * @brief Disables the I2C3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
+
+/**
+ * @brief Resets the I2C3 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
+
+/**
+ * @brief Enables the I2C4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
+
+/**
+ * @brief Disables the I2C4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
+
+/**
+ * @brief Resets the I2C4 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
+/** @} */
+
+/**
+ * @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)
+/** @} */
+
+/**
+ * @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 RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
+/** @} */
+
+/**
+ * @name SDMMC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDMMC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp)
+
+/**
+ * @brief Disables the SDMMC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC1() rccDisableAPB2(RCC_APB2ENR_SDMMC1EN)
+
+/**
+ * @brief Resets the SDMMC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
+
+/**
+ * @brief Disables the SPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
+
+/**
+ * @brief Resets the SPI2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
+
+/**
+ * @brief Enables the SPI3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
+
+/**
+ * @brief Disables the SPI3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
+
+/**
+ * @brief Resets the SPI3 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_SPI3RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
+
+/**
+ * @brief Disables the TIM2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
+
+/**
+ * @brief Resets the TIM2 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
+
+/**
+ * @brief Enables the TIM3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
+
+/**
+ * @brief Disables the TIM3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
+
+/**
+ * @brief Resets the TIM3 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
+
+/**
+ * @brief Enables the TIM4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
+
+/**
+ * @brief Disables the TIM4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
+
+/**
+ * @brief Resets the TIM4 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
+
+/**
+ * @brief Enables the TIM5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
+
+/**
+ * @brief Disables the TIM5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
+
+/**
+ * @brief Resets the TIM5 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
+
+/**
+ * @brief Enables the TIM6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
+
+/**
+ * @brief Disables the TIM6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
+
+/**
+ * @brief Resets the TIM6 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
+
+/**
+ * @brief Enables the TIM7 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
+
+/**
+ * @brief Disables the TIM7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
+
+/**
+ * @brief Resets the TIM7 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
+
+/**
+ * @brief Disables the USART2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
+
+/**
+ * @brief Resets the USART2 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
+
+/**
+ * @brief Enables the USART3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
+
+/**
+ * @brief Disables the USART3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
+
+/**
+ * @brief Resets the USART3 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
+
+/**
+ * @brief Enables the UART4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
+
+/**
+ * @brief Enables the UART5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
+
+/**
+ * @brief Disables the UART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
+
+/**
+ * @brief Resets the UART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBFSEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBFSEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBFSRST)
+/** @} */
+
+/**
+ * @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
+ */
+#define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
+
+/**
+ * @brief Disables the FSMC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
+
+/**
+ * @brief Resets the FSMC peripheral.
+ *
+ * @api
+ */
+#define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
index f8ba636424..083a6a9cca 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
@@ -1,1350 +1,1350 @@
-/*
- 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/stm32_registry.h
- * @brief STM32L4xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32L4xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 128
-#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 18
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
-} while (false)
-
-#if defined(STM32L486xx) || defined(STM32L4A6xx) || \
- defined(__DOXYGEN__)
-#define STM32_HAS_HASH1 TRUE
-#define STM32_HAS_CRYP1 TRUE
-#else
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-/*===========================================================================*/
-/* STM32L432xx. */
-/*===========================================================================*/
-
-#if defined(STM32L432xx) || defined(__DOXYGEN__)
-
-/* Clock attributes.*/
-#define STM32_CLOCK_HAS_HSI48 TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_CAN_MAX_FILTERS 14
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_DAC1_CH1_DMA_CHN 0x00003600
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_DAC1_CH2_DMA_CHN 0x00035000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 7
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 40
-#define STM32_EXTI_IMR1_MASK 0xFF820000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
-#endif
-
-/* GPIO attributes.*/
-#define STM32_HAS_GPIOA TRUE
-#define STM32_HAS_GPIOB TRUE
-#define STM32_HAS_GPIOC TRUE
-#define STM32_HAS_GPIOD FALSE
-#define STM32_HAS_GPIOE FALSE
-#define STM32_HAS_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_I2C1_RX_DMA_CHN 0x03500000
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_I2C1_TX_DMA_CHN 0x05300000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_I2C3_RX_DMA_CHN 0x00000300
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_I2C2 FALSE
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_QUADSPI1_DMA_CHN 0x03050000
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 FALSE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_RX_DMA_CHN 0x00000410
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI1_TX_DMA_CHN 0x00004100
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_SPI3_RX_DMA_CHN 0x00000003
-#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_SPI3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_SPI2 FALSE
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS TRUE
-#define STM32_TIM2_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_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 2
-
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_USART1_RX_DMA_CHN 0x02020000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_USART1_TX_DMA_CHN 0x00202000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00200000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x02000000
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART3 FALSE
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32L432xx) */
-
-/*===========================================================================*/
-/* STM32L433xx, STM32L443xx. */
-/*===========================================================================*/
-
-#if defined(STM32L433xx) || defined(STM32L443xx) || defined(__DOXYGEN__)
-
-/* Clock attributes.*/
-#define STM32_CLOCK_HAS_HSI48 TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_CAN_MAX_FILTERS 14
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_DAC1_CH1_DMA_CHN 0x00003600
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_DAC1_CH2_DMA_CHN 0x00035000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 7
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 40
-#define STM32_EXTI_IMR1_MASK 0xFF820000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 1
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_I2C1_RX_DMA_CHN 0x03500000
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_I2C1_TX_DMA_CHN 0x05300000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C2_RX_DMA_CHN 0x00030000
-#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_I2C2_TX_DMA_CHN 0x00003000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_I2C3_RX_DMA_CHN 0x00000300
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_QUADSPI1_DMA_CHN 0x03050000
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
-
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_RX_DMA_CHN 0x00000410
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI1_TX_DMA_CHN 0x00004100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_SPI2_RX_DMA_CHN 0x00001000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_SPI2_TX_DMA_CHN 0x00010000
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_SPI3_RX_DMA_CHN 0x00000003
-#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_SPI3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#define STM32_HAS_TIM2 TRUE
-#define STM32_TIM2_IS_32BITS TRUE
-#define STM32_TIM2_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_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 2
-
-#define STM32_HAS_TIM3 FALSE
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_USART1_RX_DMA_CHN 0x02020000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_USART1_TX_DMA_CHN 0x00202000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00200000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x02000000
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_USART3_RX_DMA_CHN 0x00000200
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_USART3_TX_DMA_CHN 0x00000020
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_UART4 FALSE
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32L443xx) */
-
-/*===========================================================================*/
-/* STM32L452xx. */
-/*===========================================================================*/
-
-#if defined(STM32L452xx) || defined(__DOXYGEN__)
-
-/* Clock attributes.*/
-#define STM32_CLOCK_HAS_HSI48 TRUE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 FALSE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_CAN_MAX_FILTERS 14
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_DAC1_CH1_DMA_CHN 0x00003600
-
-#define STM32_HAS_DAC1_CH2 FALSE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 7
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 40
-#define STM32_EXTI_IMR1_MASK 0xFF820000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* 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_GPIOF FALSE
-#define STM32_HAS_GPIOG FALSE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_I2C1_RX_DMA_CHN 0x03500000
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_I2C1_TX_DMA_CHN 0x05300000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C2_RX_DMA_CHN 0x00030000
-#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_I2C2_TX_DMA_CHN 0x00003000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_I2C3_RX_DMA_CHN 0x00000300
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_I2C4_RX_DMA_CHN 0x00000000
-#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_I2C4_TX_DMA_CHN 0x00000000
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_QUADSPI1_DMA_CHN 0x03050000
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
-
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_RX_DMA_CHN 0x00000410
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI1_TX_DMA_CHN 0x00004100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_SPI2_RX_DMA_CHN 0x00001000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_SPI2_TX_DMA_CHN 0x00010000
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_SPI3_RX_DMA_CHN 0x00000003
-#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_SPI3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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_TIM6 TRUE
-#define STM32_TIM6_IS_32BITS FALSE
-#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 2
-
-#define STM32_HAS_TIM4 FALSE
-#define STM32_HAS_TIM5 FALSE
-#define STM32_HAS_TIM7 FALSE
-#define STM32_HAS_TIM8 FALSE
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_USART1_RX_DMA_CHN 0x02020000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_USART1_TX_DMA_CHN 0x00202000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00200000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x02000000
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_USART3_RX_DMA_CHN 0x00000200
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_USART3_TX_DMA_CHN 0x00000020
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_UART4_RX_DMA_CHN 0x00020000
-#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_UART4_TX_DMA_CHN 0x00000200
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_UART5 FALSE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR TRUE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32L452xx) */
-
-/*===========================================================================*/
-/* STM32L476xx, STM32L486xx. */
-/*===========================================================================*/
-
-#if defined(STM32L476xx) || defined(STM32L486xx)
-
-/* Clock attributes.*/
-#define STM32_CLOCK_HAS_HSI48 FALSE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 TRUE
-#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_ADC3_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_CAN_MAX_FILTERS 14
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_DAC1_CH1_DMA_CHN 0x00003600
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_DAC1_CH2_DMA_CHN 0x00035000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 7
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 40
-#define STM32_EXTI_IMR1_MASK 0xFF820000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOFEN | \
- RCC_AHB2ENR_GPIOGEN | \
- RCC_AHB2ENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_I2C1_RX_DMA_CHN 0x03500000
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_I2C1_TX_DMA_CHN 0x05300000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C2_RX_DMA_CHN 0x00030000
-#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_I2C2_TX_DMA_CHN 0x00003000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_I2C3_RX_DMA_CHN 0x00000300
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_I2C4 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_QUADSPI1_DMA_CHN 0x03050000
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
-
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_RX_DMA_CHN 0x00000410
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI1_TX_DMA_CHN 0x00004100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_SPI2_RX_DMA_CHN 0x00001000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_SPI2_TX_DMA_CHN 0x00010000
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_SPI3_RX_DMA_CHN 0x00000003
-#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_SPI3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 2
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 2
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_USART1_RX_DMA_CHN 0x02020000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_USART1_TX_DMA_CHN 0x00202000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00200000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x02000000
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_USART3_RX_DMA_CHN 0x00000200
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_USART3_TX_DMA_CHN 0x00000020
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5)
-#define STM32_UART4_RX_DMA_CHN 0x00020000
-#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 3)
-#define STM32_UART4_TX_DMA_CHN 0x00000200
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2)
-#define STM32_UART5_RX_DMA_CHN 0x00000020
-#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1)
-#define STM32_UART5_TX_DMA_CHN 0x00000002
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_SEQUENCE_WORKAROUND
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32L476xx) */
-
-/*===========================================================================*/
-/* STM32L496xx, STM32L4A6xx. */
-/*===========================================================================*/
-
-#if defined(STM32L496xx) || defined(STM32L4A6xx)
-
-/* Clock attributes.*/
-#define STM32_CLOCK_HAS_HSI48 FALSE
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_ADC1_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC2 TRUE
-#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_ADC2_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC3 TRUE
-#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_ADC3_DMA_CHN 0x00000000
-
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_CAN_MAX_FILTERS 28
-#define STM32_HAS_CAN1 TRUE
-#define STM32_HAS_CAN2 TRUE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_DAC1_CH1_DMA_CHN 0x00003600
-
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_DAC1_CH2_DMA_CHN 0x00035000
-
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX FALSE
-#define STM32_DMA_SUPPORTS_CSELR TRUE
-#define STM32_DMA1_NUM_CHANNELS 7
-#define STM32_DMA2_NUM_CHANNELS 7
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 40
-#define STM32_EXTI_IMR1_MASK 0xFF820000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
-#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
-#endif
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI TRUE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOFEN | \
- RCC_AHB2ENR_GPIOGEN | \
- RCC_AHB2ENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_I2C1_RX_DMA_CHN 0x03500000
-#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_I2C1_TX_DMA_CHN 0x05300000
-
-#define STM32_HAS_I2C2 TRUE
-#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_I2C2_RX_DMA_CHN 0x00030000
-#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_I2C2_TX_DMA_CHN 0x00003000
-
-#define STM32_HAS_I2C3 TRUE
-#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_I2C3_RX_DMA_CHN 0x00000300
-#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_I2C3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_I2C4 TRUE
-#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_I2C4_RX_DMA_CHN 0x00000000
-#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_I2C4_TX_DMA_CHN 0x00000000
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 TRUE
-#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_QUADSPI1_DMA_CHN 0x03050000
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 5))
-#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
-
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
- STM32_DMA_STREAM_ID_MSK(2, 3))
-#define STM32_SPI1_RX_DMA_CHN 0x00000410
-#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
- STM32_DMA_STREAM_ID_MSK(2, 4))
-#define STM32_SPI1_TX_DMA_CHN 0x00004100
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
-#define STM32_SPI2_RX_DMA_CHN 0x00001000
-#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
-#define STM32_SPI2_TX_DMA_CHN 0x00010000
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
-#define STM32_SPI3_RX_DMA_CHN 0x00000003
-#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
-#define STM32_SPI3_TX_DMA_CHN 0x00000030
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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(1, 5) |\
- STM32_DMA_STREAM_ID_MSK(2, 7))
-#define STM32_USART1_RX_DMA_CHN 0x02020000
-#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
- STM32_DMA_STREAM_ID_MSK(2, 6))
-#define STM32_USART1_TX_DMA_CHN 0x00202000
-
-#define STM32_HAS_USART2 TRUE
-#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
-#define STM32_USART2_RX_DMA_CHN 0x00200000
-#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
-#define STM32_USART2_TX_DMA_CHN 0x02000000
-
-#define STM32_HAS_USART3 TRUE
-#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
-#define STM32_USART3_RX_DMA_CHN 0x00000200
-#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
-#define STM32_USART3_TX_DMA_CHN 0x00000020
-
-#define STM32_HAS_UART4 TRUE
-#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5)
-#define STM32_UART4_RX_DMA_CHN 0x00020000
-#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 3)
-#define STM32_UART4_TX_DMA_CHN 0x00000200
-
-#define STM32_HAS_UART5 TRUE
-#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2)
-#define STM32_UART5_RX_DMA_CHN 0x00000020
-#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1)
-#define STM32_UART5_TX_DMA_CHN 0x00000002
-
-#define STM32_HAS_LPUART1 TRUE
-
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_OTG_STEPPING 2
-#define STM32_HAS_OTG1 TRUE
-#define STM32_OTG1_ENDPOINTS 5
-
-#define STM32_HAS_OTG2 FALSE
-#define STM32_HAS_USB FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D TRUE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-#endif /* defined(STM32L496xx) */
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32L4xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32L4xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
+#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 18
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
+} while (false)
+
+#if defined(STM32L486xx) || defined(STM32L4A6xx) || \
+ defined(__DOXYGEN__)
+#define STM32_HAS_HASH1 TRUE
+#define STM32_HAS_CRYP1 TRUE
+#else
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+/*===========================================================================*/
+/* STM32L432xx. */
+/*===========================================================================*/
+
+#if defined(STM32L432xx) || defined(__DOXYGEN__)
+
+/* Clock attributes.*/
+#define STM32_CLOCK_HAS_HSI48 TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_CAN_MAX_FILTERS 14
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_DAC1_CH1_DMA_CHN 0x00003600
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_DAC1_CH2_DMA_CHN 0x00035000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 7
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 40
+#define STM32_EXTI_IMR1_MASK 0xFF820000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
+#endif
+
+/* GPIO attributes.*/
+#define STM32_HAS_GPIOA TRUE
+#define STM32_HAS_GPIOB TRUE
+#define STM32_HAS_GPIOC TRUE
+#define STM32_HAS_GPIOD FALSE
+#define STM32_HAS_GPIOE FALSE
+#define STM32_HAS_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_I2C1_RX_DMA_CHN 0x03500000
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_I2C1_TX_DMA_CHN 0x05300000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_I2C3_RX_DMA_CHN 0x00000300
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_I2C2 FALSE
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_QUADSPI1_DMA_CHN 0x03050000
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 FALSE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_RX_DMA_CHN 0x00000410
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI1_TX_DMA_CHN 0x00004100
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_SPI3_RX_DMA_CHN 0x00000003
+#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_SPI3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_SPI2 FALSE
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS TRUE
+#define STM32_TIM2_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_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 2
+
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_USART1_RX_DMA_CHN 0x02020000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_USART1_TX_DMA_CHN 0x00202000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00200000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x02000000
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART3 FALSE
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32L432xx) */
+
+/*===========================================================================*/
+/* STM32L433xx, STM32L443xx. */
+/*===========================================================================*/
+
+#if defined(STM32L433xx) || defined(STM32L443xx) || defined(__DOXYGEN__)
+
+/* Clock attributes.*/
+#define STM32_CLOCK_HAS_HSI48 TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_CAN_MAX_FILTERS 14
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_DAC1_CH1_DMA_CHN 0x00003600
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_DAC1_CH2_DMA_CHN 0x00035000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 7
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 40
+#define STM32_EXTI_IMR1_MASK 0xFF820000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 1
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_I2C1_RX_DMA_CHN 0x03500000
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_I2C1_TX_DMA_CHN 0x05300000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C2_RX_DMA_CHN 0x00030000
+#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_I2C2_TX_DMA_CHN 0x00003000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_I2C3_RX_DMA_CHN 0x00000300
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_QUADSPI1_DMA_CHN 0x03050000
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
+
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_RX_DMA_CHN 0x00000410
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI1_TX_DMA_CHN 0x00004100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_SPI2_RX_DMA_CHN 0x00001000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_SPI2_TX_DMA_CHN 0x00010000
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_SPI3_RX_DMA_CHN 0x00000003
+#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_SPI3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#define STM32_HAS_TIM2 TRUE
+#define STM32_TIM2_IS_32BITS TRUE
+#define STM32_TIM2_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_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 2
+
+#define STM32_HAS_TIM3 FALSE
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_USART1_RX_DMA_CHN 0x02020000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_USART1_TX_DMA_CHN 0x00202000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00200000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x02000000
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_USART3_RX_DMA_CHN 0x00000200
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_USART3_TX_DMA_CHN 0x00000020
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_UART4 FALSE
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32L443xx) */
+
+/*===========================================================================*/
+/* STM32L452xx. */
+/*===========================================================================*/
+
+#if defined(STM32L452xx) || defined(__DOXYGEN__)
+
+/* Clock attributes.*/
+#define STM32_CLOCK_HAS_HSI48 TRUE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 FALSE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_CAN_MAX_FILTERS 14
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_DAC1_CH1_DMA_CHN 0x00003600
+
+#define STM32_HAS_DAC1_CH2 FALSE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 7
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 40
+#define STM32_EXTI_IMR1_MASK 0xFF820000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* 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_GPIOF FALSE
+#define STM32_HAS_GPIOG FALSE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_I2C1_RX_DMA_CHN 0x03500000
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_I2C1_TX_DMA_CHN 0x05300000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C2_RX_DMA_CHN 0x00030000
+#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_I2C2_TX_DMA_CHN 0x00003000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_I2C3_RX_DMA_CHN 0x00000300
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_I2C4_RX_DMA_CHN 0x00000000
+#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_I2C4_TX_DMA_CHN 0x00000000
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_QUADSPI1_DMA_CHN 0x03050000
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
+
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_RX_DMA_CHN 0x00000410
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI1_TX_DMA_CHN 0x00004100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_SPI2_RX_DMA_CHN 0x00001000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_SPI2_TX_DMA_CHN 0x00010000
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_SPI3_RX_DMA_CHN 0x00000003
+#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_SPI3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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_TIM6 TRUE
+#define STM32_TIM6_IS_32BITS FALSE
+#define STM32_TIM6_CHANNELS 0
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 2
+
+#define STM32_HAS_TIM4 FALSE
+#define STM32_HAS_TIM5 FALSE
+#define STM32_HAS_TIM7 FALSE
+#define STM32_HAS_TIM8 FALSE
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_USART1_RX_DMA_CHN 0x02020000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_USART1_TX_DMA_CHN 0x00202000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00200000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x02000000
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_USART3_RX_DMA_CHN 0x00000200
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_USART3_TX_DMA_CHN 0x00000020
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_UART4_RX_DMA_CHN 0x00020000
+#define STM32_UART4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_UART4_TX_DMA_CHN 0x00000200
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_UART5 FALSE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR TRUE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32L452xx) */
+
+/*===========================================================================*/
+/* STM32L476xx, STM32L486xx. */
+/*===========================================================================*/
+
+#if defined(STM32L476xx) || defined(STM32L486xx)
+
+/* Clock attributes.*/
+#define STM32_CLOCK_HAS_HSI48 FALSE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 TRUE
+#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_ADC3_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_CAN_MAX_FILTERS 14
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_DAC1_CH1_DMA_CHN 0x00003600
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_DAC1_CH2_DMA_CHN 0x00035000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 7
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 40
+#define STM32_EXTI_IMR1_MASK 0xFF820000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOFEN | \
+ RCC_AHB2ENR_GPIOGEN | \
+ RCC_AHB2ENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_I2C1_RX_DMA_CHN 0x03500000
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_I2C1_TX_DMA_CHN 0x05300000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C2_RX_DMA_CHN 0x00030000
+#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_I2C2_TX_DMA_CHN 0x00003000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_I2C3_RX_DMA_CHN 0x00000300
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_I2C4 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_QUADSPI1_DMA_CHN 0x03050000
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
+
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_RX_DMA_CHN 0x00000410
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI1_TX_DMA_CHN 0x00004100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_SPI2_RX_DMA_CHN 0x00001000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_SPI2_TX_DMA_CHN 0x00010000
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_SPI3_RX_DMA_CHN 0x00000003
+#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_SPI3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 2
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 2
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_USART1_RX_DMA_CHN 0x02020000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_USART1_TX_DMA_CHN 0x00202000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00200000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x02000000
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_USART3_RX_DMA_CHN 0x00000200
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_USART3_TX_DMA_CHN 0x00000020
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5)
+#define STM32_UART4_RX_DMA_CHN 0x00020000
+#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 3)
+#define STM32_UART4_TX_DMA_CHN 0x00000200
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2)
+#define STM32_UART5_RX_DMA_CHN 0x00000020
+#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1)
+#define STM32_UART5_TX_DMA_CHN 0x00000002
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_SEQUENCE_WORKAROUND
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32L476xx) */
+
+/*===========================================================================*/
+/* STM32L496xx, STM32L4A6xx. */
+/*===========================================================================*/
+
+#if defined(STM32L496xx) || defined(STM32L4A6xx)
+
+/* Clock attributes.*/
+#define STM32_CLOCK_HAS_HSI48 FALSE
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 1) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_ADC1_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC2 TRUE
+#define STM32_ADC2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_ADC2_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC3 TRUE
+#define STM32_ADC3_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_ADC3_DMA_CHN 0x00000000
+
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_CAN_MAX_FILTERS 28
+#define STM32_HAS_CAN1 TRUE
+#define STM32_HAS_CAN2 TRUE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_DAC1_CH1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)|\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_DAC1_CH1_DMA_CHN 0x00003600
+
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_DAC1_CH2_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4)|\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_DAC1_CH2_DMA_CHN 0x00035000
+
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX FALSE
+#define STM32_DMA_SUPPORTS_CSELR TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#define STM32_DMA2_NUM_CHANNELS 7
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 40
+#define STM32_EXTI_IMR1_MASK 0xFF820000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
+#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
+#endif
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI TRUE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOFEN | \
+ RCC_AHB2ENR_GPIOGEN | \
+ RCC_AHB2ENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_I2C1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_I2C1_RX_DMA_CHN 0x03500000
+#define STM32_I2C1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_I2C1_TX_DMA_CHN 0x05300000
+
+#define STM32_HAS_I2C2 TRUE
+#define STM32_I2C2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_I2C2_RX_DMA_CHN 0x00030000
+#define STM32_I2C2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_I2C2_TX_DMA_CHN 0x00003000
+
+#define STM32_HAS_I2C3 TRUE
+#define STM32_I2C3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_I2C3_RX_DMA_CHN 0x00000300
+#define STM32_I2C3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_I2C3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_I2C4 TRUE
+#define STM32_I2C4_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_I2C4_RX_DMA_CHN 0x00000000
+#define STM32_I2C4_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_I2C4_TX_DMA_CHN 0x00000000
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 TRUE
+#define STM32_QUADSPI1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_QUADSPI1_DMA_CHN 0x03050000
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_SDC_SDMMC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 5))
+#define STM32_SDC_SDMMC1_DMA_CHN 0x00077000
+
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+#define STM32_SPI1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) |\
+ STM32_DMA_STREAM_ID_MSK(2, 3))
+#define STM32_SPI1_RX_DMA_CHN 0x00000410
+#define STM32_SPI1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) |\
+ STM32_DMA_STREAM_ID_MSK(2, 4))
+#define STM32_SPI1_TX_DMA_CHN 0x00004100
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+#define STM32_SPI2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4))
+#define STM32_SPI2_RX_DMA_CHN 0x00001000
+#define STM32_SPI2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 5))
+#define STM32_SPI2_TX_DMA_CHN 0x00010000
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+#define STM32_SPI3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 1))
+#define STM32_SPI3_RX_DMA_CHN 0x00000003
+#define STM32_SPI3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 2))
+#define STM32_SPI3_TX_DMA_CHN 0x00000030
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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(1, 5) |\
+ STM32_DMA_STREAM_ID_MSK(2, 7))
+#define STM32_USART1_RX_DMA_CHN 0x02020000
+#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 4) |\
+ STM32_DMA_STREAM_ID_MSK(2, 6))
+#define STM32_USART1_TX_DMA_CHN 0x00202000
+
+#define STM32_HAS_USART2 TRUE
+#define STM32_USART2_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 6))
+#define STM32_USART2_RX_DMA_CHN 0x00200000
+#define STM32_USART2_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 7))
+#define STM32_USART2_TX_DMA_CHN 0x02000000
+
+#define STM32_HAS_USART3 TRUE
+#define STM32_USART3_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3))
+#define STM32_USART3_RX_DMA_CHN 0x00000200
+#define STM32_USART3_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2))
+#define STM32_USART3_TX_DMA_CHN 0x00000020
+
+#define STM32_HAS_UART4 TRUE
+#define STM32_UART4_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 5)
+#define STM32_UART4_RX_DMA_CHN 0x00020000
+#define STM32_UART4_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 3)
+#define STM32_UART4_TX_DMA_CHN 0x00000200
+
+#define STM32_HAS_UART5 TRUE
+#define STM32_UART5_RX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 2)
+#define STM32_UART5_RX_DMA_CHN 0x00000020
+#define STM32_UART5_TX_DMA_MSK STM32_DMA_STREAM_ID_MSK(2, 1)
+#define STM32_UART5_TX_DMA_CHN 0x00000002
+
+#define STM32_HAS_LPUART1 TRUE
+
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_OTG_STEPPING 2
+#define STM32_HAS_OTG1 TRUE
+#define STM32_OTG1_ENDPOINTS 5
+
+#define STM32_HAS_OTG2 FALSE
+#define STM32_HAS_USB FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D TRUE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+#endif /* defined(STM32L496xx) */
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L5xx/hal_lld.h b/os/hal/ports/STM32/STM32L5xx/hal_lld.h
index 7425e45292..9be4751032 100644
--- a/os/hal/ports/STM32/STM32L5xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L5xx/hal_lld.h
@@ -1,2699 +1,2707 @@
-/*
- 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 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 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
+
+ #if (FOME_STM32_LSE_WAIT_MAX > 0) && (FOME_STM32_LSE_WAIT_MAX_RTCSEL == STM32_RTCSEL)
+ #error "FOME_STM32_LSE_WAIT_MAX_RTCSEL is same as STM32_RTCSEL"
+ #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_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/os/hal/ports/STM32/STM32L5xx/platform.mk b/os/hal/ports/STM32/STM32L5xx/platform.mk
index d2bfad33f6..6687ddf596 100644
--- a/os/hal/ports/STM32/STM32L5xx/platform.mk
+++ b/os/hal/ports/STM32/STM32L5xx/platform.mk
@@ -1,34 +1,34 @@
-# Required platform files.
-PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L5xx/stm32_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L5xx/hal_lld.c
-
-# Required include directories.
-PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L5xx
-
-# 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/GPIOv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
-include $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/driver.mk
-
-# Shared variables
-ALLCSRC += $(PLATFORMSRC)
-ALLINC += $(PLATFORMINC)
+# Required platform files.
+PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L5xx/stm32_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L5xx/hal_lld.c
+
+# Required include directories.
+PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L5xx
+
+# 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/GPIOv2/driver.mk
+include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/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/STM32L5xx/stm32_dmamux.h b/os/hal/ports/STM32/STM32L5xx/stm32_dmamux.h
index 89862d5ac8..d2a2e35529 100644
--- a/os/hal/ports/STM32/STM32L5xx/stm32_dmamux.h
+++ b/os/hal/ports/STM32/STM32L5xx/stm32_dmamux.h
@@ -1,162 +1,162 @@
-/*
- 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/stm32_dmamux.h
- * @brief STM32L5xx DMAMUX handler header.
- *
- * @addtogroup STM32L5xx_DMAMUX
- * @{
- */
-
-#ifndef STM32_DMAMUX_H
-#define STM32_DMAMUX_H
-
-/*===========================================================================*/
-/* Driver constants. */
-/*===========================================================================*/
-
-/**
- * @name DMAMUX1 request sources
- * @{
- */
-#define STM32_DMAMUX1_REQ_GEN0 1
-#define STM32_DMAMUX1_REQ_GEN1 2
-#define STM32_DMAMUX1_REQ_GEN2 3
-#define STM32_DMAMUX1_REQ_GEN3 4
-#define STM32_DMAMUX1_ADC1 5
-#define STM32_DMAMUX1_ADC2 7
-#define STM32_DMAMUX1_DAC1_CH1 7
-#define STM32_DMAMUX1_DAC1_CH2 8
-#define STM32_DMAMUX1_TIM6_UP 9
-#define STM32_DMAMUX1_TIM7_UP 10
-#define STM32_DMAMUX1_SPI1_RX 11
-#define STM32_DMAMUX1_SPI1_TX 12
-#define STM32_DMAMUX1_SPI2_RX 13
-#define STM32_DMAMUX1_SPI2_TX 14
-#define STM32_DMAMUX1_SPI3_RX 15
-#define STM32_DMAMUX1_SPI3_TX 16
-#define STM32_DMAMUX1_I2C1_RX 17
-#define STM32_DMAMUX1_I2C1_TX 18
-#define STM32_DMAMUX1_I2C2_RX 19
-#define STM32_DMAMUX1_I2C2_TX 20
-#define STM32_DMAMUX1_I2C3_RX 21
-#define STM32_DMAMUX1_I2C3_TX 22
-#define STM32_DMAMUX1_I2C4_RX 23
-#define STM32_DMAMUX1_I2C4_TX 24
-#define STM32_DMAMUX1_USART1_RX 25
-#define STM32_DMAMUX1_USART1_TX 26
-#define STM32_DMAMUX1_USART2_RX 27
-#define STM32_DMAMUX1_USART2_TX 28
-#define STM32_DMAMUX1_USART3_RX 29
-#define STM32_DMAMUX1_USART3_TX 30
-#define STM32_DMAMUX1_UART4_RX 31
-#define STM32_DMAMUX1_UART4_TX 32
-#define STM32_DMAMUX1_UART5_RX 33
-#define STM32_DMAMUX1_UART5_TX 34
-#define STM32_DMAMUX1_LPUART1_RX 35
-#define STM32_DMAMUX1_LPUART1_TX 36
-#define STM32_DMAMUX1_SAI1_A 37
-#define STM32_DMAMUX1_SAI1_B 38
-#define STM32_DMAMUX1_SAI2_A 39
-#define STM32_DMAMUX1_SAI2_B 20
-#define STM32_DMAMUX1_OCTOSPI1 41
-#define STM32_DMAMUX1_TIM1_CH1 42
-#define STM32_DMAMUX1_TIM1_CH2 43
-#define STM32_DMAMUX1_TIM1_CH3 44
-#define STM32_DMAMUX1_TIM1_CH4 45
-#define STM32_DMAMUX1_TIM1_UP 46
-#define STM32_DMAMUX1_TIM1_TRIG 47
-#define STM32_DMAMUX1_TIM1_COM 48
-#define STM32_DMAMUX1_TIM8_CH1 49
-#define STM32_DMAMUX1_TIM8_CH2 50
-#define STM32_DMAMUX1_TIM8_CH3 51
-#define STM32_DMAMUX1_TIM8_CH4 52
-#define STM32_DMAMUX1_TIM8_UP 53
-#define STM32_DMAMUX1_TIM8_TRIG 54
-#define STM32_DMAMUX1_TIM8_COM 55
-#define STM32_DMAMUX1_TIM2_CH1 56
-#define STM32_DMAMUX1_TIM2_CH2 57
-#define STM32_DMAMUX1_TIM2_CH3 58
-#define STM32_DMAMUX1_TIM2_CH4 59
-#define STM32_DMAMUX1_TIM2_UP 60
-#define STM32_DMAMUX1_TIM3_CH1 61
-#define STM32_DMAMUX1_TIM3_CH2 62
-#define STM32_DMAMUX1_TIM3_CH3 63
-#define STM32_DMAMUX1_TIM3_CH4 64
-#define STM32_DMAMUX1_TIM3_UP 65
-#define STM32_DMAMUX1_TIM3_TRIG 66
-#define STM32_DMAMUX1_TIM4_CH1 67
-#define STM32_DMAMUX1_TIM4_CH2 68
-#define STM32_DMAMUX1_TIM4_CH3 69
-#define STM32_DMAMUX1_TIM4_CH4 70
-#define STM32_DMAMUX1_TIM4_UP 71
-#define STM32_DMAMUX1_TIM5_CH1 72
-#define STM32_DMAMUX1_TIM5_CH2 73
-#define STM32_DMAMUX1_TIM5_CH3 74
-#define STM32_DMAMUX1_TIM5_CH4 75
-#define STM32_DMAMUX1_TIM5_UP 76
-#define STM32_DMAMUX1_TIM5_TRIG 77
-#define STM32_DMAMUX1_TIM15_CH1 78
-#define STM32_DMAMUX1_TIM15_UP 79
-#define STM32_DMAMUX1_TIM15_TRIG 80
-#define STM32_DMAMUX1_TIM15_COM 81
-#define STM32_DMAMUX1_TIM16_CH1 82
-#define STM32_DMAMUX1_TIM16_UP 83
-#define STM32_DMAMUX1_TIM17_CH1 84
-#define STM32_DMAMUX1_TIM17_UP 85
-#define STM32_DMAMUX1_DFSDM1_FLT0 86
-#define STM32_DMAMUX1_DFSDM1_FLT1 87
-#define STM32_DMAMUX1_DFSDM1_FLT2 88
-#define STM32_DMAMUX1_DFSDM1_FLT3 89
-#define STM32_DMAMUX1_AES_IN 90
-#define STM32_DMAMUX1_AES_OUT 91
-#define STM32_DMAMUX1_HASH_IN 92
-#define STM32_DMAMUX1_USBPD_TX 93
-#define STM32_DMAMUX1_USBPD_RX 94
-/** @} */
-
-/*===========================================================================*/
-/* Driver pre-compile time settings. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Derived constants and error checks. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver data structures and types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver macros. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_DMAMUX_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/stm32_dmamux.h
+ * @brief STM32L5xx DMAMUX handler header.
+ *
+ * @addtogroup STM32L5xx_DMAMUX
+ * @{
+ */
+
+#ifndef STM32_DMAMUX_H
+#define STM32_DMAMUX_H
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name DMAMUX1 request sources
+ * @{
+ */
+#define STM32_DMAMUX1_REQ_GEN0 1
+#define STM32_DMAMUX1_REQ_GEN1 2
+#define STM32_DMAMUX1_REQ_GEN2 3
+#define STM32_DMAMUX1_REQ_GEN3 4
+#define STM32_DMAMUX1_ADC1 5
+#define STM32_DMAMUX1_ADC2 7
+#define STM32_DMAMUX1_DAC1_CH1 7
+#define STM32_DMAMUX1_DAC1_CH2 8
+#define STM32_DMAMUX1_TIM6_UP 9
+#define STM32_DMAMUX1_TIM7_UP 10
+#define STM32_DMAMUX1_SPI1_RX 11
+#define STM32_DMAMUX1_SPI1_TX 12
+#define STM32_DMAMUX1_SPI2_RX 13
+#define STM32_DMAMUX1_SPI2_TX 14
+#define STM32_DMAMUX1_SPI3_RX 15
+#define STM32_DMAMUX1_SPI3_TX 16
+#define STM32_DMAMUX1_I2C1_RX 17
+#define STM32_DMAMUX1_I2C1_TX 18
+#define STM32_DMAMUX1_I2C2_RX 19
+#define STM32_DMAMUX1_I2C2_TX 20
+#define STM32_DMAMUX1_I2C3_RX 21
+#define STM32_DMAMUX1_I2C3_TX 22
+#define STM32_DMAMUX1_I2C4_RX 23
+#define STM32_DMAMUX1_I2C4_TX 24
+#define STM32_DMAMUX1_USART1_RX 25
+#define STM32_DMAMUX1_USART1_TX 26
+#define STM32_DMAMUX1_USART2_RX 27
+#define STM32_DMAMUX1_USART2_TX 28
+#define STM32_DMAMUX1_USART3_RX 29
+#define STM32_DMAMUX1_USART3_TX 30
+#define STM32_DMAMUX1_UART4_RX 31
+#define STM32_DMAMUX1_UART4_TX 32
+#define STM32_DMAMUX1_UART5_RX 33
+#define STM32_DMAMUX1_UART5_TX 34
+#define STM32_DMAMUX1_LPUART1_RX 35
+#define STM32_DMAMUX1_LPUART1_TX 36
+#define STM32_DMAMUX1_SAI1_A 37
+#define STM32_DMAMUX1_SAI1_B 38
+#define STM32_DMAMUX1_SAI2_A 39
+#define STM32_DMAMUX1_SAI2_B 20
+#define STM32_DMAMUX1_OCTOSPI1 41
+#define STM32_DMAMUX1_TIM1_CH1 42
+#define STM32_DMAMUX1_TIM1_CH2 43
+#define STM32_DMAMUX1_TIM1_CH3 44
+#define STM32_DMAMUX1_TIM1_CH4 45
+#define STM32_DMAMUX1_TIM1_UP 46
+#define STM32_DMAMUX1_TIM1_TRIG 47
+#define STM32_DMAMUX1_TIM1_COM 48
+#define STM32_DMAMUX1_TIM8_CH1 49
+#define STM32_DMAMUX1_TIM8_CH2 50
+#define STM32_DMAMUX1_TIM8_CH3 51
+#define STM32_DMAMUX1_TIM8_CH4 52
+#define STM32_DMAMUX1_TIM8_UP 53
+#define STM32_DMAMUX1_TIM8_TRIG 54
+#define STM32_DMAMUX1_TIM8_COM 55
+#define STM32_DMAMUX1_TIM2_CH1 56
+#define STM32_DMAMUX1_TIM2_CH2 57
+#define STM32_DMAMUX1_TIM2_CH3 58
+#define STM32_DMAMUX1_TIM2_CH4 59
+#define STM32_DMAMUX1_TIM2_UP 60
+#define STM32_DMAMUX1_TIM3_CH1 61
+#define STM32_DMAMUX1_TIM3_CH2 62
+#define STM32_DMAMUX1_TIM3_CH3 63
+#define STM32_DMAMUX1_TIM3_CH4 64
+#define STM32_DMAMUX1_TIM3_UP 65
+#define STM32_DMAMUX1_TIM3_TRIG 66
+#define STM32_DMAMUX1_TIM4_CH1 67
+#define STM32_DMAMUX1_TIM4_CH2 68
+#define STM32_DMAMUX1_TIM4_CH3 69
+#define STM32_DMAMUX1_TIM4_CH4 70
+#define STM32_DMAMUX1_TIM4_UP 71
+#define STM32_DMAMUX1_TIM5_CH1 72
+#define STM32_DMAMUX1_TIM5_CH2 73
+#define STM32_DMAMUX1_TIM5_CH3 74
+#define STM32_DMAMUX1_TIM5_CH4 75
+#define STM32_DMAMUX1_TIM5_UP 76
+#define STM32_DMAMUX1_TIM5_TRIG 77
+#define STM32_DMAMUX1_TIM15_CH1 78
+#define STM32_DMAMUX1_TIM15_UP 79
+#define STM32_DMAMUX1_TIM15_TRIG 80
+#define STM32_DMAMUX1_TIM15_COM 81
+#define STM32_DMAMUX1_TIM16_CH1 82
+#define STM32_DMAMUX1_TIM16_UP 83
+#define STM32_DMAMUX1_TIM17_CH1 84
+#define STM32_DMAMUX1_TIM17_UP 85
+#define STM32_DMAMUX1_DFSDM1_FLT0 86
+#define STM32_DMAMUX1_DFSDM1_FLT1 87
+#define STM32_DMAMUX1_DFSDM1_FLT2 88
+#define STM32_DMAMUX1_DFSDM1_FLT3 89
+#define STM32_DMAMUX1_AES_IN 90
+#define STM32_DMAMUX1_AES_OUT 91
+#define STM32_DMAMUX1_HASH_IN 92
+#define STM32_DMAMUX1_USBPD_TX 93
+#define STM32_DMAMUX1_USBPD_RX 94
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_DMAMUX_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L5xx/stm32_isr.c b/os/hal/ports/STM32/STM32L5xx/stm32_isr.c
index afc6948097..dc5e5ba069 100644
--- a/os/hal/ports/STM32/STM32L5xx/stm32_isr.c
+++ b/os/hal/ports/STM32/STM32L5xx/stm32_isr.c
@@ -1,192 +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.
-*/
-
-/**
- * @file STM32L5xx/stm32_isr.c
- * @brief STM32L5xx ISR handler code.
- *
- * @addtogroup STM32L5xx_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. */
-/*===========================================================================*/
-
-#include "stm32_exti0.inc"
-#include "stm32_exti1.inc"
-#include "stm32_exti2.inc"
-#include "stm32_exti3.inc"
-#include "stm32_exti4.inc"
-#include "stm32_exti5.inc"
-#include "stm32_exti6.inc"
-#include "stm32_exti7.inc"
-#include "stm32_exti8.inc"
-#include "stm32_exti9.inc"
-#include "stm32_exti10.inc"
-#include "stm32_exti11.inc"
-#include "stm32_exti12.inc"
-#include "stm32_exti13.inc"
-#include "stm32_exti14.inc"
-#include "stm32_exti15.inc"
-#include "stm32_exti16-35_38.inc"
-#include "stm32_exti17.inc"
-#include "stm32_exti18.inc"
-#include "stm32_exti19.inc"
-#include "stm32_exti20.inc"
-#include "stm32_exti21_22.inc"
-
-#include "stm32_usart1.inc"
-#include "stm32_usart2.inc"
-#include "stm32_usart3.inc"
-#include "stm32_uart4.inc"
-#include "stm32_uart5.inc"
-#include "stm32_lpuart1.inc"
-
-#include "stm32_tim1.inc"
-#include "stm32_tim2.inc"
-#include "stm32_tim3.inc"
-#include "stm32_tim4.inc"
-#include "stm32_tim5.inc"
-#include "stm32_tim6.inc"
-#include "stm32_tim7.inc"
-#include "stm32_tim8.inc"
-#include "stm32_tim15.inc"
-#include "stm32_tim16.inc"
-#include "stm32_tim17.inc"
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Enables IRQ sources.
- *
- * @notapi
- */
-void irqInit(void) {
-
- exti0_irq_init();
- exti1_irq_init();
- exti2_irq_init();
- exti3_irq_init();
- exti4_irq_init();
- exti5_irq_init();
- exti6_irq_init();
- exti7_irq_init();
- exti8_irq_init();
- exti9_irq_init();
- exti10_irq_init();
- exti11_irq_init();
- exti12_irq_init();
- exti13_irq_init();
- exti14_irq_init();
- exti15_irq_init();
- exti16_exti35_38_irq_init();
- exti17_irq_init();
- exti18_irq_init();
- exti19_irq_init();
- exti21_22_irq_init();
-
- tim1_tim15_tim16_tim17_irq_init();
- tim2_irq_init();
- tim3_irq_init();
- tim4_irq_init();
- tim5_irq_init();
- tim6_irq_init();
- tim7_irq_init();
- tim8_irq_init();
-
- usart1_irq_init();
- usart2_irq_init();
- usart3_irq_init();
- uart4_irq_init();
- uart5_irq_init();
- lpuart1_irq_init();
-}
-
-/**
- * @brief Disables IRQ sources.
- *
- * @notapi
- */
-void irqDeinit(void) {
-
- exti0_irq_deinit();
- exti1_irq_deinit();
- exti2_irq_deinit();
- exti3_irq_deinit();
- exti4_irq_deinit();
- exti5_irq_deinit();
- exti6_irq_deinit();
- exti7_irq_deinit();
- exti8_irq_deinit();
- exti9_irq_deinit();
- exti10_irq_deinit();
- exti11_irq_deinit();
- exti12_irq_deinit();
- exti13_irq_deinit();
- exti14_irq_deinit();
- exti15_irq_deinit();
- exti16_exti35_38_irq_deinit();
- exti17_irq_deinit();
- exti18_irq_deinit();
- exti19_irq_deinit();
- exti21_22_irq_deinit();
-
- tim1_tim15_tim16_tim17_irq_deinit();
- tim2_irq_deinit();
- tim3_irq_deinit();
- tim4_irq_deinit();
- tim5_irq_deinit();
- tim6_irq_deinit();
- tim7_irq_deinit();
- tim8_irq_deinit();
-
- usart1_irq_deinit();
- usart2_irq_deinit();
- usart3_irq_deinit();
- uart4_irq_deinit();
- uart5_irq_deinit();
- lpuart1_irq_deinit();
-}
-
-/** @} */
+/*
+ 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/stm32_isr.c
+ * @brief STM32L5xx ISR handler code.
+ *
+ * @addtogroup STM32L5xx_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. */
+/*===========================================================================*/
+
+#include "stm32_exti0.inc"
+#include "stm32_exti1.inc"
+#include "stm32_exti2.inc"
+#include "stm32_exti3.inc"
+#include "stm32_exti4.inc"
+#include "stm32_exti5.inc"
+#include "stm32_exti6.inc"
+#include "stm32_exti7.inc"
+#include "stm32_exti8.inc"
+#include "stm32_exti9.inc"
+#include "stm32_exti10.inc"
+#include "stm32_exti11.inc"
+#include "stm32_exti12.inc"
+#include "stm32_exti13.inc"
+#include "stm32_exti14.inc"
+#include "stm32_exti15.inc"
+#include "stm32_exti16-35_38.inc"
+#include "stm32_exti17.inc"
+#include "stm32_exti18.inc"
+#include "stm32_exti19.inc"
+#include "stm32_exti20.inc"
+#include "stm32_exti21_22.inc"
+
+#include "stm32_usart1.inc"
+#include "stm32_usart2.inc"
+#include "stm32_usart3.inc"
+#include "stm32_uart4.inc"
+#include "stm32_uart5.inc"
+#include "stm32_lpuart1.inc"
+
+#include "stm32_tim1.inc"
+#include "stm32_tim2.inc"
+#include "stm32_tim3.inc"
+#include "stm32_tim4.inc"
+#include "stm32_tim5.inc"
+#include "stm32_tim6.inc"
+#include "stm32_tim7.inc"
+#include "stm32_tim8.inc"
+#include "stm32_tim15.inc"
+#include "stm32_tim16.inc"
+#include "stm32_tim17.inc"
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables IRQ sources.
+ *
+ * @notapi
+ */
+void irqInit(void) {
+
+ exti0_irq_init();
+ exti1_irq_init();
+ exti2_irq_init();
+ exti3_irq_init();
+ exti4_irq_init();
+ exti5_irq_init();
+ exti6_irq_init();
+ exti7_irq_init();
+ exti8_irq_init();
+ exti9_irq_init();
+ exti10_irq_init();
+ exti11_irq_init();
+ exti12_irq_init();
+ exti13_irq_init();
+ exti14_irq_init();
+ exti15_irq_init();
+ exti16_exti35_38_irq_init();
+ exti17_irq_init();
+ exti18_irq_init();
+ exti19_irq_init();
+ exti21_22_irq_init();
+
+ tim1_tim15_tim16_tim17_irq_init();
+ tim2_irq_init();
+ tim3_irq_init();
+ tim4_irq_init();
+ tim5_irq_init();
+ tim6_irq_init();
+ tim7_irq_init();
+ tim8_irq_init();
+
+ usart1_irq_init();
+ usart2_irq_init();
+ usart3_irq_init();
+ uart4_irq_init();
+ uart5_irq_init();
+ lpuart1_irq_init();
+}
+
+/**
+ * @brief Disables IRQ sources.
+ *
+ * @notapi
+ */
+void irqDeinit(void) {
+
+ exti0_irq_deinit();
+ exti1_irq_deinit();
+ exti2_irq_deinit();
+ exti3_irq_deinit();
+ exti4_irq_deinit();
+ exti5_irq_deinit();
+ exti6_irq_deinit();
+ exti7_irq_deinit();
+ exti8_irq_deinit();
+ exti9_irq_deinit();
+ exti10_irq_deinit();
+ exti11_irq_deinit();
+ exti12_irq_deinit();
+ exti13_irq_deinit();
+ exti14_irq_deinit();
+ exti15_irq_deinit();
+ exti16_exti35_38_irq_deinit();
+ exti17_irq_deinit();
+ exti18_irq_deinit();
+ exti19_irq_deinit();
+ exti21_22_irq_deinit();
+
+ tim1_tim15_tim16_tim17_irq_deinit();
+ tim2_irq_deinit();
+ tim3_irq_deinit();
+ tim4_irq_deinit();
+ tim5_irq_deinit();
+ tim6_irq_deinit();
+ tim7_irq_deinit();
+ tim8_irq_deinit();
+
+ usart1_irq_deinit();
+ usart2_irq_deinit();
+ usart3_irq_deinit();
+ uart4_irq_deinit();
+ uart5_irq_deinit();
+ lpuart1_irq_deinit();
+}
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L5xx/stm32_isr.h b/os/hal/ports/STM32/STM32L5xx/stm32_isr.h
index 48b4a1da4e..62a7f11625 100644
--- a/os/hal/ports/STM32/STM32L5xx/stm32_isr.h
+++ b/os/hal/ports/STM32/STM32L5xx/stm32_isr.h
@@ -1,299 +1,299 @@
-/*
- 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/stm32_isr.h
- * @brief STM32L5xx ISR handler header.
- *
- * @addtogroup STM32L5xx_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_TIM15_SUPPRESS_ISR
-#define STM32_TIM16_SUPPRESS_ISR
-#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
-/** @} */
-
-/**
- * @name ISR names and numbers
- * @{
- */
-/*
- * ADC unit.
- */
-#define STM32_ADC12_HANDLER VectorD4
-
-#define STM32_ADC12_NUMBER 37
-
-/*
- * FDCAN unit.
- */
-#define STM32_FDCAN1_IT0_HANDLER VectorDC
-#define STM32_FDCAN1_IT1_HANDLER VectorE0
-
-#define STM32_FDCAN1_IT0_NUMBER 39
-#define STM32_FDCAN1_IT1_NUMBER 40
-
-/*
- * DMA unit.
- */
-#define STM32_DMA1_CH1_HANDLER VectorB4
-#define STM32_DMA1_CH2_HANDLER VectorB8
-#define STM32_DMA1_CH3_HANDLER VectorBC
-#define STM32_DMA1_CH4_HANDLER VectorC0
-#define STM32_DMA1_CH5_HANDLER VectorC4
-#define STM32_DMA1_CH6_HANDLER VectorC8
-#define STM32_DMA1_CH7_HANDLER VectorCC
-#define STM32_DMA1_CH8_HANDLER VectorD0
-#define STM32_DMA2_CH1_HANDLER Vector180
-#define STM32_DMA2_CH2_HANDLER Vector184
-#define STM32_DMA2_CH3_HANDLER Vector188
-#define STM32_DMA2_CH4_HANDLER Vector18C
-#define STM32_DMA2_CH5_HANDLER Vector190
-#define STM32_DMA2_CH6_HANDLER Vector194
-#define STM32_DMA2_CH7_HANDLER Vector198
-#define STM32_DMA2_CH8_HANDLER Vector19C
-
-#define STM32_DMA1_CH1_NUMBER 29
-#define STM32_DMA1_CH2_NUMBER 30
-#define STM32_DMA1_CH3_NUMBER 31
-#define STM32_DMA1_CH4_NUMBER 32
-#define STM32_DMA1_CH5_NUMBER 33
-#define STM32_DMA1_CH6_NUMBER 34
-#define STM32_DMA1_CH7_NUMBER 35
-#define STM32_DMA1_CH8_NUMBER 36
-#define STM32_DMA2_CH1_NUMBER 80
-#define STM32_DMA2_CH2_NUMBER 81
-#define STM32_DMA2_CH3_NUMBER 82
-#define STM32_DMA2_CH4_NUMBER 83
-#define STM32_DMA2_CH5_NUMBER 84
-#define STM32_DMA2_CH6_NUMBER 85
-#define STM32_DMA2_CH7_NUMBER 86
-#define STM32_DMA2_CH8_NUMBER 87
-
-/*
- * 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_HANDLER Vector9C
-#define STM32_EXTI6_HANDLER Vector9C
-#define STM32_EXTI7_HANDLER Vector9C
-#define STM32_EXTI8_HANDLER Vector9C
-#define STM32_EXTI9_HANDLER Vector9C
-#define STM32_EXTI10_HANDLER VectorE0
-#define STM32_EXTI11_HANDLER VectorE0
-#define STM32_EXTI12_HANDLER VectorE0
-#define STM32_EXTI13_HANDLER VectorE0
-#define STM32_EXTI14_HANDLER VectorE0
-#define STM32_EXTI15_HANDLER VectorE0
-#define STM32_EXTI1635_38_HANDLER Vector44 /* PVD PVM1..PVM4 */
-#define STM32_EXTI17_HANDLER Vector48 /* RTC */
-#define STM32_EXTI18_HANDLER Vector4C /* RTC (secure) */
-#define STM32_EXTI19_HANDLER Vector50 /* TAMP */
-#define STM32_EXTI20_HANDLER Vector54 /* TAMP (secure) */
-#define STM32_EXTI21_22_HANDLER Vector160 /* COMP1..2 */
-
-#define STM32_EXTI0_NUMBER 11
-#define STM32_EXTI1_NUMBER 12
-#define STM32_EXTI2_NUMBER 13
-#define STM32_EXTI3_NUMBER 14
-#define STM32_EXTI4_NUMBER 15
-#define STM32_EXTI5_NUMBER 16
-#define STM32_EXTI6_NUMBER 17
-#define STM32_EXTI7_NUMBER 18
-#define STM32_EXTI8_NUMBER 19
-#define STM32_EXTI9_NUMBER 20
-#define STM32_EXTI10_NUMBER 21
-#define STM32_EXTI11_NUMBER 22
-#define STM32_EXTI12_NUMBER 23
-#define STM32_EXTI13_NUMBER 24
-#define STM32_EXTI14_NUMBER 25
-#define STM32_EXTI15_NUMBER 26
-#define STM32_EXTI1635_38_NUMBER 1
-#define STM32_EXTI17_NUMBER 2
-#define STM32_EXTI18_NUMBER 3
-#define STM32_EXTI19_NUMBER 4
-#define STM32_EXTI20_NUMBER 5
-#define STM32_EXTI21_22_NUMBER 72
-
-/*
- * I2C units.
- */
-#define STM32_I2C1_EVENT_HANDLER Vector11C
-#define STM32_I2C1_ERROR_HANDLER Vector120
-#define STM32_I2C2_EVENT_HANDLER Vector124
-#define STM32_I2C2_ERROR_HANDLER Vector138
-#define STM32_I2C3_EVENT_HANDLER Vector188
-#define STM32_I2C3_ERROR_HANDLER Vector18C
-#define STM32_I2C4_EVENT_HANDLER Vector1B8
-#define STM32_I2C4_ERROR_HANDLER Vector1BC
-
-#define STM32_I2C1_EVENT_NUMBER 55
-#define STM32_I2C1_ERROR_NUMBER 56
-#define STM32_I2C2_EVENT_NUMBER 57
-#define STM32_I2C2_ERROR_NUMBER 58
-#define STM32_I2C3_EVENT_NUMBER 88
-#define STM32_I2C3_ERROR_NUMBER 89
-#define STM32_I2C4_EVENT_NUMBER 100
-#define STM32_I2C4_ERROR_NUMBER 101
-
-/*
- * OCTOSPI unit.
- */
-#define STM32_OCTOSPI1_HANDLER Vector170
-
-#define STM32_OCTOSPI1_NUMBER 76
-
-/*
- * SDMMC unit.
- */
-#define STM32_SDMMC1_HANDLER Vector178
-
-#define STM32_SDMMC1_NUMBER 78
-
-/*
- * TIM units.
- */
-#define STM32_TIM1_BRK_HANDLER VectorE4
-#define STM32_TIM1_UP_HANDLER VectorE8
-#define STM32_TIM1_TRGCO_HANDLER VectorEC
-#define STM32_TIM1_CC_HANDLER VectorF0
-#define STM32_TIM2_HANDLER VectorF4
-#define STM32_TIM3_HANDLER VectorF8
-#define STM32_TIM4_HANDLER VectorFC
-#define STM32_TIM5_HANDLER Vector100
-#define STM32_TIM6_HANDLER Vector104
-#define STM32_TIM7_HANDLER Vector108
-#define STM32_TIM8_BRK_HANDLER Vector10C
-#define STM32_TIM8_UP_HANDLER Vector110
-#define STM32_TIM8_TRGCO_HANDLER Vector114
-#define STM32_TIM8_CC_HANDLER Vector118
-#define STM32_TIM15_HANDLER Vector154
-#define STM32_TIM16_HANDLER Vector158
-#define STM32_TIM17_HANDLER Vector15C
-
-#define STM32_TIM1_BRK_NUMBER 41
-#define STM32_TIM1_UP_NUMBER 42
-#define STM32_TIM1_TRGCO_NUMBER 43
-#define STM32_TIM1_CC_NUMBER 44
-#define STM32_TIM2_NUMBER 45
-#define STM32_TIM3_NUMBER 46
-#define STM32_TIM4_NUMBER 47
-#define STM32_TIM5_NUMBER 48
-#define STM32_TIM6_NUMBER 49
-#define STM32_TIM7_NUMBER 50
-#define STM32_TIM8_BRK_NUMBER 51
-#define STM32_TIM8_UP_NUMBER 52
-#define STM32_TIM8_TRGCO_NUMBER 53
-#define STM32_TIM8_CC_NUMBER 54
-#define STM32_TIM15_NUMBER 69
-#define STM32_TIM16_NUMBER 70
-#define STM32_TIM17_NUMBER 71
-
-/*
- * USART/UART units.
- */
-#define STM32_USART1_HANDLER Vector134
-#define STM32_USART2_HANDLER Vector138
-#define STM32_USART3_HANDLER Vector13C
-#define STM32_UART4_HANDLER Vector140
-#define STM32_UART5_HANDLER Vector144
-#define STM32_LPUART1_HANDLER Vector148
-
-#define STM32_USART1_NUMBER 61
-#define STM32_USART2_NUMBER 62
-#define STM32_USART3_NUMBER 63
-#define STM32_UART4_NUMBER 64
-#define STM32_UART5_NUMBER 65
-#define STM32_LPUART1_NUMBER 66
-
-/*
- * USB/OTG units.
- */
-#define STM32_USB_FS_HANDLER Vector164
-
-#define STM32_USB_FS_NUMBER 73
-
-/*
- * FSMC unit.
- */
-#define STM32_FSMC_HANDLER Vector16C
-
-#define STM32_FSMC_NUMBER 75
-/** @} */
-
-/*===========================================================================*/
-/* 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 */
-
-/** @} */
+/*
+ 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/stm32_isr.h
+ * @brief STM32L5xx ISR handler header.
+ *
+ * @addtogroup STM32L5xx_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_TIM15_SUPPRESS_ISR
+#define STM32_TIM16_SUPPRESS_ISR
+#define STM32_TIM17_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_LPUART1_SUPPRESS_ISR
+/** @} */
+
+/**
+ * @name ISR names and numbers
+ * @{
+ */
+/*
+ * ADC unit.
+ */
+#define STM32_ADC12_HANDLER VectorD4
+
+#define STM32_ADC12_NUMBER 37
+
+/*
+ * FDCAN unit.
+ */
+#define STM32_FDCAN1_IT0_HANDLER VectorDC
+#define STM32_FDCAN1_IT1_HANDLER VectorE0
+
+#define STM32_FDCAN1_IT0_NUMBER 39
+#define STM32_FDCAN1_IT1_NUMBER 40
+
+/*
+ * DMA unit.
+ */
+#define STM32_DMA1_CH1_HANDLER VectorB4
+#define STM32_DMA1_CH2_HANDLER VectorB8
+#define STM32_DMA1_CH3_HANDLER VectorBC
+#define STM32_DMA1_CH4_HANDLER VectorC0
+#define STM32_DMA1_CH5_HANDLER VectorC4
+#define STM32_DMA1_CH6_HANDLER VectorC8
+#define STM32_DMA1_CH7_HANDLER VectorCC
+#define STM32_DMA1_CH8_HANDLER VectorD0
+#define STM32_DMA2_CH1_HANDLER Vector180
+#define STM32_DMA2_CH2_HANDLER Vector184
+#define STM32_DMA2_CH3_HANDLER Vector188
+#define STM32_DMA2_CH4_HANDLER Vector18C
+#define STM32_DMA2_CH5_HANDLER Vector190
+#define STM32_DMA2_CH6_HANDLER Vector194
+#define STM32_DMA2_CH7_HANDLER Vector198
+#define STM32_DMA2_CH8_HANDLER Vector19C
+
+#define STM32_DMA1_CH1_NUMBER 29
+#define STM32_DMA1_CH2_NUMBER 30
+#define STM32_DMA1_CH3_NUMBER 31
+#define STM32_DMA1_CH4_NUMBER 32
+#define STM32_DMA1_CH5_NUMBER 33
+#define STM32_DMA1_CH6_NUMBER 34
+#define STM32_DMA1_CH7_NUMBER 35
+#define STM32_DMA1_CH8_NUMBER 36
+#define STM32_DMA2_CH1_NUMBER 80
+#define STM32_DMA2_CH2_NUMBER 81
+#define STM32_DMA2_CH3_NUMBER 82
+#define STM32_DMA2_CH4_NUMBER 83
+#define STM32_DMA2_CH5_NUMBER 84
+#define STM32_DMA2_CH6_NUMBER 85
+#define STM32_DMA2_CH7_NUMBER 86
+#define STM32_DMA2_CH8_NUMBER 87
+
+/*
+ * 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_HANDLER Vector9C
+#define STM32_EXTI6_HANDLER Vector9C
+#define STM32_EXTI7_HANDLER Vector9C
+#define STM32_EXTI8_HANDLER Vector9C
+#define STM32_EXTI9_HANDLER Vector9C
+#define STM32_EXTI10_HANDLER VectorE0
+#define STM32_EXTI11_HANDLER VectorE0
+#define STM32_EXTI12_HANDLER VectorE0
+#define STM32_EXTI13_HANDLER VectorE0
+#define STM32_EXTI14_HANDLER VectorE0
+#define STM32_EXTI15_HANDLER VectorE0
+#define STM32_EXTI1635_38_HANDLER Vector44 /* PVD PVM1..PVM4 */
+#define STM32_EXTI17_HANDLER Vector48 /* RTC */
+#define STM32_EXTI18_HANDLER Vector4C /* RTC (secure) */
+#define STM32_EXTI19_HANDLER Vector50 /* TAMP */
+#define STM32_EXTI20_HANDLER Vector54 /* TAMP (secure) */
+#define STM32_EXTI21_22_HANDLER Vector160 /* COMP1..2 */
+
+#define STM32_EXTI0_NUMBER 11
+#define STM32_EXTI1_NUMBER 12
+#define STM32_EXTI2_NUMBER 13
+#define STM32_EXTI3_NUMBER 14
+#define STM32_EXTI4_NUMBER 15
+#define STM32_EXTI5_NUMBER 16
+#define STM32_EXTI6_NUMBER 17
+#define STM32_EXTI7_NUMBER 18
+#define STM32_EXTI8_NUMBER 19
+#define STM32_EXTI9_NUMBER 20
+#define STM32_EXTI10_NUMBER 21
+#define STM32_EXTI11_NUMBER 22
+#define STM32_EXTI12_NUMBER 23
+#define STM32_EXTI13_NUMBER 24
+#define STM32_EXTI14_NUMBER 25
+#define STM32_EXTI15_NUMBER 26
+#define STM32_EXTI1635_38_NUMBER 1
+#define STM32_EXTI17_NUMBER 2
+#define STM32_EXTI18_NUMBER 3
+#define STM32_EXTI19_NUMBER 4
+#define STM32_EXTI20_NUMBER 5
+#define STM32_EXTI21_22_NUMBER 72
+
+/*
+ * I2C units.
+ */
+#define STM32_I2C1_EVENT_HANDLER Vector11C
+#define STM32_I2C1_ERROR_HANDLER Vector120
+#define STM32_I2C2_EVENT_HANDLER Vector124
+#define STM32_I2C2_ERROR_HANDLER Vector138
+#define STM32_I2C3_EVENT_HANDLER Vector188
+#define STM32_I2C3_ERROR_HANDLER Vector18C
+#define STM32_I2C4_EVENT_HANDLER Vector1B8
+#define STM32_I2C4_ERROR_HANDLER Vector1BC
+
+#define STM32_I2C1_EVENT_NUMBER 55
+#define STM32_I2C1_ERROR_NUMBER 56
+#define STM32_I2C2_EVENT_NUMBER 57
+#define STM32_I2C2_ERROR_NUMBER 58
+#define STM32_I2C3_EVENT_NUMBER 88
+#define STM32_I2C3_ERROR_NUMBER 89
+#define STM32_I2C4_EVENT_NUMBER 100
+#define STM32_I2C4_ERROR_NUMBER 101
+
+/*
+ * OCTOSPI unit.
+ */
+#define STM32_OCTOSPI1_HANDLER Vector170
+
+#define STM32_OCTOSPI1_NUMBER 76
+
+/*
+ * SDMMC unit.
+ */
+#define STM32_SDMMC1_HANDLER Vector178
+
+#define STM32_SDMMC1_NUMBER 78
+
+/*
+ * TIM units.
+ */
+#define STM32_TIM1_BRK_HANDLER VectorE4
+#define STM32_TIM1_UP_HANDLER VectorE8
+#define STM32_TIM1_TRGCO_HANDLER VectorEC
+#define STM32_TIM1_CC_HANDLER VectorF0
+#define STM32_TIM2_HANDLER VectorF4
+#define STM32_TIM3_HANDLER VectorF8
+#define STM32_TIM4_HANDLER VectorFC
+#define STM32_TIM5_HANDLER Vector100
+#define STM32_TIM6_HANDLER Vector104
+#define STM32_TIM7_HANDLER Vector108
+#define STM32_TIM8_BRK_HANDLER Vector10C
+#define STM32_TIM8_UP_HANDLER Vector110
+#define STM32_TIM8_TRGCO_HANDLER Vector114
+#define STM32_TIM8_CC_HANDLER Vector118
+#define STM32_TIM15_HANDLER Vector154
+#define STM32_TIM16_HANDLER Vector158
+#define STM32_TIM17_HANDLER Vector15C
+
+#define STM32_TIM1_BRK_NUMBER 41
+#define STM32_TIM1_UP_NUMBER 42
+#define STM32_TIM1_TRGCO_NUMBER 43
+#define STM32_TIM1_CC_NUMBER 44
+#define STM32_TIM2_NUMBER 45
+#define STM32_TIM3_NUMBER 46
+#define STM32_TIM4_NUMBER 47
+#define STM32_TIM5_NUMBER 48
+#define STM32_TIM6_NUMBER 49
+#define STM32_TIM7_NUMBER 50
+#define STM32_TIM8_BRK_NUMBER 51
+#define STM32_TIM8_UP_NUMBER 52
+#define STM32_TIM8_TRGCO_NUMBER 53
+#define STM32_TIM8_CC_NUMBER 54
+#define STM32_TIM15_NUMBER 69
+#define STM32_TIM16_NUMBER 70
+#define STM32_TIM17_NUMBER 71
+
+/*
+ * USART/UART units.
+ */
+#define STM32_USART1_HANDLER Vector134
+#define STM32_USART2_HANDLER Vector138
+#define STM32_USART3_HANDLER Vector13C
+#define STM32_UART4_HANDLER Vector140
+#define STM32_UART5_HANDLER Vector144
+#define STM32_LPUART1_HANDLER Vector148
+
+#define STM32_USART1_NUMBER 61
+#define STM32_USART2_NUMBER 62
+#define STM32_USART3_NUMBER 63
+#define STM32_UART4_NUMBER 64
+#define STM32_UART5_NUMBER 65
+#define STM32_LPUART1_NUMBER 66
+
+/*
+ * USB/OTG units.
+ */
+#define STM32_USB_FS_HANDLER Vector164
+
+#define STM32_USB_FS_NUMBER 73
+
+/*
+ * FSMC unit.
+ */
+#define STM32_FSMC_HANDLER Vector16C
+
+#define STM32_FSMC_NUMBER 75
+/** @} */
+
+/*===========================================================================*/
+/* 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/STM32/STM32L5xx/stm32_rcc.h b/os/hal/ports/STM32/STM32L5xx/stm32_rcc.h
index 83e0ee0c72..6302b9e887 100644
--- a/os/hal/ports/STM32/STM32L5xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L5xx/stm32_rcc.h
@@ -1,1254 +1,1254 @@
-/*
- 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/stm32_rcc.h
- * @brief RCC helper driver header.
- * @note This file requires definitions from the ST header file
- * @p stm32l5xx.h.
- *
- * @addtogroup STM32L5xx_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 (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R1(mask, lp) { \
- RCC->APB1ENR1 |= (mask); \
- if (lp) \
- RCC->APB1SMENR1 |= (mask); \
- else \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R1(mask) { \
- RCC->APB1ENR1 &= ~(mask); \
- RCC->APB1SMENR1 &= ~(mask); \
- (void)RCC->APB1SMENR1; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R1).
- *
- * @param[in] mask APB1 R1 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R1(mask) { \
- RCC->APB1RSTR1 |= (mask); \
- RCC->APB1RSTR1 &= ~(mask); \
- (void)RCC->APB1RSTR1; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB1R2(mask, lp) { \
- RCC->APB1ENR2 |= (mask); \
- if (lp) \
- RCC->APB1SMENR2 |= (mask); \
- else \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccDisableAPB1R2(mask) { \
- RCC->APB1ENR2 &= ~(mask); \
- RCC->APB1SMENR2 &= ~(mask); \
- (void)RCC->APB1SMENR2; \
-}
-
-/**
- * @brief Resets one or more peripheral on the APB1 bus (R2).
- *
- * @param[in] mask APB1 R2 peripherals mask
- *
- * @api
- */
-#define rccResetAPB1R2(mask) { \
- RCC->APB1RSTR2 |= (mask); \
- RCC->APB1RSTR2 &= ~(mask); \
- (void)RCC->APB1RSTR2; \
-}
-
-/**
- * @brief Enables the clock of one or more peripheral on the APB2 bus.
- *
- * @param[in] mask APB2 peripherals mask
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableAPB2(mask, lp) { \
- RCC->APB2ENR |= (mask); \
- if (lp) \
- RCC->APB2SMENR |= (mask); \
- else \
- RCC->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->APB2SMENR &= ~(mask); \
- (void)RCC->APB2SMENR; \
-}
-
-/**
- * @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->AHB1SMENR |= (mask); \
- else \
- RCC->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB1SMENR &= ~(mask); \
- (void)RCC->AHB1SMENR; \
-}
-
-/**
- * @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->AHB2SMENR |= (mask); \
- else \
- RCC->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB2SMENR &= ~(mask); \
- (void)RCC->AHB2SMENR; \
-}
-
-/**
- * @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->AHB3SMENR |= (mask); \
- else \
- RCC->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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->AHB3SMENR &= ~(mask); \
- (void)RCC->AHB3SMENR; \
-}
-
-/**
- * @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 Enables the ADC1/ADC2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableADC12(lp) rccEnableAHB2(RCC_AHB2ENR_ADCEN, lp)
-
-/**
- * @brief Disables the ADC1/ADC2 peripheral clock.
- *
- * @api
- */
-#define rccDisableADC12() rccDisableAHB2(RCC_AHB2ENR_ADCEN)
-
-/**
- * @brief Resets the ADC1/ADC2 peripheral.
- *
- * @api
- */
-#define rccResetADC12() rccResetAHB2(RCC_AHB2RSTR_ADCRST)
-/** @} */
-
-/**
- * @name DAC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DAC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDAC1(lp) rccEnableAPB1R1(RCC_APB1ENR1_DAC1EN, lp)
-
-/**
- * @brief Disables the DAC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableDAC1() rccDisableAPB1R1(RCC_APB1ENR1_DAC1EN)
-
-/**
- * @brief Resets the DAC1 peripheral.
- *
- * @api
- */
-#define rccResetDAC1() rccResetAPB1R1(RCC_APB1RSTR1_DAC1RST)
-/** @} */
-
-/**
- * @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 DMAMUX peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the DMAMUX peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableDMAMUX(lp) rccEnableAHB1(RCC_AHB1ENR_DMAMUX1EN, lp)
-
-/**
- * @brief Disables the DMAMUX peripheral clock.
- *
- * @api
- */
-#define rccDisableDMAMUX() rccDisableAHB1(RCC_AHB1ENR_DMAMUX1EN)
-
-/**
- * @brief Resets the DMAMUX peripheral.
- *
- * @api
- */
-#define rccResetDMAMUX() rccResetAHB1(RCC_AHB1RSTR_DMAMUX1RST)
-/** @} */
-
-/**
- * @name PWR interface specific RCC operations
- * @{
- */
-/**
- * @brief Enables the PWR interface clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
-
-/**
- * @brief Disables PWR interface clock.
- *
- * @api
- */
-#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
-
-/**
- * @brief Resets the PWR interface.
- *
- * @api
- */
-#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
-/** @} */
-
-/**
- * @name FDCAN peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the FDCAN1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableFDCAN1(lp) rccEnableAPB1R2(RCC_APB1ENR2_FDCAN1EN, lp)
-
-/**
- * @brief Disables the FDCAN1 peripheral clock.
- *
- * @api
- */
-#define rccDisableFDCAN1() rccDisableAPB1R2(RCC_APB1ENR2_FDCAN1EN)
-
-/**
- * @brief Resets the FDCAN1 peripheral.
- *
- * @api
- */
-#define rccResetFDCAN1() rccResetAPB1R2(RCC_APB1RSTR2_FDCAN1RST)
-
-/**
- * @name I2C peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the I2C1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
-
-/**
- * @brief Disables the I2C1 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
-
-/**
- * @brief Resets the I2C1 peripheral.
- *
- * @api
- */
-#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
-
-/**
- * @brief Enables the I2C2 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
-
-/**
- * @brief Disables the I2C2 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
-
-/**
- * @brief Resets the I2C2 peripheral.
- *
- * @api
- */
-#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
-
-/**
- * @brief Enables the I2C3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
-
-/**
- * @brief Disables the I2C3 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
-
-/**
- * @brief Resets the I2C3 peripheral.
- *
- * @api
- */
-#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
-
-/**
- * @brief Enables the I2C4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
-
-/**
- * @brief Disables the I2C4 peripheral clock.
- *
- * @api
- */
-#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
-
-/**
- * @brief Resets the I2C4 peripheral.
- *
- * @api
- */
-#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
-/** @} */
-
-/**
- * @name OCTOSPI peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the OCTOSPI1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableOCTOSPI1(lp) rccEnableAHB3(RCC_AHB3ENR_OSPI1EN, lp)
-
-/**
- * @brief Disables the OCTOSPI1 peripheral clock.
- *
- * @api
- */
-#define rccDisableOCTOSPI1() rccDisableAHB3(RCC_AHB3ENR_OSPI1EN)
-
-/**
- * @brief Resets the OCTOSPI1 peripheral.
- *
- * @api
- */
-#define rccResetOCTOSPI1() rccResetAHB3(RCC_AHB3RSTR_OSPI1RST)
-
-/**
- * @name RNG peripherals specific RCC operations
- * @{
- */
-/**
- * @brief Enables the RNG peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
-
-/**
- * @brief Disables the RNG peripheral clock.
- *
- * @api
- */
-#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
-
-/**
- * @brief Resets the RNG peripheral.
- *
- * @api
- */
-#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
-/** @} */
-
-/**
- * @name SDMMC peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the SDMMC1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp)
-
-/**
- * @brief Disables the SDMMC1 peripheral clock.
- *
- * @api
- */
-#define rccDisableSDMMC1() rccDisableAPB2(RCC_APB2ENR_SDMMC1EN)
-
-/**
- * @brief Resets the SDMMC1 peripheral.
- *
- * @api
- */
-#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
-
-/**
- * @brief Disables the SPI2 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
-
-/**
- * @brief Resets the SPI2 peripheral.
- *
- * @api
- */
-#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
-
-/**
- * @brief Enables the SPI3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
-
-/**
- * @brief Disables the SPI3 peripheral clock.
- *
- * @api
- */
-#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
-
-/**
- * @brief Resets the SPI3 peripheral.
- *
- * @api
- */
-#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_SPI3RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
-
-/**
- * @brief Disables the TIM2 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
-
-/**
- * @brief Resets the TIM2 peripheral.
- *
- * @api
- */
-#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
-
-/**
- * @brief Enables the TIM3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
-
-/**
- * @brief Disables the TIM3 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
-
-/**
- * @brief Enables the TIM4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
-
-/**
- * @brief Disables the TIM4 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
-
-/**
- * @brief Resets the TIM4 peripheral.
- *
- * @api
- */
-#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
-
-/**
- * @brief Enables the TIM5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
-
-/**
- * @brief Disables the TIM5 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
-
-/**
- * @brief Resets the TIM5 peripheral.
- *
- * @api
- */
-#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
-
-/**
- * @brief Enables the TIM6 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
-
-/**
- * @brief Disables the TIM6 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
-
-/**
- * @brief Resets the TIM6 peripheral.
- *
- * @api
- */
-#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
-
-/**
- * @brief Enables the TIM7 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
-
-/**
- * @brief Disables the TIM7 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
-
-/**
- * @brief Resets the TIM7 peripheral.
- *
- * @api
- */
-#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
-
-/**
- * @brief Disables the TIM15 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
-
-/**
- * @brief Resets the TIM15 peripheral.
- *
- * @api
- */
-#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
-
-/**
- * @brief Enables the TIM16 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
-
-/**
- * @brief Disables the TIM16 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
-
-/**
- * @brief Resets the TIM16 peripheral.
- *
- * @api
- */
-#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
-
-/**
- * @brief Enables the TIM17 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
-
-/**
- * @brief Disables the TIM17 peripheral clock.
- *
- * @api
- */
-#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
-
-/**
- * @brief Resets the TIM17 peripheral.
- *
- * @api
- */
-#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
-/** @} */
-
-/**
- * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
-
-/**
- * @brief Disables the USART2 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
-
-/**
- * @brief Resets the USART2 peripheral.
- *
- * @api
- */
-#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
-
-/**
- * @brief Enables the USART3 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
-
-/**
- * @brief Disables the USART3 peripheral clock.
- *
- * @api
- */
-#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
-
-/**
- * @brief Resets the USART3 peripheral.
- *
- * @api
- */
-#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
-
-/**
- * @brief Enables the UART4 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
-
-/**
- * @brief Disables the UART4 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
-
-/**
- * @brief Resets the UART4 peripheral.
- *
- * @api
- */
-#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
-
-/**
- * @brief Enables the UART5 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
-
-/**
- * @brief Disables the UART5 peripheral clock.
- *
- * @api
- */
-#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
-
-/**
- * @brief Resets the UART5 peripheral.
- *
- * @api
- */
-#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
-
-/**
- * @brief Enables the LPUART1 peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
-
-/**
- * @brief Disables the LPUART1 peripheral clock.
- *
- * @api
- */
-#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
-
-/**
- * @brief Resets the USART1 peripheral.
- *
- * @api
- */
-#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
-/** @} */
-
-/**
- * @name USB peripheral specific RCC operations
- * @{
- */
-/**
- * @brief Enables the USB peripheral clock.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBFSEN, lp)
-
-/**
- * @brief Disables the USB peripheral clock.
- *
- * @api
- */
-#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBFSEN)
-
-/**
- * @brief Resets the USB peripheral.
- *
- * @api
- */
-#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBFSRST)
-/** @} */
-
-/**
- * @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
- */
-#define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
-
-/**
- * @brief Disables the FSMC peripheral clock.
- *
- * @api
- */
-#define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
-
-/**
- * @brief Resets the FSMC peripheral.
- *
- * @api
- */
-#define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
-/** @} */
-
-/*===========================================================================*/
-/* External declarations. */
-/*===========================================================================*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* STM32_RCC_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/stm32_rcc.h
+ * @brief RCC helper driver header.
+ * @note This file requires definitions from the ST header file
+ * @p stm32l5xx.h.
+ *
+ * @addtogroup STM32L5xx_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 (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R1(mask, lp) { \
+ RCC->APB1ENR1 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR1 |= (mask); \
+ else \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R1(mask) { \
+ RCC->APB1ENR1 &= ~(mask); \
+ RCC->APB1SMENR1 &= ~(mask); \
+ (void)RCC->APB1SMENR1; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R1).
+ *
+ * @param[in] mask APB1 R1 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R1(mask) { \
+ RCC->APB1RSTR1 |= (mask); \
+ RCC->APB1RSTR1 &= ~(mask); \
+ (void)RCC->APB1RSTR1; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB1R2(mask, lp) { \
+ RCC->APB1ENR2 |= (mask); \
+ if (lp) \
+ RCC->APB1SMENR2 |= (mask); \
+ else \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Disables the clock of one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccDisableAPB1R2(mask) { \
+ RCC->APB1ENR2 &= ~(mask); \
+ RCC->APB1SMENR2 &= ~(mask); \
+ (void)RCC->APB1SMENR2; \
+}
+
+/**
+ * @brief Resets one or more peripheral on the APB1 bus (R2).
+ *
+ * @param[in] mask APB1 R2 peripherals mask
+ *
+ * @api
+ */
+#define rccResetAPB1R2(mask) { \
+ RCC->APB1RSTR2 |= (mask); \
+ RCC->APB1RSTR2 &= ~(mask); \
+ (void)RCC->APB1RSTR2; \
+}
+
+/**
+ * @brief Enables the clock of one or more peripheral on the APB2 bus.
+ *
+ * @param[in] mask APB2 peripherals mask
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableAPB2(mask, lp) { \
+ RCC->APB2ENR |= (mask); \
+ if (lp) \
+ RCC->APB2SMENR |= (mask); \
+ else \
+ RCC->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->APB2SMENR &= ~(mask); \
+ (void)RCC->APB2SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR |= (mask); \
+ else \
+ RCC->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB1SMENR &= ~(mask); \
+ (void)RCC->AHB1SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR |= (mask); \
+ else \
+ RCC->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB2SMENR &= ~(mask); \
+ (void)RCC->AHB2SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR |= (mask); \
+ else \
+ RCC->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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->AHB3SMENR &= ~(mask); \
+ (void)RCC->AHB3SMENR; \
+}
+
+/**
+ * @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 Enables the ADC1/ADC2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableADC12(lp) rccEnableAHB2(RCC_AHB2ENR_ADCEN, lp)
+
+/**
+ * @brief Disables the ADC1/ADC2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableADC12() rccDisableAHB2(RCC_AHB2ENR_ADCEN)
+
+/**
+ * @brief Resets the ADC1/ADC2 peripheral.
+ *
+ * @api
+ */
+#define rccResetADC12() rccResetAHB2(RCC_AHB2RSTR_ADCRST)
+/** @} */
+
+/**
+ * @name DAC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DAC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDAC1(lp) rccEnableAPB1R1(RCC_APB1ENR1_DAC1EN, lp)
+
+/**
+ * @brief Disables the DAC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDAC1() rccDisableAPB1R1(RCC_APB1ENR1_DAC1EN)
+
+/**
+ * @brief Resets the DAC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetDAC1() rccResetAPB1R1(RCC_APB1RSTR1_DAC1RST)
+/** @} */
+
+/**
+ * @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 DMAMUX peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the DMAMUX peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableDMAMUX(lp) rccEnableAHB1(RCC_AHB1ENR_DMAMUX1EN, lp)
+
+/**
+ * @brief Disables the DMAMUX peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableDMAMUX() rccDisableAHB1(RCC_AHB1ENR_DMAMUX1EN)
+
+/**
+ * @brief Resets the DMAMUX peripheral.
+ *
+ * @api
+ */
+#define rccResetDMAMUX() rccResetAHB1(RCC_AHB1RSTR_DMAMUX1RST)
+/** @} */
+
+/**
+ * @name PWR interface specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the PWR interface clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnablePWRInterface(lp) rccEnableAPB1R1(RCC_APB1ENR1_PWREN, lp)
+
+/**
+ * @brief Disables PWR interface clock.
+ *
+ * @api
+ */
+#define rccDisablePWRInterface() rccDisableAPB1R1(RCC_APB1ENR1_PWREN)
+
+/**
+ * @brief Resets the PWR interface.
+ *
+ * @api
+ */
+#define rccResetPWRInterface() rccResetAPB1R1(RCC_APB1RSTR1_PWRRST)
+/** @} */
+
+/**
+ * @name FDCAN peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the FDCAN1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableFDCAN1(lp) rccEnableAPB1R2(RCC_APB1ENR2_FDCAN1EN, lp)
+
+/**
+ * @brief Disables the FDCAN1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFDCAN1() rccDisableAPB1R2(RCC_APB1ENR2_FDCAN1EN)
+
+/**
+ * @brief Resets the FDCAN1 peripheral.
+ *
+ * @api
+ */
+#define rccResetFDCAN1() rccResetAPB1R2(RCC_APB1RSTR2_FDCAN1RST)
+
+/**
+ * @name I2C peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the I2C1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C1(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C1EN, lp)
+
+/**
+ * @brief Disables the I2C1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C1() rccDisableAPB1R1(RCC_APB1ENR1_I2C1EN)
+
+/**
+ * @brief Resets the I2C1 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C1() rccResetAPB1R1(RCC_APB1RSTR1_I2C1RST)
+
+/**
+ * @brief Enables the I2C2 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C2(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C2EN, lp)
+
+/**
+ * @brief Disables the I2C2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C2() rccDisableAPB1R1(RCC_APB1ENR1_I2C2EN)
+
+/**
+ * @brief Resets the I2C2 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C2() rccResetAPB1R1(RCC_APB1RSTR1_I2C2RST)
+
+/**
+ * @brief Enables the I2C3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C3(lp) rccEnableAPB1R1(RCC_APB1ENR1_I2C3EN, lp)
+
+/**
+ * @brief Disables the I2C3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C3() rccDisableAPB1R1(RCC_APB1ENR1_I2C3EN)
+
+/**
+ * @brief Resets the I2C3 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C3() rccResetAPB1R1(RCC_APB1RSTR1_I2C3RST)
+
+/**
+ * @brief Enables the I2C4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableI2C4(lp) rccEnableAPB1R2(RCC_APB1ENR2_I2C4EN, lp)
+
+/**
+ * @brief Disables the I2C4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableI2C4() rccDisableAPB1R1(RCC_APB1ENR2_I2C4EN)
+
+/**
+ * @brief Resets the I2C4 peripheral.
+ *
+ * @api
+ */
+#define rccResetI2C4() rccResetAPB1R1(RCC_APB1RSTR2_I2C4RST)
+/** @} */
+
+/**
+ * @name OCTOSPI peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the OCTOSPI1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableOCTOSPI1(lp) rccEnableAHB3(RCC_AHB3ENR_OSPI1EN, lp)
+
+/**
+ * @brief Disables the OCTOSPI1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableOCTOSPI1() rccDisableAHB3(RCC_AHB3ENR_OSPI1EN)
+
+/**
+ * @brief Resets the OCTOSPI1 peripheral.
+ *
+ * @api
+ */
+#define rccResetOCTOSPI1() rccResetAHB3(RCC_AHB3RSTR_OSPI1RST)
+
+/**
+ * @name RNG peripherals specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the RNG peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableRNG(lp) rccEnableAHB2(RCC_AHB2ENR_RNGEN, lp)
+
+/**
+ * @brief Disables the RNG peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableRNG() rccDisableAHB2(RCC_AHB2ENR_RNGEN)
+
+/**
+ * @brief Resets the RNG peripheral.
+ *
+ * @api
+ */
+#define rccResetRNG() rccResetAHB2(RCC_AHB2RSTR_RNGRST)
+/** @} */
+
+/**
+ * @name SDMMC peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the SDMMC1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSDMMC1(lp) rccEnableAPB2(RCC_APB2ENR_SDMMC1EN, lp)
+
+/**
+ * @brief Disables the SDMMC1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSDMMC1() rccDisableAPB2(RCC_APB2ENR_SDMMC1EN)
+
+/**
+ * @brief Resets the SDMMC1 peripheral.
+ *
+ * @api
+ */
+#define rccResetSDMMC1() rccResetAPB2(RCC_APB2RSTR_SDMMC1RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_SPI2EN, lp)
+
+/**
+ * @brief Disables the SPI2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI2() rccDisableAPB1R1(RCC_APB1ENR1_SPI2EN)
+
+/**
+ * @brief Resets the SPI2 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI2() rccResetAPB1R1(RCC_APB1RSTR1_SPI2RST)
+
+/**
+ * @brief Enables the SPI3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableSPI3(lp) rccEnableAPB1R1(RCC_APB1ENR1_SPI3EN, lp)
+
+/**
+ * @brief Disables the SPI3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableSPI3() rccDisableAPB1R1(RCC_APB1ENR1_SPI3EN)
+
+/**
+ * @brief Resets the SPI3 peripheral.
+ *
+ * @api
+ */
+#define rccResetSPI3() rccResetAPB1R1(RCC_APB1RSTR1_SPI3RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_TIM2EN, lp)
+
+/**
+ * @brief Disables the TIM2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM2() rccDisableAPB1R1(RCC_APB1ENR1_TIM2EN)
+
+/**
+ * @brief Resets the TIM2 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM2() rccResetAPB1R1(RCC_APB1RSTR1_TIM2RST)
+
+/**
+ * @brief Enables the TIM3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM3(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM3EN, lp)
+
+/**
+ * @brief Disables the TIM3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM3() rccDisableAPB1R1(RCC_APB1ENR1_TIM3EN)
+
+/**
+ * @brief Resets the TIM3 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM3() rccResetAPB1R1(RCC_APB1RSTR1_TIM3RST)
+
+/**
+ * @brief Enables the TIM4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM4(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM4EN, lp)
+
+/**
+ * @brief Disables the TIM4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM4() rccDisableAPB1R1(RCC_APB1ENR1_TIM4EN)
+
+/**
+ * @brief Resets the TIM4 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM4() rccResetAPB1R1(RCC_APB1RSTR1_TIM4RST)
+
+/**
+ * @brief Enables the TIM5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM5(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM5EN, lp)
+
+/**
+ * @brief Disables the TIM5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM5() rccDisableAPB1R1(RCC_APB1ENR1_TIM5EN)
+
+/**
+ * @brief Resets the TIM5 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM5() rccResetAPB1R1(RCC_APB1RSTR1_TIM5RST)
+
+/**
+ * @brief Enables the TIM6 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM6(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM6EN, lp)
+
+/**
+ * @brief Disables the TIM6 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM6() rccDisableAPB1R1(RCC_APB1ENR1_TIM6EN)
+
+/**
+ * @brief Resets the TIM6 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM6() rccResetAPB1R1(RCC_APB1RSTR1_TIM6RST)
+
+/**
+ * @brief Enables the TIM7 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM7(lp) rccEnableAPB1R1(RCC_APB1ENR1_TIM7EN, lp)
+
+/**
+ * @brief Disables the TIM7 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM7() rccDisableAPB1R1(RCC_APB1ENR1_TIM7EN)
+
+/**
+ * @brief Resets the TIM7 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM7() rccResetAPB1R1(RCC_APB1RSTR1_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 TIM15 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM15(lp) rccEnableAPB2(RCC_APB2ENR_TIM15EN, lp)
+
+/**
+ * @brief Disables the TIM15 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM15() rccDisableAPB2(RCC_APB2ENR_TIM15EN)
+
+/**
+ * @brief Resets the TIM15 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM15() rccResetAPB2(RCC_APB2RSTR_TIM15RST)
+
+/**
+ * @brief Enables the TIM16 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM16(lp) rccEnableAPB2(RCC_APB2ENR_TIM16EN, lp)
+
+/**
+ * @brief Disables the TIM16 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM16() rccDisableAPB2(RCC_APB2ENR_TIM16EN)
+
+/**
+ * @brief Resets the TIM16 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM16() rccResetAPB2(RCC_APB2RSTR_TIM16RST)
+
+/**
+ * @brief Enables the TIM17 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableTIM17(lp) rccEnableAPB2(RCC_APB2ENR_TIM17EN, lp)
+
+/**
+ * @brief Disables the TIM17 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableTIM17() rccDisableAPB2(RCC_APB2ENR_TIM17EN)
+
+/**
+ * @brief Resets the TIM17 peripheral.
+ *
+ * @api
+ */
+#define rccResetTIM17() rccResetAPB2(RCC_APB2RSTR_TIM17RST)
+/** @} */
+
+/**
+ * @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) rccEnableAPB1R1(RCC_APB1ENR1_USART2EN, lp)
+
+/**
+ * @brief Disables the USART2 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART2() rccDisableAPB1R1(RCC_APB1ENR1_USART2EN)
+
+/**
+ * @brief Resets the USART2 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART2() rccResetAPB1R1(RCC_APB1RSTR1_USART2RST)
+
+/**
+ * @brief Enables the USART3 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSART3(lp) rccEnableAPB1R1(RCC_APB1ENR1_USART3EN, lp)
+
+/**
+ * @brief Disables the USART3 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSART3() rccDisableAPB1R1(RCC_APB1ENR1_USART3EN)
+
+/**
+ * @brief Resets the USART3 peripheral.
+ *
+ * @api
+ */
+#define rccResetUSART3() rccResetAPB1R1(RCC_APB1RSTR1_USART3RST)
+
+/**
+ * @brief Enables the UART4 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART4(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART4EN, lp)
+
+/**
+ * @brief Disables the UART4 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART4() rccDisableAPB1R1(RCC_APB1ENR1_UART4EN)
+
+/**
+ * @brief Resets the UART4 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART4() rccResetAPB1R1(RCC_APB1RSTR1_UART4RST)
+
+/**
+ * @brief Enables the UART5 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUART5(lp) rccEnableAPB1R1(RCC_APB1ENR1_UART5EN, lp)
+
+/**
+ * @brief Disables the UART5 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUART5() rccDisableAPB1R1(RCC_APB1ENR1_UART5EN)
+
+/**
+ * @brief Resets the UART5 peripheral.
+ *
+ * @api
+ */
+#define rccResetUART5() rccResetAPB1R1(RCC_APB1RSTR1_UART5RST)
+
+/**
+ * @brief Enables the LPUART1 peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableLPUART1(lp) rccEnableAPB1R2(RCC_APB1ENR2_LPUART1EN, lp)
+
+/**
+ * @brief Disables the LPUART1 peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableLPUART1() rccDisableAPB1R2(RCC_APB1ENR2_LPUART1EN)
+
+/**
+ * @brief Resets the USART1 peripheral.
+ *
+ * @api
+ */
+#define rccResetLPUART1() rccResetAPB1R2(RCC_APB1RSTR2_LPUART1RST)
+/** @} */
+
+/**
+ * @name USB peripheral specific RCC operations
+ * @{
+ */
+/**
+ * @brief Enables the USB peripheral clock.
+ *
+ * @param[in] lp low power enable flag
+ *
+ * @api
+ */
+#define rccEnableUSB(lp) rccEnableAPB1R1(RCC_APB1ENR1_USBFSEN, lp)
+
+/**
+ * @brief Disables the USB peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableUSB() rccDisableAPB1R1(RCC_APB1ENR1_USBFSEN)
+
+/**
+ * @brief Resets the USB peripheral.
+ *
+ * @api
+ */
+#define rccResetUSB() rccResetAPB1R1(RCC_APB1RSTR1_USBFSRST)
+/** @} */
+
+/**
+ * @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
+ */
+#define rccEnableFSMC(lp) rccEnableAHB3(RCC_AHB3ENR_FMCEN, lp)
+
+/**
+ * @brief Disables the FSMC peripheral clock.
+ *
+ * @api
+ */
+#define rccDisableFSMC() rccDisableAHB3(RCC_AHB3ENR_FMCEN)
+
+/**
+ * @brief Resets the FSMC peripheral.
+ *
+ * @api
+ */
+#define rccResetFSMC() rccResetAHB3(RCC_AHB3RSTR_FMCRST)
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32_RCC_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L5xx/stm32_registry.h b/os/hal/ports/STM32/STM32L5xx/stm32_registry.h
index 1b0b0246ed..ca3169d586 100644
--- a/os/hal/ports/STM32/STM32L5xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L5xx/stm32_registry.h
@@ -1,277 +1,277 @@
-/*
- 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/stm32_registry.h
- * @brief STM32L5xx capabilities registry.
- *
- * @addtogroup HAL
- * @{
- */
-
-#ifndef STM32_REGISTRY_H
-#define STM32_REGISTRY_H
-
-/*===========================================================================*/
-/* Platform capabilities. */
-/*===========================================================================*/
-
-/**
- * @name STM32L5xx capabilities
- * @{
- */
-
-/*===========================================================================*/
-/* Common. */
-/*===========================================================================*/
-
-/* RNG attributes.*/
-#define STM32_HAS_RNG1 TRUE
-
-/* RTC attributes.*/
-#define STM32_HAS_RTC TRUE
-#define STM32_RTC_HAS_SUBSECONDS TRUE
-#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
-#define STM32_RTC_NUM_ALARMS 2
-#define STM32_RTC_STORAGE_SIZE 128
-#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 18
-#define STM32_RTC_TAMP_STAMP_EXTI 19
-#define STM32_RTC_WKUP_EXTI 20
-#define STM32_RTC_IRQ_ENABLE() do { \
- nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
- nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
- nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
-} while (false)
-
-#if defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) || \
- defined(__DOXYGEN__)
-#define STM32_HAS_HASH1 TRUE
-#define STM32_HAS_CRYP1 TRUE
-#else
-#define STM32_HAS_HASH1 FALSE
-#define STM32_HAS_CRYP1 FALSE
-#endif
-
-/*===========================================================================*/
-/* STM32L4yyxx+. */
-/*===========================================================================*/
-
-#if defined(STM32L552xx) || defined(__DOXYGEN__)
-
-/* ADC attributes.*/
-#define STM32_HAS_ADC1 TRUE
-#define STM32_HAS_ADC2 TRUE
-#define STM32_HAS_ADC3 FALSE
-#define STM32_HAS_ADC4 FALSE
-
-/* CAN attributes.*/
-#define STM32_HAS_CAN1 FALSE
-#define STM32_HAS_CAN2 FALSE
-#define STM32_HAS_CAN3 FALSE
-
-/* DAC attributes.*/
-#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_HAS_DAC1_CH2 TRUE
-#define STM32_HAS_DAC2_CH1 FALSE
-#define STM32_HAS_DAC2_CH2 FALSE
-
-/* DMA attributes.*/
-#define STM32_ADVANCED_DMA TRUE
-#define STM32_DMA_SUPPORTS_DMAMUX TRUE
-#define STM32_DMA_SUPPORTS_CSELR FALSE
-#define STM32_DMA1_NUM_CHANNELS 8
-#define STM32_DMA2_NUM_CHANNELS 8
-
-/* ETH attributes.*/
-#define STM32_HAS_ETH FALSE
-
-/* EXTI attributes.*/
-#define STM32_EXTI_NUM_LINES 43
-#define STM32_EXTI_IMR1_MASK 0xFF9E0000U
-#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
-
-/* FDCAN attributes.*/
-
-/* Flash attributes.*/
-#define STM32_FLASH_NUMBER_OF_BANKS 2
-
-/* 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_GPIOF TRUE
-#define STM32_HAS_GPIOG TRUE
-#define STM32_HAS_GPIOH TRUE
-#define STM32_HAS_GPIOI FALSE
-#define STM32_HAS_GPIOJ FALSE
-#define STM32_HAS_GPIOK FALSE
-#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
- RCC_AHB2ENR_GPIOBEN | \
- RCC_AHB2ENR_GPIOCEN | \
- RCC_AHB2ENR_GPIODEN | \
- RCC_AHB2ENR_GPIOEEN | \
- RCC_AHB2ENR_GPIOFEN | \
- RCC_AHB2ENR_GPIOGEN | \
- RCC_AHB2ENR_GPIOHEN)
-
-/* I2C attributes.*/
-#define STM32_HAS_I2C1 TRUE
-#define STM32_HAS_I2C2 TRUE
-#define STM32_HAS_I2C3 TRUE
-#define STM32_HAS_I2C4 TRUE
-
-/* OCTOSPI attributes.*/
-#define STM32_HAS_OCTOSPI1 TRUE
-#define STM32_HAS_OCTOSPI2 FALSE
-
-/* QUADSPI attributes.*/
-#define STM32_HAS_QUADSPI1 FALSE
-
-/* SDMMC attributes.*/
-#define STM32_HAS_SDMMC1 TRUE
-#define STM32_HAS_SDMMC2 FALSE
-
-/* SPI attributes.*/
-#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI1_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI2 TRUE
-#define STM32_SPI2_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI3 TRUE
-#define STM32_SPI3_SUPPORTS_I2S FALSE
-
-#define STM32_HAS_SPI4 FALSE
-#define STM32_HAS_SPI5 FALSE
-#define STM32_HAS_SPI6 FALSE
-
-/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 6
-
-#define STM32_HAS_TIM1 TRUE
-#define STM32_TIM1_IS_32BITS FALSE
-#define STM32_TIM1_CHANNELS 6
-
-#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 6
-
-#define STM32_HAS_TIM15 TRUE
-#define STM32_TIM15_IS_32BITS FALSE
-#define STM32_TIM15_CHANNELS 2
-
-#define STM32_HAS_TIM16 TRUE
-#define STM32_TIM16_IS_32BITS FALSE
-#define STM32_TIM16_CHANNELS 2
-
-#define STM32_HAS_TIM17 TRUE
-#define STM32_TIM17_IS_32BITS FALSE
-#define STM32_TIM17_CHANNELS 2
-
-#define STM32_HAS_TIM9 FALSE
-#define STM32_HAS_TIM10 FALSE
-#define STM32_HAS_TIM11 FALSE
-#define STM32_HAS_TIM12 FALSE
-#define STM32_HAS_TIM13 FALSE
-#define STM32_HAS_TIM14 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_HAS_USART2 TRUE
-#define STM32_HAS_USART3 TRUE
-#define STM32_HAS_UART4 TRUE
-#define STM32_HAS_UART5 TRUE
-#define STM32_HAS_LPUART1 TRUE
-#define STM32_HAS_USART6 FALSE
-#define STM32_HAS_UART7 FALSE
-#define STM32_HAS_UART8 FALSE
-
-/* USB attributes.*/
-#define STM32_HAS_USB TRUE
-#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
-#define STM32_USB_PMA_SIZE 1024
-#define STM32_USB_HAS_BCDR FALSE
-
-#define STM32_HAS_OTG1 FALSE
-#define STM32_HAS_OTG2 FALSE
-
-/* IWDG attributes.*/
-#define STM32_HAS_IWDG TRUE
-#define STM32_IWDG_IS_WINDOWED TRUE
-
-/* LTDC attributes.*/
-#define STM32_HAS_LTDC FALSE
-
-/* DMA2D attributes.*/
-#define STM32_HAS_DMA2D FALSE
-
-/* FSMC attributes.*/
-#define STM32_HAS_FSMC TRUE
-#define STM32_FSMC_IS_FMC FALSE
-
-/* CRC attributes.*/
-#define STM32_HAS_CRC TRUE
-#define STM32_CRC_PROGRAMMABLE TRUE
-
-/* DCMI attributes.*/
-#define STM32_HAS_DCMI TRUE
-
-#endif /* defined(STM32L4R5xx) || defined(STM32L4R7xx) ||
- defined(STM32L4R9xx) || defined(STM32L4S5xx) ||
- defined(STM32L4S7xx) || defined(STM32L4S9xx) */
-
-/** @} */
-
-#endif /* STM32_REGISTRY_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/stm32_registry.h
+ * @brief STM32L5xx capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef STM32_REGISTRY_H
+#define STM32_REGISTRY_H
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name STM32L5xx capabilities
+ * @{
+ */
+
+/*===========================================================================*/
+/* Common. */
+/*===========================================================================*/
+
+/* RNG attributes.*/
+#define STM32_HAS_RNG1 TRUE
+
+/* RTC attributes.*/
+#define STM32_HAS_RTC TRUE
+#define STM32_RTC_HAS_SUBSECONDS TRUE
+#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
+#define STM32_RTC_NUM_ALARMS 2
+#define STM32_RTC_STORAGE_SIZE 128
+#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 18
+#define STM32_RTC_TAMP_STAMP_EXTI 19
+#define STM32_RTC_WKUP_EXTI 20
+#define STM32_RTC_IRQ_ENABLE() do { \
+ nvicEnableVector(STM32_RTC_TAMP_STAMP_NUMBER, STM32_IRQ_EXTI19_PRIORITY); \
+ nvicEnableVector(STM32_RTC_WKUP_NUMBER, STM32_IRQ_EXTI20_PRIORITY); \
+ nvicEnableVector(STM32_RTC_ALARM_NUMBER, STM32_IRQ_EXTI18_PRIORITY); \
+} while (false)
+
+#if defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) || \
+ defined(__DOXYGEN__)
+#define STM32_HAS_HASH1 TRUE
+#define STM32_HAS_CRYP1 TRUE
+#else
+#define STM32_HAS_HASH1 FALSE
+#define STM32_HAS_CRYP1 FALSE
+#endif
+
+/*===========================================================================*/
+/* STM32L4yyxx+. */
+/*===========================================================================*/
+
+#if defined(STM32L552xx) || defined(__DOXYGEN__)
+
+/* ADC attributes.*/
+#define STM32_HAS_ADC1 TRUE
+#define STM32_HAS_ADC2 TRUE
+#define STM32_HAS_ADC3 FALSE
+#define STM32_HAS_ADC4 FALSE
+
+/* CAN attributes.*/
+#define STM32_HAS_CAN1 FALSE
+#define STM32_HAS_CAN2 FALSE
+#define STM32_HAS_CAN3 FALSE
+
+/* DAC attributes.*/
+#define STM32_HAS_DAC1_CH1 TRUE
+#define STM32_HAS_DAC1_CH2 TRUE
+#define STM32_HAS_DAC2_CH1 FALSE
+#define STM32_HAS_DAC2_CH2 FALSE
+
+/* DMA attributes.*/
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA_SUPPORTS_DMAMUX TRUE
+#define STM32_DMA_SUPPORTS_CSELR FALSE
+#define STM32_DMA1_NUM_CHANNELS 8
+#define STM32_DMA2_NUM_CHANNELS 8
+
+/* ETH attributes.*/
+#define STM32_HAS_ETH FALSE
+
+/* EXTI attributes.*/
+#define STM32_EXTI_NUM_LINES 43
+#define STM32_EXTI_IMR1_MASK 0xFF9E0000U
+#define STM32_EXTI_IMR2_MASK 0xFFFFFF87U
+
+/* FDCAN attributes.*/
+
+/* Flash attributes.*/
+#define STM32_FLASH_NUMBER_OF_BANKS 2
+
+/* 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_GPIOF TRUE
+#define STM32_HAS_GPIOG TRUE
+#define STM32_HAS_GPIOH TRUE
+#define STM32_HAS_GPIOI FALSE
+#define STM32_HAS_GPIOJ FALSE
+#define STM32_HAS_GPIOK FALSE
+#define STM32_GPIO_EN_MASK (RCC_AHB2ENR_GPIOAEN | \
+ RCC_AHB2ENR_GPIOBEN | \
+ RCC_AHB2ENR_GPIOCEN | \
+ RCC_AHB2ENR_GPIODEN | \
+ RCC_AHB2ENR_GPIOEEN | \
+ RCC_AHB2ENR_GPIOFEN | \
+ RCC_AHB2ENR_GPIOGEN | \
+ RCC_AHB2ENR_GPIOHEN)
+
+/* I2C attributes.*/
+#define STM32_HAS_I2C1 TRUE
+#define STM32_HAS_I2C2 TRUE
+#define STM32_HAS_I2C3 TRUE
+#define STM32_HAS_I2C4 TRUE
+
+/* OCTOSPI attributes.*/
+#define STM32_HAS_OCTOSPI1 TRUE
+#define STM32_HAS_OCTOSPI2 FALSE
+
+/* QUADSPI attributes.*/
+#define STM32_HAS_QUADSPI1 FALSE
+
+/* SDMMC attributes.*/
+#define STM32_HAS_SDMMC1 TRUE
+#define STM32_HAS_SDMMC2 FALSE
+
+/* SPI attributes.*/
+#define STM32_HAS_SPI1 TRUE
+#define STM32_SPI1_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI2 TRUE
+#define STM32_SPI2_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI3 TRUE
+#define STM32_SPI3_SUPPORTS_I2S FALSE
+
+#define STM32_HAS_SPI4 FALSE
+#define STM32_HAS_SPI5 FALSE
+#define STM32_HAS_SPI6 FALSE
+
+/* TIM attributes.*/
+#define STM32_TIM_MAX_CHANNELS 6
+
+#define STM32_HAS_TIM1 TRUE
+#define STM32_TIM1_IS_32BITS FALSE
+#define STM32_TIM1_CHANNELS 6
+
+#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 6
+
+#define STM32_HAS_TIM15 TRUE
+#define STM32_TIM15_IS_32BITS FALSE
+#define STM32_TIM15_CHANNELS 2
+
+#define STM32_HAS_TIM16 TRUE
+#define STM32_TIM16_IS_32BITS FALSE
+#define STM32_TIM16_CHANNELS 2
+
+#define STM32_HAS_TIM17 TRUE
+#define STM32_TIM17_IS_32BITS FALSE
+#define STM32_TIM17_CHANNELS 2
+
+#define STM32_HAS_TIM9 FALSE
+#define STM32_HAS_TIM10 FALSE
+#define STM32_HAS_TIM11 FALSE
+#define STM32_HAS_TIM12 FALSE
+#define STM32_HAS_TIM13 FALSE
+#define STM32_HAS_TIM14 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_HAS_USART2 TRUE
+#define STM32_HAS_USART3 TRUE
+#define STM32_HAS_UART4 TRUE
+#define STM32_HAS_UART5 TRUE
+#define STM32_HAS_LPUART1 TRUE
+#define STM32_HAS_USART6 FALSE
+#define STM32_HAS_UART7 FALSE
+#define STM32_HAS_UART8 FALSE
+
+/* USB attributes.*/
+#define STM32_HAS_USB TRUE
+#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
+#define STM32_USB_PMA_SIZE 1024
+#define STM32_USB_HAS_BCDR FALSE
+
+#define STM32_HAS_OTG1 FALSE
+#define STM32_HAS_OTG2 FALSE
+
+/* IWDG attributes.*/
+#define STM32_HAS_IWDG TRUE
+#define STM32_IWDG_IS_WINDOWED TRUE
+
+/* LTDC attributes.*/
+#define STM32_HAS_LTDC FALSE
+
+/* DMA2D attributes.*/
+#define STM32_HAS_DMA2D FALSE
+
+/* FSMC attributes.*/
+#define STM32_HAS_FSMC TRUE
+#define STM32_FSMC_IS_FMC FALSE
+
+/* CRC attributes.*/
+#define STM32_HAS_CRC TRUE
+#define STM32_CRC_PROGRAMMABLE TRUE
+
+/* DCMI attributes.*/
+#define STM32_HAS_DCMI TRUE
+
+#endif /* defined(STM32L4R5xx) || defined(STM32L4R7xx) ||
+ defined(STM32L4R9xx) || defined(STM32L4S5xx) ||
+ defined(STM32L4S7xx) || defined(STM32L4S9xx) */
+
+/** @} */
+
+#endif /* STM32_REGISTRY_H */
+
+/** @} */
diff --git a/os/hal/ports/STM32/todo.txt b/os/hal/ports/STM32/todo.txt
index c30cafcd14..5dc50c8689 100644
--- a/os/hal/ports/STM32/todo.txt
+++ b/os/hal/ports/STM32/todo.txt
@@ -1,4 +1,4 @@
-- BOFF handling in DACv1.
-- Oversampling support for ADCv1 and ADCv3.
-- Implement missing ICU/PWM/GPT/ST units using shared IRQ handlers.
-- Implement I2S driver over SAI interfaces.
+- BOFF handling in DACv1.
+- Oversampling support for ADCv1 and ADCv3.
+- Implement missing ICU/PWM/GPT/ST units using shared IRQ handlers.
+- Implement I2S driver over SAI interfaces.