diff --git a/arch/arm/src/lpc17xx/lpc17_lowputc.c b/arch/arm/src/lpc17xx/lpc17_lowputc.c index 64966c7ebb3..de72ac93e76 100755 --- a/arch/arm/src/lpc17xx/lpc17_lowputc.c +++ b/arch/arm/src/lpc17xx/lpc17_lowputc.c @@ -55,27 +55,103 @@ * Private Definitions **************************************************************************/ +/* Select UART parameters for the selected console */ + +#if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART0_BASE +# define CONSOLE_BAUD CONFIG_UART0_BAUD +# define CONSOLE_BITS CONFIG_UART0_BITS +# define CONSOLE_PARITY CONFIG_UART0_PARITY +# define CONSOLE_2STOP CONFIG_UART0_2STOP +#elif defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART1_BASE +# define CONSOLE_BAUD CONFIG_UART1_BAUD +# define CONSOLE_BITS CONFIG_UART1_BITS +# define CONSOLE_PARITY CONFIG_UART1_PARITY +# define CONSOLE_2STOP CONFIG_UART1_2STOP +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART2_BASE +# define CONSOLE_BAUD CONFIG_UART2_BAUD +# define CONSOLE_BITS CONFIG_UART2_BITS +# define CONSOLE_PARITY CONFIG_UART2_PARITY +# define CONSOLE_2STOP CONFIG_UART2_2STOP +#elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define CONSOLE_BASE LPC17_UART3_BASE +# define CONSOLE_BAUD CONFIG_UART3_BAUD +# define CONSOLE_BITS CONFIG_UART3_BITS +# define CONSOLE_PARITY CONFIG_UART3_PARITY +# define CONSOLE_2STOP CONFIG_UART3_2STOP +#else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +#endif + +/* Get word length setting for the console */ + +#if CONSOLE_BITS == 5 +# define CONSOLE_LCR_WLS UART_LCR_WLS_5BIT +#elif CONSOLE_BITS == 6 +# define CONSOLE_LCR_WLS UART_LCR_WLS_6BIT +#elif CONSOLE_BITS == 7 +# define CONSOLE_LCR_WLS UART_LCR_WLS_7BIT +#elif CONSOLE_BITS == 8 +# define CONSOLE_LCR_WLS UART_LCR_WLS_8BIT +#else +# error "Invalid CONFIG_UARTn_BITS setting for console " +#endif + +/* Get parity setting for the console */ + +#if CONSOLE_PARITY == 0 +# define CONSOLE_LCR_PAR 0 +#elif CONSOLE_PARITY == 1 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) +#elif CONSOLE_PARITY == 2 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) +#elif CONSOLE_PARITY == 3 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) +#elif CONSOLE_PARITY == 4 +# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) +#else +# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" +#endif + +/* Get stop-bit setting for the console and UART0-3 */ + +#if CONSOLE_2STOP != 0 +# define CONSOLE_LCR_STOP LPC214X_LCR_STOP_2 +#else +# define CONSOLE_LCR_STOP LPC214X_LCR_STOP_1 +#endif + +/* LCR and FCR values for the console */ + +#define CONSOLE_LCR_VALUE (CONSOLE_LCR_WLS | CONSOLE_LCR_PAR | CONSOLE_LCR_STOP) +#define CONSOLE_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ + UART_FCR_RXRST | UART_FCR_FIFOEN) + /* Baud calculations - -BAUD = PCLK / (16 x (256 x DLM + DLL) x (1 + DIVADDVAL/MULVAL)) - -Where PCLK is the peripheral clock, DLM and DLL are the standard -UART baud rate divider registers, and DIVADDVAL and MULVAL are UART -fractional baud rate generator specific parameters. - -The value of MULVAL and DIVADDVAL should comply to the following conditions: - -1. 1 <= MULVAL <= 15 -2. 0 <= DIVADDVAL <= 14 -3. DIVADDVAL < MULVAL - -The peripheral clock is controlled by: - -#define SYSCON_PCLKSET_CCLK4 PCLK_peripheral = CCLK/4 -#define SYSCON_PCLKSET_CCLK PCLK_peripheral = CCLK -#define SYSCON_PCLKSET_CCLK2 PCLK_peripheral = CCLK/2 -#define SYSCON_PCLKSET_CCLK6 PCLK_peripheral = CCLK/8 (except CAN1, CAN2, and CAN) -#define SYSCON_PCLKSET_CCLK8 PCLK_peripheral = CCLK/6 (CAN1, CAN2, and CAN) + * + * BAUD = PCLK / ((16 x DL) x (1 + DIVADDVAL/MULVAL)) + * + * Where: + * + * - PCLK is the peripheral clock + * - DL is (256*DML + DLL), the standard UART baud rate divider registers, and + * - DIVADDVAL and MULVAL are UART fractional baud rate generator specific + * parameters. + * + * The value of MULVAL and DIVADDVAL should comply to the following conditions: + * + * 1. 1 <= MULVAL <= 15 + * 2. 0 <= DIVADDVAL <= 14 + * 3. DIVADDVAL < MULVAL + * + * The peripheral clock is controlled by: + * + * SYSCON_PCLKSEL_CCLK4: PCLK_peripheral = CCLK/4 + * SYSCON_PCLKSEL_CCLK: PCLK_peripheral = CCLK + * SYSCON_PCLKSEL_CCLK2: PCLK_peripheral = CCLK/2 + * SYSCON_PCLKSEL_CCLK8: PCLK_peripheral = CCLK/8 */ /************************************************************************** @@ -112,6 +188,7 @@ The peripheral clock is controlled by: void up_lowputc(char ch) { +#ifdef HAVE_UART /* Wait for the transmitter to be available */ while ((getreg32(CONSOLE_BASE+LPC17_UART_LSR_OFFSET) & UART_LSR_THRE) == 0); @@ -119,6 +196,7 @@ void up_lowputc(char ch) /* Send the character */ putreg32((uint32_t)ch, CONSOLE_BASE+LPC17_UART_THR_OFFSET); +#endif } /************************************************************************** @@ -153,6 +231,8 @@ void up_lowputc(char ch) void lpc17_lowsetup(void) { +#ifdef HAVE_UART + #if 0 uint32_t regval; @@ -288,6 +368,7 @@ void lpc17_lowsetup(void) CONSOLE_BASE+LPC17_UART_CR_OFFSET); #endif #endif /* 0 */ +#endif /* HAVE_UART */ } diff --git a/arch/arm/src/lpc17xx/lpc17_serial.c b/arch/arm/src/lpc17xx/lpc17_serial.c index 5a39e9f74e8..8df4d52497b 100755 --- a/arch/arm/src/lpc17xx/lpc17_serial.c +++ b/arch/arm/src/lpc17xx/lpc17_serial.c @@ -68,7 +68,7 @@ * provide some minimal implementation of up_putc. */ -#ifdef CONFIG_USE_SERIALDRIVER +#if defined(CONFIG_USE_SERIALDRIVER) && defined(HAVE_UART) /* Configuration *********************************************************************/ @@ -84,6 +84,7 @@ struct up_dev_s uint8_t irq; /* IRQ associated with this UART */ uint8_t parity; /* 0=none, 1=odd, 2=even */ uint8_t bits; /* Number of bits (7 or 8) */ + uint8_t cclkdiv; /* Divisor needed to get PCLK from CCLK */ bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */ }; @@ -504,7 +505,7 @@ static int up_setup(struct uart_dev_s *dev) { #ifndef CONFIG_SUPPRESS_LPC17_UART_CONFIG struct up_dev_s *priv = (struct up_dev_s*)dev->priv; - uint16_t baud; + uint16_t dl; uint8_t lcr; /* Clear fifos */ @@ -552,9 +553,9 @@ static int up_setup(struct uart_dev_s *dev) /* Set the BAUD divisor */ - baud = UART_BAUD(priv->baud); - up_serialout(priv, LPC17_UART_DLM_OFFSET, baud >> 8); - up_serialout(priv, LPC17_UART_DLL_OFFSET, baud & 0xff); + dl = lpc17_uartdl(priv->baud, priv->cclkdiv); + up_serialout(priv, LPC17_UART_DLM_OFFSET, dl >> 8); + up_serialout(priv, LPC17_UART_DLL_OFFSET, dl & 0xff); /* Clear DLAB */ @@ -961,15 +962,19 @@ void up_earlyserialinit(void) /* Disable all UARTS */ #ifdef TTYS0_DEV + TTYS0_DEV.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART0_BAUD); up_disableuartint(TTYS0_DEV.priv, NULL); #endif #ifdef TTYS1_DEV + TTYS1_DEV.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART1_BAUD); up_disableuartint(TTYS1_DEV.priv, NULL); #endif #ifdef TTYS2_DEV + TTYS2_DEV.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART2_BAUD); up_disableuartint(TTYS2_DEV.priv, NULL); #endif #ifdef TTYS3_DEV + TTYS3_DEV.cclkdiv = lpc17_uartcclkdiv(CONFIG_UART3_BAUD); up_disableuartint(TTYS3_DEV.priv, NULL); #endif @@ -1050,6 +1055,7 @@ int up_putc(int ch) int up_putc(int ch) { +#ifdef HAVE_UART /* Check for LF */ if (ch == '\n') @@ -1060,6 +1066,7 @@ int up_putc(int ch) } up_lowputc(ch); +#endif return ch; } diff --git a/arch/arm/src/lpc17xx/lpc17_serial.h b/arch/arm/src/lpc17xx/lpc17_serial.h index 9f3355011b0..c2ecae2dc11 100755 --- a/arch/arm/src/lpc17xx/lpc17_serial.h +++ b/arch/arm/src/lpc17xx/lpc17_serial.h @@ -41,6 +41,10 @@ ************************************************************************************/ #include +#include + +#include "lpc17_uart.h" +#include "lpc17_syscon.h" /************************************************************************************ * Pre-processor Definitions @@ -48,7 +52,17 @@ /* Configuration *********************************************************************/ -/* Is there a serial console? It could be on any UARTn, n=0,1,2,3 */ +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_LPC17_UART0) || defined(CONFIG_LPC17_UART1) || \ + defined(CONFIG_LPC17_UART2) || defined(CONFIG_LPC17_UART3) +# define HAVE_UART1 +#endif + +/* Is there a serial console? There should be at most one defined. It could be on + * any UARTn, n=0,1,2,3 + */ #if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_LPC17_UART0) # undef CONFIG_UART1_SERIAL_CONSOLE @@ -78,239 +92,12 @@ # undef HAVE_CONSOLE #endif -/* Select UART parameters for the selected console */ +/* We cannot allow the DLM/DLL divisor to become to small or will will lose too + * much accuracy. This following is a "fudge factor" that represents the minimum + * value of the divisor that we will permit. + */ -#if defined(CONFIG_UART0_SERIAL_CONSOLE) -# define CONSOLE_BASE LPC17_UART0_BASE -# define CONSOLE_BAUD CONFIG_UART0_BAUD -# define CONSOLE_BITS CONFIG_UART0_BITS -# define CONSOLE_PARITY CONFIG_UART0_PARITY -# define CONSOLE_2STOP CONFIG_UART0_2STOP -#elif defined(CONFIG_UART1_SERIAL_CONSOLE) -# define CONSOLE_BASE LPC17_UART1_BASE -# define CONSOLE_BAUD CONFIG_UART1_BAUD -# define CONSOLE_BITS CONFIG_UART1_BITS -# define CONSOLE_PARITY CONFIG_UART1_PARITY -# define CONSOLE_2STOP CONFIG_UART1_2STOP -#elif defined(CONFIG_UART2_SERIAL_CONSOLE) -# define CONSOLE_BASE LPC17_UART2_BASE -# define CONSOLE_BAUD CONFIG_UART2_BAUD -# define CONSOLE_BITS CONFIG_UART2_BITS -# define CONSOLE_PARITY CONFIG_UART2_PARITY -# define CONSOLE_2STOP CONFIG_UART2_2STOP -#elif defined(CONFIG_UART3_SERIAL_CONSOLE) -# define CONSOLE_BASE LPC17_UART3_BASE -# define CONSOLE_BAUD CONFIG_UART3_BAUD -# define CONSOLE_BITS CONFIG_UART3_BITS -# define CONSOLE_PARITY CONFIG_UART3_PARITY -# define CONSOLE_2STOP CONFIG_UART3_2STOP -#else -# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" -#endif - -/* Get word length setting for the console UART and UART0-3 */ - -#if CONSOLE_BITS == 5 -# define CONSOLE_LCR_WLS UART_LCR_WLS_5BIT -#elif CONSOLE_BITS == 6 -# define CONSOLE_LCR_WLS UART_LCR_WLS_6BIT -#elif CONSOLE_BITS == 7 -# define CONSOLE_LCR_WLS UART_LCR_WLS_7BIT -#elif CONSOLE_BITS == 8 -# define CONSOLE_LCR_WLS UART_LCR_WLS_8BIT -#else -# error "Invalid CONFIG_UARTn_BITS setting for console " -#endif - -#ifdef CONFIG_LPC17_UART0 -# if CONFIG_UART0_BITS == 5 -# define UART0_LCR_WLS UART_LCR_WLS_5BIT -# elif CONFIG_UART0_BITS == 6 -# define UART0_LCR_WLS UART_LCR_WLS_6BIT -# elif CONFIG_UART0_BITS == 7 -# define UART0_LCR_WLS UART_LCR_WLS_7BIT -# elif CONFIG_UART0_BITS == 8 -# define UART0_LCR_WLS UART_LCR_WLS_8BIT -# else -# error "Invalid CONFIG_UARTn_BITS setting for UART0 " -# endif -#endif - -#ifdef CONFIG_LPC17_UART1 -# if CONFIG_UART1_BITS == 5 -# define UART1_LCR_WLS UART_LCR_WLS_5BIT -# elif CONFIG_UART1_BITS == 6 -# define UART1_LCR_WLS UART_LCR_WLS_6BIT -# elif CONFIG_UART1_BITS == 7 -# define UART1_LCR_WLS UART_LCR_WLS_7BIT -# elif CONFIG_UART1_BITS == 8 -# define UART1_LCR_WLS UART_LCR_WLS_8BIT -# else -# error "Invalid CONFIG_UARTn_BITS setting for UART1 " -# endif -#endif - -#ifdef CONFIG_LPC17_UART2 -# if CONFIG_UART2_BITS == 5 -# define UART2_LCR_WLS UART_LCR_WLS_5BIT -# elif CONFIG_UART2_BITS == 6 -# define UART2_LCR_WLS UART_LCR_WLS_6BIT -# elif CONFIG_UART2_BITS == 7 -# define UART2_LCR_WLS UART_LCR_WLS_7BIT -# elif CONFIG_UART2_BITS == 8 -# define UART2_LCR_WLS UART_LCR_WLS_8BIT -# else -# error "Invalid CONFIG_UARTn_BITS setting for UART2 " -# endif -#endif - -#ifdef CONFIG_LPC17_UART3 -# if CONFIG_UART3_BITS == 5 -# define UART3_LCR_WLS UART_LCR_WLS_5BIT -# elif CONFIG_UART3_BITS == 6 -# define UART3_LCR_WLS UART_LCR_WLS_6BIT -# elif CONFIG_UART3_BITS == 7 -# define UART3_LCR_WLS UART_LCR_WLS_7BIT -# elif CONFIG_UART3_BITS == 8 -# define UART3_LCR_WLS UART_LCR_WLS_8BIT -# else -# error "Invalid CONFIG_UARTn_BITS setting for UART3 " -# endif -#endif - -/* Get parity setting for the console UART and UART0-3 */ - -#if CONSOLE_PARITY == 0 -# define CONSOLE_LCR_PAR 0 -#elif CONSOLE_PARITY == 1 -# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) -#elif CONSOLE_PARITY == 2 -# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) -#elif CONSOLE_PARITY == 3 -# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) -#elif CONSOLE_PARITY == 4 -# define CONSOLE_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) -#else -# error "Invalid CONFIG_UARTn_PARITY setting for CONSOLE" -#endif - -#ifdef CONFIG_LPC17_UART0 -# if CONFIG_UART0_PARITY == 0 -# define UART0_LCR_PAR 0 -# elif CONFIG_UART0_PARITY == 1 -# define UART0_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) -# elif CONFIG_UART0_PARITY == 2 -# define UART0_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) -# elif CONFIG_UART0_PARITY == 3 -# define UART0_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) -# elif CONFIG_UART0_PARITY == 4 -# define UART0_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) -# else -# error "Invalid CONFIG_UARTn_PARITY setting for UART0" -# endif -#endif - -#ifdef CONFIG_LPC17_UART1 -# if CONFIG_UART1_PARITY == 0 -# define UART1_LCR_PAR 0 -# elif CONFIG_UART1_PARITY == 1 -# define UART1_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) -# elif CONFIG_UART1_PARITY == 2 -# define UART1_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) -# elif CONFIG_UART1_PARITY == 3 -# define UART1_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) -# elif CONFIG_UART1_PARITY == 4 -# define UART1_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) -# else -# error "Invalid CONFIG_UARTn_PARITY setting for UART1" -# endif -#endif - -#ifdef CONFIG_LPC17_UART2 -# if CONFIG_UART2_PARITY == 0 -# define UART2_LCR_PAR 0 -# elif CONFIG_UART2_PARITY == 1 -# define UART2_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) -# elif CONFIG_UART2_PARITY == 2 -# define UART2_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) -# elif CONFIG_UART2_PARITY == 3 -# define UART2_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) -# elif CONFIG_UART2_PARITY == 4 -# define UART2_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) -# else -# error "Invalid CONFIG_UARTn_PARITY setting for UART2" -# endif -#endif - -#ifdef CONFIG_LPC17_UART3 -# if CONFIG_UART3_PARITY == 0 -# define UART3_LCR_PAR 0 -# elif CONFIG_UART3_PARITY == 1 -# define UART3_LCR_PAR (UART_LCR_PE|UART_LCR_PS_ODD) -# elif CONFIG_UART3_PARITY == 2 -# define UART3_LCR_PAR (UART_LCR_PE|UART_LCR_PS_EVEN) -# elif CONFIG_UART3_PARITY == 3 -# define UART3_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK1) -# elif CONFIG_UART3_PARITY == 4 -# define UART3_LCR_PAR (UART_LCR_PE|UART_LCR_PS_STICK0) -# else -# error "Invalid CONFIG_UARTn_PARITY setting for UART3" -# endif -#endif - -/* Get stop-bit setting for the console UART and UART0-3 */ - -#if CONSOLE_2STOP != 0 -# define CONSOLE_LCR_STOP LPC214X_LCR_STOP_2 -#else -# define CONSOLE_LCR_STOP LPC214X_LCR_STOP_1 -#endif - -#if CONFIG_UART0_2STOP != 0 -# define UART0_LCR_STOP LPC214X_LCR_STOP_2 -#else -# define UART0_LCR_STOP LPC214X_LCR_STOP_1 -#endif - -#if CONFIG_UART1_2STOP != 0 -# define UART1_LCR_STOP LPC214X_LCR_STOP_2 -#else -# define UART1_LCR_STOP LPC214X_LCR_STOP_1 -#endif - -#if CONFIG_UART2_2STOP != 0 -# define UART2_LCR_STOP LPC214X_LCR_STOP_2 -#else -# define UART2_LCR_STOP LPC214X_LCR_STOP_1 -#endif - -#if CONFIG_UART3_2STOP != 0 -# define UART3_LCR_STOP LPC214X_LCR_STOP_2 -#else -# define UART3_LCR_STOP LPC214X_LCR_STOP_1 -#endif - -/* LCR and FCR values */ - -#define CONSOLE_LCR_VALUE (CONSOLE_LCR_WLS | CONSOLE_LCR_PAR | CONSOLE_LCR_STOP) -#define CONSOLE_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ - UART_FCR_RXRST | UART_FCR_FIFOEN) - -#define UART0_LCR_VALUE (UART0_LCR_WLS | UART0_LCR_PAR | UART0_LCR_STOP) -#define UART0_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ - UART_FCR_RXRST | UART_FCR_FIFOEN) - -#define UART1_LCR_VALUE (UART1_LCR_WLS | UART1_LCR_PAR | UART1_LCR_STOP) -#define UART1_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ - UART_FCR_RXRST | UART_FCR_FIFOEN) - -#define UART2_LCR_VALUE (UART2_LCR_WLS | UART2_LCR_PAR | UART2_LCR_STOP) -#define UART2_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ - UART_FCR_RXRST | UART_FCR_FIFOEN) - -#define UART3_LCR_VALUE (UART3_LCR_WLS | UART3_LCR_PAR | UART3_LCR_STOP) -#define UART3_FCR_VALUE (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST |\ - UART_FCR_RXRST | UART_FCR_FIFOEN) +#define UART_MINDL 32 /************************************************************************************ * Public Types @@ -320,6 +107,149 @@ * Public Data ************************************************************************************/ +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lpc17_uartcclkdiv + * + * Descrption: + * Select a CCLK divider to produce the UART PCLK. The stratey 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. + * + * NOTE: This is an inline function. If a typical optimization level is used and + * a constant is provided for the desired frequency, then most of the following + * logic will be optimized away. + * + ************************************************************************************/ + +static inline uint8_t lpc17_uartcclkdiv(uint32_t baud) +{ + /* Ignoring the fractional divider, the BAUD is given by: + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Where: + * + * PCLK = CCLK / divisor. + * + * Check divisor == 1. This works if the upper limit is met + * + * DL < 0xffff, or + * PCLK / BAUD / 16 < 0xffff, or + * CCLK / BAUD / 16 < 0xffff, or + * CCLK < BAUD * 0xffff * 16 + * BAUD > CCLK / 0xffff / 16 + * + * And the lower limit is met (we can't allow DL to get very close to one). + * + * DL >= MinDL + * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 16 / MinDL + */ + + if (baud < (LPC17_CCLK / 16 / UART_MINDL )) + { + return SYSCON_PCLKSEL_CCLK; + } + + /* Check divisor == 2. This works if: + * + * 2 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 8 + * + * And + * + * 2 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 8 / MinDL + */ + + else if (baud < (LPC17_CCLK / 8 / UART_MINDL )) + { + return SYSCON_PCLKSEL_CCLK2; + } + + /* Check divisor == 4. This works if: + * + * 4 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 4 + * + * And + * + * 4 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 4 / MinDL + */ + + else if (baud < (LPC17_CCLK / 4 / UART_MINDL )) + { + return SYSCON_PCLKSEL_CCLK4; + } + + /* Check divisor == 8. This works if: + * + * 8 * CCLK / BAUD / 16 < 0xffff, or + * BAUD > CCLK / 0xffff / 2 + * + * And + * + * 8 * CCLK / BAUD / 16 >= MinDL, or + * BAUD <= CCLK / 2 / MinDL + */ + + else /* if (baud < (LPC17_CCLK / 2 / UART_MINDL )) */ + { + return SYSCON_PCLKSEL_CCLK8; + } +} + +/************************************************************************************ + * Name: lpc17_uartdl + * + * Descrption: + * Select a divider to produce the BAUD from the UART PCLK. + * + * BAUD = PCLK / (16 * DL), or + * DL = PCLK / BAUD / 16 + * + * Ignoring the fractional divider for now. + * + ************************************************************************************/ + +static inline uint32_t lpc17_uartdl(uint32_t baud, uint8_t divcode) +{ + uint32_t num; + + switch (divcode) + { + + case SYSCON_PCLKSEL_CCLK4: /* PCLK_peripheral = CCLK/4 */ + num = (LPC17_CCLK / 4); + break; + + case SYSCON_PCLKSEL_CCLK: /* PCLK_peripheral = CCLK */ + num = LPC17_CCLK; + break; + + case SYSCON_PCLKSEL_CCLK2: /* PCLK_peripheral = CCLK/2 */ + num = (LPC17_CCLK / 2); + break; + + case SYSCON_PCLKSEL_CCLK8: /* PCLK_peripheral = CCLK/8 (except CAN1, CAN2, and CAN) */ + default: + num = (LPC17_CCLK / 8); + break; + } + return num / (baud << 4); +} + /************************************************************************************ * Public Functions ************************************************************************************/ diff --git a/arch/arm/src/lpc17xx/lpc17_syscon.h b/arch/arm/src/lpc17xx/lpc17_syscon.h index 6f13726cc47..13b0c48fd8f 100755 --- a/arch/arm/src/lpc17xx/lpc17_syscon.h +++ b/arch/arm/src/lpc17xx/lpc17_syscon.h @@ -212,7 +212,7 @@ #define SYSCON_CLKSRCSEL_SHIFT (0) /* Bits 0-1: Clock selection */ #define SYSCON_CLKSRCSEL_MASK (3 << SYSCON_CLKSRCSEL_SHIFT) -# define SYSCON_CLKSRCSEL_MAIN (0 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = internal RC oscillator */ +# define SYSCON_CLKSRCSEL_INTRC (0 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = internal RC oscillator */ # define SYSCON_CLKSRCSEL_RTC (1 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = main oscillator */ # define SYSCON_CLKSRCSEL_MAIN (2 << SYSCON_CLKSRCSEL_SHIFT) /* PLL0 source = RTC oscillator */ /* Bits 2-31: Reserved */ @@ -282,12 +282,12 @@ /* Bits 8-31: Reserved */ /* Peripheral Clock Selection registers 0 and 1 */ -#define SYSCON_PCLKSET_CCLK4 (0) /* PCLK_peripheral = CCLK/4 */ -#define SYSCON_PCLKSET_CCLK (1) /* PCLK_peripheral = CCLK */ -#define SYSCON_PCLKSET_CCLK2 (2) /* PCLK_peripheral = CCLK/2 */ -#define SYSCON_PCLKSET_CCLK6 (3) /* PCLK_peripheral = CCLK/8 (except CAN1, CAN2, and CAN) */ -#define SYSCON_PCLKSET_CCLK8 (3) /* PCLK_peripheral = CCLK/6 (CAN1, CAN2, and CAN) */ -#define SYSCON_PCLKSET_MASK (3) +#define SYSCON_PCLKSEL_CCLK4 (0) /* PCLK_peripheral = CCLK/4 */ +#define SYSCON_PCLKSEL_CCLK (1) /* PCLK_peripheral = CCLK */ +#define SYSCON_PCLKSEL_CCLK2 (2) /* PCLK_peripheral = CCLK/2 */ +#define SYSCON_PCLKSEL_CCLK8 (3) /* PCLK_peripheral = CCLK/8 (except CAN1, CAN2, and CAN) */ +#define SYSCON_PCLKSEL_CCLK6 (3) /* PCLK_peripheral = CCLK/6 (CAN1, CAN2, and CAN) */ +#define SYSCON_PCLKSEL_MASK (3) #define SYSCON_PCLKSEL0_WDT_SHIFT (0) /* Bits 0-1: Peripheral clock WDT */ #define SYSCON_PCLKSEL0_WDT_MASK (3 << SYSCON_PCLKSEL0_WDT_SHIFT) diff --git a/configs/nucleus2g/include/board.h b/configs/nucleus2g/include/board.h index 058b50319cf..74965c77831 100755 --- a/configs/nucleus2g/include/board.h +++ b/configs/nucleus2g/include/board.h @@ -49,6 +49,9 @@ /* Clocking *************************************************************************/ +#define LPC17_CCLK 80000000 /* 80Mhz*/ + + /* LED definitions ******************************************************************/ #define LED_STARTED 0