From c96f0b2bbf7c911a5d23d6c9920f1c6f4d766c8c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 26 Jul 2015 06:17:10 +0000 Subject: More STM32L0xx support files. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8104 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/boards/ST_NUCLEO_L053R8/board.h | 16 +- os/hal/ports/STM32/LLD/ADCv1/adc_lld.c | 315 +++++++++++++++++++ os/hal/ports/STM32/LLD/ADCv1/adc_lld.h | 428 ++++++++++++++++++++++++++ os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c | 224 ++++++++++---- os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h | 126 ++++---- os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c | 217 +++++++++++++ os/hal/ports/STM32/LLD/EXTIv1/ext_lld.h | 155 ++++++++++ os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c | 2 +- os/hal/ports/STM32/LLD/TIMv1/st_lld.c | 22 ++ os/hal/ports/STM32/LLD/TIMv1/st_lld.h | 12 + os/hal/ports/STM32/LLD/TIMv1/stm32_tim.h | 3 + os/hal/ports/STM32/LLD/USARTv2/serial_lld.c | 5 + os/hal/ports/STM32/STM32F0xx/platform.mk | 11 +- os/hal/ports/STM32/STM32F0xx/stm32_registry.h | 21 ++ os/hal/ports/STM32/STM32F1xx/stm32_registry.h | 21 ++ os/hal/ports/STM32/STM32F37x/stm32_registry.h | 6 + os/hal/ports/STM32/STM32F3xx/stm32_registry.h | 27 ++ os/hal/ports/STM32/STM32F4xx/hal_lld.c | 2 +- os/hal/ports/STM32/STM32F4xx/stm32_registry.h | 12 + os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c | 265 ++++++++++++++++ os/hal/ports/STM32/STM32L0xx/ext_lld_isr.h | 114 +++++++ os/hal/ports/STM32/STM32L0xx/hal_lld.c | 14 +- os/hal/ports/STM32/STM32L0xx/hal_lld.h | 168 ++++++++-- os/hal/ports/STM32/STM32L0xx/platform.mk | 31 +- os/hal/ports/STM32/STM32L0xx/stm32_rcc.h | 96 ++---- os/hal/ports/STM32/STM32L0xx/stm32_registry.h | 345 ++++++++++++++++----- os/hal/ports/STM32/STM32L1xx/stm32_registry.h | 6 + 27 files changed, 2331 insertions(+), 333 deletions(-) create mode 100644 os/hal/ports/STM32/LLD/ADCv1/adc_lld.c create mode 100644 os/hal/ports/STM32/LLD/ADCv1/adc_lld.h create mode 100644 os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c create mode 100644 os/hal/ports/STM32/LLD/EXTIv1/ext_lld.h create mode 100644 os/hal/ports/STM32/STM32L0xx/ext_lld_isr.c create mode 100644 os/hal/ports/STM32/STM32L0xx/ext_lld_isr.h (limited to 'os') 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 * @{ */ @@ -31,31 +31,39 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @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 /** @} */ @@ -951,6 +987,79 @@ #error "invalid STM32_RTCSEL value specified" #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. */ @@ -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 -- cgit v1.2.3