Baud definitions (B9600 for example) are again encoded; Now supports the BOTHER settings which allows specifying the baud via c_ispeed and c_ospeed termios fields
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4970 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
6de2e45191
commit
28bd2e6071
@ -485,5 +485,11 @@ config USART3_2STOP
|
|||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config SERIAL_TERMIOS
|
||||||
|
bool "Serial driver TERMIOS supported"
|
||||||
|
depends on LPC43_USART0 || LPC43_UART1 || LPC43_USART2 || LPC43_USART3
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.).
|
||||||
|
If this is not defined, then the terminal settings (baud, parity, etc).
|
||||||
|
are not configurable at runtime; serial streams cannot be flushed, etc..
|
||||||
|
@ -1756,6 +1756,15 @@ config USART6_RXDMA
|
|||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config SERIAL_TERMIOS
|
||||||
|
bool "Serial driver TERMIOS supported"
|
||||||
|
depends on STM32_USART1 || STM32_USART2 || STM32_USART3 || STM32_UART4 || STM32_UART5 || STM32_USART6
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.).
|
||||||
|
If this is not defined, then the terminal settings (baud, parity, etc).
|
||||||
|
are not configurable at runtime; serial streams cannot be flushed, etc..
|
||||||
|
|
||||||
menu "SPI Configuration"
|
menu "SPI Configuration"
|
||||||
depends on STM32_SPI
|
depends on STM32_SPI
|
||||||
|
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
#include <nuttx/serial/serial.h>
|
#include <nuttx/serial/serial.h>
|
||||||
#include <nuttx/power/pm.h>
|
#include <nuttx/power/pm.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TERMIOS
|
||||||
|
# include <termios.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <arch/serial.h>
|
#include <arch/serial.h>
|
||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
|
|
||||||
@ -149,11 +153,23 @@ struct up_dev_s
|
|||||||
uint16_t ie; /* Saved interrupt mask bits value */
|
uint16_t ie; /* Saved interrupt mask bits value */
|
||||||
uint16_t sr; /* Saved status bits */
|
uint16_t sr; /* Saved status bits */
|
||||||
|
|
||||||
const uint8_t irq; /* IRQ associated with this USART */
|
/* If termios are supported, then the following fields may vary at
|
||||||
|
* runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TERMIOS
|
||||||
|
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 */
|
||||||
|
uint32_t baud; /* Configured baud */
|
||||||
|
#else
|
||||||
const uint8_t parity; /* 0=none, 1=odd, 2=even */
|
const uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||||
const uint8_t bits; /* Number of bits (7 or 8) */
|
const uint8_t bits; /* Number of bits (7 or 8) */
|
||||||
const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */
|
const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */
|
||||||
const uint32_t baud; /* Configured baud */
|
const uint32_t baud; /* Configured baud */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint8_t irq; /* IRQ associated with this USART */
|
||||||
const uint32_t apbclock; /* PCLK 1 or 2 frequency */
|
const uint32_t apbclock; /* PCLK 1 or 2 frequency */
|
||||||
const uint32_t usartbase; /* Base address of USART registers */
|
const uint32_t usartbase; /* Base address of USART registers */
|
||||||
const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */
|
const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */
|
||||||
@ -181,6 +197,7 @@ struct up_dev_s
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void up_setspeed(struct uart_dev_s *dev);
|
||||||
static int up_setup(struct uart_dev_s *dev);
|
static int up_setup(struct uart_dev_s *dev);
|
||||||
static void up_shutdown(struct uart_dev_s *dev);
|
static void up_shutdown(struct uart_dev_s *dev);
|
||||||
static int up_attach(struct uart_dev_s *dev);
|
static int up_attach(struct uart_dev_s *dev);
|
||||||
@ -770,6 +787,54 @@ static int up_dma_nextrx(struct up_dev_s *priv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: up_setspeed
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set the serial line speed.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_SUPPRESS_UART_CONFIG
|
||||||
|
static void up_setspeed(struct uart_dev_s *dev)
|
||||||
|
{
|
||||||
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
|
uint32_t usartdiv32;
|
||||||
|
uint32_t mantissa;
|
||||||
|
uint32_t fraction;
|
||||||
|
uint32_t brr;
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* in the Mantissa and Fraction values of USARTDIV.
|
||||||
|
*
|
||||||
|
* baud = fCK / (16 * usartdiv)
|
||||||
|
* usartdiv = fCK / (16 * baud)
|
||||||
|
*
|
||||||
|
* Where fCK is the input clock to the peripheral (PCLK1 for USART2, 3, 4, 5
|
||||||
|
* or PCLK2 for USART1)
|
||||||
|
*
|
||||||
|
* First calculate (NOTE: all stand baud values are even so dividing by two
|
||||||
|
* does not lose precision):
|
||||||
|
*
|
||||||
|
* usartdiv32 = 32 * usartdiv = fCK / (baud/2)
|
||||||
|
*/
|
||||||
|
|
||||||
|
usartdiv32 = priv->apbclock / (priv->baud >> 1);
|
||||||
|
|
||||||
|
/* The mantissa part is then */
|
||||||
|
|
||||||
|
mantissa = usartdiv32 >> 5;
|
||||||
|
brr = mantissa << USART_BRR_MANT_SHIFT;
|
||||||
|
|
||||||
|
/* The fractional remainder (with rounding) */
|
||||||
|
|
||||||
|
fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1;
|
||||||
|
brr |= fraction << USART_BRR_FRAC_SHIFT;
|
||||||
|
up_serialout(priv, STM32_USART_BRR_OFFSET, brr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: up_setup
|
* Name: up_setup
|
||||||
*
|
*
|
||||||
@ -783,10 +848,6 @@ static int up_setup(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;
|
||||||
#ifndef CONFIG_SUPPRESS_UART_CONFIG
|
#ifndef CONFIG_SUPPRESS_UART_CONFIG
|
||||||
uint32_t usartdiv32;
|
|
||||||
uint32_t mantissa;
|
|
||||||
uint32_t fraction;
|
|
||||||
uint32_t brr;
|
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
/* Note: The logic here depends on the fact that that the USART module
|
/* Note: The logic here depends on the fact that that the USART module
|
||||||
@ -858,34 +919,9 @@ static int up_setup(struct uart_dev_s *dev)
|
|||||||
|
|
||||||
up_serialout(priv, STM32_USART_CR3_OFFSET, regval);
|
up_serialout(priv, STM32_USART_CR3_OFFSET, regval);
|
||||||
|
|
||||||
/* Configure the USART Baud Rate. The baud rate for the receiver and
|
/* Configure the USART Baud Rate. */
|
||||||
* transmitter (Rx and Tx) are both set to the same value as programmed
|
|
||||||
* in the Mantissa and Fraction values of USARTDIV.
|
|
||||||
*
|
|
||||||
* baud = fCK / (16 * usartdiv)
|
|
||||||
* usartdiv = fCK / (16 * baud)
|
|
||||||
*
|
|
||||||
* Where fCK is the input clock to the peripheral (PCLK1 for USART2, 3, 4, 5
|
|
||||||
* or PCLK2 for USART1)
|
|
||||||
*
|
|
||||||
* First calculate (NOTE: all stand baud values are even so dividing by two
|
|
||||||
* does not lose precision):
|
|
||||||
*
|
|
||||||
* usartdiv32 = 32 * usartdiv = fCK / (baud/2)
|
|
||||||
*/
|
|
||||||
|
|
||||||
usartdiv32 = priv->apbclock / (priv->baud >> 1);
|
up_setspeed(dev);
|
||||||
|
|
||||||
/* The mantissa part is then */
|
|
||||||
|
|
||||||
mantissa = usartdiv32 >> 5;
|
|
||||||
brr = mantissa << USART_BRR_MANT_SHIFT;
|
|
||||||
|
|
||||||
/* The fractional remainder (with rounding) */
|
|
||||||
|
|
||||||
fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1;
|
|
||||||
brr |= fraction << USART_BRR_FRAC_SHIFT;
|
|
||||||
up_serialout(priv, STM32_USART_BRR_OFFSET, brr);
|
|
||||||
|
|
||||||
/* Enable Rx, Tx, and the USART */
|
/* Enable Rx, Tx, and the USART */
|
||||||
|
|
||||||
@ -1182,26 +1218,75 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||||||
{
|
{
|
||||||
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;
|
||||||
#ifdef CONFIG_USART_BREAKS
|
|
||||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||||
#endif
|
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case TIOCSERGSTRUCT:
|
case TIOCSERGSTRUCT:
|
||||||
{
|
{
|
||||||
struct up_dev_s *user = (struct up_dev_s*)arg;
|
struct up_dev_s *user = (struct up_dev_s*)arg;
|
||||||
if (!user)
|
if (!user)
|
||||||
{
|
{
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(user, dev, sizeof(struct up_dev_s));
|
memcpy(user, dev, sizeof(struct up_dev_s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TERMIOS
|
||||||
|
case TCGETS:
|
||||||
|
{
|
||||||
|
struct termios *termiosp = (struct termios*)arg;
|
||||||
|
|
||||||
|
if (!termiosp)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: (1) Note that only the BOTHER baud is returned; (2) Other
|
||||||
|
* termios fields are not yet initialized. Here we also exploit the
|
||||||
|
* internal knowledge that ctfsetospeed() is equivalent to
|
||||||
|
* cfsetispeed().
|
||||||
|
*/
|
||||||
|
|
||||||
|
cfsetispeed(termiosp, BOTHER);
|
||||||
|
termiosp->c_ispeed = priv->baud;
|
||||||
|
termiosp->c_ospeed = priv->baud;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TCSETS:
|
||||||
|
{
|
||||||
|
struct termios *termiosp = (struct termios*)arg;
|
||||||
|
|
||||||
|
if (!termiosp)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Only the BOTHER speed setting is supported. Here we
|
||||||
|
* also exploit the internal knowledge that ctfgetospeed() is
|
||||||
|
* equivalent to cfgetispeed().
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (cfgetospeed(termiosp) != BOTHER ||
|
||||||
|
termiosp->c_ispeed != termiosp->c_ospeed)
|
||||||
|
{
|
||||||
|
ret = -ENOSYS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->baud = termiosp->c_ispeed;
|
||||||
|
up_setspeed(dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_USART_BREAKS
|
#ifdef CONFIG_USART_BREAKS
|
||||||
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
|
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
|
||||||
|
@ -1188,6 +1188,15 @@ config UART6_2STOP
|
|||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
config SERIAL_TERMIOS
|
||||||
|
bool "Serial driver TERMIOS supported"
|
||||||
|
depends on PIC32MX_UART1 || PIC32MX_UART2 || PIC32MX_UART3 || PIC32MX_UART4 || PIC32MX_UART5 || PIC32MX_UART6
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.).
|
||||||
|
If this is not defined, then the terminal settings (baud, parity, etc).
|
||||||
|
are not configurable at runtime; serial streams cannot be flushed, etc..
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "PIC32MX PHY Selection"
|
prompt "PIC32MX PHY Selection"
|
||||||
depends on PIC32MX_ETHERNET
|
depends on PIC32MX_ETHERNET
|
||||||
|
Loading…
x
Reference in New Issue
Block a user