aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/hal/boards/ST_NUCLEO_L053R8/board.h16
-rw-r--r--os/hal/ports/STM32/LLD/ADCv1/adc_lld.c315
-rw-r--r--os/hal/ports/STM32/LLD/ADCv1/adc_lld.h428
-rw-r--r--os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c224
-rw-r--r--os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h126
-rw-r--r--os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c217
-rw-r--r--os/hal/ports/STM32/LLD/EXTIv1/ext_lld.h155
-rw-r--r--os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c2
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/st_lld.c22
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/st_lld.h12
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h3
-rw-r--r--os/hal/ports/STM32/LLD/USARTv2/serial_lld.c5
-rw-r--r--os/hal/ports/STM32/STM32F0xx/platform.mk11
-rw-r--r--os/hal/ports/STM32/STM32F0xx/stm32_registry.h21
-rw-r--r--os/hal/ports/STM32/STM32F1xx/stm32_registry.h21
-rw-r--r--os/hal/ports/STM32/STM32F37x/stm32_registry.h6
-rw-r--r--os/hal/ports/STM32/STM32F3xx/stm32_registry.h27
-rw-r--r--os/hal/ports/STM32/STM32F4xx/hal_lld.c2
-rw-r--r--os/hal/ports/STM32/STM32F4xx/stm32_registry.h12
-rw-r--r--os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c265
-rw-r--r--os/hal/ports/STM32/STM32L0xx/ext_lld_isr.h114
-rw-r--r--os/hal/ports/STM32/STM32L0xx/hal_lld.c14
-rw-r--r--os/hal/ports/STM32/STM32L0xx/hal_lld.h168
-rw-r--r--os/hal/ports/STM32/STM32L0xx/platform.mk31
-rw-r--r--os/hal/ports/STM32/STM32L0xx/stm32_rcc.h96
-rw-r--r--os/hal/ports/STM32/STM32L0xx/stm32_registry.h345
-rw-r--r--os/hal/ports/STM32/STM32L1xx/stm32_registry.h6
27 files changed, 2331 insertions, 333 deletions
diff --git a/os/hal/boards/ST_NUCLEO_L053R8/board.h b/os/hal/boards/ST_NUCLEO_L053R8/board.h
index 736bcaec3..d97ac925f 100644
--- a/os/hal/boards/ST_NUCLEO_L053R8/board.h
+++ b/os/hal/boards/ST_NUCLEO_L053R8/board.h
@@ -30,12 +30,14 @@
/*
* Board oscillators-related settings.
- * NOTE: HSE not fitted.
+ * NOTE: LSE and HSE not fitted.
*/
#if !defined(STM32_LSECLK)
#define STM32_LSECLK 0U
#endif
+#define STM32_LSEDRV (0U << 11U)
+
#if !defined(STM32_HSECLK)
#define STM32_HSECLK 0U
#endif
@@ -239,8 +241,8 @@
PIN_MODE_INPUT(GPIOA_PIN8) | \
PIN_MODE_INPUT(GPIOA_PIN9) | \
PIN_MODE_INPUT(GPIOA_PIN10) | \
- PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DM) | \
- PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DP) | \
+ PIN_MODE_INPUT(GPIOA_OTG_FS_DM) | \
+ PIN_MODE_INPUT(GPIOA_OTG_FS_DP) | \
PIN_MODE_ALTERNATE(GPIOA_SWDIO) | \
PIN_MODE_ALTERNATE(GPIOA_SWCLK) | \
PIN_MODE_INPUT(GPIOA_PIN15))
@@ -310,8 +312,8 @@
PIN_ODR_HIGH(GPIOA_PIN15))
#define VAL_GPIOA_AFRL (PIN_AFIO_AF(GPIOA_PIN0, 0) | \
PIN_AFIO_AF(GPIOA_PIN1, 0) | \
- PIN_AFIO_AF(GPIOA_USART_TX, 7) | \
- PIN_AFIO_AF(GPIOA_USART_RX, 7) | \
+ PIN_AFIO_AF(GPIOA_USART_TX, 4) | \
+ PIN_AFIO_AF(GPIOA_USART_RX, 4) | \
PIN_AFIO_AF(GPIOA_PIN4, 0) | \
PIN_AFIO_AF(GPIOA_LED_GREEN, 0) | \
PIN_AFIO_AF(GPIOA_PIN6, 0) | \
@@ -319,8 +321,8 @@
#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_PIN8, 0) | \
PIN_AFIO_AF(GPIOA_PIN9, 0) | \
PIN_AFIO_AF(GPIOA_PIN10, 0) | \
- PIN_AFIO_AF(GPIOA_OTG_FS_DM, 10) | \
- PIN_AFIO_AF(GPIOA_OTG_FS_DP, 10) | \
+ PIN_AFIO_AF(GPIOA_OTG_FS_DM, 0) | \
+ PIN_AFIO_AF(GPIOA_OTG_FS_DP, 0) | \
PIN_AFIO_AF(GPIOA_SWDIO, 0) | \
PIN_AFIO_AF(GPIOA_SWCLK, 0) | \
PIN_AFIO_AF(GPIOA_PIN15, 0))
diff --git a/os/hal/ports/STM32/LLD/ADCv1/adc_lld.c b/os/hal/ports/STM32/LLD/ADCv1/adc_lld.c
new file mode 100644
index 000000000..b77a1e21b
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/ADCv1/adc_lld.c
@@ -0,0 +1,315 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file STM32/LLD/ADCv1/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. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* 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 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)
+ ;
+ }
+}
+
+/**
+ * @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 && (STM32_ADC1_IRQ_SHARED_WITH_EXTI == FALSE)) || \
+ 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);
+
+ 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 = STM32_DMA1_STREAM1;
+ 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(12, STM32_ADC_IRQ_PRIORITY);
+
+ /* Calibration procedure.*/
+ rccEnableADC1(FALSE);
+ osalDbgAssert(ADC1->CR == 0, "invalid register state");
+ ADC1->CR |= ADC_CR_ADCAL;
+ osalDbgAssert(ADC1->CR != 0, "invalid register state");
+ while (ADC1->CR & ADC_CR_ADCAL)
+ ;
+ rccDisableADC1(FALSE);
+}
+
+/**
+ * @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) {
+ bool b;
+ b = dmaStreamAllocate(adcp->dmastp,
+ STM32_ADC_ADC1_DMA_IRQ_PRIORITY,
+ (stm32_dmaisr_t)adc_lld_serve_rx_interrupt,
+ (void *)adcp);
+ osalDbgAssert(!b, "stream already allocated");
+ dmaStreamSetPeripheral(adcp->dmastp, &ADC1->DR);
+ rccEnableADC1(FALSE);
+
+ /* Clock settings.*/
+ adcp->adc->CFGR2 = STM32_ADC_CKMODE;
+ }
+#endif /* STM32_ADC_USE_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) {
+
+ dmaStreamRelease(adcp->dmastp);
+
+ /* 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)
+ ;
+ }
+
+#if STM32_ADC_USE_ADC1
+ if (&ADCD1 == adcp)
+ rccDisableADC1(FALSE);
+#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_AWDIE;
+ adcp->adc->TR = 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->CFGR1 = 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_AWD) {
+ /* Analog watchdog error.*/
+ _adc_isr_error_code(adcp, ADC_ERR_AWD);
+ }
+ }
+}
+
+#endif /* HAL_USE_ADC */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/ADCv1/adc_lld.h b/os/hal/ports/STM32/LLD/ADCv1/adc_lld.h
new file mode 100644
index 000000000..e91f79ffe
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/ADCv1/adc_lld.h
@@ -0,0 +1,428 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file STM32/LLD/ADCv1/adc_lld.h
+ * @brief STM32 ADC subsystem low level driver header.
+ *
+ * @addtogroup ADC
+ * @{
+ */
+
+#ifndef _ADC_LLD_H_
+#define _ADC_LLD_H_
+
+#if HAL_USE_ADC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @name Sampling rates
+ * @{
+ */
+#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. */
+/** @} */
+
+/**
+ * @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 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 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 clock source selection.
+ */
+#if !defined(STM32_ADC_CKMODE) || defined(__DOXYGEN__)
+#define STM32_ADC_CKMODE STM32_ADC_CKMODE_ADCCLK
+#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 1
+#endif
+#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 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;
+
+/**
+ * @brief Type of a structure representing an ADC driver.
+ */
+typedef struct ADCDriver ADCDriver;
+
+/**
+ * @brief ADC notification callback type.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object triggering the
+ * callback
+ * @param[in] buffer pointer to the most recent samples data
+ * @param[in] n number of buffer rows available starting from @p buffer
+ */
+typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
+
+/**
+ * @brief ADC error callback type.
+ *
+ * @param[in] adcp pointer to the @p ADCDriver object triggering the
+ * callback
+ * @param[in] err ADC error code
+ */
+typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
+
+/**
+ * @brief Conversion group configuration structure.
+ * @details This implementation-dependent structure describes a conversion
+ * operation.
+ * @note The use of this configuration structure requires knowledge of
+ * STM32 ADC cell registers interface, please refer to the STM32
+ * reference manual for details.
+ */
+typedef struct {
+ /**
+ * @brief Enables the circular buffer mode for the group.
+ */
+ bool circular;
+ /**
+ * @brief Number of the analog channels belonging to the conversion group.
+ */
+ adc_channels_num_t num_channels;
+ /**
+ * @brief Callback function associated to the group or @p NULL.
+ */
+ adccallback_t end_cb;
+ /**
+ * @brief Error callback or @p NULL.
+ */
+ adcerrorcallback_t error_cb;
+ /* End of the mandatory fields.*/
+ /**
+ * @brief 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;
+#if (STM32_ADC_SUPPORTS_OVERSAMPLING == TRUE) || defined(__DOXYGEN__)
+ /**
+ * @brief ADC CFGR2 register initialization data.
+ * @note CKMODE bits must not be specified in this field and left to
+ * zero.
+ */
+ uint32_t cfgr2;
+#endif
+ /**
+ * @brief ADC TR register initialization data.
+ */
+ uint32_t tr;
+ /**
+ * @brief ADC SMPR register initialization data.
+ */
+ uint32_t smpr;
+ /**
+ * @brief ADC CHSELR register initialization data.
+ * @details 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;
+} ADCConversionGroup;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ uint32_t dummy;
+} ADCConfig;
+
+/**
+ * @brief Structure representing an ADC driver.
+ */
+struct ADCDriver {
+ /**
+ * @brief Driver state.
+ */
+ adcstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const ADCConfig *config;
+ /**
+ * @brief Current samples buffer pointer or @p NULL.
+ */
+ adcsample_t *samples;
+ /**
+ * @brief Current samples buffer depth or @p 0.
+ */
+ size_t depth;
+ /**
+ * @brief Current conversion group pointer or @p NULL.
+ */
+ const ADCConversionGroup *grpp;
+#if ADC_USE_WAIT || defined(__DOXYGEN__)
+ /**
+ * @brief Waiting thread.
+ */
+ thread_reference_t thread;
+#endif
+#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
+ /**
+ * @brief Mutex protecting the peripheral.
+ */
+ mutex_t mutex;
+#endif /* ADC_USE_MUTUAL_EXCLUSION */
+#if defined(ADC_DRIVER_EXT_FIELDS)
+ ADC_DRIVER_EXT_FIELDS
+#endif
+ /* End of the mandatory fields.*/
+ /**
+ * @brief Pointer to the ADCx registers block.
+ */
+ ADC_TypeDef *adc;
+ /**
+ * @brief Pointer to associated DMA channel.
+ */
+ const stm32_dma_stream_t *dmastp;
+ /**
+ * @brief DMA mode bit mask.
+ */
+ uint32_t dmamode;
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @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);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_ADC */
+
+#endif /* _ADC_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
index 9fd59bbff..4f0d29eb1 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
+++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
@@ -15,10 +15,10 @@
*/
/**
- * @file DMAv1/stm32_dma.c
+ * @file STM32F3xx/stm32_dma.c
* @brief DMA helper driver code.
*
- * @addtogroup STM32_DMA_V1
+ * @addtogroup STM32F3xx_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
@@ -54,6 +54,29 @@
*/
#define STM32_DMA_CCR_RESET_VALUE 0x00000000U
+/*
+ * Handling devices with shared DMA IRQ handlers.
+ */
+#if defined(STM32_DMA1_CH23_NUMBER)
+#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER
+#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER
+#endif
+
+#if defined(STM32_DMA1_CH4567_NUMBER)
+#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
+#endif
+
+#if STM32_ADVANCED_DMA == TRUE
+#define ADDR_DMA1_CSELR &DMA1_CSELR->CSELR
+#define ADDR_DMA2_CSELR &DMA2_CSELR->CSELR
+#else
+#define ADDR_DMA1_CSELR NULL
+#define ADDR_DMA2_CSELR NULL
+#endif
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@@ -65,22 +88,28 @@
* @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] = {
- {DMA1_Channel1, &DMA1->IFCR, 0, 0, STM32_DMA1_STREAM1_EVENT_NUMBER},
- {DMA1_Channel2, &DMA1->IFCR, 4, 1, STM32_DMA1_STREAM2_EVENT_NUMBER},
- {DMA1_Channel3, &DMA1->IFCR, 8, 2, STM32_DMA1_STREAM3_EVENT_NUMBER},
- {DMA1_Channel4, &DMA1->IFCR, 12, 3, STM32_DMA1_STREAM4_EVENT_NUMBER},
- {DMA1_Channel5, &DMA1->IFCR, 16, 4, STM32_DMA1_STREAM5_EVENT_NUMBER},
-#if STM32_DMA_STREAMS > 5
- {DMA1_Channel6, &DMA1->IFCR, 20, 5, STM32_DMA1_STREAM6_EVENT_NUMBER},
- {DMA1_Channel7, &DMA1->IFCR, 24, 6, STM32_DMA1_STREAM7_EVENT_NUMBER},
+const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
+ {DMA1_Channel1, &DMA1->IFCR, ADDR_DMA1_CSELR, 0, 0, STM32_DMA1_CH1_NUMBER},
+ {DMA1_Channel2, &DMA1->IFCR, ADDR_DMA1_CSELR, 4, 1, STM32_DMA1_CH2_NUMBER},
+ {DMA1_Channel3, &DMA1->IFCR, ADDR_DMA1_CSELR, 8, 2, STM32_DMA1_CH3_NUMBER},
+ {DMA1_Channel4, &DMA1->IFCR, ADDR_DMA1_CSELR, 12, 3, STM32_DMA1_CH4_NUMBER},
+ {DMA1_Channel5, &DMA1->IFCR, ADDR_DMA1_CSELR, 16, 4, STM32_DMA1_CH5_NUMBER},
+#if STM32_DMA1_NUM_CHANNELS > 5
+ {DMA1_Channel6, &DMA1->IFCR, ADDR_DMA1_CSELR, 20, 5, STM32_DMA1_CH6_NUMBER},
+#else
+ {NULL, NULL, NULL, 0, 5, 0},
#endif
-#if STM32_DMA_STREAMS > 7
- {DMA2_Channel1, &DMA2->IFCR, 0, 7, STM32_DMA2_STREAM1_EVENT_NUMBER},
- {DMA2_Channel2, &DMA2->IFCR, 4, 8, STM32_DMA2_STREAM2_EVENT_NUMBER},
- {DMA2_Channel3, &DMA2->IFCR, 8, 9, STM32_DMA2_STREAM3_EVENT_NUMBER},
- {DMA2_Channel4, &DMA2->IFCR, 12, 10, STM32_DMA2_STREAM4_EVENT_NUMBER},
- {DMA2_Channel5, &DMA2->IFCR, 16, 11, STM32_DMA2_STREAM5_EVENT_NUMBER},
+#if STM32_DMA1_NUM_CHANNELS > 6
+ {DMA1_Channel7, &DMA1->IFCR, ADDR_DMA1_CSELR, 24, 6, STM32_DMA1_CH7_NUMBER},
+#else
+ {NULL, NULL, NULL, 0, 6, 0},
+#endif
+#if STM32_DMA2_NUM_CHANNELS > 0
+ {DMA2_Channel1, &DMA2->IFCR, ADDR_DMA2_CSELR, 0, 8, STM32_DMA2_CH1_NUMBER},
+ {DMA2_Channel2, &DMA2->IFCR, ADDR_DMA2_CSELR, 4, 9, STM32_DMA2_CH2_NUMBER},
+ {DMA2_Channel3, &DMA2->IFCR, ADDR_DMA2_CSELR, 8, 10, STM32_DMA2_CH3_NUMBER},
+ {DMA2_Channel4, &DMA2->IFCR, ADDR_DMA2_CSELR, 12, 11, STM32_DMA2_CH4_NUMBER},
+ {DMA2_Channel5, &DMA2->IFCR, ADDR_DMA2_CSELR, 16, 13, STM32_DMA2_CH5_NUMBER},
#endif
};
@@ -114,13 +143,12 @@ static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS];
/* Driver interrupt handlers. */
/*===========================================================================*/
-#if defined(STM32_DMA1_STREAM1_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 1 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM1_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -132,15 +160,44 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM1_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM2_EVENT_HANDLER) || defined(__DOXYGEN__)
+/* Channels 2 and 3 are shared on some devices.*/
+#if defined(STM32_DMA1_CH23_HANDLER)
+/**
+ * @brief DMA1 streams 2 and 3 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Check on channel 2.*/
+ flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 4;
+ if (dma_isr_redir[1].dma_func)
+ dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags);
+ }
+
+ /* Check on channel 3.*/
+ flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 8;
+ if (dma_isr_redir[2].dma_func)
+ dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags);
+ }
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /*!defined(STM32_DMA1_CH23_HANDLER) */
/**
* @brief DMA1 stream 2 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM2_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -152,15 +209,13 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM2_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM3_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 3 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM3_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -172,15 +227,66 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM3_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
+#endif /*!defined(STM32_DMA1_CH23_HANDLER) */
+
+
+/* Channels 4, 5, 6 and 7 are shared on some devices.*/
+#if defined(STM32_DMA1_CH4567_HANDLER)
+/**
+ * @brief DMA1 streams 4 and 5 shared interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) {
+ uint32_t flags;
+
+ OSAL_IRQ_PROLOGUE();
+
+ /* Check on channel 4.*/
+ flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 12;
+ if (dma_isr_redir[3].dma_func)
+ dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags);
+ }
+
+ /* Check on channel 5.*/
+ flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 16;
+ if (dma_isr_redir[4].dma_func)
+ dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags);
+ }
+
+#if STM32_DMA1_NUM_CHANNELS > 5
+ /* Check on channel 6.*/
+ flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 20;
+ if (dma_isr_redir[5].dma_func)
+ dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags);
+ }
#endif
-#if defined(STM32_DMA1_STREAM4_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if STM32_DMA1_NUM_CHANNELS > 6
+ /* Check on channel 7.*/
+ flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK;
+ if (flags & STM32_DMA_ISR_MASK) {
+ DMA1->IFCR = flags << 24;
+ if (dma_isr_redir[6].dma_func)
+ dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags);
+ }
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#else /* !defined(STM32_DMA1_CH4567_HANDLER) */
/**
* @brief DMA1 stream 4 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM4_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -192,15 +298,13 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM4_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM5_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 5 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM5_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -212,15 +316,14 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM5_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA1_STREAM6_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if (STM32_DMA1_NUM_CHANNELS > 5) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 6 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM6_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -232,15 +335,15 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM6_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_DMA1_NUM_CHANNELS > 5 */
-#if defined(STM32_DMA1_STREAM7_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if (STM32_DMA1_NUM_CHANNELS > 6) || defined(__DOXYGEN__)
/**
* @brief DMA1 stream 7 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA1_STREAM7_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -252,15 +355,16 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM7_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_DMA1_NUM_CHANNELS > 6 */
+#endif /* !defined(STM32_DMA1_CH4567_HANDLER) */
-#if defined(STM32_DMA2_STREAM1_EVENT_HANDLER) || defined(__DOXYGEN__)
+#if (STM32_DMA2_NUM_CHANNELS > 0) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 1 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM1_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -272,15 +376,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM1_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM2_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 2 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM2_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -292,15 +394,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM2_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM3_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 3 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM3_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -312,15 +412,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM3_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM4_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 4 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM4_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -332,15 +430,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM4_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
-#if defined(STM32_DMA2_STREAM5_EVENT_HANDLER) || defined(__DOXYGEN__)
/**
* @brief DMA2 stream 5 shared interrupt handler.
*
* @isr
*/
-OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) {
+OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
uint32_t flags;
OSAL_IRQ_PROLOGUE();
@@ -352,7 +448,7 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) {
OSAL_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_DMA2_NUM_CHANNELS > 0 */
/*===========================================================================*/
/* Driver exported functions. */
@@ -366,13 +462,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) {
void dmaInit(void) {
int i;
- dma_streams_mask = 0;
+ dma_streams_mask = 0U;
for (i = 0; i < STM32_DMA_STREAMS; i++) {
- __stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE;
+ _stm32_dma_streams[i].channel->CCR = 0U;
dma_isr_redir[i].dma_func = NULL;
}
DMA1->IFCR = 0xFFFFFFFFU;
-#if STM32_HAS_DMA2
+#if STM32_DMA2_NUM_CHANNELS > 0
DMA2->IFCR = 0xFFFFFFFFU;
#endif
}
@@ -409,19 +505,19 @@ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
osalDbgCheck(dmastp != NULL);
/* Checks if the stream is already taken.*/
- if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
+ if ((dma_streams_mask & (1U << dmastp->selfindex)) != 0U)
return true;
/* Marks the stream as allocated.*/
dma_isr_redir[dmastp->selfindex].dma_func = func;
dma_isr_redir[dmastp->selfindex].dma_param = param;
- dma_streams_mask |= (1 << dmastp->selfindex);
+ dma_streams_mask |= (1U << dmastp->selfindex);
/* Enabling DMA clocks required by the current streams set.*/
- if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0U)
rccEnableDMA1(false);
-#if STM32_HAS_DMA2
- if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
+#if STM32_DMA2_NUM_CHANNELS > 0
+ if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0U)
rccEnableDMA2(false);
#endif
@@ -454,7 +550,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
osalDbgCheck(dmastp != NULL);
/* Check if the streams is not taken.*/
- osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
+ osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0U,
"not allocated");
/* Disables the associated IRQ vector.*/
@@ -464,10 +560,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
dma_streams_mask &= ~(1 << dmastp->selfindex);
/* Shutting down clocks that are no more required, if any.*/
- if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
+ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0U)
rccDisableDMA1(false);
-#if STM32_HAS_DMA2
- if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
+#if STM32_DMA2_NUM_CHANNELS > 0
+ if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0U)
rccDisableDMA2(false);
#endif
}
diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
index 8a19aa8b5..f8cf56dda 100644
--- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
+++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
@@ -20,7 +20,7 @@
* @note This driver uses the new naming convention used for the STM32F2xx
* so the "DMA channels" are referred as "DMA streams".
*
- * @addtogroup STM32_DMA_V1
+ * @addtogroup STM32_DMA
* @{
*/
@@ -32,30 +32,38 @@
/*===========================================================================*/
/**
+ * @brief Total number of DMA streams.
+ * @note 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 0x0F
/**
- * @brief Returns the channel associated to the specified stream.
+ * @brief Returns the request line associated to the specified stream.
+ * @note In some STM32 manuals the request line is named confusingly
+ * channel.
*
- * @param[in] n the stream number (0...STM32_DMA_STREAMS-1)
- * @param[in] c a stream/channel association word, one channel per
- * nibble, not associated channels must be set to 0xF
- * @return Always zero, in this platform there is no dynamic
- * association between streams and channels.
+ * @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(n, c) 0
+#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.
+ * @retval false invalid DMA priority.
+ * @retval true correct DMA priority.
*/
-#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3))
+#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
/**
* @brief Returns an unique numeric identifier for a DMA stream.
@@ -64,7 +72,7 @@
* @param[in] stream the stream number
* @return An unique numeric stream identifier.
*/
-#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 7) + ((stream) - 1))
+#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1U) * 7U) + ((stream) - 1U))
/**
* @brief Returns a DMA stream identifier mask.
@@ -75,18 +83,19 @@
* @return A DMA stream identifier mask.
*/
#define STM32_DMA_STREAM_ID_MSK(dma, stream) \
- (1 << STM32_DMA_STREAM_ID(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.
+ * @retval false id does not belong to the mask.
+ * @retval true id belongs to the mask.
*/
-#define STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask)))
+#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
/**
* @name DMA streams identifiers
@@ -99,7 +108,7 @@
* @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_DMA_STREAM(id) (&_stm32_dma_streams[id])
#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0)
#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1)
@@ -108,11 +117,11 @@
#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4)
#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5)
#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6)
-#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(7)
-#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(8)
-#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(9)
-#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(10)
-#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(11)
+#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(8)
+#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(9)
+#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(10)
+#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(11)
+#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(12)
/** @} */
/**
@@ -124,41 +133,52 @@
#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 0
+#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 0
+#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 0
+#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) << 12)
+#define STM32_DMA_CR_PL(n) ((n) << 12U)
+/** @} */
+
+/**
+ * @name Request line selector macro
+ * @{
+ */
+#if STM32_ADVANCED_DMA || 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 0 /**< @brief Ignored by normal DMA. */
-#define STM32_DMA_CR_CHSEL_MASK 0 /**< @brief Ignored by normal DMA. */
-#define STM32_DMA_CR_CHSEL(n) 0 /**< @brief Ignored by normal 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 0
-#define STM32_DMA_ISR_DMEIF 0
+#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
@@ -172,29 +192,6 @@
/* Derived constants and error checks. */
/*===========================================================================*/
-#if !defined(STM32_ADVANCED_DMA)
-#error "missing STM32_ADVANCED_DMA definition in registry"
-#endif
-
-#if !defined(STM32_DMA_STREAMS)
-#error "missing STM32_DMA_STREAMS definition in registry"
-#endif
-
-#if !defined(STM32_DMA_RELOCATION)
-#error "missing STM32_DMA_RELOCATION definition in registry"
-#endif
-
-#if STM32_ADVANCED_DMA == TRUE
-#error "DMAv1 driver does not support STM32_ADVANCED_DMA"
-#endif
-
-/**
- * @brief Presence of DMA2 controller.
- */
-#if (STM32_DMA_STREAMS > 7) || defined(__DOXYGEN__)
-#define STM32_HAS_DMA2 TRUE
-#endif
-
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -205,8 +202,9 @@
typedef struct {
DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
- uint8_t ishift; /**< @brief Bits offset in xIFCR
- register. */
+ volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */
+ uint8_t shift; /**< @brief Bit offset in IFCR and
+ CSELR registers. */
uint8_t selfindex; /**< @brief Index to self in array. */
uint8_t vector; /**< @brief Associated IRQ vector. */
} stm32_dma_stream_t;
@@ -297,9 +295,19 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
*
* @special
*/
+#if STM32_ADVANCED_DMA || 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.
@@ -346,7 +354,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
* @special
*/
#define dmaStreamClearInterrupt(dmastp) { \
- *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
+ *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->shift; \
}
/**
@@ -385,7 +393,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
*/
#define dmaWaitCompletion(dmastp) { \
- while ((dmastp)->channel->CNDTR > 0) \
+ while ((dmastp)->channel->CNDTR > 0U) \
; \
dmaStreamDisable(dmastp); \
}
@@ -397,7 +405,7 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
/*===========================================================================*/
#if !defined(__DOXYGEN__)
-extern const stm32_dma_stream_t __stm32_dma_streams[STM32_DMA_STREAMS];
+extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
#endif
#ifdef __cplusplus
diff --git a/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c b/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c
new file mode 100644
index 000000000..314ca2899
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c
@@ -0,0 +1,217 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file STM32/EXTIv1/ext_lld.c
+ * @brief STM32 EXT subsystem low level driver source.
+ *
+ * @addtogroup EXT
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_EXT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EXTD1 driver identifier.
+ */
+EXTDriver EXTD1;
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level EXT driver initialization.
+ *
+ * @notapi
+ */
+void ext_lld_init(void) {
+
+ /* Driver initialization.*/
+ extObjectInit(&EXTD1);
+}
+
+/**
+ * @brief Configures and activates the EXT peripheral.
+ *
+ * @param[in] extp pointer to the @p EXTDriver object
+ *
+ * @notapi
+ */
+void ext_lld_start(EXTDriver *extp) {
+ unsigned i;
+
+ if (extp->state == EXT_STOP)
+ ext_lld_exti_irq_enable();
+
+ /* Configuration of automatic channels.*/
+ for (i = 0; i < EXT_MAX_CHANNELS; i++)
+ if (extp->config->channels[i].mode & EXT_CH_MODE_AUTOSTART)
+ ext_lld_channel_enable(extp, i);
+ else
+ ext_lld_channel_disable(extp, i);
+}
+
+/**
+ * @brief Deactivates the EXT peripheral.
+ *
+ * @param[in] extp pointer to the @p EXTDriver object
+ *
+ * @notapi
+ */
+void ext_lld_stop(EXTDriver *extp) {
+
+ if (extp->state == EXT_ACTIVE)
+ ext_lld_exti_irq_disable();
+
+ EXTI->EMR = 0;
+ EXTI->IMR = 0;
+ EXTI->PR = 0xFFFFFFFF;
+#if STM32_EXTI_NUM_LINES > 32
+ EXTI->PR2 = 0xFFFFFFFF;
+#endif
+}
+
+/**
+ * @brief Enables an EXT channel.
+ *
+ * @param[in] extp pointer to the @p EXTDriver object
+ * @param[in] channel channel to be enabled
+ *
+ * @notapi
+ */
+void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
+
+ /* Setting the associated GPIO for external channels.*/
+ if (channel < 16) {
+ uint32_t n = channel >> 2;
+ uint32_t mask = ~(0xF << ((channel & 3) * 4));
+ uint32_t port = ((extp->config->channels[channel].mode &
+ EXT_MODE_GPIO_MASK) >>
+ EXT_MODE_GPIO_OFF) << ((channel & 3) * 4);
+
+#if defined(STM32F1XX)
+ AFIO->EXTICR[n] = (AFIO->EXTICR[n] & mask) | port;
+#else /* !defined(STM32F1XX) */
+ SYSCFG->EXTICR[n] = (SYSCFG->EXTICR[n] & mask) | port;
+#endif /* !defined(STM32F1XX) */
+ }
+
+#if STM32_EXTI_NUM_LINES > 32
+ if (channel < 32) {
+#endif
+ /* Programming edge registers.*/
+ if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE)
+ EXTI->RTSR |= (1 << channel);
+ else
+ EXTI->RTSR &= ~(1 << channel);
+ if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE)
+ EXTI->FTSR |= (1 << channel);
+ else
+ EXTI->FTSR &= ~(1 << channel);
+
+ /* Programming interrupt and event registers.*/
+ if (extp->config->channels[channel].cb != NULL) {
+ EXTI->IMR |= (1 << channel);
+ EXTI->EMR &= ~(1 << channel);
+ }
+ else {
+ EXTI->EMR |= (1 << channel);
+ EXTI->IMR &= ~(1 << channel);
+ }
+#if STM32_EXTI_NUM_LINES > 32
+ }
+ else {
+ /* Programming edge registers.*/
+ if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE)
+ EXTI->RTSR2 |= (1 << (32 - channel));
+ else
+ EXTI->RTSR2 &= ~(1 << (32 - channel));
+ if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE)
+ EXTI->FTSR2 |= (1 << (32 - channel));
+ else
+ EXTI->FTSR2 &= ~(1 << (32 - channel));
+
+ /* Programming interrupt and event registers.*/
+ if (extp->config->channels[channel].cb != NULL) {
+ EXTI->IMR2 |= (1 << (32 - channel));
+ EXTI->EMR2 &= ~(1 << (32 - channel));
+ }
+ else {
+ EXTI->EMR2 |= (1 << (32 - channel));
+ EXTI->IMR2 &= ~(1 << (32 - channel));
+ }
+ }
+#endif
+}
+
+/**
+ * @brief Disables an EXT channel.
+ *
+ * @param[in] extp pointer to the @p EXTDriver object
+ * @param[in] channel channel to be disabled
+ *
+ * @notapi
+ */
+void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) {
+
+ (void)extp;
+
+#if STM32_EXTI_NUM_LINES > 32
+ if (channel < 32) {
+#endif
+ EXTI->IMR &= ~(1 << channel);
+ EXTI->EMR &= ~(1 << channel);
+ EXTI->RTSR &= ~(1 << channel);
+ EXTI->FTSR &= ~(1 << channel);
+ EXTI->PR = (1 << channel);
+#if STM32_EXTI_NUM_LINES > 32
+ }
+ else {
+ EXTI->IMR2 &= ~(1 << (32 - channel));
+ EXTI->EMR2 &= ~(1 << (32 - channel));
+ EXTI->RTSR2 &= ~(1 << (32 - channel));
+ EXTI->FTSR2 &= ~(1 << (32 - channel));
+ EXTI->PR2 = (1 << (32 - channel));
+ }
+#endif
+}
+
+#endif /* HAL_USE_EXT */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.h b/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.h
new file mode 100644
index 000000000..248414bfd
--- /dev/null
+++ b/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.h
@@ -0,0 +1,155 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file STM32/EXTIv1/ext_lld.h
+ * @brief STM32 EXT subsystem low level driver header.
+ *
+ * @addtogroup EXT
+ * @{
+ */
+
+#ifndef _EXT_LLD_H_
+#define _EXT_LLD_H_
+
+#if HAL_USE_EXT || defined(__DOXYGEN__)
+
+#include "ext_lld_isr.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Available number of EXT channels.
+ */
+#define EXT_MAX_CHANNELS STM32_EXTI_NUM_LINES
+
+/**
+ * @name STM32-specific EXT channel modes
+ * @{
+ */
+#define EXT_MODE_GPIO_MASK 0xF0 /**< @brief Port field mask. */
+#define EXT_MODE_GPIO_OFF 4 /**< @brief Port field offset. */
+#define EXT_MODE_GPIOA 0x00 /**< @brief GPIOA identifier. */
+#define EXT_MODE_GPIOB 0x10 /**< @brief GPIOB identifier. */
+#define EXT_MODE_GPIOC 0x20 /**< @brief GPIOC identifier. */
+#define EXT_MODE_GPIOD 0x30 /**< @brief GPIOD identifier. */
+#define EXT_MODE_GPIOE 0x40 /**< @brief GPIOE identifier. */
+#define EXT_MODE_GPIOF 0x50 /**< @brief GPIOF identifier. */
+#define EXT_MODE_GPIOG 0x60 /**< @brief GPIOG identifier. */
+#define EXT_MODE_GPIOH 0x70 /**< @brief GPIOH identifier. */
+#define EXT_MODE_GPIOI 0x80 /**< @brief GPIOI identifier. */
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief EXT channel identifier.
+ */
+typedef uint32_t expchannel_t;
+
+/**
+ * @brief Type of an EXT generic notification callback.
+ *
+ * @param[in] extp pointer to the @p EXPDriver object triggering the
+ * callback
+ */
+typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel);
+
+/**
+ * @brief Channel configuration structure.
+ */
+typedef struct {
+ /**
+ * @brief Channel mode.
+ */
+ uint32_t mode;
+ /**
+ * @brief Channel callback.
+ * @details In the STM32 implementation a @p NULL callback pointer is
+ * valid and configures the channel as an event sources instead
+ * of an interrupt source.
+ */
+ extcallback_t cb;
+} EXTChannelConfig;
+
+/**
+ * @brief Driver configuration structure.
+ * @note It could be empty on some architectures.
+ */
+typedef struct {
+ /**
+ * @brief Channel configurations.
+ */
+ EXTChannelConfig channels[EXT_MAX_CHANNELS];
+ /* End of the mandatory fields.*/
+} EXTConfig;
+
+/**
+ * @brief Structure representing an EXT driver.
+ */
+struct EXTDriver {
+ /**
+ * @brief Driver state.
+ */
+ extstate_t state;
+ /**
+ * @brief Current configuration data.
+ */
+ const EXTConfig *config;
+ /* End of the mandatory fields.*/
+};
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern EXTDriver EXTD1;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void ext_lld_init(void);
+ void ext_lld_start(EXTDriver *extp);
+ void ext_lld_stop(EXTDriver *extp);
+ void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel);
+ void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_EXT */
+
+#endif /* _EXT_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c b/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c
index 2ba0b3b68..3a9e00db5 100644
--- a/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c
+++ b/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c
@@ -91,7 +91,7 @@ void _pal_lld_init(const PALConfig *config) {
* Enables the GPIO related clocks.
*/
#if defined(STM32L0XX)
- rccEnableAHB(AHB_EN_MASK, TRUE);
+ RCC->IOPENR |= AHB_EN_MASK;
RCC->IOPSMENR |= AHB_LPEN_MASK;
#elif defined(STM32L1XX)
rccEnableAHB(AHB_EN_MASK, TRUE);
diff --git a/os/hal/ports/STM32/LLD/TIMv1/st_lld.c b/os/hal/ports/STM32/LLD/TIMv1/st_lld.c
index db4672ea2..691951655 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/st_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/st_lld.c
@@ -98,6 +98,28 @@
#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM5_STOP
#endif
+#elif STM32_ST_USE_TIMER == 21
+#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(FALSE)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB2_FZ_DBG_TIM21_STOP
+
+#elif STM32_ST_USE_TIMER == 22
+#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(FALSE)
+#define ST_ENABLE_STOP() DBGMCU->APB1FZ |= DBGMCU_APB2_FZ_DBG_TIM21_STOP
+
#else
#error "STM32_ST_USE_TIMER specifies an unsupported timer"
#endif
diff --git a/os/hal/ports/STM32/LLD/TIMv1/st_lld.h b/os/hal/ports/STM32/LLD/TIMv1/st_lld.h
index 8adba0de3..fb75da9dc 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/st_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/st_lld.h
@@ -89,6 +89,18 @@
#endif
#define STM32_ST_TIM STM32_TIM5
+#elif STM32_ST_USE_TIMER == 21
+#if !STM32_HAS_TIM21
+#error "TIM21 not present"
+#endif
+#define STM32_ST_TIM STM32_TIM21
+
+#elif STM32_ST_USE_TIMER == 22
+#if !STM32_HAS_TIM22
+#error "TIM22 not present"
+#endif
+#define STM32_ST_TIM STM32_TIM22
+
#else
#error "STM32_ST_USE_TIMER specifies an unsupported timer"
#endif
diff --git a/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h b/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h
index 095958c8a..c2842b275 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h
@@ -392,6 +392,9 @@
#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)
/** @} */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c b/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c
index e78fe1506..bf4ac2cd6 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c
@@ -30,6 +30,11 @@
/* Driver local definitions. */
/*===========================================================================*/
+/* STM32L0xx ST headers bug.*/
+#if !defined(USART_ISR_LBDF)
+#define USART_ISR_LBDF USART_ISR_LBD
+#endif
+
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/STM32F0xx/platform.mk b/os/hal/ports/STM32/STM32F0xx/platform.mk
index 02fd58fb4..171a9d5f5 100644
--- a/os/hal/ports/STM32/STM32F0xx/platform.mk
+++ b/os/hal/ports/STM32/STM32F0xx/platform.mk
@@ -9,16 +9,15 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/adc_lld.c
endif
-ifneq ($(findstring HAL_USE_EXT TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/ext_lld_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/LLD/ext_lld.c
-endif
ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/can_lld.c
endif
ifneq ($(findstring HAL_USE_DAC TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/dac_lld.c
endif
+ifneq ($(findstring HAL_USE_EXT TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c
+endif
ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c
endif
@@ -54,10 +53,9 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
$(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/stm32_dma.c \
$(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/hal_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/adc_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32F0xx/ext_lld_isr.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/can_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/LLD/ext_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/dac_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/i2c_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c \
@@ -76,6 +74,7 @@ PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
$(CHIBIOS)/os/hal/ports/STM32/STM32F0xx \
$(CHIBIOS)/os/hal/ports/STM32/LLD \
$(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1 \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2 \
diff --git a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
index aae3016b3..273ca70e6 100644
--- a/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F0xx/stm32_registry.h
@@ -170,6 +170,9 @@
#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
@@ -344,6 +347,9 @@
#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
@@ -508,6 +514,9 @@
#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
@@ -661,6 +670,9 @@
#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
@@ -816,6 +828,9 @@
#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
@@ -977,6 +992,9 @@
#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
@@ -1143,6 +1161,9 @@
#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
diff --git a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
index ee76ca2bf..015c8423a 100644
--- a/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F1xx/stm32_registry.h
@@ -154,6 +154,9 @@
#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
@@ -323,6 +326,9 @@
#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
@@ -467,6 +473,9 @@
#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
@@ -617,6 +626,9 @@
#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
@@ -810,6 +822,9 @@
#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
@@ -1006,6 +1021,9 @@
#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
@@ -1181,6 +1199,9 @@
#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
diff --git a/os/hal/ports/STM32/STM32F37x/stm32_registry.h b/os/hal/ports/STM32/STM32F37x/stm32_registry.h
index 95255d48b..bc25f1d7c 100644
--- a/os/hal/ports/STM32/STM32F37x/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F37x/stm32_registry.h
@@ -194,6 +194,9 @@
#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
@@ -395,6 +398,9 @@
#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
diff --git a/os/hal/ports/STM32/STM32F3xx/stm32_registry.h b/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
index 694ceea51..067f5dc00 100644
--- a/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F3xx/stm32_registry.h
@@ -187,6 +187,9 @@
#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
@@ -367,6 +370,9 @@
#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
@@ -535,6 +541,9 @@
#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
@@ -703,6 +712,9 @@
#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
@@ -882,6 +894,9 @@
#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
@@ -1056,6 +1071,9 @@
#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
@@ -1226,6 +1244,9 @@
#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
@@ -1404,6 +1425,9 @@
#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
@@ -1581,6 +1605,9 @@
#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
diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.c b/os/hal/ports/STM32/STM32F4xx/hal_lld.c
index 03cd5f06f..ff9ff93fd 100644
--- a/os/hal/ports/STM32/STM32F4xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.c
@@ -261,7 +261,7 @@ void stm32_clock_init(void) {
FLASH_ACR_DCEN | STM32_FLASHBITS;
#endif
- /* Switching to the configured clock source if it is different from MSI.*/
+ /* Switching to the configured clock source if it is different from HSI.*/
#if (STM32_SW != STM32_SW_HSI)
RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
diff --git a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
index 7b5c02b29..ef5c81b77 100644
--- a/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32F4xx/stm32_registry.h
@@ -275,6 +275,9 @@
#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
@@ -555,6 +558,9 @@
#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
@@ -805,6 +811,9 @@
#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
@@ -1030,6 +1039,9 @@
#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
diff --git a/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c b/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c
new file mode 100644
index 000000000..36731f9bb
--- /dev/null
+++ b/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c
@@ -0,0 +1,265 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES 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/ext_lld_isr.c
+ * @brief STM32L0xx EXT subsystem low level driver ISR code.
+ *
+ * @addtogroup EXT
+ * @{
+ */
+
+#include "hal.h"
+
+#if HAL_USE_EXT || defined(__DOXYGEN__)
+
+#include "ext_lld_isr.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/**
+ * @brief EXTI[0]...EXTI[1] interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_EXTI_LINE01_HANDLER) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR & EXTI->IMR & ((1 << 0) | (1 << 1));
+ EXTI->PR = pr;
+ if (pr & (1 << 0))
+ EXTD1.config->channels[0].cb(&EXTD1, 0);
+ if (pr & (1 << 1))
+ EXTD1.config->channels[1].cb(&EXTD1, 1);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief EXTI[2]...EXTI[3] interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_EXTI_LINE23_HANDLER) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR & EXTI->IMR & ((1 << 2) | (1 << 3));
+ EXTI->PR = pr;
+ if (pr & (1 << 2))
+ EXTD1.config->channels[2].cb(&EXTD1, 2);
+ if (pr & (1 << 3))
+ EXTD1.config->channels[3].cb(&EXTD1, 3);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief EXTI[4]...EXTI[15] interrupt handler.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_EXTI_LINE4_15_HANDLER) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR & EXTI->IMR & ((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) |
+ (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) |
+ (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15));
+ EXTI->PR = pr;
+ if (pr & (1 << 4))
+ EXTD1.config->channels[4].cb(&EXTD1, 4);
+ if (pr & (1 << 5))
+ EXTD1.config->channels[5].cb(&EXTD1, 5);
+ if (pr & (1 << 6))
+ EXTD1.config->channels[6].cb(&EXTD1, 6);
+ if (pr & (1 << 7))
+ EXTD1.config->channels[7].cb(&EXTD1, 7);
+ if (pr & (1 << 8))
+ EXTD1.config->channels[8].cb(&EXTD1, 8);
+ if (pr & (1 << 9))
+ EXTD1.config->channels[9].cb(&EXTD1, 9);
+ if (pr & (1 << 10))
+ EXTD1.config->channels[10].cb(&EXTD1, 10);
+ if (pr & (1 << 11))
+ EXTD1.config->channels[11].cb(&EXTD1, 11);
+ if (pr & (1 << 12))
+ EXTD1.config->channels[12].cb(&EXTD1, 12);
+ if (pr & (1 << 13))
+ EXTD1.config->channels[13].cb(&EXTD1, 13);
+ if (pr & (1 << 14))
+ EXTD1.config->channels[14].cb(&EXTD1, 14);
+ if (pr & (1 << 15))
+ EXTD1.config->channels[15].cb(&EXTD1, 15);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief EXTI[16] interrupt handler (PVD).
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_EXTI_LINE16_HANDLER) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR & EXTI->IMR & (1 << 16);
+ EXTI->PR = pr;
+ if (pr & (1 << 16))
+ EXTD1.config->channels[16].cb(&EXTD1, 16);
+
+ OSAL_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief EXTI[17],EXTI[19],EXTI[20] interrupt handler (RTC, CSS).
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_EXTI_LINE171920_HANDLER) {
+ uint32_t pr;
+
+ OSAL_IRQ_PROLOGUE();
+
+ pr = EXTI->PR & EXTI->IMR & ((1 << 17) | (1 << 19) | (1 << 20));
+ EXTI->PR = pr;
+ if (pr & (1 << 17))
+ EXTD1.config->channels[17].cb(&EXTD1, 17);
+ if (pr & (1 << 19))
+ EXTD1.config->channels[19].cb(&EXTD1, 19);
+ if (pr & (1 << 20))
+ EXTD1.config->channels[20].cb(&EXTD1, 20);
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* HAL_USE_EXT */
+
+#if (HAL_USE_EXT || HAL_USE_ADC) || defined(__DOXYGEN__)
+/**
+ * @brief EXTI[20],EXTI[21] interrupt handler (ADC, COMP).
+ * @note This handler is shared with the ADC so it is handled
+ * a bit differently.
+ *
+ * @isr
+ */
+OSAL_IRQ_HANDLER(STM32_EXTI_LINE2122_HANDLER) {
+
+ OSAL_IRQ_PROLOGUE();
+
+#if HAL_USE_EXT
+ {
+ uint32_t pr;
+
+ pr = EXTI->PR & EXTI->IMR & ((1 << 21) | (1 << 22));
+ EXTI->PR = pr;
+ if (pr & (1 << 21))
+ EXTD1.config->channels[21].cb(&EXTD1, 21);
+ if (pr & (1 << 22))
+ EXTD1.config->channels[21].cb(&EXTD1, 22);
+ }
+#endif
+#if HAL_USE_ADC
+ adc_lld_serve_interrupt(&ADCD1);
+#endif
+
+ OSAL_IRQ_EPILOGUE();
+}
+#endif /* HAL_USE_EXT || HAL_USE_ADC */
+
+#if HAL_USE_EXT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables EXTI IRQ sources.
+ *
+ * @notapi
+ */
+void ext_lld_exti_irq_enable(void) {
+
+ nvicEnableVector(STM32_EXTI_LINE01_NUMBER,
+ STM32_EXT_EXTI0_1_IRQ_PRIORITY);
+ nvicEnableVector(STM32_EXTI_LINE23_NUMBER,
+ STM32_EXT_EXTI2_3_IRQ_PRIORITY);
+ nvicEnableVector(STM32_EXTI_LINE4_15_NUMBER,
+ STM32_EXT_EXTI4_15_IRQ_PRIORITY);
+ nvicEnableVector(STM32_EXTI_LINE16_NUMBER,
+ STM32_EXT_EXTI16_IRQ_PRIORITY);
+ nvicEnableVector(STM32_EXTI_LINE171920_NUMBER,
+ STM32_EXT_EXTI17_20_IRQ_PRIORITY);
+#if HAL_USE_ADC
+ /* If the ADC is not working then the vector can be enabled.*/
+ if (ADCD1.state == ADC_STOP) {
+ nvicEnableVector(STM32_EXTI_LINE2122_NUMBER,
+ STM32_EXT_EXTI21_22_IRQ_PRIORITY);
+ }
+#else
+ nvicEnableVector(STM32_EXTI_LINE2122_NUMBER,
+ STM32_EXT_EXTI21_22_IRQ_PRIORITY);
+#endif
+}
+
+/**
+ * @brief Disables EXTI IRQ sources.
+ *
+ * @notapi
+ */
+void ext_lld_exti_irq_disable(void) {
+
+ nvicDisableVector(STM32_EXTI_LINE01_NUMBER);
+ nvicDisableVector(STM32_EXTI_LINE23_NUMBER);
+ nvicDisableVector(STM32_EXTI_LINE4_15_NUMBER);
+ nvicDisableVector(STM32_EXTI_LINE16_NUMBER);
+ nvicDisableVector(STM32_EXTI_LINE2122_NUMBER);
+#if HAL_USE_ADC
+ /* If the ADC is not working then the vector can be disabled.*/
+ if (ADCD1.state == ADC_STOP) {
+ nvicDisableVector(STM32_EXTI_LINE171920_NUMBER);
+ }
+#else
+ nvicDisableVector(STM32_EXTI_LINE171920_NUMBER);
+#endif
+}
+
+#endif /* HAL_USE_EXT */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.h b/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.h
new file mode 100644
index 000000000..646ef092d
--- /dev/null
+++ b/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.h
@@ -0,0 +1,114 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES 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/ext_lld_isr.h
+ * @brief STM32L0xx EXT subsystem low level driver ISR header.
+ *
+ * @addtogroup EXT
+ * @{
+ */
+
+#ifndef _EXT_LLD_ISR_H_
+#define _EXT_LLD_ISR_H_
+
+#if HAL_USE_EXT || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief EXTI0..1 interrupt priority level setting.
+ */
+#if !defined(STM32_EXT_EXTI0_1_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI2..3 interrupt priority level setting.
+ */
+#if !defined(STM32_EXT_EXTI2_3_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI4..15 interrupt priority level setting.
+ */
+#if !defined(STM32_EXT_EXTI4_15_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI16 (PVD) interrupt priority level setting.
+ */
+#if !defined(STM32_EXT_EXTI16_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI17,19,20 interrupt priority level setting.
+ */
+#if !defined(STM32_EXT_EXTI17_20_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_EXT_EXTI17_20_IRQ_PRIORITY 3
+#endif
+
+/**
+ * @brief EXTI21,22 interrupt priority level setting.
+ */
+#if !defined(STM32_EXT_EXTI21_22_IRQ_PRIORITY) || defined(__DOXYGEN__)
+#define STM32_EXT_EXTI21_22_IRQ_PRIORITY 3
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void ext_lld_exti_irq_enable(void);
+ void ext_lld_exti_irq_disable(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_EXT */
+
+#endif /* _EXT_LLD_ISR_H_ */
+
+/** @} */
diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.c b/os/hal/ports/STM32/STM32L0xx/hal_lld.c
index b30686505..70865b9de 100644
--- a/os/hal/ports/STM32/STM32L0xx/hal_lld.c
+++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.c
@@ -22,8 +22,6 @@
* @{
*/
-/* TODO: LSEBYP like in F3. Disable HSI16 if not used.*/
-
#include "hal.h"
/*===========================================================================*/
@@ -180,6 +178,13 @@ void stm32_clock_init(void) {
/* 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;
}
@@ -212,14 +217,15 @@ void stm32_clock_init(void) {
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
#endif
-#endif /* STM32_NO_INIT */
/* Peripherals clock sources setup.*/
- RCC->CCIPR = STM32_HSI48SEL;
+ RCC->CCIPR = STM32_HSI48SEL | STM32_LPTIM1CLK | STM32_I2C1CLK |
+ STM32_LPUART1CLK | STM32_USART2CLK | STM32_USART1CLK;
/* 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 d68299aa1..1b776eea4 100644
--- a/os/hal/ports/STM32/STM32L0xx/hal_lld.h
+++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.h
@@ -233,8 +233,8 @@
#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_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. */
@@ -251,10 +251,11 @@
#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_SYSCLK (1 << 18) /**< LPTIM1 clock is SYSCLK. */
+#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 << 27) /**< HSI48SEL clock source mask.*/
#define STM32_HSI48SEL_USBPLL (0 << 27) /**< USB48 clock is PLL/2. */
@@ -273,7 +274,7 @@
* @brief Disables the PWR/RCC initialization in the HAL.
*/
#if !defined(STM32_NO_INIT) || defined(__DOXYGEN__)
-#define STM32_NO_INIT FALSE
+#define STM32_NO_INIT FALSE
#endif
/**
@@ -283,70 +284,70 @@
* the maximum voltage.
*/
#if !defined(STM32_VOS) || defined(__DOXYGEN__)
-#define STM32_VOS STM32_VOS_1P8
+#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
+#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
+#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
+#define STM32_HSI16_ENABLED TRUE
#endif
/**
* @brief Enables or disables the LSI clock source.
*/
#if !defined(STM32_LSI_ENABLED) || defined(__DOXYGEN__)
-#define STM32_LSI_ENABLED TRUE
+#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
+#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
+#define STM32_LSE_ENABLED FALSE
#endif
/**
* @brief ADC clock setting.
*/
#if !defined(STM32_ADC_CLOCK_ENABLED) || defined(__DOXYGEN__)
-#define STM32_ADC_CLOCK_ENABLED TRUE
+#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
+#define STM32_USB_CLOCK_ENABLED TRUE
#endif
/**
* @brief MSI frequency setting.
*/
#if !defined(STM32_MSIRANGE) || defined(__DOXYGEN__)
-#define STM32_MSIRANGE STM32_MSIRANGE_2M
+#define STM32_MSIRANGE STM32_MSIRANGE_2M
#endif
/**
@@ -357,7 +358,7 @@
* the internal 16MHz HSI clock.
*/
#if !defined(STM32_SW) || defined(__DOXYGEN__)
-#define STM32_SW STM32_SW_PLL
+#define STM32_SW STM32_SW_PLL
#endif
/**
@@ -368,7 +369,7 @@
* the internal 16MHz HSI clock.
*/
#if !defined(STM32_PLLSRC) || defined(__DOXYGEN__)
-#define STM32_PLLSRC STM32_PLLSRC_HSI16
+#define STM32_PLLSRC STM32_PLLSRC_HSI16
#endif
/**
@@ -378,7 +379,7 @@
* the internal 16MHz HSI clock.
*/
#if !defined(STM32_PLLMUL_VALUE) || defined(__DOXYGEN__)
-#define STM32_PLLMUL_VALUE 4
+#define STM32_PLLMUL_VALUE 4
#endif
/**
@@ -388,7 +389,7 @@
* the internal 16MHz HSI clock.
*/
#if !defined(STM32_PLLDIV_VALUE) || defined(__DOXYGEN__)
-#define STM32_PLLDIV_VALUE 2
+#define STM32_PLLDIV_VALUE 2
#endif
/**
@@ -397,56 +398,91 @@
* the internal 16MHz HSI clock.
*/
#if !defined(STM32_HPRE) || defined(__DOXYGEN__)
-#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_HPRE STM32_HPRE_DIV1
#endif
/**
* @brief APB1 prescaler value.
*/
#if !defined(STM32_PPRE1) || defined(__DOXYGEN__)
-#define STM32_PPRE1 STM32_PPRE1_DIV1
+#define STM32_PPRE1 STM32_PPRE1_DIV1
#endif
/**
* @brief APB2 prescaler value.
*/
#if !defined(STM32_PPRE2) || defined(__DOXYGEN__)
-#define STM32_PPRE2 STM32_PPRE2_DIV1
+#define STM32_PPRE2 STM32_PPRE2_DIV1
#endif
/**
* @brief MCO clock source.
*/
#if !defined(STM32_MCOSEL) || defined(__DOXYGEN__)
-#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
#endif
/**
* @brief MCO divider setting.
*/
#if !defined(STM32_MCOPRE) || defined(__DOXYGEN__)
-#define STM32_MCOPRE STM32_MCOPRE_DIV1
+#define STM32_MCOPRE STM32_MCOPRE_DIV1
#endif
/**
* @brief RTC/LCD clock source.
*/
#if !defined(STM32_RTCSEL) || defined(__DOXYGEN__)
-#define STM32_RTCSEL STM32_RTCSEL_LSI
+#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
+#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_HSI48
+#define STM32_HSI48SEL STM32_HSI48SEL_HSI48
#endif
/** @} */
@@ -952,6 +988,79 @@
#endif
/**
+ * @brief USART1 frequency.
+ */
+#if STM32_USART1SEL == STM32_USART1SEL_APB
+#define STM32_USART1CLK STM32_PCLK2
+#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK
+#define STM32_USART1CLK STM32_SYSCLK
+#elif STM32_USART1SEL == STM32_USART1SEL_HSI16
+#define STM32_USART1CLK STM32_HSI16CLK
+#elif STM32_USART1SEL == STM32_USART1SEL_LSE
+#define STM32_USART1CLK STM32_LSECLK
+#else
+#error "invalid source selected for USART1 clock"
+#endif
+
+/**
+ * @brief USART2 frequency.
+ */
+#if STM32_USART2SEL == STM32_USART2SEL_APB
+#define STM32_USART2CLK STM32_PCLK2
+#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 USART1 clock"
+#endif
+
+/**
+ * @brief LPUART1 frequency.
+ */
+#if STM32_LPUART1SEL == STM32_LPUART1SEL_APB
+#define STM32_LPUART1CLK STM32_PCLK2
+#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 frequency.
+ */
+#if STM32_I2C1SEL == STM32_I2C1SEL_APB
+#define STM32_I2C1CLK STM32_PCLK2
+#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 LPTIM1 frequency.
+ */
+#if STM32_LPTIM1SEL == STM32_LPTIM1SEL_APB
+#define STM32_LPTIM1CLK STM32_PCLK2
+#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_SYSCLK
+#define STM32_LPTIM1CLK STM32_SYSCLK
+#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 USB/RNG frequency.
*/
#if (STM32_HSI48SEL == STM32_HSI48SEL_HSI48) || defined(__DOXYGEN__)
@@ -1005,8 +1114,7 @@
/* Various helpers.*/
#include "nvic.h"
-//#include "stm32_isr.h"
-//#include "stm32_dma.h"
+#include "stm32_dma.h"
#include "stm32_rcc.h"
#ifdef __cplusplus
diff --git a/os/hal/ports/STM32/STM32L0xx/platform.mk b/os/hal/ports/STM32/STM32L0xx/platform.mk
index 2f99f0e01..4b6a6e811 100644
--- a/os/hal/ports/STM32/STM32L0xx/platform.mk
+++ b/os/hal/ports/STM32/STM32L0xx/platform.mk
@@ -4,21 +4,21 @@ HALCONF := $(strip $(shell cat halconf.h | egrep -e "define"))
PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
$(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/hal_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/st_lld.c
-ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
- $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/stm32_dma.c \
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/adc_lld.c
-endif
-ifneq ($(findstring HAL_USE_EXT TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c \
- $(CHIBIOS)/os/hal/ports/STM32/LLD/ext_lld.c
-endif
ifneq ($(findstring HAL_USE_CAN TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/can_lld.c
endif
+ifneq ($(findstring HAL_USE_ADC TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/adc_lld.c
+endif
ifneq ($(findstring HAL_USE_DAC TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/dac_lld.c
endif
+ifneq ($(findstring HAL_USE_EXT TRUE,$(HALCONF)),)
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c
+endif
ifneq ($(findstring HAL_USE_PAL TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c
endif
@@ -29,7 +29,7 @@ ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c
endif
ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),)
-PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c
+PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c
endif
ifneq ($(findstring HAL_USE_GPT TRUE,$(HALCONF)),)
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/gpt_lld.c
@@ -51,17 +51,17 @@ PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/usb_lld.c
endif
else
PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/stm32_dma.c \
$(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/hal_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/adc_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/can_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/LLD/ext_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/adc_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/dac_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/i2c_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c \
- $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1/spi_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/gpt_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/icu_lld.c \
$(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/pwm_lld.c \
@@ -75,11 +75,14 @@ endif
PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \
$(CHIBIOS)/os/hal/ports/STM32/STM32L0xx \
$(CHIBIOS)/os/hal/ports/STM32/LLD \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1 \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1 \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2 \
- $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2 \
+ $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv1 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2 \
$(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1
diff --git a/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h b/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h
index 60270a447..892cd1c9b 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_rcc.h
@@ -268,7 +268,6 @@
*/
/**
* @brief Enables the PWR interface clock.
- * @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
@@ -278,7 +277,6 @@
/**
* @brief Disables PWR interface clock.
- * @note The @p lp parameter is ignored in this family.
*
* @param[in] lp low power enable flag
*
@@ -432,138 +430,80 @@
* @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.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccDisableTIM3(lp) rccDisableAPB1(RCC_APB1ENR_TIM3EN, lp)
-
-/**
- * @brief Resets the TIM3 peripheral.
- *
- * @api
- */
-#define rccResetTIM3() rccResetAPB1(RCC_APB1RSTR_TIM3RST)
-
/**
- * @brief Enables the TIM4 peripheral clock.
+ * @brief Enables the TIM6 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
-#define rccEnableTIM4(lp) rccEnableAPB1(RCC_APB1ENR_TIM4EN, lp)
+#define rccEnableTIM6(lp) rccEnableAPB1(RCC_APB1ENR_TIM6EN, lp)
/**
- * @brief Disables the TIM4 peripheral clock.
+ * @brief Disables the TIM6 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
-#define rccDisableTIM4(lp) rccDisableAPB1(RCC_APB1ENR_TIM4EN, lp)
+#define rccDisableTIM6(lp) rccDisableAPB1(RCC_APB1ENR_TIM6EN, lp)
/**
- * @brief Resets the TIM4 peripheral.
+ * @brief Resets the TIM6 peripheral.
*
* @api
*/
-#define rccResetTIM4() rccResetAPB1(RCC_APB1RSTR_TIM4RST)
+#define rccResetTIM6() rccResetAPB1(RCC_APB1RSTR_TIM6RST)
/**
- * @brief Enables the TIM9 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
+ * @brief Enables the TIM21 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
-#define rccEnableTIM9(lp) rccEnableAPB2(RCC_APB2ENR_TIM9EN, lp)
+#define rccEnableTIM21(lp) rccEnableAPB2(RCC_APB2ENR_TIM21EN, lp)
/**
- * @brief Disables the TIM9 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
+ * @brief Disables the TIM21 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
-#define rccDisableTIM9(lp) rccDisableAPB2(RCC_APB2ENR_TIM9EN, lp)
+#define rccDisableTIM21(lp) rccDisableAPB2(RCC_APB2ENR_TIM21EN, lp)
/**
- * @brief Resets the TIM9 peripheral.
+ * @brief Resets the TIM21 peripheral.
*
* @api
*/
-#define rccResetTIM9() rccResetAPB2(RCC_APB2RSTR_TIM9RST)
+#define rccResetTIM21() rccResetAPB2(RCC_APB2RSTR_TIM21RST)
/**
- * @brief Enables the TIM10 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
+ * @brief Enables the TIM22 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
-#define rccEnableTIM10(lp) rccEnableAPB2(RCC_APB2ENR_TIM10EN, lp)
+#define rccEnableTIM22(lp) rccEnableAPB2(RCC_APB2ENR_TIM22EN, lp)
/**
- * @brief Disables the TIM10 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
+ * @brief Disables the TIM22 peripheral clock.
*
* @param[in] lp low power enable flag
*
* @api
*/
-#define rccDisableTIM10(lp) rccDisableAPB2(RCC_APB2ENR_TIM10EN, lp)
+#define rccDisableTIM22(lp) rccDisableAPB2(RCC_APB2ENR_TIM22EN, lp)
/**
- * @brief Resets the TIM10 peripheral.
+ * @brief Resets the TIM22 peripheral.
*
* @api
*/
-#define rccResetTIM10() rccResetAPB2(RCC_APB2RSTR_TIM10RST)
-
-/**
- * @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 rccEnableTIM11(lp) rccEnableAPB2(RCC_APB2ENR_TIM11EN, lp)
-
-/**
- * @brief Disables the TIM11 peripheral clock.
- * @note The @p lp parameter is ignored in this family.
- *
- * @param[in] lp low power enable flag
- *
- * @api
- */
-#define rccDisableTIM11(lp) rccDisableAPB2(RCC_APB2ENR_TIM11EN, lp)
-
-/**
- * @brief Resets the TIM11 peripheral.
- *
- * @api
- */
-#define rccResetTIM11() rccResetAPB2(RCC_APB2RSTR_TIM11RST)
-
+#define rccResetTIM22() rccResetAPB2(RCC_APB2RSTR_TIM22RST)
/** @} */
/**
diff --git a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
index 44c6f1c81..515dc5616 100644
--- a/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L0xx/stm32_registry.h
@@ -41,6 +41,15 @@
/* ADC attributes.*/
#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_IRQ_SHARED_WITH_EXTI TRUE
+#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
@@ -56,16 +65,22 @@
#define STM32_HAS_DAC2_CH2 FALSE
/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 FALSE
-#define STM32_DMA_STREAMS 5
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#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_DMA2_NUM_CHANNELS 0
/* ETH attributes.*/
#define STM32_HAS_ETH FALSE
/* EXTI attributes.*/
-#define STM32_EXTI_NUM_CHANNELS 28
+#define STM32_EXTI_NUM_CHANNELS 23
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
@@ -85,12 +100,22 @@
/* I2C attributes.*/
#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM 0
-#define STM32_I2C_I2C1_TX_DMA_STREAM 0
+#define STM32_I2C1_GLOBAL_HANDLER Vector9C
+#define STM32_I2C1_GLOBAL_NUMBER 23
+#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_I2C_I2C2_RX_DMA_STREAM 0
-#define STM32_I2C_I2C2_TX_DMA_STREAM 0
+#define STM32_I2C2_GLOBAL_HANDLER VectorA0
+#define STM32_I2C2_GLOBAL_NUMBER 24
+#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
@@ -106,12 +131,18 @@
/* SPI attributes.*/
#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI_SPI1_RX_DMA_STREAM 0
-#define STM32_SPI_SPI1_TX_DMA_STREAM 0
+#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_SPI_SPI2_RX_DMA_STREAM 0
-#define STM32_SPI_SPI2_TX_DMA_STREAM 0
+#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
@@ -119,23 +150,44 @@
#define STM32_HAS_SPI6 FALSE
/* TIM attributes.*/
-#define STM32_TIM_MAX_CHANNELS 4
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR_MASK 0xFF840000U
+
+#define STM32_EXTI_LINE01_HANDLER Vector54
+#define STM32_EXTI_LINE23_HANDLER Vector58
+#define STM32_EXTI_LINE4_15_HANDLER Vector5C
+#define STM32_EXTI_LINE171920_HANDLER Vector48
+#define STM32_EXTI_LINE2122_HANDLER Vector70
+
+#define STM32_EXTI_LINE01_NUMBER 5
+#define STM32_EXTI_LINE23_NUMBER 6
+#define STM32_EXTI_LINE4_15_NUMBER 7
+#define STM32_EXTI_LINE171920_NUMBER 2
+#define STM32_EXTI_LINE2122_NUMBER 12
#define STM32_HAS_TIM2 TRUE
#define STM32_TIM2_IS_32BITS FALSE
#define STM32_TIM2_CHANNELS 4
+#define STM32_TIM2_HANDLER Vector7C
+#define STM32_TIM2_NUMBER 15
#define STM32_HAS_TIM6 TRUE
#define STM32_TIM6_IS_32BITS FALSE
#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM20 TRUE
-#define STM32_TIM20_IS_32BITS FALSE
-#define STM32_TIM20_CHANNELS 4
+#define STM32_TIM6_HANDLER Vector84
+#define STM32_TIM6_NUMBER 17
#define STM32_HAS_TIM21 TRUE
#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 4
+#define STM32_TIM21_CHANNELS 2
+#define STM32_TIM21_HANDLER Vector90
+#define STM32_TIM21_NUMBER 20
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+#define STM32_TIM22_HANDLER Vector98
+#define STM32_TIM22_NUMBER 22
#define STM32_HAS_TIM1 FALSE
#define STM32_HAS_TIM3 FALSE
@@ -154,15 +206,28 @@
#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_UART_USART1_RX_DMA_STREAM 0
-#define STM32_UART_USART1_TX_DMA_STREAM 0
+#define STM32_USART1_HANDLER VectorAC
+#define STM32_USART1_NUMBER 27
+#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_UART_USART2_RX_DMA_STREAM 0
-#define STM32_UART_USART2_TX_DMA_STREAM 0
+#define STM32_USART2_HANDLER VectorB0
+#define STM32_USART2_NUMBER 28
+#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_USART3 FALSE
#define STM32_HAS_UART4 FALSE
@@ -195,6 +260,15 @@
/* ADC attributes.*/
#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_IRQ_SHARED_WITH_EXTI TRUE
+#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
@@ -205,23 +279,43 @@
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM 0
+#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 FALSE
#define STM32_HAS_DAC2_CH1 FALSE
#define STM32_HAS_DAC2_CH2 FALSE
/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 FALSE
-#define STM32_DMA_STREAMS 5
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#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_DMA2_NUM_CHANNELS 0
/* ETH attributes.*/
#define STM32_HAS_ETH FALSE
/* EXTI attributes.*/
-#define STM32_EXTI_NUM_CHANNELS 28
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR_MASK 0xFF840000U
+
+#define STM32_EXTI_LINE01_HANDLER Vector54
+#define STM32_EXTI_LINE23_HANDLER Vector58
+#define STM32_EXTI_LINE4_15_HANDLER Vector5C
+#define STM32_EXTI_LINE171920_HANDLER Vector48
+#define STM32_EXTI_LINE2122_HANDLER Vector70
+
+#define STM32_EXTI_LINE01_NUMBER 5
+#define STM32_EXTI_LINE23_NUMBER 6
+#define STM32_EXTI_LINE4_15_NUMBER 7
+#define STM32_EXTI_LINE171920_NUMBER 2
+#define STM32_EXTI_LINE2122_NUMBER 12
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
@@ -241,12 +335,22 @@
/* I2C attributes.*/
#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM 0
-#define STM32_I2C_I2C1_TX_DMA_STREAM 0
+#define STM32_I2C1_GLOBAL_HANDLER Vector9C
+#define STM32_I2C1_GLOBAL_NUMBER 23
+#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_I2C_I2C2_RX_DMA_STREAM 0
-#define STM32_I2C_I2C2_TX_DMA_STREAM 0
+#define STM32_I2C2_GLOBAL_HANDLER VectorA0
+#define STM32_I2C2_GLOBAL_NUMBER 24
+#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
@@ -262,12 +366,18 @@
/* SPI attributes.*/
#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI_SPI1_RX_DMA_STREAM 0
-#define STM32_SPI_SPI1_TX_DMA_STREAM 0
+#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_SPI_SPI2_RX_DMA_STREAM 0
-#define STM32_SPI_SPI2_TX_DMA_STREAM 0
+#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
@@ -280,18 +390,26 @@
#define STM32_HAS_TIM2 TRUE
#define STM32_TIM2_IS_32BITS FALSE
#define STM32_TIM2_CHANNELS 4
+#define STM32_TIM2_HANDLER Vector7C
+#define STM32_TIM2_NUMBER 15
#define STM32_HAS_TIM6 TRUE
#define STM32_TIM6_IS_32BITS FALSE
#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM20 TRUE
-#define STM32_TIM20_IS_32BITS FALSE
-#define STM32_TIM20_CHANNELS 4
+#define STM32_TIM6_HANDLER Vector84
+#define STM32_TIM6_NUMBER 17
#define STM32_HAS_TIM21 TRUE
#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 4
+#define STM32_TIM21_CHANNELS 2
+#define STM32_TIM21_HANDLER Vector90
+#define STM32_TIM21_NUMBER 20
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+#define STM32_TIM22_HANDLER Vector98
+#define STM32_TIM22_NUMBER 22
#define STM32_HAS_TIM1 FALSE
#define STM32_HAS_TIM3 FALSE
@@ -310,15 +428,28 @@
#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_UART_USART1_RX_DMA_STREAM 0
-#define STM32_UART_USART1_TX_DMA_STREAM 0
+#define STM32_USART1_HANDLER VectorAC
+#define STM32_USART1_NUMBER 27
+#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_UART_USART2_RX_DMA_STREAM 0
-#define STM32_UART_USART2_TX_DMA_STREAM 0
+#define STM32_USART2_HANDLER VectorB0
+#define STM32_USART2_NUMBER 28
+#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_USART3 FALSE
#define STM32_HAS_UART4 FALSE
@@ -330,6 +461,10 @@
#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
#define STM32_USB_PMA_SIZE 1024
#define STM32_USB_HAS_BCDR TRUE
+#define STM32_USB1_LP_HANDLER VectorBC
+#define STM32_USB1_LP_NUMBER 31
+#define STM32_USB1_HP_HANDLER VectorBC
+#define STM32_USB1_HP_NUMBER 31
#define STM32_HAS_OTG1 FALSE
#define STM32_HAS_OTG2 FALSE
@@ -355,6 +490,15 @@
/* ADC attributes.*/
#define STM32_HAS_ADC1 TRUE
+#define STM32_ADC_SUPPORTS_PRESCALER TRUE
+#define STM32_ADC_SUPPORTS_OVERSAMPLING TRUE
+#define STM32_ADC1_IRQ_SHARED_WITH_EXTI TRUE
+#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
@@ -365,23 +509,45 @@
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 FALSE
-#define STM32_DAC_DAC1_CH1_DMA_STREAM 0
+#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 FALSE
#define STM32_HAS_DAC2_CH1 FALSE
#define STM32_HAS_DAC2_CH2 FALSE
/* DMA attributes.*/
-#define STM32_ADVANCED_DMA FALSE
-#define STM32_HAS_DMA1 TRUE
-#define STM32_HAS_DMA2 FALSE
-#define STM32_DMA_STREAMS 5
+#define STM32_ADVANCED_DMA TRUE
+#define STM32_DMA1_NUM_CHANNELS 7
+#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_DMA2_NUM_CHANNELS 0
/* ETH attributes.*/
#define STM32_HAS_ETH FALSE
/* EXTI attributes.*/
-#define STM32_EXTI_NUM_CHANNELS 28
+#define STM32_EXTI_NUM_LINES 23
+#define STM32_EXTI_IMR_MASK 0xFF840000U
+
+#define STM32_EXTI_LINE01_HANDLER Vector54
+#define STM32_EXTI_LINE23_HANDLER Vector58
+#define STM32_EXTI_LINE4_15_HANDLER Vector5C
+#define STM32_EXTI_LINE16_HANDLER Vector44
+#define STM32_EXTI_LINE171920_HANDLER Vector48
+#define STM32_EXTI_LINE2122_HANDLER Vector70
+
+#define STM32_EXTI_LINE01_NUMBER 5
+#define STM32_EXTI_LINE23_NUMBER 6
+#define STM32_EXTI_LINE4_15_NUMBER 7
+#define STM32_EXTI_LINE16_NUMBER 1
+#define STM32_EXTI_LINE171920_NUMBER 2
+#define STM32_EXTI_LINE2122_NUMBER 12
/* GPIO attributes.*/
#define STM32_HAS_GPIOA TRUE
@@ -401,12 +567,22 @@
/* I2C attributes.*/
#define STM32_HAS_I2C1 TRUE
-#define STM32_I2C_I2C1_RX_DMA_STREAM 0
-#define STM32_I2C_I2C1_TX_DMA_STREAM 0
+#define STM32_I2C1_GLOBAL_HANDLER Vector9C
+#define STM32_I2C1_GLOBAL_NUMBER 23
+#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_I2C_I2C2_RX_DMA_STREAM 0
-#define STM32_I2C_I2C2_TX_DMA_STREAM 0
+#define STM32_I2C2_GLOBAL_HANDLER VectorA0
+#define STM32_I2C2_GLOBAL_NUMBER 24
+#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
@@ -422,12 +598,18 @@
/* SPI attributes.*/
#define STM32_HAS_SPI1 TRUE
-#define STM32_SPI_SPI1_RX_DMA_STREAM 0
-#define STM32_SPI_SPI1_TX_DMA_STREAM 0
+#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_SPI_SPI2_RX_DMA_STREAM 0
-#define STM32_SPI_SPI2_TX_DMA_STREAM 0
+#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
@@ -440,18 +622,26 @@
#define STM32_HAS_TIM2 TRUE
#define STM32_TIM2_IS_32BITS FALSE
#define STM32_TIM2_CHANNELS 4
+#define STM32_TIM2_HANDLER Vector7C
+#define STM32_TIM2_NUMBER 15
#define STM32_HAS_TIM6 TRUE
#define STM32_TIM6_IS_32BITS FALSE
#define STM32_TIM6_CHANNELS 0
-
-#define STM32_HAS_TIM20 TRUE
-#define STM32_TIM20_IS_32BITS FALSE
-#define STM32_TIM20_CHANNELS 4
+#define STM32_TIM6_HANDLER Vector84
+#define STM32_TIM6_NUMBER 17
#define STM32_HAS_TIM21 TRUE
#define STM32_TIM21_IS_32BITS FALSE
-#define STM32_TIM21_CHANNELS 4
+#define STM32_TIM21_CHANNELS 2
+#define STM32_TIM21_HANDLER Vector90
+#define STM32_TIM21_NUMBER 20
+
+#define STM32_HAS_TIM22 TRUE
+#define STM32_TIM22_IS_32BITS FALSE
+#define STM32_TIM22_CHANNELS 2
+#define STM32_TIM22_HANDLER Vector98
+#define STM32_TIM22_NUMBER 22
#define STM32_HAS_TIM1 FALSE
#define STM32_HAS_TIM3 FALSE
@@ -470,15 +660,28 @@
#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_UART_USART1_RX_DMA_STREAM 0
-#define STM32_UART_USART1_TX_DMA_STREAM 0
+#define STM32_USART1_HANDLER VectorAC
+#define STM32_USART1_NUMBER 27
+#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_UART_USART2_RX_DMA_STREAM 0
-#define STM32_UART_USART2_TX_DMA_STREAM 0
+#define STM32_USART2_HANDLER VectorB0
+#define STM32_USART2_NUMBER 28
+#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_USART3 FALSE
#define STM32_HAS_UART4 FALSE
@@ -490,6 +693,10 @@
#define STM32_USB_ACCESS_SCHEME_2x16 TRUE
#define STM32_USB_PMA_SIZE 1024
#define STM32_USB_HAS_BCDR TRUE
+#define STM32_USB1_LP_HANDLER VectorBC
+#define STM32_USB1_LP_NUMBER 31
+#define STM32_USB1_HP_HANDLER VectorBC
+#define STM32_USB1_HP_NUMBER 31
#define STM32_HAS_OTG1 FALSE
#define STM32_HAS_OTG2 FALSE
diff --git a/os/hal/ports/STM32/STM32L1xx/stm32_registry.h b/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
index 62e8d4d31..53833f657 100644
--- a/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L1xx/stm32_registry.h
@@ -170,6 +170,9 @@
#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
@@ -350,6 +353,9 @@
#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