|
|
|
@ -96,6 +96,19 @@
@@ -96,6 +96,19 @@
|
|
|
|
|
# endif |
|
|
|
|
# endif |
|
|
|
|
|
|
|
|
|
/* Currently RS-485 support cannot be enabled when RXDMA is in use due to lack
|
|
|
|
|
* of testing - RS-485 support was developed on STM32F1x |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ |
|
|
|
|
(defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \
|
|
|
|
|
(defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \
|
|
|
|
|
(defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \
|
|
|
|
|
(defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) || \
|
|
|
|
|
(defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_RS485)) \
|
|
|
|
|
# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" |
|
|
|
|
# endif |
|
|
|
|
|
|
|
|
|
/* For the F4, there are alternate DMA channels for USART1 and 6.
|
|
|
|
|
* Logic in the board.h file make the DMA channel selection by defining |
|
|
|
|
* the following in the board.h file. |
|
|
|
@ -215,6 +228,11 @@ struct up_dev_s
@@ -215,6 +228,11 @@ struct up_dev_s
|
|
|
|
|
uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ |
|
|
|
|
char *const rxfifo; /* Receive DMA buffer */ |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_RS485 |
|
|
|
|
const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ |
|
|
|
|
const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
@ -409,6 +427,15 @@ static struct up_dev_s g_usart1priv =
@@ -409,6 +427,15 @@ static struct up_dev_s g_usart1priv =
|
|
|
|
|
.rxfifo = g_usart1rxfifo, |
|
|
|
|
#endif |
|
|
|
|
.vector = up_interrupt_usart1, |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USART1_RS485 |
|
|
|
|
.rs485_dir_gpio = GPIO_USART1_RS485_DIR, |
|
|
|
|
# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) |
|
|
|
|
.rs485_dir_polarity = false, |
|
|
|
|
# else |
|
|
|
|
.rs485_dir_polarity = true, |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -460,6 +487,15 @@ static struct up_dev_s g_usart2priv =
@@ -460,6 +487,15 @@ static struct up_dev_s g_usart2priv =
|
|
|
|
|
.rxfifo = g_usart2rxfifo, |
|
|
|
|
#endif |
|
|
|
|
.vector = up_interrupt_usart2, |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USART2_RS485 |
|
|
|
|
.rs485_dir_gpio = GPIO_USART2_RS485_DIR, |
|
|
|
|
# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) |
|
|
|
|
.rs485_dir_polarity = false, |
|
|
|
|
# else |
|
|
|
|
.rs485_dir_polarity = true, |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -511,6 +547,15 @@ static struct up_dev_s g_usart3priv =
@@ -511,6 +547,15 @@ static struct up_dev_s g_usart3priv =
|
|
|
|
|
.rxfifo = g_usart3rxfifo, |
|
|
|
|
#endif |
|
|
|
|
.vector = up_interrupt_usart3, |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USART3_RS485 |
|
|
|
|
.rs485_dir_gpio = GPIO_USART3_RS485_DIR, |
|
|
|
|
# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) |
|
|
|
|
.rs485_dir_polarity = false, |
|
|
|
|
# else |
|
|
|
|
.rs485_dir_polarity = true, |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -562,6 +607,15 @@ static struct up_dev_s g_uart4priv =
@@ -562,6 +607,15 @@ static struct up_dev_s g_uart4priv =
|
|
|
|
|
.rxfifo = g_uart4rxfifo, |
|
|
|
|
#endif |
|
|
|
|
.vector = up_interrupt_uart4, |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_UART4_RS485 |
|
|
|
|
.rs485_dir_gpio = GPIO_UART4_RS485_DIR, |
|
|
|
|
# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) |
|
|
|
|
.rs485_dir_polarity = false, |
|
|
|
|
# else |
|
|
|
|
.rs485_dir_polarity = true, |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -613,6 +667,15 @@ static struct up_dev_s g_uart5priv =
@@ -613,6 +667,15 @@ static struct up_dev_s g_uart5priv =
|
|
|
|
|
.rxfifo = g_uart5rxfifo, |
|
|
|
|
#endif |
|
|
|
|
.vector = up_interrupt_uart5, |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_UART5_RS485 |
|
|
|
|
.rs485_dir_gpio = GPIO_UART5_RS485_DIR, |
|
|
|
|
# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) |
|
|
|
|
.rs485_dir_polarity = false, |
|
|
|
|
# else |
|
|
|
|
.rs485_dir_polarity = true, |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -664,6 +727,15 @@ static struct up_dev_s g_usart6priv =
@@ -664,6 +727,15 @@ static struct up_dev_s g_usart6priv =
|
|
|
|
|
.rxfifo = g_usart6rxfifo, |
|
|
|
|
#endif |
|
|
|
|
.vector = up_interrupt_usart6, |
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USART6_RS485 |
|
|
|
|
.rs485_dir_gpio = GPIO_USART6_RS485_DIR, |
|
|
|
|
# if (CONFIG_USART6_RS485_DIR_POLARITY == 0) |
|
|
|
|
.rs485_dir_polarity = false, |
|
|
|
|
# else |
|
|
|
|
.rs485_dir_polarity = true, |
|
|
|
|
# endif |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -736,8 +808,8 @@ static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie)
@@ -736,8 +808,8 @@ static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie)
|
|
|
|
|
/* And restore the interrupt state (see the interrupt enable/usage table above) */ |
|
|
|
|
|
|
|
|
|
cr = up_serialin(priv, STM32_USART_CR1_OFFSET); |
|
|
|
|
cr &= ~(USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE); |
|
|
|
|
cr |= (ie & (USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE)); |
|
|
|
|
cr &= ~(USART_CR1_USED_INTS); |
|
|
|
|
cr |= (ie & (USART_CR1_USED_INTS)); |
|
|
|
|
up_serialout(priv, STM32_USART_CR1_OFFSET, cr); |
|
|
|
|
|
|
|
|
|
cr = up_serialin(priv, STM32_USART_CR3_OFFSET); |
|
|
|
@ -764,7 +836,7 @@ static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
@@ -764,7 +836,7 @@ static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
|
|
|
|
|
* USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used) |
|
|
|
|
* USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read |
|
|
|
|
* " " USART_SR_ORE Overrun Error Detected |
|
|
|
|
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used) |
|
|
|
|
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (used only for RS-485) |
|
|
|
|
* USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty |
|
|
|
|
* USART_CR1_PEIE 8 USART_SR_PE Parity Error |
|
|
|
|
* |
|
|
|
@ -783,7 +855,7 @@ static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
@@ -783,7 +855,7 @@ static inline void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
|
|
|
|
|
* overlap. This logic would fail if we needed the break interrupt! |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
*ie = (cr1 & (USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE)) | (cr3 & USART_CR3_EIE); |
|
|
|
|
*ie = (cr1 & (USART_CR1_USED_INTS)) | (cr3 & USART_CR3_EIE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Disable all interrupts */ |
|
|
|
@ -893,6 +965,14 @@ static int up_setup(struct uart_dev_s *dev)
@@ -893,6 +965,14 @@ static int up_setup(struct uart_dev_s *dev)
|
|
|
|
|
stm32_configgpio(priv->rts_gpio); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if HAVE_RS485 |
|
|
|
|
if (priv->rs485_dir_gpio != 0) |
|
|
|
|
{ |
|
|
|
|
stm32_configgpio(priv->rs485_dir_gpio); |
|
|
|
|
stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* Configure CR2 */ |
|
|
|
|
/* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ |
|
|
|
|
|
|
|
|
@ -1174,7 +1254,7 @@ static int up_interrupt_common(struct up_dev_s *priv)
@@ -1174,7 +1254,7 @@ static int up_interrupt_common(struct up_dev_s *priv)
|
|
|
|
|
* USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used) |
|
|
|
|
* USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read |
|
|
|
|
* " " USART_SR_ORE Overrun Error Detected |
|
|
|
|
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used) |
|
|
|
|
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (used only for RS-485) |
|
|
|
|
* USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty |
|
|
|
|
* USART_CR1_PEIE 8 USART_SR_PE Parity Error |
|
|
|
|
* |
|
|
|
@ -1189,6 +1269,21 @@ static int up_interrupt_common(struct up_dev_s *priv)
@@ -1189,6 +1269,21 @@ static int up_interrupt_common(struct up_dev_s *priv)
|
|
|
|
|
* being used. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifdef HAVE_RS485 |
|
|
|
|
/* Transmission of whole buffer is over - TC is set, TXEIE is cleared.
|
|
|
|
|
* Note - this should be first, to have the most recent TC bit value from |
|
|
|
|
* SR register - sending data affects TC, but without refresh we will not |
|
|
|
|
* know that... |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if ((priv->sr & USART_SR_TC) != 0 && (priv->ie & USART_CR1_TCIE) != 0 && |
|
|
|
|
(priv->ie & USART_CR1_TXEIE) == 0) |
|
|
|
|
{ |
|
|
|
|
stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); |
|
|
|
|
up_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* Handle incoming, receive bytes. */ |
|
|
|
|
|
|
|
|
|
if ((priv->sr & USART_SR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0) |
|
|
|
@ -1222,13 +1317,14 @@ static int up_interrupt_common(struct up_dev_s *priv)
@@ -1222,13 +1317,14 @@ static int up_interrupt_common(struct up_dev_s *priv)
|
|
|
|
|
|
|
|
|
|
if ((priv->sr & USART_SR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0) |
|
|
|
|
{ |
|
|
|
|
/* Transmit data regiser empty ... process outgoing bytes */ |
|
|
|
|
/* Transmit data register empty ... process outgoing bytes */ |
|
|
|
|
|
|
|
|
|
uart_xmitchars(&priv->dev); |
|
|
|
|
handled = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return OK; |
|
|
|
|
|
|
|
|
|
return OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
@ -1527,6 +1623,10 @@ static bool up_dma_rxavailable(struct uart_dev_s *dev)
@@ -1527,6 +1623,10 @@ static bool up_dma_rxavailable(struct uart_dev_s *dev)
|
|
|
|
|
static void up_send(struct uart_dev_s *dev, int ch) |
|
|
|
|
{ |
|
|
|
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv; |
|
|
|
|
#ifdef HAVE_RS485 |
|
|
|
|
if (priv->rs485_dir_gpio != 0) |
|
|
|
|
stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); |
|
|
|
|
#endif |
|
|
|
|
up_serialout(priv, STM32_USART_DR_OFFSET, (uint32_t)ch); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1547,7 +1647,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
@@ -1547,7 +1647,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|
|
|
|
* |
|
|
|
|
* Enable Bit Status Meaning Usage |
|
|
|
|
* ------------------ --- --------------- ---------------------------- ---------- |
|
|
|
|
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used) |
|
|
|
|
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (used only for RS-485) |
|
|
|
|
* USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty |
|
|
|
|
* USART_CR3_CTSIE 10 USART_SR_CTS CTS flag (not used) |
|
|
|
|
*/ |
|
|
|
@ -1558,7 +1658,20 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
@@ -1558,7 +1658,20 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|
|
|
|
/* Set to receive an interrupt when the TX data register is empty */ |
|
|
|
|
|
|
|
|
|
#ifndef CONFIG_SUPPRESS_SERIAL_INTS |
|
|
|
|
up_restoreusartint(priv, priv->ie | USART_CR1_TXEIE); |
|
|
|
|
uint16_t ie = priv->ie | USART_CR1_TXEIE; |
|
|
|
|
|
|
|
|
|
/* If RS-485 is supported on this U[S]ART, then also enable the
|
|
|
|
|
* transmission complete interrupt. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
# ifdef HAVE_RS485 |
|
|
|
|
if (priv->rs485_dir_gpio != 0) |
|
|
|
|
{ |
|
|
|
|
ie |= USART_CR1_TCIE; |
|
|
|
|
} |
|
|
|
|
# endif |
|
|
|
|
|
|
|
|
|
up_restoreusartint(priv, ie); |
|
|
|
|
|
|
|
|
|
/* Fake a TX interrupt here by just calling uart_xmitchars() with
|
|
|
|
|
* interrupts disabled (note this may recurse). |
|
|
|
@ -1573,6 +1686,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
@@ -1573,6 +1686,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|
|
|
|
|
|
|
|
|
up_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
irqrestore(flags); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|