STM32 Serial: PX4 HW workarround for flaky STM32 RTS. From David Sidrane
This commit is contained in:
parent
d597e94332
commit
59c6f42be4
@ -3109,6 +3109,16 @@ config SERIAL_DISABLE_REORDERING
|
|||||||
want the side effect of having all serial port names change when just
|
want the side effect of having all serial port names change when just
|
||||||
the console is moved from serial to USB.
|
the console is moved from serial to USB.
|
||||||
|
|
||||||
|
config STM32_FLOWCONTROL_BROKEN
|
||||||
|
bool "Use Software UART RTS flow control"
|
||||||
|
depends on STM32_USART
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable UART RTS flow control using Software. Because STM
|
||||||
|
Current STM32 have broken HW based RTS behavior (they assert
|
||||||
|
nRTS after every byte received) Enable this setting workaround
|
||||||
|
this issue by useing software based management of RTS
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
config STM32_USART_SINGLEWIRE
|
config STM32_USART_SINGLEWIRE
|
||||||
|
@ -410,6 +410,9 @@ static const struct uart_ops_s g_uart_dma_ops =
|
|||||||
.receive = up_dma_receive,
|
.receive = up_dma_receive,
|
||||||
.rxint = up_dma_rxint,
|
.rxint = up_dma_rxint,
|
||||||
.rxavailable = up_dma_rxavailable,
|
.rxavailable = up_dma_rxavailable,
|
||||||
|
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||||
|
.rxflowcontrol = up_rxflowcontrol,
|
||||||
|
#endif
|
||||||
.send = up_send,
|
.send = up_send,
|
||||||
.txint = up_txint,
|
.txint = up_txint,
|
||||||
.txready = up_txready,
|
.txready = up_txready,
|
||||||
@ -1294,7 +1297,7 @@ static void up_set_format(struct uart_dev_s *dev)
|
|||||||
regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
|
regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
|
||||||
regval &= ~(USART_CR3_CTSE|USART_CR3_RTSE);
|
regval &= ~(USART_CR3_CTSE|USART_CR3_RTSE);
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32_FLOWCONTROL_BROKEN)
|
||||||
if (priv->iflow && (priv->rts_gpio != 0))
|
if (priv->iflow && (priv->rts_gpio != 0))
|
||||||
{
|
{
|
||||||
regval |= USART_CR3_RTSE;
|
regval |= USART_CR3_RTSE;
|
||||||
@ -1437,8 +1440,15 @@ static int up_setup(struct uart_dev_s *dev)
|
|||||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||||
if (priv->rts_gpio != 0)
|
if (priv->rts_gpio != 0)
|
||||||
{
|
{
|
||||||
stm32_configgpio(priv->rts_gpio);
|
uint32_t config = priv->rts_gpio;
|
||||||
}
|
|
||||||
|
#ifdef CONFIG_STM32_FLOWCONTROL_BROKEN
|
||||||
|
/* Instead of letting hw manage this pin, we will bitbang */
|
||||||
|
|
||||||
|
config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT;
|
||||||
|
#endif
|
||||||
|
stm32_configgpio(config);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_RS485
|
#if HAVE_RS485
|
||||||
@ -2140,6 +2150,18 @@ static bool up_rxavailable(struct uart_dev_s *dev)
|
|||||||
* Return true if UART activated RX flow control to block more incoming
|
* Return true if UART activated RX flow control to block more incoming
|
||||||
* data
|
* data
|
||||||
*
|
*
|
||||||
|
* Input parameters:
|
||||||
|
* dev - UART device instance
|
||||||
|
* nbuffered - the number of characters currently buffered
|
||||||
|
* (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is
|
||||||
|
* not defined the value will be 0 for an empty buffer or the
|
||||||
|
* defined buffer size for a full buffer)
|
||||||
|
* upper - true indicates the upper watermark was crossed where
|
||||||
|
* false indicates the lower watermark has been crossed
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* true if RX flow control activated.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||||
@ -2149,6 +2171,16 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev,
|
|||||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
uint16_t ie;
|
uint16_t ie;
|
||||||
|
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
stm32_gpiowrite(priv->rts_gpio, upper);
|
||||||
|
return upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
if (priv->iflow)
|
if (priv->iflow)
|
||||||
{
|
{
|
||||||
/* Is the RX buffer full? */
|
/* Is the RX buffer full? */
|
||||||
@ -2185,6 +2217,7 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev,
|
|||||||
up_rxint(dev, true);
|
up_rxint(dev, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user