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:
parent
a71055cddd
commit
c708897b46
@ -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 */
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <arch/serial.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "stm32_uart.h"
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
#include "os_internal.h"
|
||||
@ -99,54 +100,54 @@
|
||||
/* Which USART with be tty0/console and which tty1? */
|
||||
|
||||
#if defined(CONFIG_USART1_SERIAL_CONSOLE)
|
||||
# define CONSOLE_DEV g_USART1port /* USART1 is console */
|
||||
# define TTYS0_DEV g_USART1port /* USART1 is ttyS0 */
|
||||
# define CONSOLE_DEV g_usart1port /* USART1 is console */
|
||||
# define TTYS0_DEV g_usart1port /* USART1 is ttyS0 */
|
||||
# ifndef CONFIG_USART2_DISABLE
|
||||
# define TTYS1_DEV g_USART2port /* USART2 is ttyS1 */
|
||||
# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */
|
||||
# ifndef CONFIG_USART3_DISABLE
|
||||
# define TTYS2_DEV g_USART3port /* USART3 is ttyS2 */
|
||||
# define TTYS2_DEV g_usart3port /* USART3 is ttyS2 */
|
||||
# else
|
||||
# undef TTYS1_DEV /* No ttyS2 */
|
||||
# endif
|
||||
# else
|
||||
# ifndef CONFIG_USART3_DISABLE
|
||||
# define TTYS1_DEV g_USART3port /* USART3 is ttyS1 */
|
||||
# define TTYS1_DEV g_usart3port /* USART3 is ttyS1 */
|
||||
# else
|
||||
# undef TTYS1_DEV /* No ttyS1 */
|
||||
# endif
|
||||
# undef TTYS2_DEV /* No ttyS2 */
|
||||
# endif
|
||||
#elif defined(CONFIG_USART2_SERIAL_CONSOLE)
|
||||
# define CONSOLE_DEV g_USART2port /* USART2 is console */
|
||||
# define TTYS0_DEV g_USART2port /* USART2 is ttyS0 */
|
||||
# define CONSOLE_DEV g_usart2port /* USART2 is console */
|
||||
# define TTYS0_DEV g_usart2port /* USART2 is ttyS0 */
|
||||
# ifndef CONFIG_USART1_DISABLE
|
||||
# define TTYS1_DEV g_USART1port /* USART1 is ttyS1 */
|
||||
# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */
|
||||
# ifndef CONFIG_USART3_DISABLE
|
||||
# define TTYS2_DEV g_USART3port /* USART3 is ttyS2 */
|
||||
# define TTYS2_DEV g_usart3port /* USART3 is ttyS2 */
|
||||
# else
|
||||
# undef TTYS1_DEV /* No ttyS2 */
|
||||
# endif
|
||||
# else
|
||||
# ifndef CONFIG_USART3_DISABLE
|
||||
# define TTYS1_DEV g_USART3port /* USART3 is ttyS1 */
|
||||
# define TTYS1_DEV g_usart3port /* USART3 is ttyS1 */
|
||||
# else
|
||||
# undef TTYS1_DEV /* No ttyS1 */
|
||||
# endif
|
||||
# undef TTYS2_DEV /* No ttyS2 */
|
||||
# endif
|
||||
#elif defined(CONFIG_USART3_SERIAL_CONSOLE)
|
||||
# define CONSOLE_DEV g_USART3port /* USART3 is console */
|
||||
# define TTYS0_DEV g_USART3port /* USART3 is ttyS0 */
|
||||
# define CONSOLE_DEV g_usart3port /* USART3 is console */
|
||||
# define TTYS0_DEV g_usart3port /* USART3 is ttyS0 */
|
||||
# ifndef CONFIG_USART1_DISABLE
|
||||
# define TTYS1_DEV g_USART1port /* USART1 is ttyS1 */
|
||||
# define TTYS1_DEV g_usart1port /* USART1 is ttyS1 */
|
||||
# ifndef CONFIG_USART2_DISABLE
|
||||
# define TTYS2_DEV g_USART2port /* USART2 is ttyS2 */
|
||||
# define TTYS2_DEV g_usart2port /* USART2 is ttyS2 */
|
||||
# else
|
||||
# undef TTYS1_DEV /* No ttyS2 */
|
||||
# endif
|
||||
# else
|
||||
# ifndef CONFIG_USART2_DISABLE
|
||||
# define TTYS1_DEV g_USART2port /* USART2 is ttyS1 */
|
||||
# define TTYS1_DEV g_usart2port /* USART2 is ttyS1 */
|
||||
# else
|
||||
# undef TTYS1_DEV /* No ttyS1 */
|
||||
# endif
|
||||
@ -160,9 +161,11 @@
|
||||
|
||||
struct up_dev_s
|
||||
{
|
||||
uint32 USARTbase; /* Base address of USART registers */
|
||||
uint32 usartbase; /* Base address of USART registers */
|
||||
uint32 apbclock; /* PCLK 1 or 2 frequency */
|
||||
uint32 baud; /* Configured baud */
|
||||
uint32 im; /* Saved IM value */
|
||||
uint16 ie; /* Saved interrupt mask bits value */
|
||||
uint16 sr; /* Saved status bits */
|
||||
ubyte irq; /* IRQ associated with this USART */
|
||||
ubyte parity; /* 0=none, 1=odd, 2=even */
|
||||
ubyte bits; /* Number of bits (7 or 8) */
|
||||
@ -173,25 +176,24 @@ struct up_dev_s
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static int up_setup(struct USART_dev_s *dev);
|
||||
static void up_shutdown(struct USART_dev_s *dev);
|
||||
static int up_attach(struct USART_dev_s *dev);
|
||||
static void up_detach(struct USART_dev_s *dev);
|
||||
static int up_setup(struct uart_dev_s *dev);
|
||||
static void up_shutdown(struct uart_dev_s *dev);
|
||||
static int up_attach(struct uart_dev_s *dev);
|
||||
static void up_detach(struct uart_dev_s *dev);
|
||||
static int up_interrupt(int irq, void *context);
|
||||
static int up_ioctl(struct file *filep, int cmd, unsigned long arg);
|
||||
static int up_receive(struct USART_dev_s *dev, uint32 *status);
|
||||
static void up_rxint(struct USART_dev_s *dev, boolean enable);
|
||||
static boolean up_rxavailable(struct USART_dev_s *dev);
|
||||
static void up_send(struct USART_dev_s *dev, int ch);
|
||||
static void up_txint(struct USART_dev_s *dev, boolean enable);
|
||||
static boolean up_txready(struct USART_dev_s *dev);
|
||||
static boolean up_txempty(struct USART_dev_s *dev);
|
||||
static int up_receive(struct uart_dev_s *dev, uint32 *status);
|
||||
static void up_rxint(struct uart_dev_s *dev, boolean enable);
|
||||
static boolean up_rxavailable(struct uart_dev_s *dev);
|
||||
static void up_send(struct uart_dev_s *dev, int ch);
|
||||
static void up_txint(struct uart_dev_s *dev, boolean enable);
|
||||
static boolean up_txready(struct uart_dev_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
struct USART_ops_s g_USART_ops =
|
||||
struct uart_ops_s g_uart_ops =
|
||||
{
|
||||
.setup = up_setup,
|
||||
.shutdown = up_shutdown,
|
||||
@ -204,30 +206,31 @@ struct USART_ops_s g_USART_ops =
|
||||
.send = up_send,
|
||||
.txint = up_txint,
|
||||
.txready = up_txready,
|
||||
.txempty = up_txempty,
|
||||
.txempty = up_txready,
|
||||
};
|
||||
|
||||
/* I/O buffers */
|
||||
|
||||
#ifndef CONFIG_USART1_DISABLE
|
||||
static char g_USART1rxbuffer[CONFIG_USART1_RXBUFSIZE];
|
||||
static char g_USART1txbuffer[CONFIG_USART1_TXBUFSIZE];
|
||||
static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE];
|
||||
static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE];
|
||||
#endif
|
||||
#ifndef CONFIG_USART2_DISABLE
|
||||
static char g_USART2rxbuffer[CONFIG_USART2_RXBUFSIZE];
|
||||
static char g_USART2txbuffer[CONFIG_USART2_TXBUFSIZE];
|
||||
static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE];
|
||||
static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE];
|
||||
#endif
|
||||
#ifndef CONFIG_USART3_DISABLE
|
||||
static char g_USART3rxbuffer[CONFIG_USART3_RXBUFSIZE];
|
||||
static char g_USART3txbuffer[CONFIG_USART3_TXBUFSIZE];
|
||||
static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE];
|
||||
static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE];
|
||||
#endif
|
||||
|
||||
/* This describes the state of the STM32 USART1 ports. */
|
||||
|
||||
#ifndef CONFIG_USART1_DISABLE
|
||||
static struct up_dev_s g_USART1priv =
|
||||
static struct up_dev_s g_usart1priv =
|
||||
{
|
||||
.USARTbase = STM32_USART1_BASE,
|
||||
.usartbase = STM32_USART1_BASE,
|
||||
.apbclock = STM32_PCLK2_FREQUENCY,
|
||||
.baud = CONFIG_USART1_BAUD,
|
||||
.irq = STM32_IRQ_USART1,
|
||||
.parity = CONFIG_USART1_PARITY,
|
||||
@ -235,29 +238,30 @@ static struct up_dev_s g_USART1priv =
|
||||
.stopbits2 = CONFIG_USART1_2STOP,
|
||||
};
|
||||
|
||||
static USART_dev_t g_USART1port =
|
||||
static uart_dev_t g_usart1port =
|
||||
{
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_USART1_RXBUFSIZE,
|
||||
.buffer = g_USART1rxbuffer,
|
||||
.buffer = g_usart1rxbuffer,
|
||||
},
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_USART1_TXBUFSIZE,
|
||||
.buffer = g_USART1txbuffer,
|
||||
.buffer = g_usart1txbuffer,
|
||||
},
|
||||
.ops = &g_USART_ops,
|
||||
.priv = &g_USART1priv,
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_usart1priv,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This describes the state of the STM32 USART2 port. */
|
||||
|
||||
#ifndef CONFIG_USART2_DISABLE
|
||||
static struct up_dev_s g_USART2priv =
|
||||
static struct up_dev_s g_usart2priv =
|
||||
{
|
||||
.USARTbase = STM32_USART2_BASE,
|
||||
.usartbase = STM32_USART2_BASE,
|
||||
.apbclock = STM32_PCLK1_FREQUENCY,
|
||||
.baud = CONFIG_USART2_BAUD,
|
||||
.irq = STM32_IRQ_USART2,
|
||||
.parity = CONFIG_USART2_PARITY,
|
||||
@ -265,29 +269,30 @@ static struct up_dev_s g_USART2priv =
|
||||
.stopbits2 = CONFIG_USART2_2STOP,
|
||||
};
|
||||
|
||||
static USART_dev_t g_USART2port =
|
||||
static uart_dev_t g_usart2port =
|
||||
{
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_USART2_RXBUFSIZE,
|
||||
.buffer = g_USART2rxbuffer,
|
||||
.buffer = g_usart2rxbuffer,
|
||||
},
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_USART2_TXBUFSIZE,
|
||||
.buffer = g_USART2txbuffer,
|
||||
.buffer = g_usart2txbuffer,
|
||||
},
|
||||
.ops = &g_USART_ops,
|
||||
.priv = &g_USART2priv,
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_usart2priv,
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This describes the state of the STM32 USART3 port. */
|
||||
|
||||
#ifndef CONFIG_USART3_DISABLE
|
||||
static struct up_dev_s g_USART3priv =
|
||||
static struct up_dev_s g_usart3priv =
|
||||
{
|
||||
.USARTbase = STM32_USART3_BASE,
|
||||
.usartbase = STM32_USART3_BASE,
|
||||
.apbclock = STM32_PCLK1_FREQUENCY,
|
||||
.baud = CONFIG_USART3_BAUD,
|
||||
.irq = STM32_IRQ_USART3,
|
||||
.parity = CONFIG_USART3_PARITY,
|
||||
@ -295,20 +300,20 @@ static struct up_dev_s g_USART3priv =
|
||||
.stopbits2 = CONFIG_USART3_2STOP,
|
||||
};
|
||||
|
||||
static USART_dev_t g_USART3port =
|
||||
static uart_dev_t g_usart3port =
|
||||
{
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_USART3_RXBUFSIZE,
|
||||
.buffer = g_USART3rxbuffer,
|
||||
.buffer = g_usart3rxbuffer,
|
||||
},
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_USART3_TXBUFSIZE,
|
||||
.buffer = g_USART3txbuffer,
|
||||
.buffer = g_usart3txbuffer,
|
||||
},
|
||||
.ops = &g_USART_ops,
|
||||
.priv = &g_USART3priv,
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_usart3priv,
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -320,94 +325,210 @@ static USART_dev_t g_USART3port =
|
||||
* Name: up_serialin
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32 up_serialin(struct up_dev_s *priv, int offset)
|
||||
static inline uint16 up_serialin(struct up_dev_s *priv, int offset)
|
||||
{
|
||||
return getreg32(priv->USARTbase + offset);
|
||||
return getreg16(priv->usartbase + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_serialout
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_serialout(struct up_dev_s *priv, int offset, uint32 value)
|
||||
static inline void up_serialout(struct up_dev_s *priv, int offset, uint16 value)
|
||||
{
|
||||
putreg32(value, priv->USARTbase + offset);
|
||||
putreg16(value, priv->usartbase + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_serialout32
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_serialout32(struct up_dev_s *priv, int offset, uint32 value)
|
||||
{
|
||||
putreg32(value, priv->usartbase + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_disableusartint
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_disableusartint(struct up_dev_s *priv, uint32 *im)
|
||||
static inline void up_disableusartint(struct up_dev_s *priv, uint16 *ie)
|
||||
{
|
||||
/* Return the current interrupt mask value */
|
||||
|
||||
if (im)
|
||||
if (ie)
|
||||
{
|
||||
*im = priv->im;
|
||||
uint16 cr1;
|
||||
uint16 cr3;
|
||||
|
||||
/* USART interrupts:
|
||||
*
|
||||
* Enable Bit Status Meaning Usage
|
||||
* ------------------ --- --------------- ------------------------------ ----------
|
||||
* USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
|
||||
* USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
|
||||
* " " USART_SR_ORE Overrun Error Detected
|
||||
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used)
|
||||
* USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty
|
||||
* USART_CR1_PEIE 8 USART_SR_PE Parity Error
|
||||
*
|
||||
* USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
|
||||
* USART_CR3_EIE 0 USART_SR_FE Framing Error
|
||||
* " " USART_SR_NE Noise Error
|
||||
* " " USART_SR_ORE Overrun Error Detected
|
||||
* USART_CR3_CTSIE 10 USART_SR_CTS CTS flag (not used)
|
||||
*/
|
||||
|
||||
cr1 = up_serialin(priv, STM32_USART_CR1_OFFSET);
|
||||
cr3 = up_serialin(priv, STM32_USART_CR3_OFFSET);
|
||||
|
||||
/* Return the current interrupt mask value for the used interrupts. Notice
|
||||
* that this depends on the fact that none of the used interrupt enable bits
|
||||
* overlap. This logic would fail if we needed the break interrupt!
|
||||
*/
|
||||
|
||||
*ie = (cr1 & (USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE)) | (cr3 & USART_CR3_EIE);
|
||||
}
|
||||
|
||||
/* Disable all interrupts */
|
||||
|
||||
priv->im = 0;
|
||||
up_restoreusartint(priv, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_restoreusartint
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_restoreusartint(struct up_dev_s *priv, uint32 im)
|
||||
static inline void up_restoreusartint(struct up_dev_s *priv, uint16 ie)
|
||||
{
|
||||
priv->im = im;
|
||||
uint16 cr;
|
||||
|
||||
/* Save the interrupt mask */
|
||||
|
||||
priv->ie = ie;
|
||||
|
||||
/* And restore the interrupt state (see the interrupt enable/usage table above) */
|
||||
|
||||
cr = up_serialin(priv, STM32_USART_CR1_OFFSET);
|
||||
cr &= ~(USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE);
|
||||
cr |= (cr1 & (USART_CR1_RXNEIE|USART_CR1_TXEIE|USART_CR1_PEIE));
|
||||
up_serialout((priv, STM32_USART_CR1_OFFSET, cr)
|
||||
|
||||
cr = up_serialin(priv, STM32_USART_CR3_OFFSET);
|
||||
cr &= ~USART_CR3_EIE;
|
||||
cr |= (cr1 & USART_CR3_EIE);
|
||||
up_serialout((priv, STM32_USART_CR3_OFFSET, cr)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the USART baud, bits, parity, fifos, etc. This
|
||||
* method is called the first time that the serial port is
|
||||
* opened.
|
||||
* Configure the USART baud, bits, parity, fifos, etc. This method is
|
||||
* called the first time that the serial port is opened.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int up_setup(struct USART_dev_s *dev)
|
||||
static int up_setup(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
|
||||
/* Note: The logic here depends on the fact that that the USART module
|
||||
* was enabled and the GPIOs were configured in up_lowsetup().
|
||||
*/
|
||||
|
||||
/* Disable the USART */
|
||||
|
||||
/* Calculate BAUD rate from the SYS clock */
|
||||
|
||||
/* Set the USART to interrupt whenever the TX FIFO is almost empty or when
|
||||
* any character is received.
|
||||
*/
|
||||
|
||||
/* Flush the Rx and Tx FIFOs */
|
||||
|
||||
/* Enable Rx interrupts from the USART except for Tx interrupts. We don't want
|
||||
* Tx interrupts until we have something to send. We will check for serial
|
||||
* errors as part of Rx interrupt processing (no interrupts will be received
|
||||
* yet because the interrupt is still disabled at the interrupt controller.
|
||||
*/
|
||||
|
||||
/* Enable the FIFOs */
|
||||
|
||||
#ifdef CONFIG_SUPPRESS_USART_CONFIG
|
||||
#endif
|
||||
uint32 uartdiv32;
|
||||
uint32 mantissa;
|
||||
uint32 fraction;
|
||||
uint32 brr;
|
||||
uint16 regval;
|
||||
|
||||
/* Note: The logic here depends on the fact that that the USART module
|
||||
* was enabled and the pins were configured in up_lowsetup().
|
||||
*/
|
||||
|
||||
/* Configure CR2 */
|
||||
/* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */
|
||||
|
||||
regval = up_serialin(priv, STM32_USART_CR2_OFFSET);
|
||||
regval &= ~(USART_CR2_STOP_MASK|USART_CR2_CLKEN|USART_CR2_CPOL|
|
||||
USART_CR2_CPHA|USART_CR2_LBCL|USART_CR2_LBDIE);
|
||||
|
||||
/* Configure STOP bits */
|
||||
|
||||
if (priv->stopbits2)
|
||||
{
|
||||
regval |= USART_CR2_STOP2;
|
||||
}
|
||||
up_serialout(priv, STM32_USART_CR2_OFFSET, regval);
|
||||
|
||||
/* Configure CR1 */
|
||||
/* Clear M, PCE, PS, TE, REm and all interrupt enable bits */
|
||||
|
||||
regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
|
||||
regval &= ~(USART_CR1_M|USART_CR1_PCE|USART_CR1_PS|USART_CR1_TE|
|
||||
USART_CR1_RE|USART_CR1_ALLINTS);
|
||||
|
||||
/* Configure word length and parity mode */
|
||||
|
||||
if (priv->bits == 9) /* Default: 1 start, 8 data, n stop */
|
||||
{
|
||||
regval |= USART_CR1_M; /* 1 start, 9 data, n stop */
|
||||
}
|
||||
|
||||
if (priv->parity == 1) /* Odd parity */
|
||||
{
|
||||
regval |= (USART_CR1_PCE|USART_CR1_PS);
|
||||
}
|
||||
else if (priv->parity == 2) /* Even parity */
|
||||
{
|
||||
regval |= USART_CR1_PCE;
|
||||
}
|
||||
up_serialout(priv, STM32_USART_CR1_OFFSET, regval);
|
||||
|
||||
/* Configure CR3 */
|
||||
/* Clear CTSE, RTSE, and all interrupt enable bits */
|
||||
|
||||
regval = up_serialin(priv, STM32_USART_CR3_OFFSET);
|
||||
regval &= ~(USART_CR3_CTSIE|USART_CR3_CTSE|USART_CR3_RTSE|USART_CR3_EIE);
|
||||
|
||||
/* Configure hardware flow control -- Not yet supported */
|
||||
|
||||
up_serialout(priv, STM32_USART_CR1_OFFSET, regval);
|
||||
|
||||
/* Configure the USART Baud Rate. 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)
|
||||
*/
|
||||
|
||||
usartdiv32 = priv->apbclock / (priv->baud >> 1);
|
||||
|
||||
/* The mantissa part is then */
|
||||
|
||||
mantissa = usartdiv32 >> 5;
|
||||
brr = mantissa << USART_BRR_MANT_SHIFT;
|
||||
|
||||
/* The fractional remainder (with rounding) */
|
||||
|
||||
fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1;
|
||||
brr |= fraction << USART_BRR_FRAC_SHIFT;
|
||||
up_serialout32(priv, STM32_USART1_BRR, brr);
|
||||
|
||||
/* Enable Rx, Tx, and the USART */
|
||||
|
||||
#ifdef CONFIG_SUPPRESS_USART_CONFIG
|
||||
regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
|
||||
regval |= (USART_CR1_UE|USART_CR1_TE|USART_CR1_RE);
|
||||
up_serialout(priv, STM32_USART_CR1_OFFSET, regval);
|
||||
#endif
|
||||
|
||||
/* Set up the cache IM value */
|
||||
/* Set up the cache interrupt enables value */
|
||||
|
||||
// priv->im =
|
||||
priv->ie = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -420,10 +541,20 @@ static int up_setup(struct USART_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_shutdown(struct USART_dev_s *dev)
|
||||
static void up_shutdown(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
uint16 regval;
|
||||
|
||||
/* Disable all interrupts */
|
||||
|
||||
up_disableusartint(priv, NULL);
|
||||
|
||||
/* Disable Rx, Tx, and the UART */
|
||||
|
||||
regval = up_serialin(priv, STM32_USART_CR1_OFFSET);
|
||||
regval &= ~(USART_CR1_UE|USART_CR1_TE|USART_CR1_RE
|
||||
up_serialout(priv, STM32_USART_CR1_OFFSET, regval);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -441,7 +572,7 @@ static void up_shutdown(struct USART_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int up_attach(struct USART_dev_s *dev)
|
||||
static int up_attach(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
int ret;
|
||||
@ -470,7 +601,7 @@ static int up_attach(struct USART_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_detach(struct USART_dev_s *dev)
|
||||
static void up_detach(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
up_disable_irq(priv->irq);
|
||||
@ -485,35 +616,35 @@ static void up_detach(struct USART_dev_s *dev)
|
||||
* interrupt received on the 'irq' It should call uart_transmitchars or
|
||||
* uart_receivechar to perform the appropriate data transfers. The
|
||||
* interrupt handling logic must be able to map the 'irq' number into the
|
||||
* approprite USART_dev_s structure in order to call these functions.
|
||||
* approprite uart_dev_s structure in order to call these functions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int up_interrupt(int irq, void *context)
|
||||
{
|
||||
struct USART_dev_s *dev = NULL;
|
||||
struct uart_dev_s *dev = NULL;
|
||||
struct up_dev_s *priv;
|
||||
int passes;
|
||||
boolean handled;
|
||||
|
||||
#ifndef CONFIG_USART1_DISABLE
|
||||
if (g_USART1priv.irq == irq)
|
||||
if (g_usart1priv.irq == irq)
|
||||
{
|
||||
dev = &g_USART1port;
|
||||
dev = &g_usart1port;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CONFIG_USART2_DISABLE
|
||||
if (g_USART2priv.irq == irq)
|
||||
if (g_usart2priv.irq == irq)
|
||||
{
|
||||
dev = &g_USART2port;
|
||||
dev = &g_usart2port;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifndef CONFIG_USART3_DISABLE
|
||||
if (g_USART3priv.irq == irq)
|
||||
if (g_usart3priv.irq == irq)
|
||||
{
|
||||
dev = &g_USART3port;
|
||||
dev = &g_usart3port;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -533,10 +664,35 @@ static int up_interrupt(int irq, void *context)
|
||||
|
||||
/* Get the masked USART status and clear the pending interrupts. */
|
||||
|
||||
priv->sr = up_serialin(priv, STM32_USART_SR_OFFSET);
|
||||
|
||||
/* USART interrupts:
|
||||
*
|
||||
* Enable Bit Status Meaning Usage
|
||||
* ------------------ --- --------------- ------------------------------- ----------
|
||||
* USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
|
||||
* USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
|
||||
* " " USART_SR_ORE Overrun Error Detected
|
||||
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used)
|
||||
* USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty
|
||||
* USART_CR1_PEIE 8 USART_SR_PE Parity Error
|
||||
*
|
||||
* USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
|
||||
* USART_CR3_EIE 0 USART_SR_FE Framing Error
|
||||
* " " USART_SR_NE Noise Error
|
||||
* " " USART_SR_ORE Overrun Error Detected
|
||||
* USART_CR3_CTSIE 10 USART_SR_CTS CTS flag (not used)
|
||||
*
|
||||
* NOTE: Some of these status bits must be cleared by explicity writing zero
|
||||
* to the SR register: USART_SR_CTS, USART_SR_LBD. Note of those are currently
|
||||
* being used.
|
||||
*/
|
||||
|
||||
/* Handle incoming, receive bytes (with or without timeout) */
|
||||
|
||||
if ((priv->sr & USART_SR_RXNE) != 0 && (priv->ie & USART_CR1_RXNEIE) != 0)
|
||||
{
|
||||
/* Rx buffer not empty ... process incoming bytes */
|
||||
/* Received data ready... process incoming bytes */
|
||||
|
||||
uart_recvchars(dev);
|
||||
handled = TRUE;
|
||||
@ -544,8 +700,9 @@ static int up_interrupt(int irq, void *context)
|
||||
|
||||
/* Handle outgoing, transmit bytes */
|
||||
|
||||
if ((priv->sr & USART_SR_TXE) != 0 && (priv->ie & USART_CR1_TXEIE) != 0)
|
||||
{
|
||||
/* Tx FIFO not full ... process outgoing bytes */
|
||||
/* Transmit data regiser empty ... process outgoing bytes */
|
||||
|
||||
uart_xmitchars(dev);
|
||||
handled = TRUE;
|
||||
@ -565,7 +722,10 @@ static int up_interrupt(int irq, void *context)
|
||||
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = filep->f_inode;
|
||||
struct USART_dev_s *dev = inode->i_private;
|
||||
struct uart_dev_s *dev = inode->i_private;
|
||||
#ifdef CONFIG_USART_BREAKS
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
#endif
|
||||
int ret = OK;
|
||||
|
||||
switch (cmd)
|
||||
@ -584,6 +744,27 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_USART_BREAKS
|
||||
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
|
||||
{
|
||||
irqstate_t flags = irqsave();
|
||||
uint32 cr2 = up_serialin(priv, STM32_USART_CR2_OFFSET);
|
||||
up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 | USART_CR2_LINEN);
|
||||
irqrestore(flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
|
||||
{
|
||||
irqstate_t flags;
|
||||
flags = irqsave();
|
||||
uint32 cr1 = up_serialin(priv, STM32_USART_CR2_OFFSET);
|
||||
up_serialout(priv, STM32_USART_CR2_OFFSET, cr2 & ~USART_CR2_LINEN);
|
||||
irqrestore(flags);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
@ -602,18 +783,23 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int up_receive(struct USART_dev_s *dev, uint32 *status)
|
||||
static int up_receive(struct uart_dev_s *dev, uint32 *status)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
uint32 rxd;
|
||||
uint16 dr;
|
||||
|
||||
/* Get the Rx byte */
|
||||
|
||||
dr = up_serialin(priv, STM32_USART_DR_OFFSET);
|
||||
|
||||
/* Get the Rx byte plux error information. Return those in status */
|
||||
|
||||
*status = rxd;
|
||||
*status = (uint32)priv->sr << 16 | dr;
|
||||
priv->sr = 0;
|
||||
|
||||
/* Then return the actual received byte */
|
||||
|
||||
return rxd & 0xff;
|
||||
return dr & 0xff;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -624,9 +810,27 @@ static int up_receive(struct USART_dev_s *dev, uint32 *status)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_rxint(struct USART_dev_s *dev, boolean enable)
|
||||
static void up_rxint(struct uart_dev_s *dev, boolean enable)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
uint16 ie;
|
||||
|
||||
/* USART receive interrupts:
|
||||
*
|
||||
* Enable Bit Status Meaning Usage
|
||||
* ------------------ --- --------------- ------------------------------- ----------
|
||||
* USART_CR1_IDLEIE 4 USART_SR_IDLE Idle Line Detected (not used)
|
||||
* USART_CR1_RXNEIE 5 USART_SR_RXNE Received Data Ready to be Read
|
||||
* " " USART_SR_ORE Overrun Error Detected
|
||||
* USART_CR1_PEIE 8 USART_SR_PE Parity Error
|
||||
*
|
||||
* USART_CR2_LBDIE 6 USART_SR_LBD Break Flag (not used)
|
||||
* USART_CR3_EIE 0 USART_SR_FE Framing Error
|
||||
* " " USART_SR_NE Noise Error
|
||||
* " " USART_SR_ORE Overrun Error Detected
|
||||
*/
|
||||
|
||||
ie = priv->ie;
|
||||
if (enable)
|
||||
{
|
||||
/* Receive an interrupt when their is anything in the Rx FIFO (or an Rx
|
||||
@ -634,13 +838,21 @@ static void up_rxint(struct USART_dev_s *dev, boolean enable)
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
// priv->im |= ;
|
||||
#ifdef CONFIG_USART_ERRINTS
|
||||
ie |= (USART_CR1_RXNEIE|USART_CR1_PEIE|USART_CR3_EIE);
|
||||
#else
|
||||
ie |= USART_CR1_RXNEIE;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// priv->im &= ~();
|
||||
ie &= ~(USART_CR1_RXNEIE|USART_CR1_PEIE|USART_CR3_EIE);
|
||||
}
|
||||
|
||||
/* Then set the new interrupt state */
|
||||
|
||||
up_restoreusartint(priv, ie);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -651,10 +863,10 @@ static void up_rxint(struct USART_dev_s *dev, boolean enable)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static boolean up_rxavailable(struct USART_dev_s *dev)
|
||||
static boolean up_rxavailable(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
return 0;
|
||||
return ((up_serialin(priv, STM32_USART_SR_OFFSET) & USART_SR_RXNE) != 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -665,9 +877,10 @@ static boolean up_rxavailable(struct USART_dev_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_send(struct USART_dev_s *dev, int ch)
|
||||
static void up_send(struct uart_dev_s *dev, int ch)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
up_serialout(priv, STM32_USART_DR_OFFSET, (uint16)ch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -678,23 +891,31 @@ static void up_send(struct USART_dev_s *dev, int ch)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_txint(struct USART_dev_s *dev, boolean enable)
|
||||
static void up_txint(struct uart_dev_s *dev, boolean enable)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
irqstate_t flags;
|
||||
uint16 ie;
|
||||
|
||||
/* USART transmit interrupts:
|
||||
*
|
||||
* Enable Bit Status Meaning Usage
|
||||
* ------------------ --- --------------- ---------------------------- ----------
|
||||
* USART_CR1_TCIE 6 USART_SR_TC Transmission Complete (not used)
|
||||
* USART_CR1_TXEIE 7 USART_SR_TXE Transmit Data Register Empty
|
||||
* USART_CR3_CTSIE 10 USART_SR_CTS CTS flag (not used)
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
if (enable)
|
||||
{
|
||||
/* Set to receive an interrupt when the TX fifo is half emptied */
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
// priv->im |= ;
|
||||
up_serialout(priv, stm32_USART_IM_OFFSET, priv->im);
|
||||
up_restoreusartint(priv, priv->ie | USART_CR1_TXEIE);
|
||||
|
||||
/* Fake a TX interrupt here by just calling uart_xmitchars() with
|
||||
* interrupts disabled (note that the may recurse and that priv->im
|
||||
* may be altered.
|
||||
* interrupts disabled (note this may recurse).
|
||||
*/
|
||||
|
||||
uart_xmitchars(dev);
|
||||
@ -704,7 +925,7 @@ static void up_txint(struct USART_dev_s *dev, boolean enable)
|
||||
{
|
||||
/* Disable the TX interrupt */
|
||||
|
||||
// priv->im &= ~();
|
||||
up_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE);
|
||||
}
|
||||
irqrestore(flags);
|
||||
}
|
||||
@ -717,24 +938,10 @@ static void up_txint(struct USART_dev_s *dev, boolean enable)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static boolean up_txready(struct USART_dev_s *dev)
|
||||
static boolean up_txready(struct uart_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_txempty
|
||||
*
|
||||
* Description:
|
||||
* Return TRUE if the transmit fifo is empty
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static boolean up_txempty(struct USART_dev_s *dev)
|
||||
{
|
||||
struct up_dev_s *priv = (struct up_dev_s*)dev->priv;
|
||||
return 0;
|
||||
return ((up_serialin(priv, STM32_USART_SR_OFFSET) & USART_SR_TXE) != 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -815,9 +1022,9 @@ int up_putc(int ch)
|
||||
{
|
||||
#ifdef HAVE_CONSOLE
|
||||
struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv;
|
||||
uint32 im;
|
||||
uint16 ie;
|
||||
|
||||
up_disableusartint(priv, &im);
|
||||
up_disableusartint(priv, &ie);
|
||||
|
||||
/* Check for LF */
|
||||
|
||||
@ -829,7 +1036,7 @@ int up_putc(int ch)
|
||||
}
|
||||
|
||||
up_lowputc(ch);
|
||||
up_restoreusartint(priv, im);
|
||||
up_restoreusartint(priv, ie);
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user