mirror of
https://github.com/apache/nuttx.git
synced 2026-06-08 10:32:47 +08:00
USART driver implementation
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2095 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 10-8: APB Low speed prescaler (APB1) */
|
||||
#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT)
|
||||
# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */
|
||||
# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */
|
||||
# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */
|
||||
# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */
|
||||
# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */
|
||||
# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */
|
||||
@@ -230,7 +230,7 @@
|
||||
#define RCC_AHBENR_SRAMEN (1 << 2) /* Bit 2: SRAM interface clock enable */
|
||||
#define RCC_AHBENR_FLITFEN (1 << 4) /* Bit 4: FLITF clock enable */
|
||||
#define RCC_AHBENR_CRCEN (1 << 6) /* Bit 6: CRC clock enable */
|
||||
#define RCC_AHBENR_SDIOEN (1 << 8) /* Bit 8: FSMC clock enable */
|
||||
#define RCC_AHBENR_FSMCEN (1 << 8) /* Bit 8: FSMC clock enable */
|
||||
#define RCC_AHBENR_SDIOEN (1 << 10) /* Bit 10: SDIO clock enable */
|
||||
|
||||
/* APB2 Peripheral Clock enable register */
|
||||
|
||||
+356
-149
File diff suppressed because it is too large
Load Diff
@@ -113,6 +113,9 @@
|
||||
#define USART_SR_LBD (1 << 8) /* Bit 8: LIN Break Detection Flag */
|
||||
#define USART_SR_CTS (1 << 9) /* Bit 9: CTS Flag */
|
||||
|
||||
#define USART_SR_ALLBITS (0x03ff)
|
||||
#define USART_SR_CLRBITS (USART_SR_CTS|USART_SR_LBD) /* Cleared by SW write to SR */
|
||||
|
||||
/* Data register */
|
||||
|
||||
#define USART_DR_SHIFT (0) /* Bits 8:0: Data value */
|
||||
@@ -142,6 +145,8 @@
|
||||
#define USART_CR1_M (1 << 12) /* Bit 12: word length */
|
||||
#define USART_CR1_UE (1 << 13) /* Bit 13: USART Enable */
|
||||
|
||||
#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE|USART_CR1_TCIE|USART_CR1_PEIE)
|
||||
|
||||
/* Control register 2 */
|
||||
|
||||
#define USART_CR2_ADD_SHIFT (0) /* Bits 3-0: Address of the USART node */
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
|
||||
/* Clocking *************************************************************************/
|
||||
|
||||
# warning "This frequencies are still needed"
|
||||
#define STM32_PCLK1_FREQUENCY 1
|
||||
#define STM32_PCLK2_FREQUENCY 1
|
||||
|
||||
/* LED definitions ******************************************************************/
|
||||
|
||||
#define LED_STARTED 0
|
||||
|
||||
Reference in New Issue
Block a user