arch/arm/src/stm32l4: LPUART1 support

Signed-off-by: Harri Luhtala <harri.luhtala@haltian.com>
This commit is contained in:
Harri Luhtala 2021-08-12 15:43:21 +03:00 committed by David Sidrane
parent 198c30eaa6
commit 7e3c813346
5 changed files with 235 additions and 40 deletions

View File

@ -571,6 +571,7 @@ config STM32L4_STM32L4X3
bool
default n
select ARCH_HAVE_FPU
select STM32L4_HAVE_LPUART1
select STM32L4_HAVE_USART1
select STM32L4_HAVE_USART2
select STM32L4_HAVE_USART3 if !(STM32L4_STM32L432XX || STM32L4_STM32L442XX)
@ -586,6 +587,7 @@ config STM32L4_STM32L4X5
bool
default n
select ARCH_HAVE_FPU
select STM32L4_HAVE_LPUART1
select STM32L4_HAVE_USART1
select STM32L4_HAVE_USART2
select STM32L4_HAVE_USART3
@ -616,6 +618,7 @@ config STM32L4_STM32L4X6
bool
default n
select ARCH_HAVE_FPU
select STM32L4_HAVE_LPUART1
select STM32L4_HAVE_USART1
select STM32L4_HAVE_USART2
select STM32L4_HAVE_USART3
@ -646,6 +649,7 @@ config STM32L4_STM32L4XR
bool
default n
select ARCH_HAVE_FPU
select STM32L4_HAVE_LPUART1
select STM32L4_HAVE_USART1
select STM32L4_HAVE_USART2
select STM32L4_HAVE_USART3
@ -1127,6 +1131,10 @@ config STM32L4_HAVE_TIM17
bool
default n
config STM32L4_HAVE_LPUART1
bool
default n
config STM32L4_HAVE_USART1
bool
default n
@ -1491,6 +1499,13 @@ config STM32L4_SPI3
select SPI
select STM32L4_SPI
config STM32L4_LPUART1
bool "LPUART1"
default n
depends on STM32L4_HAVE_LPUART1
select ARCH_HAVE_SERIAL_TERMIOS
select STM32L4_USART
config STM32L4_USART2
bool "USART2"
default n
@ -5486,9 +5501,54 @@ config STM32L4_SERIALDRIVER
config STM32L4_1WIREDRIVER
bool
menu "U[S]ART Configuration"
menu "[LP]U[S]ART Configuration"
depends on STM32L4_USART
choice
prompt "LPUART1 Driver Configuration"
default STM32L4_LPUART1_SERIALDRIVER
depends on STM32L4_LPUART1
config STM32L4_LPUART1_SERIALDRIVER
bool "Standard serial driver"
select LPUART1_SERIALDRIVER
select STM32L4_SERIALDRIVER
config STM32L4_LPUART1_1WIREDRIVER
bool "1-Wire driver"
select STM32L4_1WIREDRIVER
endchoice # LPUART1 Driver Configuration
if LPUART1_SERIALDRIVER
config LPUART1_RS485
bool "RS-485 on LPUART1"
default n
depends on STM32L4_LPUART1
---help---
Enable RS-485 interface on LPUART1. Your board config will have to
provide GPIO_LPUART1_RS485_DIR pin definition. Currently it cannot be
used with LPUART1_RXDMA.
config LPUART1_RS485_DIR_POLARITY
int "LPUART1 RS-485 DIR pin polarity"
default 1
range 0 1
depends on LPUART1_RS485
---help---
Polarity of DIR pin for RS-485 on LPUART1. Set to state on DIR pin which
enables TX (0 - low / nTXEN, 1 - high / TXEN).
config LPUART1_RXDMA
bool "LPUART1 Rx DMA"
default n
depends on STM32L4_LPUART1 && (STM32L4_DMA1 || STM32L4_DMA2 || STM32L4_DMAMUX)
---help---
In high data rate usage, Rx DMA may eliminate Rx overrun errors
endif # LPUART1_SERIALDRIVER
choice
prompt "USART1 Driver Configuration"
default STM32L4_USART1_SERIALDRIVER

View File

@ -46,8 +46,8 @@ MSI : OK
LSE : OK
RCC : All registers defined, peripherals enabled, basic clock working
SYSCTL : All registers defined
USART : Working in normal mode (no DMA, to be tested, code is written)
DMA : works; at least tested with QSPI
USART : OK
DMA : OK
SRAM2 : OK; can be included in MM region or left separate for special app
: purposes
SPI : OK, tested (including DMA)
@ -81,7 +81,8 @@ FIREWALL : Code written, to be tested, requires support from ldscript
TSC : TODO (Touch Screen Controller)
SWP : TODO (Single wire protocol master, to connect with NFC enabled
: SIM cards)
LPUART : TODO (Low power UART working with LSE at low baud rates)
LPUART : Experimental support (Low power UART working with LSE at low
: baud rates)
LPTIM : Code written, to be tested (Low power TIMER)
OPAMP : TODO (Analog operational amplifier)
COMP : There is some code (Analog comparators)
@ -94,7 +95,7 @@ DCMI : TODO (Digital Camera interfaces)
New peripherals only in STM32L4+:
DMAMUX1 : TODO
DMAMUX1 : OK
DSI : TODO
GFXMMU : TODO
LTDC : TODO

View File

@ -45,7 +45,26 @@
/* Select USART parameters for the selected console */
#ifdef HAVE_CONSOLE
# if defined(CONFIG_USART1_SERIAL_CONSOLE)
# if defined(CONFIG_LPUART1_SERIAL_CONSOLE)
# define STM32L4_CONSOLE_BASE STM32L4_LPUART1_BASE
# define STM32L4_APBCLOCK STM32L4_PCLK1_FREQUENCY
# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB1ENR2
# define STM32L4_CONSOLE_APBEN RCC_APB1ENR2_LPUART1EN
# define STM32L4_CONSOLE_BAUD CONFIG_LPUART1_BAUD
# define STM32L4_CONSOLE_BITS CONFIG_LPUART1_BITS
# define STM32L4_CONSOLE_PARITY CONFIG_LPUART1_PARITY
# define STM32L4_CONSOLE_2STOP CONFIG_LPUART1_2STOP
# define STM32L4_CONSOLE_TX GPIO_LPUART1_TX
# define STM32L4_CONSOLE_RX GPIO_LPUART1_RX
# ifdef CONFIG_LPUART1_RS485
# define STM32L4_CONSOLE_RS485_DIR GPIO_LPUART1_RS485_DIR
# if (CONFIG_LPUART1_RS485_DIR_POLARITY == 0)
# define STM32L4_CONSOLE_RS485_DIR_POLARITY false
# else
# define STM32L4_CONSOLE_RS485_DIR_POLARITY true
# endif
# endif
# elif defined(CONFIG_USART1_SERIAL_CONSOLE)
# define STM32L4_CONSOLE_BASE STM32L4_USART1_BASE
# define STM32L4_APBCLOCK STM32L4_PCLK2_FREQUENCY
# define STM32L4_CONSOLE_APBREG STM32L4_RCC_APB2ENR

View File

@ -391,6 +391,14 @@ static const struct uart_ops_s g_uart_dma_ops =
/* I/O buffers */
#ifdef CONFIG_STM32L4_LPUART1_SERIALDRIVER
static char g_lpuart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE];
static char g_lpuart1txbuffer[CONFIG_LPUART1_TXBUFSIZE];
# ifdef CONFIG_LPUART1_RXDMA
static char g_lpuart1rxfifo[RXDMA_BUFFER_SIZE];
# endif
#endif
#ifdef CONFIG_STM32L4_USART1_SERIALDRIVER
static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE];
static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE];
@ -431,14 +439,75 @@ static char g_uart5rxfifo[RXDMA_BUFFER_SIZE];
# endif
#endif
/* This describes the state of the STM32 USART1 ports. */
/* This describes the state of the STM32 LPUART1 port. */
#ifdef CONFIG_STM32L4_LPUART1_SERIALDRIVER
static struct stm32l4_serial_s g_lpuart1priv =
{
.dev =
{
#if CONSOLE_UART == 1
.isconsole = true,
#endif
.recv =
{
.size = CONFIG_LPUART1_RXBUFSIZE,
.buffer = g_lpuart1rxbuffer,
},
.xmit =
{
.size = CONFIG_LPUART1_TXBUFSIZE,
.buffer = g_lpuart1txbuffer,
},
#ifdef CONFIG_LPUART1_RXDMA
.ops = &g_uart_dma_ops,
#else
.ops = &g_uart_ops,
#endif
.priv = &g_lpuart1priv,
},
.irq = STM32L4_IRQ_LPUART1,
.parity = CONFIG_LPUART1_PARITY,
.bits = CONFIG_LPUART1_BITS,
.stopbits2 = CONFIG_LPUART1_2STOP,
.baud = CONFIG_LPUART1_BAUD,
.apbclock = STM32L4_PCLK1_FREQUENCY,
.usartbase = STM32L4_LPUART1_BASE,
.tx_gpio = GPIO_LPUART1_TX,
.rx_gpio = GPIO_LPUART1_RX,
#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL)
.oflow = true,
.cts_gpio = GPIO_LPUART1_CTS,
#endif
#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL)
.iflow = true,
.rts_gpio = GPIO_LPUART1_RTS,
#endif
#ifdef CONFIG_LPUART1_RXDMA
.rxdma_channel = DMAMAP_LPUART1_RX,
.rxfifo = g_lpuart1rxfifo,
#endif
#ifdef CONFIG_LPUART1_RS485
.rs485_dir_gpio = GPIO_LPUART1_RS485_DIR,
# if (CONFIG_USART1_RS485_DIR_POLARITY == 0)
.rs485_dir_polarity = false,
# else
.rs485_dir_polarity = true,
# endif
#endif
};
#endif
/* This describes the state of the STM32 USART1 port. */
#ifdef CONFIG_STM32L4_USART1_SERIALDRIVER
static struct stm32l4_serial_s g_usart1priv =
{
.dev =
{
#if CONSOLE_UART == 1
#if CONSOLE_UART == 2
.isconsole = true,
#endif
.recv =
@ -499,7 +568,7 @@ static struct stm32l4_serial_s g_usart2priv =
{
.dev =
{
#if CONSOLE_UART == 2
#if CONSOLE_UART == 3
.isconsole = true,
#endif
.recv =
@ -560,7 +629,7 @@ static struct stm32l4_serial_s g_usart3priv =
{
.dev =
{
#if CONSOLE_UART == 3
#if CONSOLE_UART == 4
.isconsole = true,
#endif
.recv =
@ -621,7 +690,7 @@ static struct stm32l4_serial_s g_uart4priv =
{
.dev =
{
#if CONSOLE_UART == 4
#if CONSOLE_UART == 5
.isconsole = true,
#endif
.recv =
@ -682,7 +751,7 @@ static struct stm32l4_serial_s g_uart5priv =
{
.dev =
{
#if CONSOLE_UART == 5
#if CONSOLE_UART == 6
.isconsole = true,
#endif
.recv =
@ -739,22 +808,25 @@ static struct stm32l4_serial_s g_uart5priv =
/* This table lets us iterate over the configured USARTs */
FAR static struct stm32l4_serial_s *
const g_uart_devs[STM32L4_NUSART + STM32L4_NUART] =
const g_uart_devs[STM32L4_NLPUART + STM32L4_NUSART + STM32L4_NUART] =
{
#ifdef CONFIG_STM32L4_LPUART1_SERIALDRIVER
[0] = &g_lpuart1priv,
#endif
#ifdef CONFIG_STM32L4_USART1_SERIALDRIVER
[0] = &g_usart1priv,
[1] = &g_usart1priv,
#endif
#ifdef CONFIG_STM32L4_USART2_SERIALDRIVER
[1] = &g_usart2priv,
[2] = &g_usart2priv,
#endif
#ifdef CONFIG_STM32L4_USART3_SERIALDRIVER
[2] = &g_usart3priv,
[3] = &g_usart3priv,
#endif
#ifdef CONFIG_STM32L4_UART4_SERIALDRIVER
[3] = &g_uart4priv,
[4] = &g_uart4priv,
#endif
#ifdef CONFIG_STM32L4_UART5_SERIALDRIVER
[4] = &g_uart5priv,
[5] = &g_uart5priv,
#endif
};
@ -1215,7 +1287,7 @@ static void stm32l4serial_pm_setsuspend(bool suspend)
g_serialpm.serial_suspended = suspend;
for (n = 0; n < STM32L4_NUSART + STM32L4_NUART; n++)
for (n = 0; n < STM32L4_NLPUART + STM32L4_NUSART + STM32L4_NUART; n++)
{
struct stm32l4_serial_s *priv = g_uart_devs[n];
@ -1254,6 +1326,12 @@ static void stm32l4serial_setapbclock(FAR struct uart_dev_s *dev, bool on)
{
default:
return;
#ifdef CONFIG_STM32L4_LPUART1_SERIALDRIVER
case STM32L4_LPUART1_BASE:
rcc_en = RCC_APB1ENR2_LPUART1EN;
regaddr = STM32L4_RCC_APB1ENR2;
break;
#endif
#ifdef CONFIG_STM32L4_USART1_SERIALDRIVER
case STM32L4_USART1_BASE:
rcc_en = RCC_APB2ENR_USART1EN;
@ -2885,7 +2963,7 @@ static int stm32l4serial_pmprepare(FAR struct pm_callback_s *cb, int domain,
* buffers.
*/
for (n = 0; n < STM32L4_NUSART + STM32L4_NUART; n++)
for (n = 0; n < STM32L4_NLPUART + STM32L4_NUSART + STM32L4_NUART; n++)
{
struct stm32l4_serial_s *priv = g_uart_devs[n];
@ -2955,7 +3033,7 @@ void arm_earlyserialinit(void)
/* Disable all USART interrupts */
for (i = 0; i < STM32L4_NUSART + STM32L4_NUART; i++)
for (i = 0; i < STM32L4_NLPUART + STM32L4_NUSART + STM32L4_NUART; i++)
{
if (g_uart_devs[i])
{
@ -3024,7 +3102,7 @@ void arm_serialinit(void)
strcpy(devname, "/dev/ttySx");
for (i = 0; i < STM32L4_NUSART + STM32L4_NUART; i++)
for (i = 0; i < STM32L4_NLPUART + STM32L4_NUSART + STM32L4_NUART; i++)
{
/* Don't create a device for non-configured ports. */
@ -3068,6 +3146,13 @@ void stm32l4_serial_dma_poll(void)
flags = enter_critical_section();
#ifdef CONFIG_LPUART1_RXDMA
if (g_lpuart1priv.rxdma != NULL)
{
stm32l4serial_dmarxcallback(g_lpuart1priv.rxdma, 0, &g_lpuart1priv);
}
#endif
#ifdef CONFIG_USART1_RXDMA
if (g_usart1priv.rxdma != NULL)
{

View File

@ -60,9 +60,16 @@
#if !defined(CONFIG_STM32L4_HAVE_USART1)
# undef CONFIG_STM32L4_USART1
#endif
#if !defined(CONFIG_STM32L4_HAVE_LPUART1)
# undef CONFIG_STM32L4_LPUART1
#endif
/* Sanity checks */
#if !defined(CONFIG_STM32L4_LPUART1)
# undef CONFIG_STM32L4_LPUART1_SERIALDRIVER
# undef CONFIG_STM32L4_LPUART1_1WIREDRIVER
#endif
#if !defined(CONFIG_STM32L4_USART1)
# undef CONFIG_STM32L4_USART1_SERIALDRIVER
# undef CONFIG_STM32L4_USART1_1WIREDRIVER
@ -86,50 +93,64 @@
/* Is there a USART enabled? */
#if defined(CONFIG_STM32L4_USART1) || defined(CONFIG_STM32L4_USART2) || \
defined(CONFIG_STM32L4_USART3) || defined(CONFIG_STM32L4_UART4) || \
defined(CONFIG_STM32L4_UART5)
#if defined(CONFIG_STM32L4_LPUART1) || defined(CONFIG_STM32L4_USART1) || \
defined(CONFIG_STM32L4_USART2) || defined(CONFIG_STM32L4_USART3) || \
defined(CONFIG_STM32L4_UART4) || defined(CONFIG_STM32L4_UART5)
# define HAVE_UART 1
#endif
/* Is there a serial console? */
#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART1_SERIALDRIVER)
#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_LPUART1_SERIALDRIVER)
# undef CONFIG_USART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_USART3_SERIAL_CONSOLE
# undef CONFIG_UART4_SERIAL_CONSOLE
# undef CONFIG_UART5_SERIAL_CONSOLE
# define CONSOLE_UART 1
# define HAVE_CONSOLE 1
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART2_SERIALDRIVER)
# undef CONFIG_USART1_SERIAL_CONSOLE
#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART1_SERIALDRIVER)
# undef CONFIG_LPUART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_USART3_SERIAL_CONSOLE
# undef CONFIG_UART4_SERIAL_CONSOLE
# undef CONFIG_UART5_SERIAL_CONSOLE
# define CONSOLE_UART 2
# define HAVE_CONSOLE 1
#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART3_SERIALDRIVER)
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART2_SERIALDRIVER)
# undef CONFIG_LPUART1_SERIAL_CONSOLE
# undef CONFIG_USART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_USART3_SERIAL_CONSOLE
# undef CONFIG_UART4_SERIAL_CONSOLE
# undef CONFIG_UART5_SERIAL_CONSOLE
# define CONSOLE_UART 3
# define HAVE_CONSOLE 1
#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_USART3_SERIALDRIVER)
# undef CONFIG_LPUART1_SERIAL_CONSOLE
# undef CONFIG_USART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_UART4_SERIAL_CONSOLE
# undef CONFIG_UART5_SERIAL_CONSOLE
# define CONSOLE_UART 4
# define HAVE_CONSOLE 1
#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_UART4_SERIALDRIVER)
# undef CONFIG_LPUART1_SERIAL_CONSOLE
# undef CONFIG_USART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_USART3_SERIAL_CONSOLE
# undef CONFIG_UART5_SERIAL_CONSOLE
# define CONSOLE_UART 4
# define CONSOLE_UART 5
# define HAVE_CONSOLE 1
#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32L4_UART5_SERIALDRIVER)
# undef CONFIG_LPUART1_SERIAL_CONSOLE
# undef CONFIG_USART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_USART3_SERIAL_CONSOLE
# undef CONFIG_UART4_SERIAL_CONSOLE
# define CONSOLE_UART 5
# define CONSOLE_UART 6
# define HAVE_CONSOLE 1
#else
# undef CONFIG_LPUART1_SERIAL_CONSOLE
# undef CONFIG_USART1_SERIAL_CONSOLE
# undef CONFIG_USART2_SERIAL_CONSOLE
# undef CONFIG_USART3_SERIAL_CONSOLE
@ -144,6 +165,7 @@
*/
#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA)
# undef CONFIG_LPUART1_RXDMA
# undef CONFIG_USART1_RXDMA
# undef CONFIG_USART2_RXDMA
# undef CONFIG_USART3_RXDMA
@ -153,6 +175,10 @@
/* Disable the DMA configuration on all unused USARTs */
#ifndef CONFIG_STM32L4_LPUART1_SERIALDRIVER
# undef CONFIG_LPUART1_RXDMA
#endif
#ifndef CONFIG_STM32L4_USART1_SERIALDRIVER
# undef CONFIG_USART1_RXDMA
#endif
@ -176,16 +202,18 @@
/* Is DMA available on any (enabled) USART? */
#undef SERIAL_HAVE_RXDMA
#if defined(CONFIG_USART1_RXDMA) || defined(CONFIG_USART2_RXDMA) || \
defined(CONFIG_USART3_RXDMA) || defined(CONFIG_UART4_RXDMA) || \
defined(CONFIG_UART5_RXDMA)
#if defined(CONFIG_LPUART1_RXDMA) || defined(CONFIG_USART1_RXDMA) || \
defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) || \
defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA)
# define SERIAL_HAVE_RXDMA 1
#endif
/* Is DMA used on the console UART? */
#undef SERIAL_HAVE_CONSOLE_DMA
#if defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA)
#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_LPUART1_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_USART1_SERIAL_CONSOLE) && defined(CONFIG_USART1_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
#elif defined(CONFIG_USART2_SERIAL_CONSOLE) && defined(CONFIG_USART2_RXDMA)
# define SERIAL_HAVE_CONSOLE_DMA 1
@ -200,7 +228,9 @@
/* Is DMA used on all (enabled) USARTs */
#define SERIAL_HAVE_ONLY_DMA 1
#if defined(CONFIG_STM32L4_USART1_SERIALDRIVER) && !defined(CONFIG_USART1_RXDMA)
#if defined(CONFIG_STM32L4_LPUART1_SERIALDRIVER) && !defined(CONFIG_LPUART1_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32L4_USART1_SERIALDRIVER) && !defined(CONFIG_USART1_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
#elif defined(CONFIG_STM32L4_USART2_SERIALDRIVER) && !defined(CONFIG_USART2_RXDMA)
# undef SERIAL_HAVE_ONLY_DMA
@ -214,9 +244,9 @@
/* Is RS-485 used? */
#if defined(CONFIG_USART1_RS485) || defined(CONFIG_USART2_RS485) || \
defined(CONFIG_USART3_RS485) || defined(CONFIG_UART4_RS485) || \
defined(CONFIG_UART5_RS485)
#if defined(CONFIG_LPUART1_RS485) || defined(CONFIG_USART1_RS485) || \
defined(CONFIG_USART2_RS485) || defined(CONFIG_USART3_RS485) || \
defined(CONFIG_UART4_RS485) || defined(CONFIG_UART5_RS485)
# define HAVE_RS485 1
#endif