From 7a6a1679a413987ffa47f2f9892e241f3448f5f0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 May 2012 18:31:34 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4232 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM0-STM32F051-DISCOVERY/halconf.h | 2 +- demos/ARMCM0-STM32F051-DISCOVERY/mcuconf.h | 16 + os/hal/platforms/STM32/serial_lld.c | 129 ++++++- os/hal/platforms/STM32/serial_lld.h | 30 ++ os/hal/platforms/STM32/spi_lld.c | 11 +- os/hal/platforms/STM32/spi_lld.h | 39 ++ os/hal/platforms/STM32/stm32.h | 26 +- os/hal/platforms/STM32F0xx/hal_lld.h | 22 +- os/hal/platforms/STM32F0xx/platform.mk | 11 +- os/hal/platforms/STM32F0xx/serial_lld.c | 322 ----------------- os/hal/platforms/STM32F0xx/serial_lld.h | 182 ---------- os/hal/platforms/STM32F0xx/stm32_dma.c | 296 +++++++++++++++ os/hal/platforms/STM32F0xx/stm32_dma.h | 395 +++++++++++++++++++++ os/hal/platforms/STM32F1xx/stm32_dma.h | 28 +- os/hal/platforms/STM32F2xx/stm32_dma.h | 10 + os/hal/platforms/STM32F4xx/stm32_dma.h | 10 + os/hal/platforms/STM32L1xx/stm32_dma.h | 14 +- os/ports/GCC/ARMCMx/chcore.h | 6 + os/ports/GCC/ARMCMx/chcore_v6m.h | 9 + os/ports/GCC/ARMCMx/chcore_v7m.h | 11 +- os/ports/IAR/ARMCMx/chcore.h | 8 +- os/ports/IAR/ARMCMx/chcore_v6m.h | 9 + os/ports/IAR/ARMCMx/chcore_v7m.h | 13 +- os/ports/RVCT/ARMCMx/chcore.h | 8 +- os/ports/RVCT/ARMCMx/chcore_v6m.h | 9 + os/ports/RVCT/ARMCMx/chcore_v7m.h | 13 +- readme.txt | 2 + 27 files changed, 1080 insertions(+), 551 deletions(-) delete mode 100644 os/hal/platforms/STM32F0xx/serial_lld.c delete mode 100644 os/hal/platforms/STM32F0xx/serial_lld.h create mode 100644 os/hal/platforms/STM32F0xx/stm32_dma.c create mode 100644 os/hal/platforms/STM32F0xx/stm32_dma.h diff --git a/demos/ARMCM0-STM32F051-DISCOVERY/halconf.h b/demos/ARMCM0-STM32F051-DISCOVERY/halconf.h index c9b3ad25a..d3766e0fd 100644 --- a/demos/ARMCM0-STM32F051-DISCOVERY/halconf.h +++ b/demos/ARMCM0-STM32F051-DISCOVERY/halconf.h @@ -143,7 +143,7 @@ * @brief Enables the SPI subsystem. */ #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) -#define HAL_USE_SPI FALSE +#define HAL_USE_SPI TRUE #endif /** diff --git a/demos/ARMCM0-STM32F051-DISCOVERY/mcuconf.h b/demos/ARMCM0-STM32F051-DISCOVERY/mcuconf.h index 42633e046..5f4b3377b 100644 --- a/demos/ARMCM0-STM32F051-DISCOVERY/mcuconf.h +++ b/demos/ARMCM0-STM32F051-DISCOVERY/mcuconf.h @@ -64,5 +64,21 @@ */ #define STM32_SERIAL_USE_USART1 TRUE #define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USE_USART6 FALSE #define STM32_SERIAL_USART1_PRIORITY 3 #define STM32_SERIAL_USART2_PRIORITY 3 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 TRUE +#define STM32_SPI_USE_SPI2 TRUE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 2 +#define STM32_SPI_SPI2_IRQ_PRIORITY 2 +#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() diff --git a/os/hal/platforms/STM32/serial_lld.c b/os/hal/platforms/STM32/serial_lld.c index a93d36523..fdb99cbc8 100644 --- a/os/hal/platforms/STM32/serial_lld.c +++ b/os/hal/platforms/STM32/serial_lld.c @@ -82,6 +82,129 @@ static const SerialConfig default_config = /* Driver local functions. */ /*===========================================================================*/ +/* Local functions have different implementations depending on the USART type, + STM32F0xx devices and newer have and enhanced peripheral with slightly + different register interface.*/ + +#if defined(STM32F0XX) + +/** + * @brief USART initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] config the architecture-dependent serial driver configuration + */ +static void usart_init(SerialDriver *sdp, const SerialConfig *config) { + USART_TypeDef *u = sdp->usart; + + /* + * Baud rate setting. + */ + if (sdp->usart == USART1) + u->BRR = STM32_USART1CLK / config->sc_speed; + else + u->BRR = STM32_PCLK / config->sc_speed; + + /* + * Note that some bits are enforced. + */ + u->CR1 = config->sc_cr1 | USART_CR1_UE | USART_CR1_PEIE | + USART_CR1_RXNEIE | USART_CR1_TE | + USART_CR1_RE; + u->CR2 = config->sc_cr2 | USART_CR2_LBDIE; + u->CR3 = config->sc_cr3 | USART_CR3_EIE; + u->ICR = 0xFFFFFFFF; +} + +/** + * @brief USART de-initialization. + * @details This function must be invoked with interrupts disabled. + * + * @param[in] u pointer to an USART I/O block + */ +static void usart_deinit(USART_TypeDef *u) { + + u->CR1 = 0; + u->CR2 = 0; + u->CR3 = 0; +} + +/** + * @brief Error handling routine. + * + * @param[in] sdp pointer to a @p SerialDriver object + * @param[in] isr USART ISR register value + */ +static void set_error(SerialDriver *sdp, uint16_t isr) { + chnflags_t sts = 0; + + if (isr & USART_ISR_ORE) + sts |= SD_OVERRUN_ERROR; + if (isr & USART_ISR_PE) + sts |= SD_PARITY_ERROR; + if (isr & USART_ISR_FE) + sts |= SD_FRAMING_ERROR; + if (isr & USART_ISR_NE) + sts |= SD_NOISE_ERROR; + chSysLockFromIsr(); + chnAddFlagsI(sdp, sts); + chSysUnlockFromIsr(); +} + +/** + * @brief Common IRQ handler. + * + * @param[in] sdp communication channel associated to the USART + */ +static void serve_interrupt(SerialDriver *sdp) { + USART_TypeDef *u = sdp->usart; + uint16_t cr1 = u->CR1; + uint16_t isr; + + /* Reading and clearing status.*/ + isr = u->ISR; + u->ICR = isr; + + /* Error condition detection.*/ + if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE)) + set_error(sdp, isr); + /* Special case, LIN break detection.*/ + if (isr & USART_ISR_LBD) { + chSysLockFromIsr(); + chnAddFlagsI(sdp, SD_BREAK_DETECTED); + chSysUnlockFromIsr(); + } + /* Data available.*/ + if (isr & USART_ISR_RXNE) { + chSysLockFromIsr(); + sdIncomingDataI(sdp, (uint8_t)u->RDR); + chSysUnlockFromIsr(); + } + /* Transmission buffer empty.*/ + if ((cr1 & USART_CR1_TXEIE) && (isr & USART_ISR_TXE)) { + msg_t b; + chSysLockFromIsr(); + b = chOQGetI(&sdp->oqueue); + if (b < Q_OK) { + chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); + u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE; + } + else + u->TDR = b; + chSysUnlockFromIsr(); + } + /* Physical transmission end.*/ + if (isr & USART_ISR_TC) { + chSysLockFromIsr(); + chnAddFlagsI(sdp, CHN_TRANSMISSION_END); + chSysUnlockFromIsr(); + u->CR1 = cr1 & ~USART_CR1_TCIE; + } +} + +#else /* !defined(STM32F0XX) */ + /** * @brief USART initialization. * @details This function must be invoked with interrupts disabled. @@ -130,9 +253,6 @@ static void usart_deinit(USART_TypeDef *u) { u->CR3 = 0; } -#if STM32_SERIAL_USE_USART1 || STM32_SERIAL_USE_USART2 || \ - STM32_SERIAL_USE_USART3 || STM32_SERIAL_USE_UART4 || \ - STM32_SERIAL_USE_UART5 || STM32_SERIAL_USE_USART6 /** * @brief Error handling routine. * @@ -204,7 +324,8 @@ static void serve_interrupt(SerialDriver *sdp) { u->SR &= ~USART_SR_TC; } } -#endif + +#endif /* !defined(STM32F0XX) */ #if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__) static void notify1(GenericQueue *qp) { diff --git a/os/hal/platforms/STM32/serial_lld.h b/os/hal/platforms/STM32/serial_lld.h index 7589da600..20905e367 100644 --- a/os/hal/platforms/STM32/serial_lld.h +++ b/os/hal/platforms/STM32/serial_lld.h @@ -174,6 +174,36 @@ #error "SERIAL driver activated but no USART/UART peripheral assigned" #endif +#if STM32_SERIAL_USE_USART1 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SERIAL_USART1_PRIORITY) +#error "Invalid IRQ priority assigned to USART1" +#endif + +#if STM32_SERIAL_USE_USART2 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SERIAL_USART2_PRIORITY) +#error "Invalid IRQ priority assigned to USART2" +#endif + +#if STM32_SERIAL_USE_USART3 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SERIAL_USART3_PRIORITY) +#error "Invalid IRQ priority assigned to USART3" +#endif + +#if STM32_SERIAL_USE_UART4 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SERIAL_UART4_PRIORITY) +#error "Invalid IRQ priority assigned to UART4" +#endif + +#if STM32_SERIAL_USE_UART5 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SERIAL_UART5_PRIORITY) +#error "Invalid IRQ priority assigned to UART5" +#endif + +#if STM32_SERIAL_USE_USART6 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SERIAL_USART6_PRIORITY) +#error "Invalid IRQ priority assigned to USART6" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/spi_lld.c b/os/hal/platforms/STM32/spi_lld.c index eeeb47f53..113b89fe1 100644 --- a/os/hal/platforms/STM32/spi_lld.c +++ b/os/hal/platforms/STM32/spi_lld.c @@ -273,13 +273,20 @@ void spi_lld_start(SPIDriver *spip) { } /* Configuration-specific DMA setup.*/ - if ((spip->config->cr1 & SPI_CR1_DFF) == 0) { /* 8 bits transfers. */ +#if defined(STM32F0XX) + if ((spip->config->cr1 & SPI_CR2_DS) < + (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0)) { +#else /* !defined(STM32F0XX) */ + if ((spip->config->cr1 & SPI_CR1_DFF) == 0) { +#endif /* !defined(STM32F0XX) */ + /* Frame width is 8 bits or smaller.*/ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) | STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; } - else { /* 16 bits transfers. */ + else { + /* Frame width is larger than 8 bits.*/ spip->rxdmamode = (spip->rxdmamode & ~STM32_DMA_CR_SIZE_MASK) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; spip->txdmamode = (spip->txdmamode & ~STM32_DMA_CR_SIZE_MASK) | diff --git a/os/hal/platforms/STM32/spi_lld.h b/os/hal/platforms/STM32/spi_lld.h index 7de182339..cb68065c0 100644 --- a/os/hal/platforms/STM32/spi_lld.h +++ b/os/hal/platforms/STM32/spi_lld.h @@ -180,6 +180,14 @@ #else /* !STM32_ADVANCED_DMA */ +#if defined(STM32F0XX) +/* Fixed values for STM32F0xx devices.*/ +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) + +#else /* !defined(STM32F0XX) */ /* Fixed streams for platforms using the old DMA peripheral, the values are valid for both STM32F1xx and STM32L1xx.*/ #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) @@ -188,6 +196,7 @@ #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) #define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#endif /* !defined(STM32F0XX) */ #endif /* !STM32_ADVANCED_DMA*/ /** @} */ @@ -212,6 +221,36 @@ #error "SPI driver activated but no SPI peripheral assigned" #endif +#if STM32_SPI_USE_SPI1 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI1" +#endif + +#if STM32_SPI_USE_SPI2 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI2_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI2" +#endif + +#if STM32_SPI_USE_SPI3 && \ + !CORTEX_IS_VALID_KERNEL_PRIORITY(STM32_SPI_SPI3_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI3" +#endif + +#if STM32_SPI_USE_SPI1 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI1_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI1" +#endif + +#if STM32_SPI_USE_SPI2 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI2_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI2" +#endif + +#if STM32_SPI_USE_SPI3 && \ + !STM32_DMA_IS_VALID_PRIORITY(STM32_SPI_SPI3_DMA_PRIORITY) +#error "Invalid DMA priority assigned to SPI3" +#endif + #if STM32_SPI_USE_SPI1 && \ !STM32_DMA_IS_VALID_ID(STM32_SPI_SPI1_RX_DMA_STREAM, STM32_SPI1_RX_DMA_MSK) #error "invalid DMA stream associated to SPI1 RX" diff --git a/os/hal/platforms/STM32/stm32.h b/os/hal/platforms/STM32/stm32.h index 24929cf3a..49c1c08bb 100644 --- a/os/hal/platforms/STM32/stm32.h +++ b/os/hal/platforms/STM32/stm32.h @@ -24,6 +24,7 @@ * @pre One of the following macros must be defined before including * this header, the macro selects the inclusion of the appropriate * vendor header: + * - STM32F0XX for Entry Level devices. * - STM32F10X_LD_VL for Value Line Low Density devices. * - STM32F10X_MD_VL for Value Line Medium Density devices. * - STM32F10X_LD for Performance Low Density devices. @@ -43,24 +44,27 @@ #ifndef _STM32_H_ #define _STM32_H_ -#if defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \ - defined(STM32F10X_HD_VL) || defined(STM32F10X_LD) || \ - defined(STM32F10X_MD) || defined(STM32F10X_HD) || \ - defined(STM32F10X_XL) || defined(STM32F10X_CL) || \ - defined(__DOXYGEN__) +#if defined(STM32F0XX) +#include "stm32f0xx.h" + +#elif defined(STM32F10X_LD_VL) || defined(STM32F10X_MD_VL) || \ + defined(STM32F10X_HD_VL) || defined(STM32F10X_LD) || \ + defined(STM32F10X_MD) || defined(STM32F10X_HD) || \ + defined(STM32F10X_XL) || defined(STM32F10X_CL) || \ + defined(__DOXYGEN__) #include "stm32f10x.h" -#endif -#if defined(STM32F2XX) || defined(__DOXYGEN__) +#elif defined(STM32F2XX) || defined(__DOXYGEN__) #include "stm32f2xx.h" -#endif -#if defined(STM32F4XX) || defined(__DOXYGEN__) +#elif defined(STM32F4XX) || defined(__DOXYGEN__) #include "stm32f4xx.h" -#endif -#if defined(STM32L1XX_MD) || defined(__DOXYGEN__) +#elif defined(STM32L1XX_MD) || defined(__DOXYGEN__) #include "stm32l1xx.h" + +#else +#error "STM32 device not specified" #endif /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F0xx/hal_lld.h b/os/hal/platforms/STM32F0xx/hal_lld.h index 1bd31c168..30a46fa79 100644 --- a/os/hal/platforms/STM32F0xx/hal_lld.h +++ b/os/hal/platforms/STM32F0xx/hal_lld.h @@ -38,7 +38,7 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "stm32f0xx.h" +#include "stm32.h" /*===========================================================================*/ /* Driver constants. */ @@ -223,8 +223,20 @@ */ /* ADC attributes.*/ #define STM32_HAS_ADC1 TRUE +#define STM32_ADC1_DMA_DEFAULT STM32_DMA_STREAM_ID(1, 0) +#define STM32_ADC1_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 0) | \ + STM32_DMA_STREAM_ID_MSK(1, 1)) +#define STM32_ADC1_DMA_CHN 0x00000000 + #define STM32_HAS_ADC2 FALSE +#define STM32_ADC2_DMA_DEFAULT 0 +#define STM32_ADC2_DMA_MSK 0x00000000 +#define STM32_ADC2_DMA_CHN 0x00000000 + #define STM32_HAS_ADC3 FALSE +#define STM32_ADC3_DMA_DEFAULT 0 +#define STM32_ADC3_DMA_MSK 0x00000000 +#define STM32_ADC3_DMA_CHN 0x00000000 /* CAN attributes.*/ #define STM32_HAS_CAN1 FALSE @@ -322,9 +334,11 @@ /* USART attributes.*/ #define STM32_HAS_USART1 TRUE -#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3)) +#define STM32_USART1_RX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 3) | \ + STM32_DMA_STREAM_ID_MSK(1, 5)) #define STM32_USART1_RX_DMA_CHN 0x00000000 -#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2)) +#define STM32_USART1_TX_DMA_MSK (STM32_DMA_STREAM_ID_MSK(1, 2) | \ + STM32_DMA_STREAM_ID_MSK(1, 4)) #define STM32_USART1_TX_DMA_CHN 0x00000000 #define STM32_HAS_USART2 TRUE @@ -939,7 +953,7 @@ /*===========================================================================*/ /* STM32 DMA and RCC helpers.*/ -/*#include "stm32_dma.h"*/ +#include "stm32_dma.h" #include "stm32_rcc.h" #ifdef __cplusplus diff --git a/os/hal/platforms/STM32F0xx/platform.mk b/os/hal/platforms/STM32F0xx/platform.mk index e34e8dd8e..9d13d064a 100644 --- a/os/hal/platforms/STM32F0xx/platform.mk +++ b/os/hal/platforms/STM32F0xx/platform.mk @@ -1,8 +1,11 @@ # List of all the STM32F1xx platform files. -PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F0xx/hal_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32F0xx/serial_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c +PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F0xx/stm32_dma.c \ + ${CHIBIOS}/os/hal/platforms/STM32F0xx/hal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/serial_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F0xx \ - ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 + ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \ + ${CHIBIOS}/os/hal/platforms/STM32 diff --git a/os/hal/platforms/STM32F0xx/serial_lld.c b/os/hal/platforms/STM32F0xx/serial_lld.c deleted file mode 100644 index a611279a4..000000000 --- a/os/hal/platforms/STM32F0xx/serial_lld.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file STM32/serial_lld.c - * @brief STM32 low level serial driver code. - * - * @addtogroup SERIAL - * @{ - */ - -#include "ch.h" -#include "hal.h" - -#if HAL_USE_SERIAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** @brief USART1 serial driver identifier.*/ -#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__) -SerialDriver SD1; -#endif - -/** @brief USART2 serial driver identifier.*/ -#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__) -SerialDriver SD2; -#endif - -/*===========================================================================*/ -/* Driver local variables. */ -/*===========================================================================*/ - -/** @brief Driver default configuration.*/ -static const SerialConfig default_config = -{ - SERIAL_DEFAULT_BITRATE, - 0, - USART_CR2_STOP1_BITS | USART_CR2_LINEN, - 0 -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief USART initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration - */ -static void usart_init(SerialDriver *sdp, const SerialConfig *config) { - USART_TypeDef *u = sdp->usart; - - /* - * Baud rate setting. - */ - if (sdp->usart == USART1) - u->BRR = STM32_USART1CLK / config->sc_speed; - else - u->BRR = STM32_PCLK / config->sc_speed; - - /* - * Note that some bits are enforced. - */ - u->CR1 = config->sc_cr1 | USART_CR1_UE | USART_CR1_PEIE | - USART_CR1_RXNEIE | USART_CR1_TE | - USART_CR1_RE; - u->CR2 = config->sc_cr2 | USART_CR2_LBDIE; - u->CR3 = config->sc_cr3 | USART_CR3_EIE; - u->ICR = 0xFFFFFFFF; -} - -/** - * @brief USART de-initialization. - * @details This function must be invoked with interrupts disabled. - * - * @param[in] u pointer to an USART I/O block - */ -static void usart_deinit(USART_TypeDef *u) { - - u->CR1 = 0; - u->CR2 = 0; - u->CR3 = 0; -} - -#if STM32_SERIAL_USE_USART1 || STM32_SERIAL_USE_USART2 -/** - * @brief Error handling routine. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] isr USART ISR register value - */ -static void set_error(SerialDriver *sdp, uint16_t isr) { - chnflags_t sts = 0; - - if (isr & USART_ISR_ORE) - sts |= SD_OVERRUN_ERROR; - if (isr & USART_ISR_PE) - sts |= SD_PARITY_ERROR; - if (isr & USART_ISR_FE) - sts |= SD_FRAMING_ERROR; - if (isr & USART_ISR_NE) - sts |= SD_NOISE_ERROR; - chSysLockFromIsr(); - chnAddFlagsI(sdp, sts); - chSysUnlockFromIsr(); -} - -/** - * @brief Common IRQ handler. - * - * @param[in] sdp communication channel associated to the USART - */ -static void serve_interrupt(SerialDriver *sdp) { - USART_TypeDef *u = sdp->usart; - uint16_t cr1 = u->CR1; - uint16_t isr; - - /* Reading and clearing status.*/ - isr = u->ISR; - u->ICR = isr; - - /* Error condition detection.*/ - if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE)) - set_error(sdp, isr); - /* Special case, LIN break detection.*/ - if (isr & USART_ISR_LBD) { - chSysLockFromIsr(); - chnAddFlagsI(sdp, SD_BREAK_DETECTED); - chSysUnlockFromIsr(); - } - /* Data available.*/ - if (isr & USART_ISR_RXNE) { - chSysLockFromIsr(); - sdIncomingDataI(sdp, (uint8_t)u->RDR); - chSysUnlockFromIsr(); - } - /* Transmission buffer empty.*/ - if ((cr1 & USART_CR1_TXEIE) && (isr & USART_ISR_TXE)) { - msg_t b; - chSysLockFromIsr(); - b = chOQGetI(&sdp->oqueue); - if (b < Q_OK) { - chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); - u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE; - } - else - u->TDR = b; - chSysUnlockFromIsr(); - } - /* Physical transmission end.*/ - if (isr & USART_ISR_TC) { - chSysLockFromIsr(); - chnAddFlagsI(sdp, CHN_TRANSMISSION_END); - chSysUnlockFromIsr(); - u->CR1 = cr1 & ~USART_CR1_TCIE; - } -} -#endif - -#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__) -static void notify1(GenericQueue *qp) { - - (void)qp; - USART1->CR1 |= USART_CR1_TXEIE; -} -#endif - -#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__) -static void notify2(GenericQueue *qp) { - - (void)qp; - USART2->CR1 |= USART_CR1_TXEIE; -} -#endif - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if STM32_SERIAL_USE_USART1 || defined(__DOXYGEN__) -/** - * @brief USART1 interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(USART1_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - serve_interrupt(&SD1); - - CH_IRQ_EPILOGUE(); -} -#endif - -#if STM32_SERIAL_USE_USART2 || defined(__DOXYGEN__) -/** - * @brief USART2 interrupt handler. - * - * @isr - */ -CH_IRQ_HANDLER(USART2_IRQHandler) { - - CH_IRQ_PROLOGUE(); - - serve_interrupt(&SD2); - - CH_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level serial driver initialization. - * - * @notapi - */ -void sd_lld_init(void) { - -#if STM32_SERIAL_USE_USART1 - sdObjectInit(&SD1, NULL, notify1); - SD1.usart = USART1; -#endif - -#if STM32_SERIAL_USE_USART2 - sdObjectInit(&SD2, NULL, notify2); - SD2.usart = USART2; -#endif -} - -/** - * @brief Low level serial driver configuration and (re)start. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration. - * If this parameter is set to @p NULL then a default - * configuration is used. - * - * @notapi - */ -void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { - - if (config == NULL) - config = &default_config; - - if (sdp->state == SD_STOP) { -#if STM32_SERIAL_USE_USART1 - if (&SD1 == sdp) { - rccEnableUSART1(FALSE); - nvicEnableVector(USART1_IRQn, - CORTEX_PRIORITY_MASK(STM32_SERIAL_USART1_PRIORITY)); - } -#endif -#if STM32_SERIAL_USE_USART2 - if (&SD2 == sdp) { - rccEnableUSART2(FALSE); - nvicEnableVector(USART2_IRQn, - CORTEX_PRIORITY_MASK(STM32_SERIAL_USART2_PRIORITY)); - } -#endif - } - usart_init(sdp, config); -} - -/** - * @brief Low level serial driver stop. - * @details De-initializes the USART, stops the associated clock, resets the - * interrupt vector. - * - * @param[in] sdp pointer to a @p SerialDriver object - * - * @notapi - */ -void sd_lld_stop(SerialDriver *sdp) { - - if (sdp->state == SD_READY) { - usart_deinit(sdp->usart); -#if STM32_SERIAL_USE_USART1 - if (&SD1 == sdp) { - rccDisableUSART1(FALSE); - nvicDisableVector(USART1_IRQn); - return; - } -#endif -#if STM32_SERIAL_USE_USART2 - if (&SD2 == sdp) { - rccDisableUSART2(FALSE); - nvicDisableVector(USART2_IRQn); - return; - } -#endif - } -} - -#endif /* HAL_USE_SERIAL */ - -/** @} */ diff --git a/os/hal/platforms/STM32F0xx/serial_lld.h b/os/hal/platforms/STM32F0xx/serial_lld.h deleted file mode 100644 index da41e66da..000000000 --- a/os/hal/platforms/STM32F0xx/serial_lld.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file STM32/serial_lld.h - * @brief STM32 low level serial driver header. - * - * @addtogroup SERIAL - * @{ - */ - -#ifndef _SERIAL_LLD_H_ -#define _SERIAL_LLD_H_ - -#if HAL_USE_SERIAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief USART1 driver enable switch. - * @details If set to @p TRUE the support for USART1 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_SERIAL_USE_USART1) || defined(__DOXYGEN__) -#define STM32_SERIAL_USE_USART1 TRUE -#endif - -/** - * @brief USART2 driver enable switch. - * @details If set to @p TRUE the support for USART2 is included. - * @note The default is @p TRUE. - */ -#if !defined(STM32_SERIAL_USE_USART2) || defined(__DOXYGEN__) -#define STM32_SERIAL_USE_USART2 TRUE -#endif - -/** - * @brief USART1 interrupt priority level setting. - */ -#if !defined(STM32_SERIAL_USART1_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SERIAL_USART1_PRIORITY 3 -#endif - -/** - * @brief USART2 interrupt priority level setting. - */ -#if !defined(STM32_SERIAL_USART2_PRIORITY) || defined(__DOXYGEN__) -#define STM32_SERIAL_USART2_PRIORITY 3 -#endif -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if STM32_SERIAL_USE_USART1 && !STM32_HAS_USART1 -#error "USART1 not present in the selected device" -#endif - -#if STM32_SERIAL_USE_USART2 && !STM32_HAS_USART2 -#error "USART2 not present in the selected device" -#endif - -#if !STM32_SERIAL_USE_USART1 && !STM32_SERIAL_USE_USART2 -#error "SERIAL driver activated but no USART/UART peripheral assigned" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief STM32 Serial Driver configuration structure. - * @details An instance of this structure must be passed to @p sdStart() - * in order to configure and start a serial driver operations. - * @note This structure content is architecture dependent, each driver - * implementation defines its own version and the custom static - * initializers. - */ -typedef struct { - /** - * @brief Bit rate. - */ - uint32_t sc_speed; - /** - * @brief Initialization value for the CR1 register. - */ - uint16_t sc_cr1; - /** - * @brief Initialization value for the CR2 register. - */ - uint16_t sc_cr2; - /** - * @brief Initialization value for the CR3 register. - */ - uint16_t sc_cr3; -} SerialConfig; - -/** - * @brief @p SerialDriver specific data. - */ -#define _serial_driver_data \ - _base_asynchronous_channel_data \ - /* Driver state.*/ \ - sdstate_t state; \ - /* Input queue.*/ \ - InputQueue iqueue; \ - /* Output queue.*/ \ - OutputQueue oqueue; \ - /* Input circular buffer.*/ \ - uint8_t ib[SERIAL_BUFFERS_SIZE]; \ - /* Output circular buffer.*/ \ - uint8_t ob[SERIAL_BUFFERS_SIZE]; \ - /* End of the mandatory fields.*/ \ - /* Pointer to the USART registers block.*/ \ - USART_TypeDef *usart; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/* - * Extra USARTs definitions here (missing from the ST header file). - */ -#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/ -#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/ -#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/ -#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if STM32_SERIAL_USE_USART1 && !defined(__DOXYGEN__) -extern SerialDriver SD1; -#endif -#if STM32_SERIAL_USE_USART2 && !defined(__DOXYGEN__) -extern SerialDriver SD2; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void sd_lld_init(void); - void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); - void sd_lld_stop(SerialDriver *sdp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_SERIAL */ - -#endif /* _SERIAL_LLD_H_ */ - -/** @} */ diff --git a/os/hal/platforms/STM32F0xx/stm32_dma.c b/os/hal/platforms/STM32F0xx/stm32_dma.c new file mode 100644 index 000000000..f5191f954 --- /dev/null +++ b/os/hal/platforms/STM32F0xx/stm32_dma.c @@ -0,0 +1,296 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32F0xx/stm32_dma.c + * @brief DMA helper driver code. + * + * @addtogroup STM32F0xx_DMA + * @details DMA sharing helper driver. In the STM32 the DMA streams are a + * shared resource, this driver allows to allocate and free DMA + * streams at runtime in order to allow all the other device + * drivers to coordinate the access to the resource. + * @note The DMA ISR handlers are all declared into this module because + * sharing, the various device drivers can associate a callback to + * ISRs when allocating streams. + * @{ + */ + +#include "ch.h" +#include "hal.h" + +/* The following macro is only defined if some driver requiring DMA services + has been enabled.*/ +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/** + * @brief Mask of the DMA1 streams in @p dma_streams_mask. + */ +#define STM32_DMA1_STREAMS_MASK 0x0000007F + +/** + * @brief Mask of the DMA2 streams in @p dma_streams_mask. + */ +#define STM32_DMA2_STREAMS_MASK 0x00000F80 + +/** + * @brief Post-reset value of the stream CCR register. + */ +#define STM32_DMA_CCR_RESET_VALUE 0x00000000 + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief DMA streams descriptors. + * @details This table keeps the association between an unique stream + * identifier and the involved physical registers. + * @note Don't use this array directly, use the appropriate wrapper macros + * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. + */ +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {DMA1_Channel1, &DMA1->IFCR, 0, 0, DMA1_Channel1_IRQn}, + {DMA1_Channel2, &DMA1->IFCR, 4, 1, DMA1_Channel2_3_IRQn}, + {DMA1_Channel3, &DMA1->IFCR, 8, 2, DMA1_Channel2_3_IRQn}, + {DMA1_Channel4, &DMA1->IFCR, 12, 3, DMA1_Channel4_5_IRQn}, + {DMA1_Channel5, &DMA1->IFCR, 16, 4, DMA1_Channel4_5_IRQn} +}; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief DMA ISR redirector type. + */ +typedef struct { + stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */ + void *dma_param; /**< @brief DMA callback parameter. */ +} dma_isr_redir_t; + +/** + * @brief Mask of the allocated streams. + */ +static uint32_t dma_streams_mask; + +/** + * @brief DMA IRQ redirectors. + */ +static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/** + * @brief DMA1 stream 1 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch1_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + flags = (DMA1->ISR >> 0) & STM32_DMA_ISR_MASK; + DMA1->IFCR = STM32_DMA_ISR_MASK << 0; + if (dma_isr_redir[0].dma_func) + dma_isr_redir[0].dma_func(dma_isr_redir[0].dma_param, flags); + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 streams 2 and 3 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch2_3_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + /* Check on channel 2.*/ + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = STM32_DMA_ISR_MASK << 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 = STM32_DMA_ISR_MASK << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + } + + CH_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 streams 4 and 5 shared interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(DMA1_Ch4_5_IRQHandler) { + uint32_t flags; + + CH_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = STM32_DMA_ISR_MASK << 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 = STM32_DMA_ISR_MASK << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + } + + CH_IRQ_EPILOGUE(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA helper initialization. + * + * @init + */ +void dmaInit(void) { + int i; + + dma_streams_mask = 0; + for (i = 0; i < STM32_DMA_STREAMS; i++) { + _stm32_dma_streams[i].channel->CCR = 0; + dma_isr_redir[i].dma_func = NULL; + } + DMA1->IFCR = 0xFFFFFFFF; +} + +/** + * @brief Allocates a DMA stream. + * @details The stream is allocated and, if required, the DMA clock enabled. + * The function also enables the IRQ vector associated to the stream + * and initializes its priority. + * @pre The stream must not be already in use or an error is returned. + * @post The stream is allocated and the default ISR handler redirected + * to the specified function. + * @post The stream ISR vector is enabled and its priority configured. + * @post The stream must be freed using @p dmaStreamRelease() before it can + * be reused with another peripheral. + * @post The stream is in its post-reset state. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] priority IRQ priority mask for the DMA stream + * @param[in] func handling function pointer, can be @p NULL + * @param[in] param a parameter to be passed to the handling function + * @return The operation status. + * @retval FALSE no error, stream taken. + * @retval TRUE error, stream already taken. + * + * @special + */ +bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param) { + + chDbgCheck(dmastp != NULL, "dmaAllocate"); + + /* Checks if the stream is already taken.*/ + if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + 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); + + /* Enabling DMA clocks required by the current streams set.*/ + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + rccEnableDMA1(FALSE); + + /* Putting the stream in a safe state.*/ + dmaStreamDisable(dmastp); + dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; + + /* Enables the associated IRQ vector if a callback is defined.*/ + if (func != NULL) + nvicEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); + + return FALSE; +} + +/** + * @brief Releases a DMA stream. + * @details The stream is freed and, if required, the DMA clock disabled. + * Trying to release a unallocated stream is an illegal operation + * and is trapped if assertions are enabled. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post The stream is again available. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { + + chDbgCheck(dmastp != NULL, "dmaRelease"); + + /* Check if the streams is not taken.*/ + chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + "dmaRelease(), #1", "not allocated"); + + /* Disables the associated IRQ vector.*/ + nvicDisableVector(dmastp->vector); + + /* Marks the stream as not allocated.*/ + 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) + rccDisableDMA1(FALSE); +} + +#endif /* STM32_DMA_REQUIRED */ + +/** @} */ diff --git a/os/hal/platforms/STM32F0xx/stm32_dma.h b/os/hal/platforms/STM32F0xx/stm32_dma.h new file mode 100644 index 000000000..1677bc285 --- /dev/null +++ b/os/hal/platforms/STM32F0xx/stm32_dma.h @@ -0,0 +1,395 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32F0xx/stm32_dma.h + * @brief DMA helper driver header. + * @note This file requires definitions from the ST header file stm32l1xx.h. + * @note This driver uses the new naming convention used for the STM32F2xx + * so the "DMA channels" are referred as "DMA streams". + * + * @addtogroup STM32F0xx_DMA + * @{ + */ + +#ifndef _STM32_DMA_H_ +#define _STM32_DMA_H_ + +/*===========================================================================*/ +/* 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 5 + +/** + * @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. + * + * @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. + */ +#define STM32_DMA_GETCHANNEL(n, c) 0 + +/** + * @brief Checks if a DMA priority is within the valid range. + * @param[in] prio DMA priority + * + * @retval The check result. + * @retval FALSE invalid DMA priority. + * @retval TRUE correct DMA priority. + */ +#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3)) + +/** + * @brief Returns an unique numeric identifier for a DMA stream. + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return An unique numeric stream identifier. + */ +#define STM32_DMA_STREAM_ID(dma, stream) ((stream) - 1) + +/** + * @brief Returns a DMA stream identifier mask. + * + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return A DMA stream identifier mask. + */ +#define STM32_DMA_STREAM_ID_MSK(dma, stream) \ + (1 << STM32_DMA_STREAM_ID(dma, stream)) + +/** + * @brief Checks if a DMA stream unique identifier belongs to a mask. + * @param[in] id the stream numeric identifier + * @param[in] mask the stream numeric identifiers mask + * + * @retval The check result. + * @retval FALSE id does not belong to the mask. + * @retval TRUE id belongs to the mask. + */ +#define STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask))) + +/** + * @name DMA streams identifiers + * @{ + */ +/** + * @brief Returns a pointer to a stm32_dma_stream_t structure. + * + * @param[in] id the stream numeric identifier + * @return A pointer to the stm32_dma_stream_t constant structure + * associated to the DMA stream. + */ +#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id]) + +#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) +#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) +#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2) +#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3) +#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4) +/** @} */ + +/** + * @name CR register constants common to all DMA types + * @{ + */ +#define STM32_DMA_CR_EN DMA_CCR_EN +#define STM32_DMA_CR_TEIE DMA_CCR_TEIE +#define STM32_DMA_CR_HTIE DMA_CCR_HTIE +#define STM32_DMA_CR_TCIE DMA_CCR_TCIE +#define STM32_DMA_CR_DIR_MASK (DMA_CCR_DIR | DMA_CCR_MEM2MEM) +#define STM32_DMA_CR_DIR_P2M 0 +#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_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_HWORD DMA_CCR_MSIZE_0 +#define STM32_DMA_CR_MSIZE_WORD DMA_CCR_MSIZE_1 +#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_MSIZE_MASK | \ + STM32_DMA_CR_MSIZE_MASK) +#define STM32_DMA_CR_PL_MASK DMA_CCR_PL +#define STM32_DMA_CR_PL(n) ((n) << 12) +/** @} */ + +/** + * @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. */ +/** @} */ + +/** + * @name Status flags passed to the ISR callbacks + * @{ + */ +#define STM32_DMA_ISR_FEIF 0 +#define STM32_DMA_ISR_DMEIF 0 +#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 +#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 +#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief STM32 DMA stream descriptor structure. + */ +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. */ + uint8_t selfindex; /**< @brief Index to self in array. */ + uint8_t vector; /**< @brief Associated IRQ vector. */ +} stm32_dma_stream_t; + +/** + * @brief STM32 DMA ISR function type. + * + * @param[in] p parameter for the registered function + * @param[in] flags pre-shifted content of the ISR register, the bits + * are aligned to bit zero + */ +typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Associates a peripheral data register to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CPAR register + * + * @special + */ +#define dmaStreamSetPeripheral(dmastp, addr) { \ + (dmastp)->channel->CPAR = (uint32_t)(addr); \ +} + +/** + * @brief Associates a memory destination to a DMA stream. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] addr value to be written in the CMAR register + * + * @special + */ +#define dmaStreamSetMemory0(dmastp, addr) { \ + (dmastp)->channel->CMAR = (uint32_t)(addr); \ +} + +/** + * @brief Sets the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] size value to be written in the CNDTR register + * + * @special + */ +#define dmaStreamSetTransactionSize(dmastp, size) { \ + (dmastp)->channel->CNDTR = (uint32_t)(size); \ +} + +/** + * @brief Returns the number of transfers to be performed. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @return The number of transfers to be performed. + * + * @special + */ +#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) + +/** + * @brief Programs the stream mode settings. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register + * + * @special + */ +#define dmaStreamSetMode(dmastp, mode) { \ + (dmastp)->channel->CCR = (uint32_t)(mode); \ +} + +/** + * @brief DMA stream enable. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamEnable(dmastp) { \ + (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ +} + +/** + * @brief DMA stream disable. + * @details The function disables the specified stream and then clears any + * pending interrupt. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamDisable(dmastp) { \ + (dmastp)->channel->CCR &= ~STM32_DMA_CR_EN; \ + dmaStreamClearInterrupt(dmastp); \ +} + +/** + * @brief DMA stream interrupt sources clear. + * @note This function can be invoked in both ISR or thread context. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * + * @special + */ +#define dmaStreamClearInterrupt(dmastp) { \ + *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \ +} + +/** + * @brief Starts a memory to memory operation using the specified stream. + * @note The default transfer data mode is "byte to byte" but it can be + * changed by specifying extra options in the @p mode parameter. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + * @param[in] mode value to be written in the CCR register, this value + * is implicitly ORed with: + * - @p STM32_DMA_CR_MINC + * - @p STM32_DMA_CR_PINC + * - @p STM32_DMA_CR_DIR_M2M + * - @p STM32_DMA_CR_EN + * . + * @param[in] src source address + * @param[in] dst destination address + * @param[in] n number of data units to copy + */ +#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ + dmaStreamSetPeripheral(dmastp, src); \ + dmaStreamSetMemory0(dmastp, dst); \ + dmaStreamSetTransactionSize(dmastp, n); \ + dmaStreamSetMode(dmastp, (mode) | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ + STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ +} + +/** + * @brief Polled wait for DMA transfer end. + * @pre The stream must have been allocated using @p dmaStreamAllocate(). + * @post After use the stream can be released using @p dmaStreamRelease(). + * + * @param[in] dmastp pointer to a stm32_dma_stream_t structure + */ +#define dmaWaitCompletion(dmastp) { \ + while ((dmastp)->channel->CNDTR > 0) \ + ; \ + dmaStreamDisable(dmastp); \ +} +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dmaInit(void); + bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, + uint32_t priority, + stm32_dmaisr_t func, + void *param); + void dmaStreamRelease(const stm32_dma_stream_t *dmastp); +#ifdef __cplusplus +} +#endif + +#endif /* _STM32_DMA_H_ */ + +/** @} */ diff --git a/os/hal/platforms/STM32F1xx/stm32_dma.h b/os/hal/platforms/STM32F1xx/stm32_dma.h index a4cae4ea6..aa612d592 100644 --- a/os/hal/platforms/STM32F1xx/stm32_dma.h +++ b/os/hal/platforms/STM32F1xx/stm32_dma.h @@ -62,6 +62,25 @@ */ #define STM32_DMA_GETCHANNEL(n, c) 0 +/** + * @brief Checks if a DMA priority is within the valid range. + * @param[in] prio DMA priority + * + * @retval The check result. + * @retval FALSE invalid DMA priority. + * @retval TRUE correct DMA priority. + */ +#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3)) + +/** + * @brief Returns an unique numeric identifier for a DMA stream. + * + * @param[in] dma the DMA unit number + * @param[in] stream the stream number + * @return An unique numeric stream identifier. + */ +#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 7) + ((stream) - 1)) + /** * @brief Returns a DMA stream identifier mask. * @@ -88,15 +107,6 @@ * @name DMA streams identifiers * @{ */ -/** - * @brief Returns an unique numeric identifier for a DMA stream. - * - * @param[in] dma the DMA unit number - * @param[in] stream the stream number - * @return An unique numeric stream identifier. - */ -#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1) * 7) + ((stream) - 1)) - /** * @brief Returns a pointer to a stm32_dma_stream_t structure. * diff --git a/os/hal/platforms/STM32F2xx/stm32_dma.h b/os/hal/platforms/STM32F2xx/stm32_dma.h index 53097c297..d9434acd5 100644 --- a/os/hal/platforms/STM32F2xx/stm32_dma.h +++ b/os/hal/platforms/STM32F2xx/stm32_dma.h @@ -56,6 +56,16 @@ */ #define STM32_DMA_GETCHANNEL(id, c) (((c) >> (((id) & 7) * 4)) & 7) +/** + * @brief Checks if a DMA priority is within the valid range. + * @param[in] prio DMA priority + * + * @retval The check result. + * @retval FALSE invalid DMA priority. + * @retval TRUE correct DMA priority. + */ +#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3)) + /** * @brief Returns an unique numeric identifier for a DMA stream. * diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index 473ce9613..af466b01d 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -56,6 +56,16 @@ */ #define STM32_DMA_GETCHANNEL(id, c) (((c) >> (((id) & 7) * 4)) & 7) +/** + * @brief Checks if a DMA priority is within the valid range. + * @param[in] prio DMA priority + * + * @retval The check result. + * @retval FALSE invalid DMA priority. + * @retval TRUE correct DMA priority. + */ +#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3)) + /** * @brief Returns an unique numeric identifier for a DMA stream. * diff --git a/os/hal/platforms/STM32L1xx/stm32_dma.h b/os/hal/platforms/STM32L1xx/stm32_dma.h index bf3f3f3ca..71af4a339 100644 --- a/os/hal/platforms/STM32L1xx/stm32_dma.h +++ b/os/hal/platforms/STM32L1xx/stm32_dma.h @@ -59,9 +59,15 @@ #define STM32_DMA_GETCHANNEL(n, c) 0 /** - * @name DMA streams identifiers - * @{ + * @brief Checks if a DMA priority is within the valid range. + * @param[in] prio DMA priority + * + * @retval The check result. + * @retval FALSE invalid DMA priority. + * @retval TRUE correct DMA priority. */ +#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0) && ((prio) <= 3)) + /** * @brief Returns an unique numeric identifier for a DMA stream. * @@ -93,6 +99,10 @@ */ #define STM32_DMA_IS_VALID_ID(id, mask) (((1 << (id)) & (mask))) +/** + * @name DMA streams identifiers + * @{ + */ /** * @brief Returns a pointer to a stm32_dma_stream_t structure. * diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h index 18ee5a364..ec534fdb2 100644 --- a/os/ports/GCC/ARMCMx/chcore.h +++ b/os/ports/GCC/ARMCMx/chcore.h @@ -86,6 +86,12 @@ #define CORTEX_IS_VALID_PRIORITY(n) \ (((n) >= 0) && ((n) < CORTEX_PRIORITY_LEVELS)) +/** + * @brief Priority level verification macro. + */ +#define CORTEX_IS_VALID_KERNEL_PRIORITY(n) \ + (((n) >= CORTEX_MAX_KERNEL_PRIORITY) && ((n) < CORTEX_PRIORITY_LEVELS)) + /** * @brief Priority level to priority mask conversion macro. */ diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index b36e405ea..76bfbf184 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -107,6 +107,15 @@ /* Port derived parameters. */ /*===========================================================================*/ +/** + * @brief Maximum usable priority for normal ISRs. + */ +#if CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) +#define CORTEX_MAX_KERNEL_PRIORITY 1 +#else +#define CORTEX_MAX_KERNEL_PRIORITY 0 +#endif + /*===========================================================================*/ /* Port exported info. */ /*===========================================================================*/ diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h index 6fdfd44d6..ea9b8dab5 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.h +++ b/os/ports/GCC/ARMCMx/chcore_v7m.h @@ -145,14 +145,21 @@ /* Port derived parameters. */ /*===========================================================================*/ +#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) +/** + * @brief Maximum usable priority for normal ISRs. + */ +#define CORTEX_MAX_KERNEL_PRIORITY (CORTEX_PRIORITY_SVCALL + 1) + /** * @brief BASEPRI level within kernel lock. * @note In compact kernel mode this constant value is enforced to zero. */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) #define CORTEX_BASEPRI_KERNEL \ - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1) + CORTEX_PRIORITY_MASK(CORTEX_MAX_KERNEL_PRIORITY) #else + +#define CORTEX_MAX_KERNEL_PRIORITY 1 #define CORTEX_BASEPRI_KERNEL 0 #endif diff --git a/os/ports/IAR/ARMCMx/chcore.h b/os/ports/IAR/ARMCMx/chcore.h index fd21b92ac..a3e9733f0 100644 --- a/os/ports/IAR/ARMCMx/chcore.h +++ b/os/ports/IAR/ARMCMx/chcore.h @@ -86,6 +86,12 @@ #define CORTEX_IS_VALID_PRIORITY(n) \ (((n) >= 0) && ((n) < CORTEX_PRIORITY_LEVELS)) +/** + * @brief Priority level verification macro. + */ +#define CORTEX_IS_VALID_KERNEL_PRIORITY(n) \ + (((n) >= CORTEX_MAX_KERNEL_PRIORITY) && ((n) < CORTEX_PRIORITY_LEVELS)) + /** * @brief Priority level to priority mask conversion macro. */ @@ -170,7 +176,7 @@ struct intctx {}; */ #define chSchIsPreemptionRequired() \ (currp->p_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \ - firstprio(&rlist.r_queue) >= currp->p_prio) + firstprio(&rlist.r_queue) >= currp->p_prio) #else /* CH_TIME_QUANTUM == 0 */ #define chSchIsPreemptionRequired() \ (firstprio(&rlist.r_queue) > currp->p_prio) diff --git a/os/ports/IAR/ARMCMx/chcore_v6m.h b/os/ports/IAR/ARMCMx/chcore_v6m.h index 1b79f2b25..a63bd1f18 100644 --- a/os/ports/IAR/ARMCMx/chcore_v6m.h +++ b/os/ports/IAR/ARMCMx/chcore_v6m.h @@ -107,6 +107,15 @@ /* Port derived parameters. */ /*===========================================================================*/ +/** + * @brief Maximum usable priority for normal ISRs. + */ +#if CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) +#define CORTEX_MAX_KERNEL_PRIORITY 1 +#else +#define CORTEX_MAX_KERNEL_PRIORITY 0 +#endif + /*===========================================================================*/ /* Port exported info. */ /*===========================================================================*/ diff --git a/os/ports/IAR/ARMCMx/chcore_v7m.h b/os/ports/IAR/ARMCMx/chcore_v7m.h index 24145d409..413f36707 100644 --- a/os/ports/IAR/ARMCMx/chcore_v7m.h +++ b/os/ports/IAR/ARMCMx/chcore_v7m.h @@ -129,7 +129,7 @@ * @brief NVIC VTOR initialization expression. */ #if !defined(CORTEX_VTOR_INIT) || defined(__DOXYGEN__) -#define CORTEX_VTOR_INIT 0x00000000 +#define CORTEX_VTOR_INIT 0x00000000 #endif /** @@ -145,14 +145,21 @@ /* Port derived parameters. */ /*===========================================================================*/ +#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) +/** + * @brief Maximum usable priority for normal ISRs. + */ +#define CORTEX_MAX_KERNEL_PRIORITY (CORTEX_PRIORITY_SVCALL + 1) + /** * @brief BASEPRI level within kernel lock. * @note In compact kernel mode this constant value is enforced to zero. */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) #define CORTEX_BASEPRI_KERNEL \ - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1) + CORTEX_PRIORITY_MASK(CORTEX_MAX_KERNEL_PRIORITY) #else + +#define CORTEX_MAX_KERNEL_PRIORITY 1 #define CORTEX_BASEPRI_KERNEL 0 #endif diff --git a/os/ports/RVCT/ARMCMx/chcore.h b/os/ports/RVCT/ARMCMx/chcore.h index 950cc571f..ef3bc623c 100644 --- a/os/ports/RVCT/ARMCMx/chcore.h +++ b/os/ports/RVCT/ARMCMx/chcore.h @@ -86,6 +86,12 @@ #define CORTEX_IS_VALID_PRIORITY(n) \ (((n) >= 0) && ((n) < CORTEX_PRIORITY_LEVELS)) +/** + * @brief Priority level verification macro. + */ +#define CORTEX_IS_VALID_KERNEL_PRIORITY(n) \ + (((n) >= CORTEX_MAX_KERNEL_PRIORITY) && ((n) < CORTEX_PRIORITY_LEVELS)) + /** * @brief Priority level to priority mask conversion macro. */ @@ -169,7 +175,7 @@ struct intctx {}; */ #define chSchIsPreemptionRequired() \ (currp->p_preempt ? firstprio(&rlist.r_queue) > currp->p_prio : \ - firstprio(&rlist.r_queue) >= currp->p_prio) + firstprio(&rlist.r_queue) >= currp->p_prio) #else /* CH_TIME_QUANTUM == 0 */ #define chSchIsPreemptionRequired() \ (firstprio(&rlist.r_queue) > currp->p_prio) diff --git a/os/ports/RVCT/ARMCMx/chcore_v6m.h b/os/ports/RVCT/ARMCMx/chcore_v6m.h index e659912ee..685eddaef 100644 --- a/os/ports/RVCT/ARMCMx/chcore_v6m.h +++ b/os/ports/RVCT/ARMCMx/chcore_v6m.h @@ -107,6 +107,15 @@ /* Port derived parameters. */ /*===========================================================================*/ +/** + * @brief Maximum usable priority for normal ISRs. + */ +#if CORTEX_ALTERNATE_SWITCH || defined(__DOXYGEN__) +#define CORTEX_MAX_KERNEL_PRIORITY 1 +#else +#define CORTEX_MAX_KERNEL_PRIORITY 0 +#endif + /*===========================================================================*/ /* Port exported info. */ /*===========================================================================*/ diff --git a/os/ports/RVCT/ARMCMx/chcore_v7m.h b/os/ports/RVCT/ARMCMx/chcore_v7m.h index c31bbcffe..8ff4f630f 100644 --- a/os/ports/RVCT/ARMCMx/chcore_v7m.h +++ b/os/ports/RVCT/ARMCMx/chcore_v7m.h @@ -129,7 +129,7 @@ * @brief NVIC VTOR initialization expression. */ #if !defined(CORTEX_VTOR_INIT) || defined(__DOXYGEN__) -#define CORTEX_VTOR_INIT 0x00000000 +#define CORTEX_VTOR_INIT 0x00000000 #endif /** @@ -145,14 +145,21 @@ /* Port derived parameters. */ /*===========================================================================*/ +#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) +/** + * @brief Maximum usable priority for normal ISRs. + */ +#define CORTEX_MAX_KERNEL_PRIORITY (CORTEX_PRIORITY_SVCALL + 1) + /** * @brief BASEPRI level within kernel lock. * @note In compact kernel mode this constant value is enforced to zero. */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) #define CORTEX_BASEPRI_KERNEL \ - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL+1) + CORTEX_PRIORITY_MASK(CORTEX_MAX_KERNEL_PRIORITY) #else + +#define CORTEX_MAX_KERNEL_PRIORITY 1 #define CORTEX_BASEPRI_KERNEL 0 #endif diff --git a/readme.txt b/readme.txt index a09aee449..ad53b6919 100644 --- a/readme.txt +++ b/readme.txt @@ -25,12 +25,14 @@ | | +--platforms/ - HAL low level drivers implementations. | | | +--AT91SAM7/ - Drivers for AT91SAM7 platform. | | | +--AVR/ - Drivers for AVR platform. + | | | +--LPC11Uxx/ - Drivers for LPC11Uxx platform. | | | +--LPC11xx/ - Drivers for LPC11xx platform. | | | +--LPC13xx/ - Drivers for LPC13xx platform. | | | +--LPC214x/ - Drivers for LPC214x platform. | | | +--MSP430/ - Drivers for MSP430 platform. | | | +--SPC56x/ - Drivers for SPC56x/MPC563xx platforms. | | | +--STM32/ - Drivers for STM32 platform (common). + | | | +--STM32F0xx/- Drivers for STM32F0xx platform. | | | +--STM32F1xx/- Drivers for STM32F1xx platform. | | | +--STM32F2xx/- Drivers for STM32F2xx platform. | | | +--STM32F4xx/- Drivers for STM32F4xx platform.