From 55c5d04c84b9da16ac50274293fb37716ca6f3d1 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 8 Mar 2015 12:27:55 -0600 Subject: [PATCH] SAMV71: Fix a few typos; Use factional value in BAUD calculation --- arch/arm/src/samv7/chip/sam_uart.h | 2 + arch/arm/src/samv7/sam_lowputc.c | 106 +++++++++++++++++++++-------- arch/arm/src/samv7/sam_serial.c | 31 +++++---- 3 files changed, 99 insertions(+), 40 deletions(-) diff --git a/arch/arm/src/samv7/chip/sam_uart.h b/arch/arm/src/samv7/chip/sam_uart.h index 3eee1f5ea5..c0fdac8acf 100644 --- a/arch/arm/src/samv7/chip/sam_uart.h +++ b/arch/arm/src/samv7/chip/sam_uart.h @@ -390,8 +390,10 @@ #define UART_BRGR_CD_SHIFT (0) /* Bits 0-15: Clock Divisor (Common) */ #define UART_BRGR_CD_MASK (0xffff << UART_BRGR_CD_SHIFT) +# define UART_BRGR_CD(n) ((uint32_t)(n) << UART_BRGR_CD_SHIFT) #define UART_BRGR_FP_SHIFT (16) /* Bits 16-18: Fractional Part (USART only) */ #define UART_BRGR_FP_MASK (7 << UART_BRGR_FP_SHIFT) +# define UART_BRGR_FP(n) ((uint32_t)(n) << UART_BRGR_FP_SHIFT) /* Comparison Register (UART only) */ diff --git a/arch/arm/src/samv7/sam_lowputc.c b/arch/arm/src/samv7/sam_lowputc.c index 1a8de23ced..93e201df7a 100644 --- a/arch/arm/src/samv7/sam_lowputc.c +++ b/arch/arm/src/samv7/sam_lowputc.c @@ -272,40 +272,68 @@ int up_putc(int ch) void sam_lowsetup(void) { +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + uint64_t divb3; + uint32_t intpart; + uint32_t fracpart; + uint32_t regval; +#endif + /* Enable clocking for all selected UART/USARTs */ -#ifdef CONFIG_SAM34_UART0 +#ifdef CONFIG_SAMV7_UART0 sam_uart0_enableclk(); #endif -#ifdef CONFIG_SAM34_UART1 +#ifdef CONFIG_SAMV7_UART1 sam_uart1_enableclk(); #endif -#ifdef CONFIG_SAM34_USART0 +#ifdef CONFIG_SAMV7_UART2 + sam_uart2_enableclk(); +#endif +#ifdef CONFIG_SAMV7_UART3 + sam_uart3_enableclk(); +#endif +#ifdef CONFIG_SAMV7_UART4 + sam_uart4_enableclk(); +#endif +#ifdef CONFIG_SAMV7_USART0 sam_usart0_enableclk(); #endif -#ifdef CONFIG_SAM34_USART1 +#ifdef CONFIG_SAMV7_USART1 sam_usart1_enableclk(); #endif -#ifdef CONFIG_SAM34_USART2 +#ifdef CONFIG_SAMV7_USART2 sam_usart2_enableclk(); #endif -#ifdef CONFIG_SAM34_USART3 - sam_usart3_enableclk(); -#endif /* Configure UART pins for all selected UART/USARTs */ -#ifdef CONFIG_SAM34_UART0 +#ifdef CONFIG_SAMV7_UART0 (void)sam_configgpio(GPIO_UART0_RXD); (void)sam_configgpio(GPIO_UART0_TXD); #endif -#ifdef CONFIG_SAM34_UART1 +#ifdef CONFIG_SAMV7_UART1 (void)sam_configgpio(GPIO_UART1_RXD); (void)sam_configgpio(GPIO_UART1_TXD); #endif -#ifdef CONFIG_SAM34_USART0 +#ifdef CONFIG_SAMV7_UART2 + (void)sam_configgpio(GPIO_UART2_RXD); + (void)sam_configgpio(GPIO_UART2_TXD); +#endif + +#ifdef CONFIG_SAMV7_UART3 + (void)sam_configgpio(GPIO_UART3_RXD); + (void)sam_configgpio(GPIO_UART3_TXD); +#endif + +#ifdef CONFIG_SAMV7_UART4 + (void)sam_configgpio(GPIO_UART4_RXD); + (void)sam_configgpio(GPIO_UART4_TXD); +#endif + +#ifdef CONFIG_SAMV7_USART0 (void)sam_configgpio(GPIO_USART0_RXD); (void)sam_configgpio(GPIO_USART0_TXD); #ifdef CONFIG_USART0_OFLOWCONTROL @@ -316,7 +344,7 @@ void sam_lowsetup(void) #endif #endif -#ifdef CONFIG_SAM34_USART1 +#ifdef CONFIG_SAMV7_USART1 (void)sam_configgpio(GPIO_USART1_RXD); (void)sam_configgpio(GPIO_USART1_TXD); #ifdef CONFIG_USART1_OFLOWCONTROL @@ -327,7 +355,7 @@ void sam_lowsetup(void) #endif #endif -#ifdef CONFIG_SAM34_USART2 +#ifdef CONFIG_SAMV7_USART2 (void)sam_configgpio(GPIO_USART2_RXD); (void)sam_configgpio(GPIO_USART2_TXD); #ifdef CONFIG_USART2_OFLOWCONTROL @@ -336,17 +364,6 @@ void sam_lowsetup(void) #ifdef CONFIG_USART2_IFLOWCONTROL (void)sam_configgpio(GPIO_USART2_RTS); #endif -#endif - -#ifdef CONFIG_SAM34_USART3 - (void)sam_configgpio(GPIO_USART3_RXD); - (void)sam_configgpio(GPIO_USART3_TXD); -#ifdef CONFIG_USART3_OFLOWCONTROL - (void)sam_configgpio(GPIO_USART3_CTS); -#endif -#ifdef CONFIG_USART3_IFLOWCONTROL - (void)sam_configgpio(GPIO_USART3_RTS); -#endif #endif /* Configure the console (only) */ @@ -364,12 +381,45 @@ void sam_lowsetup(void) putreg32(MR_VALUE, SAM_CONSOLE_BASE + SAM_UART_MR_OFFSET); - /* Configure the console baud. NOTE: Oversampling by 8 is not supported. - * This may limit BAUD rates for lower USART clocks. + /* Configure the console baud: + * + * Fbaud = USART_CLOCK / (16 * divisor) + * divisor = USART_CLOCK / (16 * Fbaud) + * + * NOTE: Oversampling by 8 is not supported. This may limit BAUD rates + * for lower USART clocks. */ - putreg32(((FAST_USART_CLOCK + (SAM_CONSOLE_BAUD << 3)) / (SAM_CONSOLE_BAUD << 4)), - SAM_CONSOLE_BASE + SAM_UART_BRGR_OFFSET); + divb3 = ((FAST_USART_CLOCK + (priv->baud << 3)) << 3) / (priv->baud << 4); + intpart = (divb3 >> 3); + fracpart = (divb3 & 7) + + /* Retain the fast MR peripheral clock UNLESS unless using that clock + * would result in an excessively large divider. + * + * REVISIT: The fractional divider is not used. + */ + + if ((regval & UART_BRGR_CD_MASK) != 0) + { + /* Use the divided USART clock */ + + divb3 = ((FAST_USART_CLOCK + (priv->baud << 3)) << 3) / (priv->baud << 4); + intpart = (divb3 >> 3); + fracpart = (divb3 & 7) + + /* Re-select the clock source */ + + regval = sam_serialin(priv, SAM_UART_MR_OFFSET); + regval &= ~UART_MR_USCLKS_MASK; + regval |= UART_MR_USCLKS_MCKDIV; + sam_serialout(priv, SAM_UART_MR_OFFSET, regval); + } + + /* Save the BAUD divider (the fractional part is not used for UARTs) */ + + regval = UART_BRGR_CD(intpart) | UART_BRGR_FP(fracpart); + putreg32(regval, SAM_CONSOLE_BASE + SAM_UART_BRGR_OFFSET); /* Enable receiver & transmitter */ diff --git a/arch/arm/src/samv7/sam_serial.c b/arch/arm/src/samv7/sam_serial.c index df73ac431d..30f72c3e90 100644 --- a/arch/arm/src/samv7/sam_serial.c +++ b/arch/arm/src/samv7/sam_serial.c @@ -756,6 +756,9 @@ static int sam_setup(struct uart_dev_s *dev) { struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv; #ifndef CONFIG_SUPPRESS_UART_CONFIG + uint32_t divb3; + uint32_t intpart; + uint32_t fracpart; uint32_t regval; /* Note: The logic here depends on the fact that that the USART module @@ -867,18 +870,23 @@ static int sam_setup(struct uart_dev_s *dev) * for lower USART clocks. */ - regval = (FAST_USART_CLOCK + (priv->baud << 3)) / (priv->baud << 4); + divb3 = ((FAST_USART_CLOCK + (priv->baud << 3)) << 3) / (priv->baud << 4); + intpart = (divb3 >> 3); + fracpart = (divb3 & 7) - /* Retain the peripheral clock UNLESS unless using that clock would result - * in a very small BAUD divisor, say smaller than 8. + /* Retain the fast MR peripheral clock UNLESS unless using that clock + * would result in an excessively large divider. + * + * REVISIT: The fractional divider is not used. */ - if (regval < 8) + if ((regval & UART_BRGR_CD_MASK) != 0) { - /* Use the devided USART clock */ + /* Use the divided USART clock */ - regval = (SLOW_USART_CLOCK + (priv->baud << 3)) / (priv->baud << 4); - sam_serialout(priv, SAM_UART_BRGR_OFFSET, regval); + divb3 = ((FAST_USART_CLOCK + (priv->baud << 3)) << 3) / (priv->baud << 4); + intpart = (divb3 >> 3); + fracpart = (divb3 & 7) /* Re-select the clock source */ @@ -887,12 +895,11 @@ static int sam_setup(struct uart_dev_s *dev) regval |= UART_MR_USCLKS_MCKDIV; sam_serialout(priv, SAM_UART_MR_OFFSET, regval); } - else - { - /* Use the undivided USART clock */ - sam_serialout(priv, SAM_UART_BRGR_OFFSET, regval); - } + /* Save the BAUD divider (the fractional part is not used for UARTs) */ + + regval = UART_BRGR_CD(intpart) | UART_BRGR_FP(fracpart); + sam_serialout(priv, SAM_UART_BRGR_OFFSET, regval); /* Enable receiver & transmitter */