Skip to content

Commit

Permalink
Author: Gregory Nutt <[email protected]>
Browse files Browse the repository at this point in the history
    Run all .c and .h files in last PR through tools/nxstyle and fix all complaints.

Author: macman88 <[email protected]>

    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
  • Loading branch information
jjlange authored and gregory-nutt committed Jan 2, 2020
1 parent f9f8c6a commit 0ee8241
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 51 deletions.
30 changes: 30 additions & 0 deletions arch/arm/src/lpc17xx_40xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
44 changes: 26 additions & 18 deletions arch/arm/src/lpc17xx_40xx/lpc17_40_lowputc.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -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
Expand All @@ -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:
*
Expand All @@ -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:
*
Expand All @@ -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:
*
Expand All @@ -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:
*
Expand All @@ -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 */

Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -396,22 +398,28 @@ 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
*/

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 */

Expand Down
Loading

0 comments on commit 0ee8241

Please sign in to comment.