diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2012-05-24 18:31:34 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2012-05-24 18:31:34 +0000 |
commit | 7a6a1679a413987ffa47f2f9892e241f3448f5f0 (patch) | |
tree | 88c38d7e249eeedc7b51979486262a0c7619bc0e /os/hal/platforms/STM32 | |
parent | 293eddc33f8957f1bb896ef074bb56bf2ec2f895 (diff) | |
download | ChibiOS-7a6a1679a413987ffa47f2f9892e241f3448f5f0.tar.gz ChibiOS-7a6a1679a413987ffa47f2f9892e241f3448f5f0.tar.bz2 ChibiOS-7a6a1679a413987ffa47f2f9892e241f3448f5f0.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4232 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms/STM32')
-rw-r--r-- | os/hal/platforms/STM32/serial_lld.c | 129 | ||||
-rw-r--r-- | os/hal/platforms/STM32/serial_lld.h | 30 | ||||
-rw-r--r-- | os/hal/platforms/STM32/spi_lld.c | 11 | ||||
-rw-r--r-- | os/hal/platforms/STM32/spi_lld.h | 39 | ||||
-rw-r--r-- | os/hal/platforms/STM32/stm32.h | 26 |
5 files changed, 218 insertions, 17 deletions
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*/
/** @} */
@@ -213,6 +222,36 @@ #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"
#endif
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
/*===========================================================================*/
|