mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
stm32: Add support to TIOCGICOUNT ioctl
This commit adds support to TIOCGICOUNT for STM32, this way a userspace application can collect information about UART errors. Signed-off-by: Alan C. Assis <acassis@gmail.com>
This commit is contained in:
committed by
Mateusz Szafoni
parent
5a6e5a8fb4
commit
3594f9d879
@@ -465,6 +465,9 @@ struct up_dev_s
|
|||||||
#ifdef CONFIG_SERIAL_OFLOWCONTROL
|
#ifdef CONFIG_SERIAL_OFLOWCONTROL
|
||||||
const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */
|
const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_SERIAL_TIOCGICOUNT
|
||||||
|
struct serial_icounter_s icount; /* U[S]ART error report */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TX DMA state */
|
/* TX DMA state */
|
||||||
|
|
||||||
@@ -1485,7 +1488,7 @@ static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie)
|
|||||||
* USART_CR1_TXEIE USART_SR_TXE Tx Data Register Empty
|
* USART_CR1_TXEIE USART_SR_TXE Tx Data Register Empty
|
||||||
* USART_CR1_PEIE USART_SR_PE Parity Error
|
* USART_CR1_PEIE USART_SR_PE Parity Error
|
||||||
*
|
*
|
||||||
* USART_CR2_LBDIE USART_SR_LBD Break Flag (not used)
|
* USART_CR2_LBDIE USART_SR_LBD Break Flag
|
||||||
* USART_CR3_EIE USART_SR_FE Framing Error
|
* USART_CR3_EIE USART_SR_FE Framing Error
|
||||||
* " " USART_SR_NE Noise Error
|
* " " USART_SR_NE Noise Error
|
||||||
* " " USART_SR_ORE Overrun Error Detected
|
* " " USART_SR_ORE Overrun Error Detected
|
||||||
@@ -2358,7 +2361,7 @@ static int up_interrupt(int irq, void *context, void *arg)
|
|||||||
* USART_CR1_TXEIE USART_SR_TXE Tx Data Register Empty
|
* USART_CR1_TXEIE USART_SR_TXE Tx Data Register Empty
|
||||||
* USART_CR1_PEIE USART_SR_PE Parity Error
|
* USART_CR1_PEIE USART_SR_PE Parity Error
|
||||||
*
|
*
|
||||||
* USART_CR2_LBDIE USART_SR_LBD Break Flag (not used)
|
* USART_CR2_LBDIE USART_SR_LBD Break Flag
|
||||||
* USART_CR3_EIE USART_SR_FE Framing Error
|
* USART_CR3_EIE USART_SR_FE Framing Error
|
||||||
* " " USART_SR_NE Noise Error
|
* " " USART_SR_NE Noise Error
|
||||||
* " " USART_SR_ORE Overrun Error Detected
|
* " " USART_SR_ORE Overrun Error Detected
|
||||||
@@ -2369,6 +2372,30 @@ static int up_interrupt(int irq, void *context, void *arg)
|
|||||||
* those are currently being used.
|
* those are currently being used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Error report */
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TIOCGICOUNT
|
||||||
|
if (priv->sr & USART_SR_FE)
|
||||||
|
{
|
||||||
|
priv->icount.frame++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->sr & USART_SR_ORE)
|
||||||
|
{
|
||||||
|
priv->icount.overrun++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->sr & USART_SR_PE)
|
||||||
|
{
|
||||||
|
priv->icount.parity++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->sr & USART_SR_LBD)
|
||||||
|
{
|
||||||
|
priv->icount.brk++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_RS485
|
#ifdef HAVE_RS485
|
||||||
/* Transmission of whole buffer is over - TC is set, TXEIE is cleared.
|
/* 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
|
* Note - this should be first, to have the most recent TC bit value
|
||||||
@@ -2403,7 +2430,8 @@ static int up_interrupt(int irq, void *context, void *arg)
|
|||||||
* error conditions.
|
* error conditions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if ((priv->sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE)) != 0)
|
else if ((priv->sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE |
|
||||||
|
USART_SR_LBD)) != 0)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
|
#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
|
||||||
defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32G4XXX)
|
defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32G4XXX)
|
||||||
@@ -2412,7 +2440,8 @@ static int up_interrupt(int irq, void *context, void *arg)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
up_serialout(priv, STM32_USART_ICR_OFFSET,
|
up_serialout(priv, STM32_USART_ICR_OFFSET,
|
||||||
(USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF));
|
(USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF |
|
||||||
|
USART_ICR_LBDCF));
|
||||||
#else
|
#else
|
||||||
/* If an error occurs, read from DR to clear the error (data has
|
/* If an error occurs, read from DR to clear the error (data has
|
||||||
* been lost). If ORE is set along with RXNE then it tells you
|
* been lost). If ORE is set along with RXNE then it tells you
|
||||||
@@ -2452,12 +2481,14 @@ static int up_interrupt(int irq, void *context, void *arg)
|
|||||||
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) \
|
#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) \
|
||||||
|
|| defined(CONFIG_SERIAL_TIOCGICOUNT) \
|
||||||
|| defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT) \
|
|| defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT) \
|
||||||
|| defined(CONFIG_STM32_USART_SINGLEWIRE)
|
|| defined(CONFIG_STM32_USART_SINGLEWIRE)
|
||||||
struct inode *inode = filep->f_inode;
|
struct inode *inode = filep->f_inode;
|
||||||
struct uart_dev_s *dev = inode->i_private;
|
struct uart_dev_s *dev = inode->i_private;
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_SERIAL_TERMIOS) \
|
#if defined(CONFIG_SERIAL_TERMIOS) \
|
||||||
|
|| defined(CONFIG_SERIAL_TIOCGICOUNT) \
|
||||||
|| defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT) \
|
|| defined(CONFIG_STM32_SERIALBRK_BSDCOMPAT) \
|
||||||
|| defined(CONFIG_STM32_USART_SINGLEWIRE)
|
|| defined(CONFIG_STM32_USART_SINGLEWIRE)
|
||||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||||
@@ -2482,6 +2513,24 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TIOCGICOUNT
|
||||||
|
/* Get U(S)ART error counters */
|
||||||
|
|
||||||
|
case TIOCGICOUNT:
|
||||||
|
{
|
||||||
|
struct serial_icounter_s *icount = (struct serial_icounter_s *)arg;
|
||||||
|
if (icount == NULL)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(icount, &priv->icount, sizeof(struct serial_icounter_s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_STM32_USART_SINGLEWIRE
|
#ifdef CONFIG_STM32_USART_SINGLEWIRE
|
||||||
case TIOCSSINGLEWIRE:
|
case TIOCSSINGLEWIRE:
|
||||||
{
|
{
|
||||||
@@ -2764,7 +2813,7 @@ static void up_rxint(struct uart_dev_s *dev, bool enable)
|
|||||||
* " " USART_SR_ORE Overrun Error Detected
|
* " " USART_SR_ORE Overrun Error Detected
|
||||||
* USART_CR1_PEIE USART_SR_PE Parity Error
|
* USART_CR1_PEIE USART_SR_PE Parity Error
|
||||||
*
|
*
|
||||||
* USART_CR2_LBDIE USART_SR_LBD Break Flag (not used)
|
* USART_CR2_LBDIE USART_SR_LBD Break Flag
|
||||||
* USART_CR3_EIE USART_SR_FE Framing Error
|
* USART_CR3_EIE USART_SR_FE Framing Error
|
||||||
* " " USART_SR_NE Noise Error
|
* " " USART_SR_NE Noise Error
|
||||||
* " " USART_SR_ORE Overrun Error Detected
|
* " " USART_SR_ORE Overrun Error Detected
|
||||||
|
|||||||
Reference in New Issue
Block a user