Author: Gregory Nutt <gnutt@nuttx.org>
Run all .c and .h files in last PR through tools/nxstyle and fix all complaints. Author: macman88 <jjlange91@gmail.com> LPC17xx serial updates (#29) * Save CONFIG_ARCH_BOARD_CUSTOM when running 'make savedefconfig' * Don't compile up_earlyserialinit if USE_EARLYSERIALINIT is not defined * Added support for RS485 direction control on LPC17xx UART1 * First pass at fractional baud rate divider on LPC17xx/40xx * Added support for fractional divider to console UART
This commit is contained in:
parent
f9f8c6a79b
commit
0ee8241606
@ -561,6 +561,36 @@ config LPC17_40_UART1_RINGINDICATOR
|
||||
---help---
|
||||
Enable UART1 ring indicator
|
||||
|
||||
config LPC17_40_UART1_RS485
|
||||
bool "RS-485 on UART1"
|
||||
default n
|
||||
depends on LPC17_40_UART1
|
||||
---help---
|
||||
Enable RS-485 interface on UART1. Your board config will have to
|
||||
provide GPIO_UART1_RS485_DIR pin definition.
|
||||
|
||||
config LPC17_40_RS485_DIR_POLARITY
|
||||
int "UART1 RS-485 DIR pin polarity"
|
||||
default 1
|
||||
range 0 1
|
||||
depends on LPC17_40_UART1_RS485
|
||||
---help---
|
||||
Polarity of DIR pin for RS-485 on UART1. Set to state on DIR pin which
|
||||
enables TX (0 - low / nTXEN, 1 - high / TXEN).
|
||||
|
||||
config LPC17_40_UART1_RS485_DIR_DTR
|
||||
bool "UART1 RS-485 DIR pin use DTR"
|
||||
default n
|
||||
depends on LPC17_40_UART1_RS485
|
||||
---help---
|
||||
Selects between RTS and DTR pins for RS485 DIR. This must correspond to
|
||||
the GPIO_USART1_RS485_DIR pin specified in your board config. The DTR pin
|
||||
will be used if selected, the RTS pin will be used otherwise.
|
||||
|
||||
config LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
bool "Use fractional divider for UART baud rate"
|
||||
default n
|
||||
|
||||
endmenu
|
||||
|
||||
menu "ADC driver options"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc17xx_40xx/lpc17_40_lowputc.c
|
||||
*
|
||||
* Copyright (C) 2010-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2010-2013, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -154,9 +154,6 @@
|
||||
* And for the LPC178x/40xx, the PCLK is determined by the global divisor setting in
|
||||
* the PLKSEL register.
|
||||
*
|
||||
* Ignoring the fractional divider for now. (If you want to extend this driver
|
||||
* to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses
|
||||
* the same peripheral and that logic could easily leveraged here).
|
||||
*/
|
||||
|
||||
#ifdef LPC178x_40xx
|
||||
@ -165,6 +162,10 @@
|
||||
# define CONSOLE_NUMERATOR BOARD_PCLK_FREQUENCY
|
||||
|
||||
#else
|
||||
# ifdef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK)
|
||||
# else
|
||||
/* Calculate and optimal PCLKSEL0/1 divisor.
|
||||
* First, check divisor == 1. This works if the upper limit is met:
|
||||
*
|
||||
@ -181,9 +182,9 @@
|
||||
* BAUD <= CCLK / 16 / MinDL
|
||||
*/
|
||||
|
||||
# if CONSOLE_BAUD < (LPC17_40_CCLK / 16 / UART_MINDL)
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK)
|
||||
# if CONSOLE_BAUD < (LPC17_40_CCLK / 16 / UART_MINDL)
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK)
|
||||
|
||||
/* Check divisor == 2. This works if:
|
||||
*
|
||||
@ -196,9 +197,9 @@
|
||||
* BAUD <= CCLK / 8 / MinDL
|
||||
*/
|
||||
|
||||
# elif CONSOLE_BAUD < (LPC17_40_CCLK / 8 / UART_MINDL)
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK2
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK / 2)
|
||||
# elif CONSOLE_BAUD < (LPC17_40_CCLK / 8 / UART_MINDL)
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK2
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK / 2)
|
||||
|
||||
/* Check divisor == 4. This works if:
|
||||
*
|
||||
@ -211,9 +212,9 @@
|
||||
* BAUD <= CCLK / 4 / MinDL
|
||||
*/
|
||||
|
||||
# elif CONSOLE_BAUD < (LPC17_40_CCLK / 4 / UART_MINDL)
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK4
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK / 4)
|
||||
# elif CONSOLE_BAUD < (LPC17_40_CCLK / 4 / UART_MINDL)
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK4
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK / 4)
|
||||
|
||||
/* Check divisor == 8. This works if:
|
||||
*
|
||||
@ -226,9 +227,10 @@
|
||||
* BAUD <= CCLK / 2 / MinDL
|
||||
*/
|
||||
|
||||
# else /* if CONSOLE_BAUD < (LPC17_40_CCLK / 2 / UART_MINDL) */
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK8
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK / 8)
|
||||
# else /* if CONSOLE_BAUD < (LPC17_40_CCLK / 2 / UART_MINDL) */
|
||||
# define CONSOLE_CCLKDIV SYSCON_PCLKSEL_CCLK8
|
||||
# define CONSOLE_NUMERATOR (LPC17_40_CCLK / 8)
|
||||
# endif
|
||||
# endif
|
||||
#endif /* LPC178x_40xx */
|
||||
|
||||
@ -273,11 +275,11 @@ void up_lowputc(char ch)
|
||||
#if defined HAVE_UART && defined HAVE_CONSOLE
|
||||
/* Wait for the transmitter to be available */
|
||||
|
||||
while ((getreg32(CONSOLE_BASE+LPC17_40_UART_LSR_OFFSET) & UART_LSR_THRE) == 0);
|
||||
while ((getreg32(CONSOLE_BASE + LPC17_40_UART_LSR_OFFSET) & UART_LSR_THRE) == 0);
|
||||
|
||||
/* Send the character */
|
||||
|
||||
putreg32((uint32_t)ch, CONSOLE_BASE+LPC17_40_UART_THR_OFFSET);
|
||||
putreg32((uint32_t)ch, CONSOLE_BASE + LPC17_40_UART_THR_OFFSET);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -396,6 +398,7 @@ void lpc17_40_lowsetup(void)
|
||||
putreg32(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8,
|
||||
CONSOLE_BASE + LPC17_40_UART_FCR_OFFSET);
|
||||
|
||||
#ifndef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
/* Disable FDR (fractional divider),
|
||||
* ignored by baudrate calculation => has to be disabled
|
||||
*/
|
||||
@ -403,15 +406,20 @@ void lpc17_40_lowsetup(void)
|
||||
putreg32((1 << UART_FDR_MULVAL_SHIFT) + (0 << UART_FDR_DIVADDVAL_SHIFT),
|
||||
CONSOLE_BASE + LPC17_40_UART_FDR_OFFSET);
|
||||
|
||||
#endif
|
||||
/* Set up the LCR and set DLAB=1 */
|
||||
|
||||
putreg32(CONSOLE_LCR_VALUE | UART_LCR_DLAB,
|
||||
CONSOLE_BASE + LPC17_40_UART_LCR_OFFSET);
|
||||
|
||||
#ifdef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
up_setbaud(CONSOLE_BASE, CONSOLE_NUMERATOR, CONSOLE_BAUD);
|
||||
#else
|
||||
/* Set the BAUD divisor */
|
||||
|
||||
putreg32(CONSOLE_DL >> 8, CONSOLE_BASE + LPC17_40_UART_DLM_OFFSET);
|
||||
putreg32(CONSOLE_DL & 0xff, CONSOLE_BASE + LPC17_40_UART_DLL_OFFSET);
|
||||
#endif
|
||||
|
||||
/* Clear DLAB */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc17xx_40xx/lpc17_40_serial.c
|
||||
*
|
||||
* Copyright (C) 2010-2013, 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2010-2013, 2017-2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -547,20 +547,156 @@ static inline void up_enablebreaks(struct up_dev_s *priv, bool enable)
|
||||
up_serialout(priv, LPC17_40_UART_LCR_OFFSET, lcr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
/****************************************************************************
|
||||
* Name: lpc17_40_setbaud
|
||||
*
|
||||
* Description:
|
||||
* Configure the UART divisors to accomplish the desired BAUD given the
|
||||
* UART base frequency.
|
||||
*
|
||||
* This computationally intensive algorithm is based on the same logic
|
||||
* used in the NXP sample code.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud)
|
||||
{
|
||||
uint32_t lcr; /* Line control register value */
|
||||
uint32_t dl; /* Best DLM/DLL full value */
|
||||
uint32_t mul; /* Best FDR MULVALL value */
|
||||
uint32_t divadd; /* Best FDR DIVADDVAL value */
|
||||
uint32_t best; /* Error value associated with best {dl, mul, divadd} */
|
||||
uint32_t cdl; /* Candidate DLM/DLL full value */
|
||||
uint32_t cmul; /* Candidate FDR MULVALL value */
|
||||
uint32_t cdivadd; /* Candidate FDR DIVADDVAL value */
|
||||
uint32_t errval; /* Error value associated with the candidate */
|
||||
|
||||
/* The UART buad is given by:
|
||||
*
|
||||
* Fbaud = Fbase * mul / (mul + divadd) / (16 * dl)
|
||||
* dl = Fbase * mul / (mul + divadd) / Fbaud / 16
|
||||
* = Fbase * mul / ((mul + divadd) * Fbaud * 16)
|
||||
* = ((Fbase * mul) >> 4) / ((mul + divadd) * Fbaud)
|
||||
*
|
||||
* Where the value of MULVAL and DIVADDVAL comply with:
|
||||
*
|
||||
* 0 < mul < 16
|
||||
* 0 <= divadd < mul
|
||||
*/
|
||||
|
||||
best = UINT32_MAX;
|
||||
divadd = 0;
|
||||
mul = 0;
|
||||
dl = 0;
|
||||
|
||||
/* Try each multiplier value in the valid range */
|
||||
|
||||
for (cmul = 1 ; cmul < 16; cmul++)
|
||||
{
|
||||
/* Try each divider value in the valid range */
|
||||
|
||||
for (cdivadd = 0 ; cdivadd < cmul ; cdivadd++)
|
||||
{
|
||||
/* Candidate:
|
||||
* dl = ((Fbase * mul) >> 4) / ((mul + cdivadd) * Fbaud)
|
||||
* (dl << 32) = (Fbase << 28) * cmul / ((mul + cdivadd) * Fbaud)
|
||||
*/
|
||||
|
||||
uint64_t dl64 = ((uint64_t)basefreq << 28) * cmul /
|
||||
((cmul + cdivadd) * baud);
|
||||
|
||||
/* The lower 32-bits of this value is the error */
|
||||
|
||||
errval = (uint32_t)(dl64 & 0x00000000ffffffffull);
|
||||
|
||||
/* The upper 32-bits is the candidate DL value */
|
||||
|
||||
cdl = (uint32_t)(dl64 >> 32);
|
||||
|
||||
/* Round up */
|
||||
|
||||
if (errval > (1 << 31))
|
||||
{
|
||||
errval = -errval;
|
||||
cdl++;
|
||||
}
|
||||
|
||||
/* Check if the resulting candidate DL value is within range */
|
||||
|
||||
if (cdl < 1 || cdl > 65536)
|
||||
{
|
||||
/* No... try a different divadd value */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is this the best combination that we have seen so far? */
|
||||
|
||||
if (errval < best)
|
||||
{
|
||||
/* Yes.. then the candidate is out best guess so far */
|
||||
|
||||
best = errval;
|
||||
dl = cdl;
|
||||
divadd = cdivadd;
|
||||
mul = cmul;
|
||||
|
||||
/* If the new best guess is exact (within our precision), then
|
||||
* we are finished.
|
||||
*/
|
||||
|
||||
if (best == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGASSERT(dl > 0);
|
||||
|
||||
/* Enter DLAB=1 */
|
||||
|
||||
lcr = getreg32(uartbase + LPC17_40_UART_LCR_OFFSET);
|
||||
putreg32(lcr | UART_LCR_DLAB, uartbase + LPC17_40_UART_LCR_OFFSET);
|
||||
|
||||
/* Save the divider values */
|
||||
|
||||
putreg32(dl >> 8, uartbase + LPC17_40_UART_DLM_OFFSET);
|
||||
putreg32(dl & 0xff, uartbase + LPC17_40_UART_DLL_OFFSET);
|
||||
|
||||
/* Clear DLAB */
|
||||
|
||||
putreg32(lcr & ~UART_LCR_DLAB, uartbase + LPC17_40_UART_LCR_OFFSET);
|
||||
|
||||
/* Then save the fractional divider values */
|
||||
|
||||
putreg32((mul << UART_FDR_MULVAL_SHIFT) | (divadd << UART_FDR_DIVADDVAL_SHIFT),
|
||||
uartbase + LPC17_40_UART_FDR_OFFSET);
|
||||
}
|
||||
# ifdef LPC176x
|
||||
static inline uint32_t lpc17_40_uartcclkdiv(uint32_t baud)
|
||||
{
|
||||
/* If we're using the fractional divider, assume that the full PCLK speed
|
||||
* will be acceptable.
|
||||
*/
|
||||
|
||||
return SYSCON_PCLKSEL_CCLK;
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
/************************************************************************************
|
||||
* Name: lpc17_40_uartcclkdiv
|
||||
*
|
||||
* Description:
|
||||
* Select a CCLK divider to produce the UART PCLK. The stratey is to select the
|
||||
* Select a CCLK divider to produce the UART PCLK. The strategy is to select the
|
||||
* smallest divisor that results in an solution within range of the 16-bit
|
||||
* DLM and DLL divisor:
|
||||
*
|
||||
* PCLK = CCLK / divisor
|
||||
* BAUD = PCLK / (16 * DL)
|
||||
*
|
||||
* Ignoring the fractional divider for now. (If you want to extend this driver
|
||||
* to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses
|
||||
* the same peripheral and that logic could easily leveraged here).
|
||||
*
|
||||
* For the LPC176x the PCLK is determined by the UART-specific divisor in
|
||||
* PCLKSEL0 or PCLKSEL1:
|
||||
@ -576,7 +712,7 @@ static inline void up_enablebreaks(struct up_dev_s *priv, bool enable)
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef LPC176x
|
||||
# ifdef LPC176x
|
||||
static inline uint32_t lpc17_40_uartcclkdiv(uint32_t baud)
|
||||
{
|
||||
/* Ignoring the fractional divider, the BAUD is given by:
|
||||
@ -662,8 +798,8 @@ static inline uint32_t lpc17_40_uartcclkdiv(uint32_t baud)
|
||||
return SYSCON_PCLKSEL_CCLK8;
|
||||
}
|
||||
}
|
||||
#endif /* LPC176x */
|
||||
|
||||
# endif /* LPC176x */
|
||||
#endif /* CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER */
|
||||
/************************************************************************************
|
||||
* Name: lpc17_40_uart0config, uart1config, uart2config, and uart3config
|
||||
*
|
||||
@ -734,7 +870,21 @@ static inline void lpc17_40_uart1config(void)
|
||||
putreg32(regval, LPC17_40_SYSCON_PCLKSEL0);
|
||||
#endif
|
||||
|
||||
/* Step 3: Configure I/O pins */
|
||||
/* Step 3: Configure RS-485 control register */
|
||||
|
||||
#ifdef CONFIG_LPC17_40_UART1_RS485
|
||||
regval = getreg32(LPC17_40_UART1_RS485CTRL);
|
||||
regval |= UART_RS485CTRL_DCTRL;
|
||||
#if (CONFIG_LPC17_40_RS485_DIR_POLARITY == 1)
|
||||
regval |= UART_RS485CTRL_OINV;
|
||||
#endif
|
||||
#ifdef CONFIG_LPC17_40_UART1_RS485_DIR_DTR
|
||||
regval |= UART_RS485CTRL_SEL;
|
||||
#endif
|
||||
putreg32(regval, LPC17_40_UART1_RS485CTRL);
|
||||
#endif
|
||||
|
||||
/* Step 4: Configure I/O pins */
|
||||
|
||||
lpc17_40_configgpio(GPIO_UART1_TXD);
|
||||
lpc17_40_configgpio(GPIO_UART1_RXD);
|
||||
@ -748,6 +898,11 @@ static inline void lpc17_40_uart1config(void)
|
||||
lpc17_40_configgpio(GPIO_UART1_RI);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LPC17_40_UART1_RS485
|
||||
lpc17_40_configgpio(GPIO_UART1_RS485_DIR);
|
||||
#endif
|
||||
|
||||
leave_critical_section(flags);
|
||||
};
|
||||
#endif
|
||||
@ -821,13 +976,10 @@ static inline void lpc17_40_uart3config(void)
|
||||
* BAUD = PCLK / (16 * DL), or
|
||||
* DL = PCLK / BAUD / 16
|
||||
*
|
||||
* Ignoring the fractional divider for now. (If you want to extend this driver
|
||||
* to support the fractional divider, see lpc43xx_uart.c. The LPC43xx uses
|
||||
* the same peripheral and that logic could easily leveraged here).
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef LPC176x
|
||||
#ifndef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
# ifdef LPC176x
|
||||
static inline uint32_t lpc17_40_uartdl(uint32_t baud, uint8_t divcode)
|
||||
{
|
||||
uint32_t num;
|
||||
@ -859,6 +1011,7 @@ static inline uint32_t lpc17_40_uartdl(uint32_t baud)
|
||||
{
|
||||
return (uint32_t)BOARD_PCLK_FREQUENCY / (baud << 4);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -878,16 +1031,20 @@ static int up_setup(struct uart_dev_s *dev)
|
||||
{
|
||||
#ifndef CONFIG_SUPPRESS_UART_CONFIG
|
||||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
# ifndef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
uint16_t dl;
|
||||
# endif
|
||||
uint32_t lcr;
|
||||
|
||||
/* Clear fifos */
|
||||
|
||||
up_serialout(priv, LPC17_40_UART_FCR_OFFSET, (UART_FCR_RXRST | UART_FCR_TXRST));
|
||||
up_serialout(priv, LPC17_40_UART_FCR_OFFSET,
|
||||
(UART_FCR_RXRST | UART_FCR_TXRST));
|
||||
|
||||
/* Set trigger */
|
||||
|
||||
up_serialout(priv, LPC17_40_UART_FCR_OFFSET, (UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8));
|
||||
up_serialout(priv, LPC17_40_UART_FCR_OFFSET,
|
||||
(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8));
|
||||
|
||||
/* Set up the IER */
|
||||
|
||||
@ -920,12 +1077,14 @@ static int up_setup(struct uart_dev_s *dev)
|
||||
lcr |= (UART_LCR_PE | UART_LCR_PS_EVEN);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
/* Disable FDR (fractional divider),
|
||||
* ignored by baudrate calculation => has to be disabled
|
||||
*/
|
||||
|
||||
up_serialout(priv, LPC17_40_UART_FDR_OFFSET,
|
||||
(1 << UART_FDR_MULVAL_SHIFT) + (0 << UART_FDR_DIVADDVAL_SHIFT));
|
||||
#endif
|
||||
|
||||
/* Enter DLAB=1 */
|
||||
|
||||
@ -933,13 +1092,17 @@ static int up_setup(struct uart_dev_s *dev)
|
||||
|
||||
/* Set the BAUD divisor */
|
||||
|
||||
#ifdef LPC176x
|
||||
dl = lpc17_40_uartdl(priv->baud, priv->cclkdiv);
|
||||
#ifdef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
up_setbaud(priv->uartbase, LPC17_40_CCLK / priv->cclkdiv, priv->baud);
|
||||
#else
|
||||
# ifdef LPC176x
|
||||
dl = lpc17_40_uartdl(priv->baud, priv->cclkdiv);
|
||||
# else
|
||||
dl = lpc17_40_uartdl(priv->baud);
|
||||
#endif
|
||||
# endif
|
||||
up_serialout(priv, LPC17_40_UART_DLM_OFFSET, dl >> 8);
|
||||
up_serialout(priv, LPC17_40_UART_DLL_OFFSET, dl & 0xff);
|
||||
#endif
|
||||
|
||||
/* Clear DLAB */
|
||||
|
||||
@ -1135,7 +1298,8 @@ static int up_interrupt(int irq, void *context, void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1212,8 +1376,10 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
case TCSETS:
|
||||
{
|
||||
struct termios *termiosp = (struct termios *)arg;
|
||||
# ifndef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
uint32_t lcr; /* Holds current values of line control register */
|
||||
uint16_t dl; /* Divisor latch */
|
||||
# endif
|
||||
|
||||
if (!termiosp)
|
||||
{
|
||||
@ -1234,10 +1400,14 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
* and reset the divider in the CLKSEL0/1 register.
|
||||
*/
|
||||
|
||||
#if 0 /* ifdef LPC176x */
|
||||
# ifdef CONFIG_LPC17_40_UART_USE_FRACTIONAL_DIVIDER
|
||||
up_setbaud(priv->uartbase, LPC17_40_CCLK / priv->cclkdiv, priv->baud);
|
||||
# else
|
||||
# if 0 /* ifdef LPC176x */
|
||||
priv->cclkdiv = lpc17_40_uartcclkdiv(priv->baud);
|
||||
#endif
|
||||
# endif
|
||||
/* DLAB open latch */
|
||||
|
||||
/* REVISIT: Shouldn't we just call up_setup() to do all of the following? */
|
||||
|
||||
lcr = getreg32(priv->uartbase + LPC17_40_UART_LCR_OFFSET);
|
||||
@ -1245,17 +1415,18 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
/* Set the BAUD divisor */
|
||||
|
||||
#ifdef LPC176x
|
||||
# ifdef LPC176x
|
||||
dl = lpc17_40_uartdl(priv->baud, priv->cclkdiv);
|
||||
#else
|
||||
# else
|
||||
dl = lpc17_40_uartdl(priv->baud);
|
||||
#endif
|
||||
# endif
|
||||
up_serialout(priv, LPC17_40_UART_DLM_OFFSET, dl >> 8);
|
||||
up_serialout(priv, LPC17_40_UART_DLL_OFFSET, dl & 0xff);
|
||||
|
||||
/* Clear DLAB */
|
||||
|
||||
up_serialout(priv, LPC17_40_UART_LCR_OFFSET, lcr);
|
||||
# endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -1422,6 +1593,7 @@ static bool up_txempty(struct uart_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef USE_EARLYSERIALINIT
|
||||
void up_earlyserialinit(void)
|
||||
{
|
||||
/* Configure all UARTs (except the CONSOLE UART) and disable interrupts */
|
||||
@ -1475,6 +1647,8 @@ void up_earlyserialinit(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_serialinit
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/lpc17xx_40xx/lpc17_40_serial.h
|
||||
*
|
||||
* Copyright (C) 2010, 2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2010, 2013, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -130,4 +130,6 @@
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
void up_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud);
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_LPC17XX_40XX_LPC17_40_SERIAL_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc43xx/lpc43_uart.c
|
||||
*
|
||||
* Copyright (C) 2012, 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012, 2017, 2019 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -159,11 +159,11 @@ void up_lowputc(char ch)
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
/* Wait for the transmitter to be available */
|
||||
|
||||
while ((getreg32(CONSOLE_BASE+LPC43_UART_LSR_OFFSET) & UART_LSR_THRE) == 0);
|
||||
while ((getreg32(CONSOLE_BASE + LPC43_UART_LSR_OFFSET) & UART_LSR_THRE) == 0);
|
||||
|
||||
/* Send the character */
|
||||
|
||||
putreg32((uint32_t)ch, CONSOLE_BASE+LPC43_UART_THR_OFFSET);
|
||||
putreg32((uint32_t)ch, CONSOLE_BASE + LPC43_UART_THR_OFFSET);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -175,7 +175,9 @@ void up_lowputc(char ch)
|
||||
* console. Its purpose is to get the console output available as soon
|
||||
* as possible.
|
||||
*
|
||||
* The USART0/2/3 and UART1 peripherals are configured using the following registers:
|
||||
* The USART0/2/3 and UART1 peripherals are configured using the following
|
||||
* registers:
|
||||
*
|
||||
* 1. Baud rate: In the LCR register, set bit DLAB = 1. This enables access
|
||||
* to registers DLL and DLM for setting the baud rate. Also, if needed,
|
||||
* set the fractional baud rate in the fractional divider
|
||||
@ -457,7 +459,6 @@ void lpc43_usart2_setup(void)
|
||||
regval |= CCU_CLK_CFG_RUN;
|
||||
putreg32(regval, LPC43_CCU2_APB2_USART2_CFG);
|
||||
|
||||
|
||||
/* Configure I/O pins. NOTE that multiple pin configuration options must
|
||||
* be disambiguated by defining the pin configuration in the board.h
|
||||
* header file.
|
||||
@ -619,7 +620,7 @@ void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud)
|
||||
mul = 0;
|
||||
dl = 0;
|
||||
|
||||
/* Try each mulitplier value in the valid range */
|
||||
/* Try each multiplier value in the valid range */
|
||||
|
||||
for (cmul = 1 ; cmul < 16; cmul++)
|
||||
{
|
||||
@ -690,7 +691,7 @@ void lpc43_setbaud(uintptr_t uartbase, uint32_t basefreq, uint32_t baud)
|
||||
lcr = getreg32(uartbase + LPC43_UART_LCR_OFFSET);
|
||||
putreg32(lcr | UART_LCR_DLAB, uartbase + LPC43_UART_LCR_OFFSET);
|
||||
|
||||
/* Save then divider values */
|
||||
/* Save the divider values */
|
||||
|
||||
putreg32(dl >> 8, uartbase + LPC43_UART_DLM_OFFSET);
|
||||
putreg32(dl & 0xff, uartbase + LPC43_UART_DLL_OFFSET);
|
||||
|
Loading…
Reference in New Issue
Block a user