You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

429 lines
15 KiB

diff --git NuttX/nuttx/arch/arm/src/stm32/stm32_serial.c NuttX/nuttx/arch/arm/src/stm32/stm32_serial.c
index 644c810..c3b08b8 100644
--- NuttX/nuttx/arch/arm/src/stm32/stm32_serial.c
+++ NuttX/nuttx/arch/arm/src/stm32/stm32_serial.c
@@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/stm32/stm32_serial.c
*
- * Copyright (C) 2009-2014, 2016 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2009-2014, 2016, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -70,6 +70,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+
/* Some sanity checks *******************************************************/
/* DMA configuration */
@@ -150,7 +151,8 @@
# endif
# elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
- defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F30XX)
+ defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
+ defined(CONFIG_STM32_STM32F37XX)
# if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \
defined(CONFIG_USART3_RXDMA)
@@ -180,14 +182,21 @@
* When streaming data, the generic serial layer will be called
* every time the FIFO receives half this number of bytes.
*/
-
-# define RXDMA_BUFFER_SIZE 32
+# if !defined(CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE)
+# define CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE 32
+# endif
+# define RXDMA_MUTIPLE 4
+# define RXDMA_MUTIPLE_MASK (RXDMA_MUTIPLE -1)
+# define RXDMA_BUFFER_SIZE ((CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE \
+ + RXDMA_MUTIPLE_MASK) \
+ & ~RXDMA_MUTIPLE_MASK)
/* DMA priority */
# ifndef CONFIG_USART_DMAPRIO
# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
- defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
+ defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
+ defined(CONFIG_STM32_STM32F37XX)
# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED
# elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
# define CONFIG_USART_DMAPRIO DMA_SCR_PRIMED
@@ -196,7 +205,8 @@
# endif
# endif
# if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
- defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
+ defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
+ defined(CONFIG_STM32_STM32F37XX)
# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0
# error "Illegal value for CONFIG_USART_DMAPRIO"
# endif
@@ -208,7 +218,7 @@
# error "Unknown STM32 DMA"
# endif
-/* DMA control words */
+/* DMA control word */
# if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX)
# define SERIAL_DMA_CONTROL_WORD \
@@ -220,16 +230,6 @@
CONFIG_USART_DMAPRIO | \
DMA_SCR_PBURST_SINGLE | \
DMA_SCR_MBURST_SINGLE)
-# ifdef CONFIG_SERIAL_IFLOWCONTROL
-# define SERIAL_DMA_IFLOW_CONTROL_WORD \
- (DMA_SCR_DIR_P2M | \
- DMA_SCR_MINC | \
- DMA_SCR_PSIZE_8BITS | \
- DMA_SCR_MSIZE_8BITS | \
- CONFIG_USART_DMAPRIO | \
- DMA_SCR_PBURST_SINGLE | \
- DMA_SCR_MBURST_SINGLE)
-# endif
# else
# define SERIAL_DMA_CONTROL_WORD \
(DMA_CCR_CIRC | \
@@ -237,13 +237,6 @@
DMA_CCR_PSIZE_8BITS | \
DMA_CCR_MSIZE_8BITS | \
CONFIG_USART_DMAPRIO)
-# ifdef CONFIG_SERIAL_IFLOWCONTROL
-# define SERIAL_DMA_IFLOW_CONTROL_WORD \
- (DMA_CCR_MINC | \
- DMA_CCR_PSIZE_8BITS | \
- DMA_CCR_MSIZE_8BITS | \
- CONFIG_USART_DMAPRIO)
-# endif
# endif
#endif
@@ -556,7 +549,11 @@ static struct up_dev_s g_usart1priv =
.bits = CONFIG_USART1_BITS,
.stopbits2 = CONFIG_USART1_2STOP,
.baud = CONFIG_USART1_BAUD,
+#if defined(CONFIG_STM32_STM32F33XX)
+ .apbclock = STM32_PCLK1_FREQUENCY, /* Errata 2.5.1 */
+#else
.apbclock = STM32_PCLK2_FREQUENCY,
+#endif
.usartbase = STM32_USART1_BASE,
.tx_gpio = GPIO_USART1_TX,
.rx_gpio = GPIO_USART1_RX,
@@ -1088,10 +1085,10 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, uint32_t valu
}
/****************************************************************************
- * Name: up_restoreusartint
+ * Name: up_setusartint
****************************************************************************/
-static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie)
+static inline void up_setusartint(struct up_dev_s *priv, uint16_t ie)
{
uint32_t cr;
@@ -1113,11 +1110,30 @@ static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie)
}
/****************************************************************************
+ * Name: up_restoreusartint
+ ****************************************************************************/
+
+static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie)
+{
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ up_setusartint(priv, ie);
+
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
* Name: up_disableusartint
****************************************************************************/
-static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
+static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
{
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
if (ie)
{
uint32_t cr1;
@@ -1154,7 +1170,9 @@ static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
/* Disable all interrupts */
- up_restoreusartint(priv, 0);
+ up_setusartint(priv, 0);
+
+ leave_critical_section(flags);
}
/****************************************************************************
@@ -1189,7 +1207,8 @@ static int up_dma_nextrx(struct up_dev_s *priv)
static void up_set_format(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
-#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
+#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
+ defined(CONFIG_STM32_STM32F37XX)
uint32_t usartdiv8;
#else
uint32_t usartdiv32;
@@ -1203,7 +1222,8 @@ static void up_set_format(struct uart_dev_s *dev)
regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
-#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
+#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX)|| \
+ defined(CONFIG_STM32_STM32F37XX)
/* This first implementation is for U[S]ARTs that support oversampling
* by 8 in additional to the standard oversampling by 16.
* With baud rate of fCK / Divider for oversampling by 16.
@@ -1608,28 +1628,13 @@ static int up_dma_setup(struct uart_dev_s *dev)
priv->rxdma = stm32_dmachannel(priv->rxdma_channel);
-#ifdef CONFIG_SERIAL_IFLOWCONTROL
- if (priv->iflow)
- {
- /* Configure for non-circular DMA reception into the RX FIFO */
-
- stm32_dmasetup(priv->rxdma,
- priv->usartbase + STM32_USART_RDR_OFFSET,
- (uint32_t)priv->rxfifo,
- RXDMA_BUFFER_SIZE,
- SERIAL_DMA_IFLOW_CONTROL_WORD);
- }
- else
-#endif
- {
- /* Configure for circular DMA reception into the RX FIFO */
+ /* Configure for circular DMA reception into the RX fifo */
- stm32_dmasetup(priv->rxdma,
- priv->usartbase + STM32_USART_RDR_OFFSET,
- (uint32_t)priv->rxfifo,
- RXDMA_BUFFER_SIZE,
- SERIAL_DMA_CONTROL_WORD);
- }
+ stm32_dmasetup(priv->rxdma,
+ priv->usartbase + STM32_USART_RDR_OFFSET,
+ (uint32_t)priv->rxfifo,
+ RXDMA_BUFFER_SIZE,
+ SERIAL_DMA_CONTROL_WORD);
/* Reset our DMA shadow pointer to match the address just
* programmed above.
@@ -1643,26 +1648,12 @@ static int up_dma_setup(struct uart_dev_s *dev)
regval |= USART_CR3_DMAR;
up_serialout(priv, STM32_USART_CR3_OFFSET, regval);
-#ifdef CONFIG_SERIAL_IFLOWCONTROL
- if (priv->iflow)
- {
- /* Start the DMA channel, and arrange for callbacks at the full point
- * in the FIFO. After buffer gets full, hardware flow-control kicks
- * in and DMA transfer is stopped.
- */
-
- stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false);
- }
- else
-#endif
- {
- /* Start the DMA channel, and arrange for callbacks at the half and
- * full points in the FIFO. This ensures that we have half a FIFO
- * worth of time to claim bytes before they are overwritten.
- */
+ /* Start the DMA channel, and arrange for callbacks at the half and
+ * full points in the FIFO. This ensures that we have half a FIFO
+ * worth of time to claim bytes before they are overwritten.
+ */
- stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true);
- }
+ stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, true);
return OK;
}
@@ -1789,6 +1780,7 @@ static int up_attach(struct uart_dev_s *dev)
up_enable_irq(priv->irq);
}
+
return ret;
}
@@ -1900,7 +1892,8 @@ static int up_interrupt_common(struct up_dev_s *priv)
else if ((priv->sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE)) != 0)
{
-#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
+#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
+ defined(CONFIG_STM32_STM32F37XX)
/* These errors are cleared by writing the corresponding bit to the
* interrupt clear register (ICR).
*/
@@ -1945,11 +1938,11 @@ static int up_interrupt_common(struct up_dev_s *priv)
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
{
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) \
- || defined(CONFIG_STM32F7_SERIALBRK_BSDCOMPAT)
+ || defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT)
struct inode *inode = filep->f_inode;
struct uart_dev_s *dev = inode->i_private;
#endif
-#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_STM32F7_SERIALBRK_BSDCOMPAT)
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT)
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
#endif
int ret = OK;
@@ -2316,9 +2309,11 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev,
unsigned int nbuffered, bool upper)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+#if !(defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && defined(CONFIG_STM32_FLOWCONTROL_BROKEN))
+ uint16_t ie;
+#endif
-#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \
- defined(CONFIG_STM32_FLOWCONTROL_BROKEN)
+#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && defined(CONFIG_STM32_FLOWCONTROL_BROKEN)
if (priv->iflow && (priv->rts_gpio != 0))
{
/* Assert/de-assert nRTS set it high resume/stop sending */
@@ -2346,7 +2341,9 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev,
* enable Rx interrupts.
*/
- uart_disablerxint(dev);
+ ie = priv->ie;
+ ie &= ~USART_CR1_RXNEIE;
+ up_restoreusartint(priv, ie);
return true;
}
@@ -2359,7 +2356,7 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev,
* received.
*/
- uart_enablerxint(dev);
+ up_rxint(dev, true);
}
}
#endif
@@ -2391,18 +2388,7 @@ static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status)
priv->rxdmanext++;
if (priv->rxdmanext == RXDMA_BUFFER_SIZE)
{
-#ifdef CONFIG_SERIAL_IFLOWCONTROL
- if (priv->iflow)
- {
- /* RX DMA buffer full. RX paused, RTS line pulled up to prevent
- * more input data from other end.
- */
- }
- else
-#endif
- {
- priv->rxdmanext = 0;
- }
+ priv->rxdmanext = 0;
}
}
@@ -2411,40 +2397,6 @@ static int up_dma_receive(struct uart_dev_s *dev, unsigned int *status)
#endif
/****************************************************************************
- * Name: up_dma_reenable
- *
- * Description:
- * Call to re-enable RX DMA.
- *
- ****************************************************************************/
-
-#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL)
-static void up_dma_reenable(struct up_dev_s *priv)
-{
- /* Configure for non-circular DMA reception into the RX fifo */
-
- stm32_dmasetup(priv->rxdma,
- priv->usartbase + STM32_USART_RDR_OFFSET,
- (uint32_t)priv->rxfifo,
- RXDMA_BUFFER_SIZE,
- SERIAL_DMA_IFLOW_CONTROL_WORD);
-
- /* Reset our DMA shadow pointer to match the address just
- * programmed above.
- */
-
- priv->rxdmanext = 0;
-
- /* Start the DMA channel, and arrange for callbacks at the full point in
- * the FIFO. After buffer gets full, hardware flow-control kicks in and
- * DMA transfer is stopped.
- */
-
- stm32_dmastart(priv->rxdma, up_dma_rxcallback, (void *)priv, false);
-}
-#endif
-
-/****************************************************************************
* Name: up_dma_rxint
*
* Description:
@@ -2466,15 +2418,6 @@ static void up_dma_rxint(struct uart_dev_s *dev, bool enable)
*/
priv->rxenable = enable;
-
-#ifdef CONFIG_SERIAL_IFLOWCONTROL
- if (priv->iflow && priv->rxenable && (priv->rxdmanext == RXDMA_BUFFER_SIZE))
- {
- /* Re-enable RX DMA. */
-
- up_dma_reenable(priv);
- }
-#endif
}
#endif
@@ -2683,16 +2626,6 @@ static void up_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg)
if (priv->rxenable && up_dma_rxavailable(&priv->dev))
{
uart_recvchars(&priv->dev);
-
-#ifdef CONFIG_SERIAL_IFLOWCONTROL
- if (priv->iflow && priv->rxenable &&
- (priv->rxdmanext == RXDMA_BUFFER_SIZE))
- {
- /* Re-enable RX DMA. */
-
- up_dma_reenable(priv);
- }
-#endif
}
}
#endif
@@ -2791,6 +2724,7 @@ static void up_pm_notify(struct pm_callback_s *cb, int domain,
* return non-zero values when reverting back to higher power
* consumption modes!
*
+ *
****************************************************************************/
#ifdef CONFIG_PM