Skip to content
Snippets Groups Projects
Commit bef5552e authored by David Sidrane's avatar David Sidrane
Browse files

Support BSD compatible breaks on stm32fl4 U[S]ART

parent 3ffe7c37
No related branches found
No related tags found
No related merge requests found
......@@ -782,6 +782,26 @@ config STM32L4_FLOWCONTROL_BROKEN
nRTS after every byte received) Enable this setting workaround
this issue by useing software based management of RTS
config STM32L4_USART_BREAKS
bool "Add TIOxSBRK to support sending Breaks"
depends on STM32_USART
default n
---help---
Add TIOCxBRK routines to send a line break per the STM32 manual, the
break will be a pulse based on the value M. This is not a BSD compatible
break.
config STM32L4_SERIALBRK_BSDCOMPAT
bool "Use GPIO To send Break"
depends on STM32_USART && STM32_USART_BREAKS
default n
---help---
Enable using GPIO on the TX pin to send a BSD compatible break:
TIOCSBRK will start the break and TIOCCBRK will end the break.
The current STM32 U[S]ARTS have no way to leave the break (TX=LOW)
on because the SW starts the break and then the HW automatically clears
the break. This makes it is difficult to sent a long break.
endmenu
menu "SPI Configuration"
......
......@@ -208,6 +208,23 @@
# define PM_IDLE_DOMAIN 0 /* Revisit */
#endif
/*
* Keep track if a Break was set
*
* Note:
*
* 1) This value is set in the priv->ie but never written to the control
* register. It must not collide with USART_CR1_USED_INTS or USART_CR3_EIE
* 2) USART_CR3_EIE is also carried in the up_dev_s ie member.
*
* see up_restoreusartint where the masking is done.
*/
#ifdef CONFIG_STM32L4_SERIALBRK_BSDCOMPAT
# define USART_CR1_IE_BREAK_INPROGRESS_SHFTS 15
# define USART_CR1_IE_BREAK_INPROGRESS (1 << USART_CR1_IE_BREAK_INPROGRESS_SHFTS)
#endif
#ifdef USE_SERIALDRIVER
#ifdef HAVE_UART
......@@ -1720,8 +1737,52 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
#endif /* CONFIG_SERIAL_TERMIOS */
#ifdef CONFIG_USART_BREAKS
#ifdef CONFIG_STM32L4_USART_BREAKS
# ifdef CONFIG_STM32L4_SERIALBRK_BSDCOMPAT
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags;
uint32_t tx_break;
flags = enter_critical_section();
/* Disable any further tx activity */
priv->ie |= USART_CR1_IE_BREAK_INPROGRESS;
up_txint(dev, false);
/* Configure TX as a GPIO output pin and Send a break signal*/
tx_break = GPIO_OUTPUT | (~(GPIO_MODE_MASK|GPIO_OUTPUT_SET) & priv->tx_gpio);
stm32_configgpio(tx_break);
leave_critical_section(flags);
}
break;
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
{
uint32_t cr1;
irqstate_t flags;
flags = enter_critical_section();
/* Configure TX back to U(S)ART */
stm32_configgpio(priv->tx_gpio);
priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS;
/* Enable further tx activity */
up_txint(dev, true);
leave_critical_section(flags);
}
break;
# else
case TIOCSBRK: /* No BSD compatibility: Turn break on for M bit times */
{
uint32_t cr1;
irqstate_t flags;
......@@ -1733,7 +1794,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
}
break;
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
case TIOCCBRK: /* No BSD compatibility: May turn off break too soon */
{
uint32_t cr1;
irqstate_t flags;
......@@ -1744,6 +1805,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
leave_critical_section(flags);
}
break;
# endif
#endif
default:
......@@ -2132,6 +2194,12 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
ie |= USART_CR1_TCIE;
}
# endif
# ifdef CONFIG_STM32L4_SERIALBRK_BSDCOMPAT
if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS)
{
return;
}
# endif
up_restoreusartint(priv, ie);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment