From 766890cba924de0dff8aa855e0456b07ff73e4fd Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 26 Sep 2009 18:59:09 +0000 Subject: USART driver implementation git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2095 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/stm32/stm32_lowputc.c | 172 ++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 5 deletions(-) (limited to 'nuttx/arch/arm/src/stm32/stm32_lowputc.c') diff --git a/nuttx/arch/arm/src/stm32/stm32_lowputc.c b/nuttx/arch/arm/src/stm32/stm32_lowputc.c index 4ed14ee23..61a4765e8 100644 --- a/nuttx/arch/arm/src/stm32/stm32_lowputc.c +++ b/nuttx/arch/arm/src/stm32/stm32_lowputc.c @@ -44,6 +44,9 @@ #include "up_arch.h" #include "chip.h" +#include "stm32_rcc.h" +#include "stm32_gpio.h" +#include "stm32_uart.h" #include "stm32_internal.h" /************************************************************************** @@ -77,18 +80,21 @@ #if defined(CONFIG_USART1_SERIAL_CONSOLE) # define STM32_CONSOLE_BASE STM32_USART1_BASE +# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY # define STM32_CONSOLE_BAUD CONFIG_USART1_BAUD # define STM32_CONSOLE_BITS CONFIG_USART1_BITS # define STM32_CONSOLE_PARITY CONFIG_USART1_PARITY # define STM32_CONSOLE_2STOP CONFIG_USART1_2STOP #elif defined(CONFIG_USART2_SERIAL_CONSOLE) # define STM32_CONSOLE_BASE STM32_USART2_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY # define STM32_CONSOLE_BAUD CONFIG_USART2_BAUD # define STM32_CONSOLE_BITS CONFIG_USART2_BITS # define STM32_CONSOLE_PARITY CONFIG_USART2_PARITY # define STM32_CONSOLE_2STOP CONFIG_USART2_2STOP #elif defined(CONFIG_USART3_SERIAL_CONSOLE) # define STM32_CONSOLE_BASE STM32_USART2_BASE +# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY # define STM32_CONSOLE_BAUD CONFIG_USART2_BAUD # define STM32_CONSOLE_BITS CONFIG_USART2_BITS # define STM32_CONSOLE_PARITY CONFIG_USART2_PARITY @@ -97,7 +103,62 @@ # error "No CONFIG_USARTn_SERIAL_CONSOLE Setting" #endif -/* Calculate BAUD rate from the SYS clock */ +/* CR1 settings */ + +#if CONFIG_USART2_BITS == 9 +# define USART_CR1_M_VALUE USART_CR1_M +#else +# define USART_CR1_M_VALUE 0 +#endif + +#if CONFIG_USART2_PARITY == 1 +# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) +#elif CONFIG_USART2_PARITY == 2 +# define USART_CR1_PARITY_VALUE USART_CR1_PCE +#else +# define USART_CR1_PARITY_VALUE 0 +#endif + +#define USART_CR1_CLRBITS (USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE|USART_CR1_RE|USART_CR1_ALLINTS) +#define USART_CR1_SETBITS (USART_CR1_M_VALUE|USART_CR1_PARITY_VALUE) + +/* CR2 settings */ + +#if CONFIG_USART2_2STOP != 0 +# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 +#else +# define USART_CR2_STOP2_VALUE 0 +#endif + +#define USART_CR2_CLRBITS (USART_CR2_STOP_MASK|USART_CR2_CLKEN|USART_CR2_CPOL|USART_CR2_CPHA|USART_CR2_LBCL|USART_CR2_LBDIE) +#define USART_CR2_SETBITS USART_CR2_STOP2_VALUE + +/* CR3 settings */ + +#define USART_CR3_CLRBITS (USART_CR3_CTSIE|USART_CR3_CTSE|USART_CR3_RTSE|USART_CR3_EIE) +#define USART_CR3_SETBITS 0 + +/* Calculate USART BAUD rate divider + * + * 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) + */ + +#define STM32_USARTDIV32 (STM32_APBCLOCK / (STM32_CONSOLE_BAUD >> 1)) +#define STM32_MANTISSA (STM32_USARTDIV32 >> 5) +#define STM32_FRACTION ((STM32_USARTDIV32 - (STM32_MANTISSA << 5) + 1) >> 1) +#define STM32_BRR_VALUE ((STM32_MANTISSA << USART_BRR_MANT_SHIFT) | (STM32_FRACTION << USART_BRR_FRAC_SHIFT)) /************************************************************************** * Private Types @@ -136,8 +197,11 @@ void up_lowputc(char ch) #ifdef HAVE_CONSOLE /* Wait until the TX FIFO is not full */ + while ((getreg16(STM32_CONSOLE_BASE + STM32_USART_SR_OFFSET) & USART_SR_TXE) != 0); /* Then send the character */ + + putreg16((uint16)ch, STM32_CONSOLE_BASE + STM32_USART_DR_OFFSET); #endif } @@ -153,24 +217,122 @@ void up_lowputc(char ch) void up_lowsetup(void) { +#if !defined(CONFIG_USART1_DISABLE) || !defined(CONFIG_USART2_DISABLE) || !defined(CONFIG_USART3_DISABLE) + uint32 enr; + uint32 mapr; +#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_USART_CONFIG) + uint32 cr; +#endif + /* Enable the selected USARTs and configure GPIO pins need byed the * the selected USARTs. NOTE: The serial driver later depends on * this pin configuration -- whether or not a serial console is selected. */ -#ifndef CONFIG_USART1_DISABLE -#endif + mapr = getreg32(STM32_AFIO_MAPR); #ifndef CONFIG_USART1_DISABLE -#endif + /* Enable USART1 clocking */ + + enr = getreg32(STM32_RCC_APB2ENR_OFFSET); + enr |= RCC_APB2ENR_USART1EN; + putreg32(enr, STM32_RCC_APB2ENR_OFFSET); + + /* Assume default pin mapping: + * + * Alternate USART1_REMAP USART1_REMAP + * Function = 0 = 1 + * ---------- ------------ ------------ + * USART1_TX PA9 PB6 + * USART1_RX PA10 PB7 + */ + + mapr &= ~AFIO_MAPR_USART1_REMAP; + +#endif /* !CONFIG_USART1_DISABLE */ + +#if !defined(CONFIG_USART2_DISABLE) && !defined(CONFIG_USART3_DISABLE) + enr = getreg32(STM32_RCC_APB1ENR_OFFSET); #ifndef CONFIG_USART2_DISABLE -#endif + /* Enable USART2 clocking */ + + enr |= RCC_APB1ENR_USART2EN; + + /* Assume default pin mapping: + * + * Alternate USART2_REMAP USART2_REMAP + * Function = 0 = 1 + * ---------- ------------ ------------ + * USART2_TX PA2 PD5 + * USART2_RX PA3 PD6 + */ + + mapr &= ~AFIO_MAPR_USART2_REMAP; + +#endif /* !CONFIG_USART2_DISABLE */ + +#ifndef CONFIG_USART3_DISABLE + /* Enable USART3 clocking */ + + enr |= RCC_APB1ENR_USART3EN; + + /* Assume default pin mapping: + * + * + * Alternate USART3_REMAP[1:0] USART3_REMAP[1:0] USART3_REMAP[1:0] + * Function = “00” (no remap) = “01” (partial remap) = “11” (full remap) + * --------- ------------------ ---------------------- -------------------- + * USART3_TX PB10 PC10 PD8 + * USART3_RX PB11 PC11 PD9 + */ + + mapr &= ~AFIO_MAPR_USART3_REMAP_MASK; + +#endif /* !CONFIG_USART3_DISABLE */ + /* Save the UART enable settings */ + + putreg32(enr, STM32_RCC_APB1ENR_OFFSET); +#endif /* !CONFIG_USART2_DISABLE && !CONFIG_USART3_DISABLE */ + /* Save the USART pin mappings */ + + putreg32(mapr, STM32_AFIO_MAPR); /* Enable and configure the selected console device */ #if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_USART_CONFIG) + /* Configure CR2 */ + + cr = getreg16(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr &= ~USART_CR2_CLRBITS; + cr |= USART_CR2_SETBITS; + putreg16(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + + /* Configure CR1 */ + + cr = getreg16(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + cr &= ~USART_CR1_CLRBITS; + cr |= USART_CR1_SETBITS; + putreg16(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); + + /* Configure CR3 */ + + cr = getreg16(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + cr &= ~USART_CR3_CLRBITS; + cr |= USART_CR3_SETBITS; + putreg16(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); + + /* Configure the USART Baud Rate */ + + putreg32(STM32_BRR_VALUE, STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + + /* Enable Rx, Tx, and the USART */ + + cr = getreg16(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); + cr |= (USART_CR1_UE|USART_CR1_TE|USART_CR1_RE); + putreg16(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); #endif +#endif /* !CONFIG_USART1_DISABLE && !CONFIG_USART2_DISABLE && !CONFIG_USART3_DISABLE */ } -- cgit v1.2.3