Skip to content

Commit

Permalink
Merge branch 'hardware_flow_control' into integration
Browse files Browse the repository at this point in the history
  • Loading branch information
LorenzMeier committed Jun 6, 2013
2 parents 79ce6ad + e4903c7 commit bc5c15a
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 43 deletions.
168 changes: 125 additions & 43 deletions nuttx/arch/arm/src/stm32/stm32_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,15 @@ struct up_dev_s
uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (7 or 8) */
bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */
bool iflow; /* input flow control (RTS) enabled */
bool oflow; /* output flow control (CTS) enabled */
uint32_t baud; /* Configured baud */
#else
const uint8_t parity; /* 0=none, 1=odd, 2=even */
const uint8_t bits; /* Number of bits (7 or 8) */
const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */
const bool iflow; /* input flow control (RTS) enabled */
const bool oflow; /* output flow control (CTS) enabled */
const uint32_t baud; /* Configured baud */
#endif

Expand Down Expand Up @@ -298,7 +302,7 @@ struct up_dev_s
* Private Function Prototypes
****************************************************************************/

static void up_setspeed(struct uart_dev_s *dev);
static void up_set_format(struct uart_dev_s *dev);
static int up_setup(struct uart_dev_s *dev);
static void up_shutdown(struct uart_dev_s *dev);
static int up_attach(struct uart_dev_s *dev);
Expand Down Expand Up @@ -492,6 +496,8 @@ static struct up_dev_s g_usart1priv =
.parity = CONFIG_USART1_PARITY,
.bits = CONFIG_USART1_BITS,
.stopbits2 = CONFIG_USART1_2STOP,
.iflow = false,
.oflow = false,
.baud = CONFIG_USART1_BAUD,
.apbclock = STM32_PCLK2_FREQUENCY,
.usartbase = STM32_USART1_BASE,
Expand Down Expand Up @@ -552,6 +558,8 @@ static struct up_dev_s g_usart2priv =
.parity = CONFIG_USART2_PARITY,
.bits = CONFIG_USART2_BITS,
.stopbits2 = CONFIG_USART2_2STOP,
.iflow = false,
.oflow = false,
.baud = CONFIG_USART2_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_USART2_BASE,
Expand Down Expand Up @@ -612,6 +620,8 @@ static struct up_dev_s g_usart3priv =
.parity = CONFIG_USART3_PARITY,
.bits = CONFIG_USART3_BITS,
.stopbits2 = CONFIG_USART3_2STOP,
.iflow = false,
.oflow = false,
.baud = CONFIG_USART3_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_USART3_BASE,
Expand Down Expand Up @@ -672,17 +682,15 @@ static struct up_dev_s g_uart4priv =
.parity = CONFIG_UART4_PARITY,
.bits = CONFIG_UART4_BITS,
.stopbits2 = CONFIG_UART4_2STOP,
.iflow = false,
.oflow = false,
.baud = CONFIG_UART4_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_UART4_BASE,
.tx_gpio = GPIO_UART4_TX,
.rx_gpio = GPIO_UART4_RX,
#ifdef GPIO_UART4_CTS
.cts_gpio = GPIO_UART4_CTS,
#endif
#ifdef GPIO_UART4_RTS
.rts_gpio = GPIO_UART4_RTS,
#endif
.cts_gpio = 0, /* flow control not supported on this port */
.rts_gpio = 0, /* flow control not supported on this port */
#ifdef CONFIG_UART4_RXDMA
.rxdma_channel = DMAMAP_UART4_RX,
.rxfifo = g_uart4rxfifo,
Expand Down Expand Up @@ -732,17 +740,15 @@ static struct up_dev_s g_uart5priv =
.parity = CONFIG_UART5_PARITY,
.bits = CONFIG_UART5_BITS,
.stopbits2 = CONFIG_UART5_2STOP,
.iflow = false,
.oflow = false,
.baud = CONFIG_UART5_BAUD,
.apbclock = STM32_PCLK1_FREQUENCY,
.usartbase = STM32_UART5_BASE,
.tx_gpio = GPIO_UART5_TX,
.rx_gpio = GPIO_UART5_RX,
#ifdef GPIO_UART5_CTS
.cts_gpio = GPIO_UART5_CTS,
#endif
#ifdef GPIO_UART5_RTS
.rts_gpio = GPIO_UART5_RTS,
#endif
.cts_gpio = 0, /* flow control not supported on this port */
.rts_gpio = 0, /* flow control not supported on this port */
#ifdef CONFIG_UART5_RXDMA
.rxdma_channel = DMAMAP_UART5_RX,
.rxfifo = g_uart5rxfifo,
Expand Down Expand Up @@ -792,6 +798,8 @@ static struct up_dev_s g_usart6priv =
.parity = CONFIG_USART6_PARITY,
.bits = CONFIG_USART6_BITS,
.stopbits2 = CONFIG_USART6_2STOP,
.iflow = false,
.oflow = false,
.baud = CONFIG_USART6_BAUD,
.apbclock = STM32_PCLK2_FREQUENCY,
.usartbase = STM32_USART6_BASE,
Expand Down Expand Up @@ -1091,15 +1099,15 @@ static int up_dma_nextrx(struct up_dev_s *priv)
#endif

/****************************************************************************
* Name: up_setspeed
* Name: up_set_format
*
* Description:
* Set the serial line speed.
* Set the serial line format and speed.
*
****************************************************************************/

#ifndef CONFIG_SUPPRESS_UART_CONFIG
static void up_setspeed(struct uart_dev_s *dev)
static void up_set_format(struct uart_dev_s *dev)
{
#ifdef CONFIG_STM32_STM32F30XX

Expand Down Expand Up @@ -1168,6 +1176,7 @@ static void up_setspeed(struct uart_dev_s *dev)
uint32_t mantissa;
uint32_t fraction;
uint32_t brr;
uint32_t regval;

/* Configure the USART Baud Rate. The baud rate for the receiver and
* transmitter (Rx and Tx) are both set to the same value as programmed
Expand Down Expand Up @@ -1198,9 +1207,52 @@ static void up_setspeed(struct uart_dev_s *dev)
brr |= fraction << USART_BRR_FRAC_SHIFT;
up_serialout(priv, STM32_USART_BRR_OFFSET, brr);

/* Configure parity mode */

regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
regval &= ~(USART_CR1_PCE|USART_CR1_PS);

if (priv->parity == 1) /* Odd parity */
{
regval |= (USART_CR1_PCE|USART_CR1_PS);
}
else if (priv->parity == 2) /* Even parity */
{
regval |= USART_CR1_PCE;
}

up_serialout(priv, STM32_USART_CR1_OFFSET, regval);

/* Configure STOP bits */

regval = up_serialin(priv, STM32_USART_CR2_OFFSET);
regval &= ~(USART_CR2_STOP_MASK);

if (priv->stopbits2)
{
regval |= USART_CR2_STOP2;
}
up_serialout(priv, STM32_USART_CR2_OFFSET, regval);

/* Configure hardware flow control */

regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
regval &= ~(USART_CR3_CTSE|USART_CR3_RTSE);

if (priv->iflow && (priv->rts_gpio != 0))
{
regval |= USART_CR3_RTSE;
}
if (priv->oflow && (priv->cts_gpio != 0))
{
regval |= USART_CR3_CTSE;
}

up_serialout(priv, STM32_USART_CR3_OFFSET, regval);

#endif
}
#endif
#endif /* CONFIG_SUPPRESS_UART_CONFIG */

/****************************************************************************
* Name: up_setup
Expand Down Expand Up @@ -1246,10 +1298,10 @@ static int up_setup(struct uart_dev_s *dev)
#endif

/* Configure CR2 */
/* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */
/* Clear CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */

regval = up_serialin(priv, STM32_USART_CR2_OFFSET);
regval &= ~(USART_CR2_STOP_MASK|USART_CR2_CLKEN|USART_CR2_CPOL|
regval &= ~(USART_CR2_CLKEN|USART_CR2_CPOL|
USART_CR2_CPHA|USART_CR2_LBCL|USART_CR2_LBDIE);

/* Configure STOP bits */
Expand All @@ -1262,28 +1314,19 @@ static int up_setup(struct uart_dev_s *dev)
up_serialout(priv, STM32_USART_CR2_OFFSET, regval);

/* Configure CR1 */
/* Clear M, PCE, PS, TE, REm and all interrupt enable bits */
/* Clear M, TE, REm and all interrupt enable bits */

regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
regval &= ~(USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE|
regval &= ~(USART_CR1_M|USART_CR1_TE|
USART_CR1_RE|USART_CR1_ALLINTS);

/* Configure word length and parity mode */
/* Configure word length */

if (priv->bits == 9) /* Default: 1 start, 8 data, n stop */
{
regval |= USART_CR1_M; /* 1 start, 9 data, n stop */
}

if (priv->parity == 1) /* Odd parity */
{
regval |= (USART_CR1_PCE|USART_CR1_PS);
}
else if (priv->parity == 2) /* Even parity */
{
regval |= USART_CR1_PCE;
}

up_serialout(priv, STM32_USART_CR1_OFFSET, regval);

/* Configure CR3 */
Expand All @@ -1292,13 +1335,11 @@ static int up_setup(struct uart_dev_s *dev)
regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
regval &= ~(USART_CR3_CTSIE|USART_CR3_CTSE|USART_CR3_RTSE|USART_CR3_EIE);

/* Configure hardware flow control -- Not yet supported */

up_serialout(priv, STM32_USART_CR3_OFFSET, regval);

/* Configure the USART Baud Rate. */
/* Configure the USART line format and speed. */

up_setspeed(dev);
up_set_format(dev);

/* Enable Rx, Tx, and the USART */

Expand Down Expand Up @@ -1679,12 +1720,21 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
}

/* TODO: Other termios fields are not yet returned.
* Note that only cfsetospeed is not necessary because we have
* knowledge that only one speed is supported.
cfsetispeed(termiosp, priv->baud);

/* Note that since we only support 8/9 bit modes and
* there is no way to report 9-bit mode, we always claim 8.
*/

cfsetispeed(termiosp, priv->baud);
termiosp->c_cflag =
((priv->parity != 0) ? PARENB : 0) |
((priv->parity == 1) ? PARODD : 0) |
((priv->stopbits2) ? CSTOPB : 0) |
((priv->oflow) ? CCTS_OFLOW : 0) |
((priv->iflow) ? CRTS_IFLOW : 0) |
CS8;

/* TODO: CCTS_IFLOW, CCTS_OFLOW */
}
break;

Expand All @@ -1698,16 +1748,48 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
break;
}

/* TODO: Handle other termios settings.
* Note that only cfgetispeed is used besued we have knowledge
/* Perform some sanity checks before accepting any changes */

if (((termiosp->c_cflag & CSIZE) != CS8) ||
((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) ||
((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)))
{
ret = -EINVAL;
break;
}

if (termiosp->c_cflag & PARENB)
{
priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2;
}
else
{
priv->parity = 0;
}

priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0;
priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0;
priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0;

/* Note that since there is no way to request 9-bit mode
* and no way to support 5/6/7-bit modes, we ignore them
* all here.
*/

/* Note that only cfgetispeed is used because we have knowledge
* that only one speed is supported.
*/

priv->baud = cfgetispeed(termiosp);
up_setspeed(dev);

/* effect the changes immediately - note that we do not implement
* TCSADRAIN / TCSAFLUSH
*/

up_set_format(dev);
}
break;
#endif
#endif /* CONFIG_SERIAL_TERMIOS */

#ifdef CONFIG_USART_BREAKS
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
Expand Down
12 changes: 12 additions & 0 deletions nuttx/include/nuttx/serial/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
#include <stdint.h>
#include <stdbool.h>
#include <semaphore.h>
#ifdef CONFIG_SERIAL_TERMIOS
# include <termios.h>
#endif

#include <nuttx/fs/fs.h>

Expand Down Expand Up @@ -217,6 +220,15 @@ struct uart_dev_s
#ifndef CONFIG_DISABLE_POLL
struct pollfd *fds[CONFIG_SERIAL_NPOLLWAITERS];
#endif

/* Terminal control flags */

#ifdef CONFIG_SERIAL_TERMIOS
tcflag_t tc_iflag; /* Input modes */
tcflag_t tc_oflag; /* Output modes */
tcflag_t tc_lflag; /* Local modes */
#endif

};

typedef struct uart_dev_s uart_dev_t;
Expand Down
3 changes: 3 additions & 0 deletions nuttx/include/termios.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@
#define PARODD (1 << 5) /* Bit 5: Odd parity, else even */
#define HUPCL (1 << 6) /* Bit 6: Hang up on last close */
#define CLOCAL (1 << 7) /* Bit 7: Ignore modem status lines */
#define CCTS_OFLOW (1 << 8) /* Bit 8: CTS flow control of output */
#define CRTSCTS CCTS_OFLOW
#define CRTS_IFLOW (1 << 9) /* Bit 9: RTS flow control of input */

/* Local Modes (c_lflag in the termios structure) */

Expand Down

0 comments on commit bc5c15a

Please sign in to comment.