diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2010-07-30 18:02:52 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2010-07-30 18:02:52 +0000 |
commit | da5080f92aa8b725e99d26269c714294c32e9d82 (patch) | |
tree | 6b2e12221b3e6af52cd3e7e203e1b48f7d867d24 /os | |
parent | 5ff9f39050d5bd8e64ed00eb6ba198882d8cfc15 (diff) | |
download | ChibiOS-da5080f92aa8b725e99d26269c714294c32e9d82.tar.gz ChibiOS-da5080f92aa8b725e99d26269c714294c32e9d82.tar.bz2 ChibiOS-da5080f92aa8b725e99d26269c714294c32e9d82.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2098 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/platforms/STM32/uart_lld.c | 106 | ||||
-rw-r--r-- | os/hal/platforms/STM32/uart_lld.h | 66 |
2 files changed, 169 insertions, 3 deletions
diff --git a/os/hal/platforms/STM32/uart_lld.c b/os/hal/platforms/STM32/uart_lld.c index 7f55fabb0..6708fe1e6 100644 --- a/os/hal/platforms/STM32/uart_lld.c +++ b/os/hal/platforms/STM32/uart_lld.c @@ -39,6 +39,16 @@ UARTDriver UARTD1;
#endif
+/** @brief USART2 UART driver identifier.*/
+#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
+UARTDriver UARTD2;
+#endif
+
+/** @brief USART3 UART driver identifier.*/
+#if STM32_UART_USE_USART3 || defined(__DOXYGEN__)
+UARTDriver UARTD3;
+#endif
+
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
@@ -272,6 +282,9 @@ CH_IRQ_HANDLER(DMA1_Ch5_IRQHandler) { CH_IRQ_EPILOGUE();
}
+/**
+ * @brief USART1 IRQ handler.
+ */
CH_IRQ_HANDLER(USART1_IRQHandler) {
CH_IRQ_PROLOGUE();
@@ -280,7 +293,62 @@ CH_IRQ_HANDLER(USART1_IRQHandler) { CH_IRQ_EPILOGUE();
}
-#endif
+#endif /* STM32_UART_USE_USART1 */
+
+#if STM32_UART_USE_USART2 || defined(__DOXYGEN__)
+/**
+ * @brief USART2 RX DMA interrupt handler (channel 6).
+ */
+CH_IRQ_HANDLER(DMA1_Ch6_IRQHandler) {
+ UARTDriver *uartp;
+
+ CH_IRQ_PROLOGUE();
+
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
+ uartp = &UARTD2;
+ if (uartp->ud_rxstate == UART_RX_IDLE) {
+ /* Fast IRQ path, this is why it is not centralized in serve_rx_end_irq().*/
+ /* Receiver in idle state, a callback is generated, if enabled, for each
+ received character and then the driver stays in the same state.*/
+ if (uartp->ud_config->uc_rxchar != NULL)
+ uartp->ud_config->uc_rxchar(uartp->ud_rxbuf);
+ }
+ else {
+ /* Receiver in active state, a callback is generated, if enabled, after
+ a completed transfer.*/
+ dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_6);
+ serve_rx_end_irq(uartp);
+ }
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief USART2 TX DMA interrupt handler (channel 7).
+ */
+CH_IRQ_HANDLER(DMA1_Ch7_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ dmaClearChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
+ dmaDisableChannel(STM32_DMA1, STM32_DMA_CHANNEL_7);
+ serve_tx_end_irq(&UARTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+
+/**
+ * @brief USART2 IRQ handler.
+ */
+CH_IRQ_HANDLER(USART2_IRQHandler) {
+
+ CH_IRQ_PROLOGUE();
+
+ serve_usart_irq(&UARTD2);
+
+ CH_IRQ_EPILOGUE();
+}
+#endif /* STM32_UART_USE_USART2 */
/*===========================================================================*/
/* Driver exported functions. */
@@ -300,6 +368,16 @@ void uart_lld_init(void) { UARTD1.ud_dmatx = STM32_DMA_CHANNEL_5;
UARTD1.ud_dmaccr = 0;
#endif
+
+#if STM32_UART_USE_USART2
+ RCC->APB1RSTR = RCC_APB1RSTR_USART2RST;
+ RCC->APB1RSTR = 0;
+ uartObjectInit(&UARTD2);
+ UARTD1.ud_usart = USART2;
+ UARTD1.ud_dmarx = STM32_DMA_CHANNEL_6;
+ UARTD1.ud_dmatx = STM32_DMA_CHANNEL_7;
+ UARTD1.ud_dmaccr = 0;
+#endif
}
/**
@@ -323,6 +401,19 @@ void uart_lld_start(UARTDriver *uartp) { }
#endif
+#if STM32_UART_USE_USART2
+ if (&UARTD2 == uartp) {
+ dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
+ NVICEnableVector(USART2_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
+ NVICEnableVector(DMA1_Channel6_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
+ NVICEnableVector(DMA1_Channel7_IRQn,
+ CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY));
+ RCC->APB1ENR |= RCC_APB2ENR_USART1EN;
+ }
+#endif
+
/* Static DMA setup, the transfer size depends on the USART settings,
it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
uartp->ud_dmaccr = STM32_UART_USART1_DMA_PRIORITY << 12;
@@ -357,6 +448,17 @@ void uart_lld_stop(UARTDriver *uartp) { return;
}
#endif
+
+#if STM32_UART_USE_USART2
+ if (&UARTD2 == uartp) {
+ NVICDisableVector(USART2_IRQn);
+ NVICDisableVector(DMA1_Channel6_IRQn);
+ NVICDisableVector(DMA1_Channel7_IRQn);
+ dmaDisable(DMA1_ID);
+ RCC->APB1ENR &= ~RCC_APB1ENR_USART2EN;
+ return;
+ }
+#endif
}
}
@@ -372,7 +474,7 @@ void uart_lld_stop(UARTDriver *uartp) { void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
/* TX DMA channel preparation and start.*/
- dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmatx, n, &uartp->ud_txbuf,
+ dmaSetupChannel(uartp->ud_dmap, uartp->ud_dmatx, n, txbuf,
uartp->ud_dmaccr | DMA_CCR1_TEIE | DMA_CCR1_TCIE);
dmaEnableChannel(uartp->ud_dmap, uartp->ud_dmatx);
}
diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h index 50eacbd9c..d1033050e 100644 --- a/os/hal/platforms/STM32/uart_lld.h +++ b/os/hal/platforms/STM32/uart_lld.h @@ -48,6 +48,24 @@ #endif
/**
+ * @brief UART driver on USART2 enable switch.
+ * @details If set to @p TRUE the support for USART2 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART2) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART2 TRUE
+#endif
+
+/**
+ * @brief UART driver on USART3 enable switch.
+ * @details If set to @p TRUE the support for USART3 is included.
+ * @note The default is @p FALSE.
+ */
+#if !defined(STM32_UART_USE_USART3) || defined(__DOXYGEN__)
+#define STM32_UART_USE_USART3 TRUE
+#endif
+
+/**
* @brief USART1 interrupt priority level setting.
*/
#if !defined(STM32_UART_USART1_IRQ_PRIO) || defined(__DOXYGEN__)
@@ -55,14 +73,48 @@ #endif
/**
+ * @brief USART2 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART2_IRQ_PRIO) || defined(__DOXYGEN__)
+#define STM32_UART_USART2_IRQ_PRIORITY 12
+#endif
+
+/**
+ * @brief USART3 interrupt priority level setting.
+ */
+#if !defined(STM32_UART_USART3_IRQ_PRIO) || defined(__DOXYGEN__)
+#define STM32_UART_USART3_IRQ_PRIORITY 12
+#endif
+
+/**
* @brief USART1 DMA priority (0..3|lowest..highest).
* @note The priority level is used for both the TX and RX DMA channels but
* because of the channels ordering the RX channel has always priority
* over the TX channel.
*/
#if !defined(STM32_UART_USART1_DMA_PRIO) || defined(__DOXYGEN__)
-#define STM32_UART_USART1_DMA_PRIORITY 1
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#endif
+
+/**
+ * @brief USART2 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART2_DMA_PRIO) || defined(__DOXYGEN__)
+#define STM32_UART_USART2_DMA_PRIORITY 0
#endif
+/**
+ * @brief USART3 DMA priority (0..3|lowest..highest).
+ * @note The priority level is used for both the TX and RX DMA channels but
+ * because of the channels ordering the RX channel has always priority
+ * over the TX channel.
+ */
+#if !defined(STM32_UART_USART3_DMA_PRIO) || defined(__DOXYGEN__)
+#define STM32_UART_USART3_DMA_PRIORITY 0
+#endif
+
/*===========================================================================*/
/* Derived constants and error checks. */
@@ -159,6 +211,18 @@ typedef struct { /* External declarations. */
/*===========================================================================*/
+#if STM32_UART_USE_USART1 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD1;
+#endif
+
+#if STM32_UART_USE_USART2 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD2;
+#endif
+
+#if STM32_UART_USE_USART3 && !defined(__DOXYGEN__)
+extern UARTDriver UARTD3;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
|