summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/stm32/stm32_lowputc.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-26 18:59:09 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2009-09-26 18:59:09 +0000
commit766890cba924de0dff8aa855e0456b07ff73e4fd (patch)
tree47b9f0a4944f1f16410d121ff3bf3fa69ad19a13 /nuttx/arch/arm/src/stm32/stm32_lowputc.c
parentdb457913b33ab75f743e6b9a11931f9d962f2910 (diff)
downloadpx4-nuttx-766890cba924de0dff8aa855e0456b07ff73e4fd.tar.gz
px4-nuttx-766890cba924de0dff8aa855e0456b07ff73e4fd.tar.bz2
px4-nuttx-766890cba924de0dff8aa855e0456b07ff73e4fd.zip
USART driver implementation
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2095 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src/stm32/stm32_lowputc.c')
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_lowputc.c172
1 files changed, 167 insertions, 5 deletions
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 */
}