diff --git a/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c b/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c index b6249c2b1a5..e24840d7dd6 100644 --- a/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c +++ b/arch/arm/src/common/stm32/stm32_lowputc_usart_m33_v3.c @@ -46,16 +46,17 @@ #ifdef HAVE_CONSOLE # if defined(CONFIG_LPUART1_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_LPUART1_BASE -# define STM32_APBCLOCK STM32_LPUART1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_LPUART1_RCC_REG -# define STM32_CONSOLE_APBEN STM32_LPUART1_RCC_EN -# define STM32_CONSOLE_BAUD CONFIG_LPUART1_BAUD -# define STM32_CONSOLE_BITS CONFIG_LPUART1_BITS -# define STM32_CONSOLE_PARITY CONFIG_LPUART1_PARITY -# define STM32_CONSOLE_2STOP CONFIG_LPUART1_2STOP -# define STM32_CONSOLE_TX GPIO_LPUART1_TX -# define STM32_CONSOLE_RX GPIO_LPUART1_RX +# define STM32_CONSOLE_IS_LPUART 1 +# define STM32_CONSOLE_BASE STM32_LPUART1_BASE +# define STM32_APBCLOCK STM32_LPUART1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_LPUART1_RCC_REG +# define STM32_CONSOLE_APBEN STM32_LPUART1_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_LPUART1_BAUD +# define STM32_CONSOLE_BITS CONFIG_LPUART1_BITS +# define STM32_CONSOLE_PARITY CONFIG_LPUART1_PARITY +# define STM32_CONSOLE_2STOP CONFIG_LPUART1_2STOP +# define STM32_CONSOLE_TX GPIO_LPUART1_TX +# define STM32_CONSOLE_RX GPIO_LPUART1_RX # ifdef CONFIG_LPUART1_RS485 # define STM32_CONSOLE_RS485_DIR GPIO_LPUART1_RS485_DIR # if (CONFIG_LPUART1_RS485_DIR_POLARITY == 0) @@ -65,16 +66,17 @@ # endif # endif # elif defined(CONFIG_USART1_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART1_BASE -# define STM32_APBCLOCK STM32_USART1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_USART1_RCC_REG -# define STM32_CONSOLE_APBEN STM32_USART1_RCC_EN -# 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 -# define STM32_CONSOLE_TX GPIO_USART1_TX -# define STM32_CONSOLE_RX GPIO_USART1_RX +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_USART1_BASE +# define STM32_APBCLOCK STM32_USART1_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_USART1_RCC_REG +# define STM32_CONSOLE_APBEN STM32_USART1_RCC_EN +# 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 +# define STM32_CONSOLE_TX GPIO_USART1_TX +# define STM32_CONSOLE_RX GPIO_USART1_RX # ifdef CONFIG_USART1_RS485 # define STM32_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR # if (CONFIG_USART1_RS485_DIR_POLARITY == 0) @@ -84,16 +86,17 @@ # endif # endif # elif defined(CONFIG_USART2_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART2_BASE -# define STM32_APBCLOCK STM32_USART2_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_USART2_RCC_REG -# define STM32_CONSOLE_APBEN STM32_USART2_RCC_EN -# 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 -# define STM32_CONSOLE_TX GPIO_USART2_TX -# define STM32_CONSOLE_RX GPIO_USART2_RX +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_USART2_BASE +# define STM32_APBCLOCK STM32_USART2_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_USART2_RCC_REG +# define STM32_CONSOLE_APBEN STM32_USART2_RCC_EN +# 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 +# define STM32_CONSOLE_TX GPIO_USART2_TX +# define STM32_CONSOLE_RX GPIO_USART2_RX # ifdef CONFIG_USART2_RS485 # define STM32_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR # if (CONFIG_USART2_RS485_DIR_POLARITY == 0) @@ -103,16 +106,17 @@ # endif # endif # elif defined(CONFIG_USART3_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART3_BASE -# define STM32_APBCLOCK STM32_USART3_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_USART3_RCC_REG -# define STM32_CONSOLE_APBEN STM32_USART3_RCC_EN -# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART3_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP -# define STM32_CONSOLE_TX GPIO_USART3_TX -# define STM32_CONSOLE_RX GPIO_USART3_RX +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_USART3_BASE +# define STM32_APBCLOCK STM32_USART3_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_USART3_RCC_REG +# define STM32_CONSOLE_APBEN STM32_USART3_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD +# define STM32_CONSOLE_BITS CONFIG_USART3_BITS +# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY +# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP +# define STM32_CONSOLE_TX GPIO_USART3_TX +# define STM32_CONSOLE_RX GPIO_USART3_RX # ifdef CONFIG_USART3_RS485 # define STM32_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR # if (CONFIG_USART3_RS485_DIR_POLARITY == 0) @@ -122,16 +126,17 @@ # endif # endif # elif defined(CONFIG_UART4_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART4_BASE -# define STM32_APBCLOCK STM32_UART4_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_UART4_RCC_REG -# define STM32_CONSOLE_APBEN STM32_UART4_RCC_EN -# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART4_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP -# define STM32_CONSOLE_TX GPIO_UART4_TX -# define STM32_CONSOLE_RX GPIO_UART4_RX +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_UART4_BASE +# define STM32_APBCLOCK STM32_UART4_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_UART4_RCC_REG +# define STM32_CONSOLE_APBEN STM32_UART4_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART4_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP +# define STM32_CONSOLE_TX GPIO_UART4_TX +# define STM32_CONSOLE_RX GPIO_UART4_RX # ifdef CONFIG_UART4_RS485 # define STM32_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR # if (CONFIG_UART4_RS485_DIR_POLARITY == 0) @@ -141,16 +146,17 @@ # endif # endif # elif defined(CONFIG_UART5_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART5_BASE -# define STM32_APBCLOCK STM32_UART5_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_UART5_RCC_REG -# define STM32_CONSOLE_APBEN STM32_UART5_RCC_EN -# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART5_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP -# define STM32_CONSOLE_TX GPIO_UART5_TX -# define STM32_CONSOLE_RX GPIO_UART5_RX +# define STM32_CONSOLE_IS_LPUART 0 +# define STM32_CONSOLE_BASE STM32_UART5_BASE +# define STM32_APBCLOCK STM32_UART5_FREQUENCY +# define STM32_CONSOLE_APBREG STM32_UART5_RCC_REG +# define STM32_CONSOLE_APBEN STM32_UART5_RCC_EN +# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD +# define STM32_CONSOLE_BITS CONFIG_UART5_BITS +# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY +# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP +# define STM32_CONSOLE_TX GPIO_UART5_TX +# define STM32_CONSOLE_RX GPIO_UART5_RX # ifdef CONFIG_UART5_RS485 # define STM32_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR # if (CONFIG_UART5_RS485_DIR_POLARITY == 0) @@ -218,36 +224,21 @@ # define USART_CR3_SETBITS 0 -# undef USE_OVER8 - - /* Calculate USART BAUD rate divider */ - - /* Baud rate for standard USART (SPI mode included): - * - * In case of oversampling by 16, the equation is: - * baud = fCK / UARTDIV - * UARTDIV = fCK / baud - * - * In case of oversampling by 8, the equation is: - * - * baud = 2 * fCK / UARTDIV - * UARTDIV = 2 * fCK / baud + /* Calculate all baud rate dividers, rounded to the nearest integer. + * LPUART uses 256 * fCK / baud. USART uses fCK / baud for oversampling + * by 16, or 2 * fCK / baud for oversampling by 8. */ +# define STM32_LPUART_BRR_VALUE \ + ((((uint64_t)STM32_APBCLOCK << 8) + \ + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) # define STM32_USARTDIV8 \ (((STM32_APBCLOCK << 1) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) # define STM32_USARTDIV16 \ ((STM32_APBCLOCK + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) - - /* Use oversamply by 8 only if the divisor is small. But what is small? */ - -# if STM32_USARTDIV8 > 2000 -# define STM32_BRR_VALUE STM32_USARTDIV16 -# else -# define USE_OVER8 1 -# define STM32_BRR_VALUE \ - ((STM32_USARTDIV8 & 0xfff0) | ((STM32_USARTDIV8 & 0x000f) >> 1)) -# endif +# define STM32_USART_BRR_VALUE \ + (STM32_USARTDIV8 > 2000 ? STM32_USARTDIV16 : \ + ((STM32_USARTDIV8 & 0xfff0) | ((STM32_USARTDIV8 & 0x000f) >> 1))) #endif /* HAVE_CONSOLE */ @@ -377,18 +368,29 @@ void stm32_lowsetup(void) /* Configure the USART Baud Rate */ - putreg32(STM32_BRR_VALUE, - STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + if (STM32_CONSOLE_IS_LPUART) + { + putreg32(STM32_LPUART_BRR_VALUE, + STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + } + else + { + putreg32(STM32_USART_BRR_VALUE, + STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); + } - /* Select oversampling by 8 or by 16 */ + /* Only USART uses oversampling by 8, and only for small divisors. */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); -#ifdef USE_OVER8 - cr |= USART_CR1_OVER8; -#else - cr &= ~USART_CR1_OVER8; -#endif + if (!STM32_CONSOLE_IS_LPUART && STM32_USARTDIV8 <= 2000) + { + cr |= USART_CR1_OVER8; + } + else + { + cr &= ~USART_CR1_OVER8; + } /* Enable Rx, Tx, and the USART */ diff --git a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c index 301e9306b60..4ebaa17f8ba 100644 --- a/arch/arm/src/common/stm32/stm32_serial_m33_v3.c +++ b/arch/arm/src/common/stm32/stm32_serial_m33_v3.c @@ -260,6 +260,7 @@ struct stm32_serial_s #endif const uint8_t irq; /* IRQ associated with this USART */ + const bool islpuart; /* True: This device is an LPUART */ const uint32_t apbclock; /* PCLK 1 or 2 frequency */ const uint32_t rccreg; /* RCC enable register */ const uint32_t rccen; /* RCC enable bit */ @@ -475,6 +476,7 @@ static struct stm32_serial_s g_lpuart1priv = }, .irq = STM32_IRQ_LPUART1, + .islpuart = true, .parity = CONFIG_LPUART1_PARITY, .bits = CONFIG_LPUART1_BITS, .stopbits2 = CONFIG_LPUART1_2STOP, @@ -537,6 +539,7 @@ static struct stm32_serial_s g_usart1priv = }, .irq = STM32_IRQ_USART1, + .islpuart = false, .parity = CONFIG_USART1_PARITY, .bits = CONFIG_USART1_BITS, .stopbits2 = CONFIG_USART1_2STOP, @@ -601,6 +604,7 @@ static struct stm32_serial_s g_usart2priv = }, .irq = STM32_IRQ_USART2, + .islpuart = false, .parity = CONFIG_USART2_PARITY, .bits = CONFIG_USART2_BITS, .stopbits2 = CONFIG_USART2_2STOP, @@ -665,6 +669,7 @@ static struct stm32_serial_s g_usart3priv = }, .irq = STM32_IRQ_USART3, + .islpuart = false, .parity = CONFIG_USART3_PARITY, .bits = CONFIG_USART3_BITS, .stopbits2 = CONFIG_USART3_2STOP, @@ -729,6 +734,7 @@ static struct stm32_serial_s g_uart4priv = }, .irq = STM32_IRQ_UART4, + .islpuart = false, .parity = CONFIG_UART4_PARITY, .bits = CONFIG_UART4_BITS, .stopbits2 = CONFIG_UART4_2STOP, @@ -793,6 +799,7 @@ static struct stm32_serial_s g_uart5priv = }, .irq = STM32_IRQ_UART5, + .islpuart = false, .parity = CONFIG_UART5_PARITY, .bits = CONFIG_UART5_BITS, .stopbits2 = CONFIG_UART5_2STOP, @@ -1036,49 +1043,60 @@ static void stm32serial_setformat(struct uart_dev_s *dev) uint32_t cr1; uint32_t brr; - /* In case of oversampling by 8, the equation is: - * - * baud = 2 * fCK / usartdiv8 - * usartdiv8 = 2 * fCK / baud - */ - - usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; - - /* Baud rate for standard USART (SPI mode included): - * - * In case of oversampling by 16, the equation is: - * baud = fCK / usartdiv16 - * usartdiv16 = fCK / baud - * = 2 * usartdiv8 - */ - - /* Use oversamply by 8 only if the divisor is small. But what is small? */ - - cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); - if (usartdiv8 > 2000) + if (priv->islpuart) { - /* Use usartdiv16 */ + /* LPUART BRR = 256 * fCK / baud */ - brr = (usartdiv8 + 1) >> 1; - - /* Clear oversampling by 8 to enable oversampling by 16 */ - - cr1 &= ~USART_CR1_OVER8; + brr = (((uint64_t)priv->apbclock << 8) + + (priv->baud >> 1)) / priv->baud; } else { - DEBUGASSERT(usartdiv8 >= 8); + /* In case of oversampling by 8, the equation is: + * + * baud = 2 * fCK / usartdiv8 + * usartdiv8 = 2 * fCK / baud + */ - /* Perform mysterious operations on bits 0-3 */ + usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; - brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + /* Baud rate for standard USART (SPI mode included): + * + * In case of oversampling by 16, the equation is: + * baud = fCK / usartdiv16 + * usartdiv16 = fCK / baud + * = usartdiv8 / 2 + */ - /* Set oversampling by 8 */ + /* Use oversampling by 8 only if the divisor is small */ - cr1 |= USART_CR1_OVER8; + cr1 = stm32serial_getreg(priv, STM32_USART_CR1_OFFSET); + if (usartdiv8 > 2000) + { + /* Use usartdiv16 */ + + brr = (usartdiv8 + 1) >> 1; + + /* Clear oversampling by 8 to enable oversampling by 16 */ + + cr1 &= ~USART_CR1_OVER8; + } + else + { + DEBUGASSERT(usartdiv8 >= 8); + + /* Perform mysterious operations on bits 0-3 */ + + brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); + + /* Set oversampling by 8 */ + + cr1 |= USART_CR1_OVER8; + } + + stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); } - stm32serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); stm32serial_putreg(priv, STM32_USART_BRR_OFFSET, brr); /* Configure parity mode */ diff --git a/arch/arm/src/stm32l5/CMakeLists.txt b/arch/arm/src/stm32l5/CMakeLists.txt index 3f64e9362d2..7d13f669095 100644 --- a/arch/arm/src/stm32l5/CMakeLists.txt +++ b/arch/arm/src/stm32l5/CMakeLists.txt @@ -25,9 +25,7 @@ list( APPEND SRCS - stm32l5_lowputc.c stm32l5_rcc.c - stm32l5_serial.c stm32l5_spi.c stm32l5_lse.c stm32l5_lsi.c diff --git a/arch/arm/src/stm32l5/Kconfig b/arch/arm/src/stm32l5/Kconfig index e12c16cbf11..d411b7b27d2 100644 --- a/arch/arm/src/stm32l5/Kconfig +++ b/arch/arm/src/stm32l5/Kconfig @@ -12,6 +12,7 @@ config STM32_L5_PERIPHERALS default y select STM32_HAVE_IP_EXTI_M33_V1 select STM32_HAVE_IP_GPIO_M33_V1 + select STM32_HAVE_IP_USART_M33_V3 select STM32_HAVE_RTC_SUBSECONDS select STM32_HAVE_RTC_MAGIC select STM32_HAVE_RTC diff --git a/arch/arm/src/stm32l5/Make.defs b/arch/arm/src/stm32l5/Make.defs index 829d324bb85..a0d9d8a4725 100644 --- a/arch/arm/src/stm32l5/Make.defs +++ b/arch/arm/src/stm32l5/Make.defs @@ -33,8 +33,7 @@ include common/stm32/Make.defs # Required STM32L5 files CHIP_ASRCS = -CHIP_CSRCS += stm32l5_lowputc.c stm32l5_rcc.c -CHIP_CSRCS += stm32l5_serial.c +CHIP_CSRCS += stm32l5_rcc.c CHIP_CSRCS += stm32l5_spi.c stm32l5_lse.c stm32l5_lsi.c CHIP_CSRCS += stm32l5_pwr.c stm32l5_tim.c stm32l5_flash.c diff --git a/arch/arm/src/stm32l5/hardware/stm32l5_uart.h b/arch/arm/src/stm32l5/hardware/stm32l5_uart.h deleted file mode 100644 index 65880b3175f..00000000000 --- a/arch/arm/src/stm32l5/hardware/stm32l5_uart.h +++ /dev/null @@ -1,309 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32l5/hardware/stm32l5_uart.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32L5_HARDWARE_STM32L5_UART_H -#define __ARCH_ARM_SRC_STM32L5_HARDWARE_STM32L5_UART_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "chip.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Register Offsets *********************************************************/ - -#define STM32_USART_CR1_OFFSET 0x0000 /* Control register 1 */ -#define STM32_USART_CR2_OFFSET 0x0004 /* Control register 2 */ -#define STM32_USART_CR3_OFFSET 0x0008 /* Control register 3 */ -#define STM32_USART_BRR_OFFSET 0x000c /* Baud Rate register */ -#define STM32_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */ -#define STM32_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */ -#define STM32_USART_RQR_OFFSET 0x0018 /* Request register */ -#define STM32_USART_ISR_OFFSET 0x001c /* Interrupt and status register */ -#define STM32_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */ -#define STM32_USART_RDR_OFFSET 0x0024 /* Receive Data register */ -#define STM32_USART_TDR_OFFSET 0x0028 /* Transmit Data register */ -#define STM32_USART_PRESC_OFFSET 0x002c /* Prescaler register */ - -/* Register Addresses *******************************************************/ - -#if STM32_NUSART > 0 -# define STM32_USART1_CR1 (STM32_USART1_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART1_CR2 (STM32_USART1_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART1_CR3 (STM32_USART1_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART1_BRR (STM32_USART1_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART1_GTPR (STM32_USART1_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART1_RTOR (STM32_USART1_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART1_RQR (STM32_USART1_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART1_ISR (STM32_USART1_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART1_ICR (STM32_USART1_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART1_RDR (STM32_USART1_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART1_TDR (STM32_USART1_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART1_PRESC (STM32_USART1_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 1 -# define STM32_USART2_CR1 (STM32_USART2_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART2_CR2 (STM32_USART2_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART2_CR3 (STM32_USART2_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART2_BRR (STM32_USART2_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART2_GTPR (STM32_USART2_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART2_RTOR (STM32_USART2_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART2_RQR (STM32_USART2_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART2_ISR (STM32_USART2_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART2_ICR (STM32_USART2_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART2_RDR (STM32_USART2_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART2_TDR (STM32_USART2_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART2_PRESC (STM32_USART2_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 2 -# define STM32_USART3_CR1 (STM32_USART3_BASE + STM32_USART_CR1_OFFSET) -# define STM32_USART3_CR2 (STM32_USART3_BASE + STM32_USART_CR2_OFFSET) -# define STM32_USART3_CR3 (STM32_USART3_BASE + STM32_USART_CR3_OFFSET) -# define STM32_USART3_BRR (STM32_USART3_BASE + STM32_USART_BRR_OFFSET) -# define STM32_USART3_GTPR (STM32_USART3_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_USART3_RTOR (STM32_USART3_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_USART3_RQR (STM32_USART3_BASE + STM32_USART_RQR_OFFSET) -# define STM32_USART3_ISR (STM32_USART3_BASE + STM32_USART_ISR_OFFSET) -# define STM32_USART3_ICR (STM32_USART3_BASE + STM32_USART_ICR_OFFSET) -# define STM32_USART3_RDR (STM32_USART3_BASE + STM32_USART_RDR_OFFSET) -# define STM32_USART3_TDR (STM32_USART3_BASE + STM32_USART_TDR_OFFSET) -# define STM32_USART3_PRESC (STM32_USART3_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 3 -# define STM32_UART4_CR1 (STM32_UART4_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART4_CR2 (STM32_UART4_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART4_CR3 (STM32_UART4_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART4_BRR (STM32_UART4_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART4_GTPR (STM32_UART4_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART4_RTOR (STM32_UART4_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART4_RQR (STM32_UART4_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART4_ISR (STM32_UART4_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART4_ICR (STM32_UART4_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART4_RDR (STM32_UART4_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART4_TDR (STM32_UART4_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART4_PRESC (STM32_UART4_BASE + STM32_USART_PRESC_OFFSET) -#endif - -#if STM32_NUSART > 4 -# define STM32_UART5_CR1 (STM32_UART5_BASE + STM32_USART_CR1_OFFSET) -# define STM32_UART5_CR2 (STM32_UART5_BASE + STM32_USART_CR2_OFFSET) -# define STM32_UART5_CR3 (STM32_UART5_BASE + STM32_USART_CR3_OFFSET) -# define STM32_UART5_BRR (STM32_UART5_BASE + STM32_USART_BRR_OFFSET) -# define STM32_UART5_GTPR (STM32_UART5_BASE + STM32_USART_GTPR_OFFSET) -# define STM32_UART5_RTOR (STM32_UART5_BASE + STM32_USART_RTOR_OFFSET) -# define STM32_UART5_RQR (STM32_UART5_BASE + STM32_USART_RQR_OFFSET) -# define STM32_UART5_ISR (STM32_UART5_BASE + STM32_USART_ISR_OFFSET) -# define STM32_UART5_ICR (STM32_UART5_BASE + STM32_USART_ICR_OFFSET) -# define STM32_UART5_RDR (STM32_UART5_BASE + STM32_USART_RDR_OFFSET) -# define STM32_UART5_TDR (STM32_UART5_BASE + STM32_USART_TDR_OFFSET) -# define STM32_UART5_PRESC (STM32_UART5_BASE + STM32_USART_PRESC_OFFSET) -#endif - -/* Register Bitfield Definitions ********************************************/ - -/* Control register 1 */ - -#define USART_CR1_UE (1 << 0) /* Bit 0: USART Enable */ -#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode */ -#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */ -#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */ -#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */ -#define USART_CR1_RXNEIE (1 << 5) /* Bit 5: RXNE Interrupt Enable */ -#define USART_CR1_TCIE (1 << 6) /* Bit 6: Transmission Complete Interrupt Enable */ -#define USART_CR1_TXEIE (1 << 7) /* Bit 7: TXE Interrupt Enable */ -#define USART_CR1_PEIE (1 << 8) /* Bit 8: PE Interrupt Enable */ -#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */ -#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */ -#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */ -#define USART_CR1_M0 (1 << 12) /* Bit 12: Word length */ -#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */ -#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */ -#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */ - -#define USART_CR1_DEDT_SHIFT (16) /* Bits 16..20 DE deactivation delay */ -#define USART_CR1_DEDT_MASK (0x1f << USART_CR1_DEDT_SHIFT) - -#define USART_CR1_DEAT_SHIFT (21) /* Bits 21..25 DE activation delay */ -#define USART_CR1_DEAT_MASK (0x1f << USART_CR1_DEAT_SHIFT) - -#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */ -#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of block interrupt enable */ -#define USART_CR1_M1 (1 << 28) /* Bit 28: Word length */ - -#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE| \ - USART_CR1_TCIE|USART_CR1_TXEIE| \ - USART_CR1_PEIE|USART_CR1_CMIE| \ - USART_CR1_RTOIE|USART_CR1_EOBIE) - -/* Control register 2 */ - -#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: 7-bit/4-bit Address Detection */ -#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */ -#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */ -#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */ -#define USART_CR2_CPHA (1 << 9) /* Bit 9: Clock Phase */ -#define USART_CR2_CPOL (1 << 10) /* Bit 10: Clock Polarity */ -#define USART_CR2_CLKEN (1 << 11) /* Bit 11: Clock Enable */ - -#define USART_CR2_STOP_SHIFT (12) /* Bits 13-12: STOP bits */ -#define USART_CR2_STOP_MASK (3 << USART_CR2_STOP_SHIFT) -# define USART_CR2_STOP1 (0 << USART_CR2_STOP_SHIFT) /* 00: 1 Stop bit */ -# define USART_CR2_STOP0p5 (1 << USART_CR2_STOP_SHIFT) /* 01: 0.5 Stop bit */ -# define USART_CR2_STOP2 (2 << USART_CR2_STOP_SHIFT) /* 10: 2 Stop bits */ -# define USART_CR2_STOP1p5 (3 << USART_CR2_STOP_SHIFT) /* 11: 1.5 Stop bit */ - -#define USART_CR2_LINEN (1 << 14) /* Bit 14: LIN mode enable */ -#define USART_CR2_SWAP (1 << 15) /* Bit 15: Swap TX/RX pins */ -#define USART_CR2_RXINV (1 << 16) /* Bit 16: RX pin active level inversion */ -#define USART_CR2_TXINV (1 << 17) /* Bit 17: TX pin active level inversion */ -#define USART_CR2_DATAINV (1 << 18) /* Bit 18: Binary data inversion */ -#define USART_CR2_MSBFIRST (1 << 19) /* Bit 19: Most significant bit first */ -#define USART_CR2_ABREN (1 << 20) /* Bit 20: Auto Baud rate enable */ - -#define USART_CR2_ABRMOD_SHIFT (21) /* Bits 21-22: Autobaud rate mode*/ -#define USART_CR2_ABRMOD_MASK (3 << USART_CR2_ABRMOD_SHIFT) -#define USART_CR2_ABRMOD_START (0 << USART_CR2_ABRMOD_SHIFT) /* 00: Start bit */ -#define USART_CR2_ABRMOD_EDGES (1 << USART_CR2_ABRMOD_SHIFT) /* 01: Falling-to-falling edge -> frame must start with 10xxxxxx */ -#define USART_CR2_ABRMOD_7F (2 << USART_CR2_ABRMOD_SHIFT) /* 10: 0x7F */ -#define USART_CR2_ABRMOD_55 (3 << USART_CR2_ABRMOD_SHIFT) /* 11: 0x55 */ - -#define USART_CR2_RTOEN (1 << 23) /* Bit 23: Receiver timeout enable */ - -#define USART_CR2_ADD_SHIFT (24) /* Bits 24-31: Address of the USART node */ -#define USART_CR2_ADD_MASK (0xff << USART_CR2_ADD_SHIFT) - -/* Control register 3 */ - -#define USART_CR3_EIE (1 << 0) /* Bit 0: Error Interrupt Enable */ -#define USART_CR3_IREN (1 << 1) /* Bit 1: IrDA mode Enable */ -#define USART_CR3_IRLP (1 << 2) /* Bit 2: IrDA Low-Power */ -#define USART_CR3_HDSEL (1 << 3) /* Bit 3: Half-Duplex Selection */ -#define USART_CR3_NACK (1 << 4) /* Bit 4: Smartcard NACK enable */ -#define USART_CR3_SCEN (1 << 5) /* Bit 5: Smartcard mode enable */ -#define USART_CR3_DMAR (1 << 6) /* Bit 6: DMA Enable Receiver */ -#define USART_CR3_DMAT (1 << 7) /* Bit 7: DMA Enable Transmitter */ -#define USART_CR3_RTSE (1 << 8) /* Bit 8: RTS Enable */ -#define USART_CR3_CTSE (1 << 9) /* Bit 9: CTS Enable */ -#define USART_CR3_CTSIE (1 << 10) /* Bit 10: CTS Interrupt Enable */ -#define USART_CR3_ONEBIT (1 << 11) /* Bit 11: One sample bit method Enable */ -#define USART_CR3_OVRDIS (1 << 12) /* Bit 12: Overrun Disable */ -#define USART_CR3_DDRE (1 << 13) /* Bit 13: DMA disable on Reception error */ -#define USART_CR3_DEM (1 << 14) /* Bit 14: Driver Enable mode */ -#define USART_CR3_DEP (1 << 15) /* Bit 15: Driver Enable polarity selection */ -#define USART_CR3_SCARCNT2_SHIFT (17) /* Bits 17-19: Smart card auto retry count */ -#define USART_CR3_SCARCNT2_MASK (7 << USART_CR3_SCARCNT2_SHIFT) -#define USART_CR3_WUS_SHIFT (20) /* Bits 20-21: Wakeup from Stop mode interrupt flag selection */ -#define USART_CR3_WUS_MASK (3 << USART_CR3_WUS_SHIFT) -#define USART_CR3_WUS_ADDRESS (0 << USART_CR3_WUS_SHIFT) /* 00: WUF active on address match */ -#define USART_CR3_WUS_START (2 << USART_CR3_WUS_SHIFT) /* 10: WUF active on Start bit detection */ -#define USART_CR3_WUS_RXNE (3 << USART_CR3_WUS_SHIFT) /* 11: WUF active on RXNE */ -#define USART_CR3_WUFIE (1 << 22) /* Bit 22: Wakeup from Stop mode interrupt enable */ - -/* Baud Rate Register */ - -#define USART_BRR_FRAC_SHIFT (0) /* Bits 3-0: fraction of USARTDIV */ -#define USART_BRR_FRAC_MASK (0x0f << USART_BRR_FRAC_SHIFT) -#define USART_BRR_MANT_SHIFT (4) /* Bits 15-4: mantissa of USARTDIV */ -#define USART_BRR_MANT_MASK (0x0fff << USART_BRR_MANT_SHIFT) - -/* Guard time and prescaler register */ - -#define USART_GTPR_PSC_SHIFT (0) /* Bits 0-7: Prescaler value */ -#define USART_GTPR_PSC_MASK (0xff << USART_GTPR_PSC_SHIFT) -#define USART_GTPR_GT_SHIFT (8) /* Bits 8-15: Guard time value */ -#define USART_GTPR_GT_MASK (0xff << USART_GTPR_GT_SHIFT) - -/* Receiver timeout register */ - -/* Request Register */ - -#define USART_CR1_SBRKQ (1 << 1) /* Bit 1: Send Break */ - -/* Interrupt and Status register */ - -#define USART_ISR_PE (1 << 0) /* Bit 0: Parity Error */ -#define USART_ISR_FE (1 << 1) /* Bit 1: Framing Error */ -#define USART_ISR_NF (1 << 2) /* Bit 2: Noise Error Flag */ -#define USART_ISR_ORE (1 << 3) /* Bit 3: OverRun Error */ -#define USART_ISR_IDLE (1 << 4) /* Bit 4: IDLE line detected */ -#define USART_ISR_RXNE (1 << 5) /* Bit 5: Read Data Register Not Empty */ -#define USART_ISR_TC (1 << 6) /* Bit 6: Transmission Complete */ -#define USART_ISR_TXE (1 << 7) /* Bit 7: Transmit Data Register Empty */ -#define USART_ISR_LBDF (1 << 8) /* Bit 8: LIN Break Detection Flag */ -#define USART_ISR_CTSIF (1 << 9) /* Bit 9: CTS Interrupt Flag */ -#define USART_ISR_CTS (1 << 10) /* Bit 10: CTS Flag */ -#define USART_ISR_RTOF (1 << 11) /* Bit 11: Receiver timeout Flag */ -#define USART_ISR_EOBF (1 << 12) /* Bit 12: End of block Flag */ -#define USART_ISR_UDR (1 << 13) /* Bit 13: SPI slave underrun error flag */ -#define USART_ISR_ABRE (1 << 14) /* Bit 14: Auto baud rate Error */ -#define USART_ISR_ABRF (1 << 15) /* Bit 15: Auto baud rate Flag */ -#define USART_ISR_BUSY (1 << 16) /* Bit 16: Busy Flag */ -#define USART_ISR_CMF (1 << 17) /* Bit 17: Character match Flag */ -#define USART_ISR_SBKF (1 << 18) /* Bit 18: Send break Flag */ -#define USART_ISR_RWU (1 << 19) /* Bit 19: Receiver wakeup from Mute mode */ -#define USART_ISR_WUF (1 << 20) /* Bit 20: Wakeup from Stop mode Flag */ -#define USART_ISR_TEACK (1 << 21) /* Bit 21: Transmit enable acknowledge Flag */ -#define USART_ISR_REACK (1 << 22) /* Bit 22: Receive enable acknowledge Flag */ - -/* ICR */ - -#define USART_ICR_PECF (1 << 0) /* Bit 0: Parity error clear flag */ -#define USART_ICR_FECF (1 << 1) /* Bit 1: Framing error clear flag */ -#define USART_ICR_NCF (1 << 2) /* Bit 2: Noise detected clear flag */ -#define USART_ICR_ORECF (1 << 3) /* Bit 3: Overrun error clear flag */ -#define USART_ICR_IDLECF (1 << 4) /* Bit 4: Idle line detected clear flag */ -#define USART_ICR_TCCF (1 << 6) /* Bit 6: Transmission complete clear flag */ -#define USART_ICR_LBDCF (1 << 8) /* Bit 8: LIN break detection clear flag */ -#define USART_ICR_CTSCF (1 << 9) /* Bit 9: CTS clear flag */ -#define USART_ICR_RTOCF (1 << 11) /* Bit 11: Receiver timeout clear flag */ -#define USART_ICR_EOBCF (1 << 12) /* Bit 12: End of block clear flag */ -#define USART_ICR_CMCF (1 << 17) /* Bit 17: Character match clear flag */ -#define USART_ICR_WUCF (1 << 20) /* Bit 20: Wakeup from Stop mode clear flag */ - -/* Receive Data register */ - -#define USART_RDR_SHIFT (0) /* Bits 8:0: Data value */ -#define USART_RDR_MASK (0xff << USART_RDR_SHIFT) - -/* Transmit Data register */ - -#define USART_TDR_SHIFT (0) /* Bits 8:0: Data value */ -#define USART_TDR_MASK (0xff << USART_TDR_SHIFT) - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#endif /* __ARCH_ARM_SRC_STM32L5_HARDWARE_STM32L5_UART_H */ diff --git a/arch/arm/src/stm32l5/stm32.h b/arch/arm/src/stm32l5/stm32.h index 500e470d7ef..96214211e42 100644 --- a/arch/arm/src/stm32l5/stm32.h +++ b/arch/arm/src/stm32l5/stm32.h @@ -44,7 +44,7 @@ #include "stm32_rcc.h" #include "stm32l5_spi.h" #include "stm32l5_tim.h" -#include "stm32l5_uart.h" -#include "stm32l5_lowputc.h" +#include "stm32_uart.h" +#include "stm32_lowputc.h" #endif /* __ARCH_ARM_SRC_STM32L5_STM32L5_H */ diff --git a/arch/arm/src/stm32l5/stm32_rcc_m33.h b/arch/arm/src/stm32l5/stm32_rcc_m33.h index 248fd4a1942..3343fb33bd5 100644 --- a/arch/arm/src/stm32l5/stm32_rcc_m33.h +++ b/arch/arm/src/stm32l5/stm32_rcc_m33.h @@ -42,6 +42,32 @@ * Pre-processor Definitions ****************************************************************************/ +/* USART clock and RCC definitions */ + +#define STM32_LPUART1_FREQUENCY STM32_PCLK1_FREQUENCY +#define STM32_LPUART1_RCC_REG STM32_RCC_APB1ENR2 +#define STM32_LPUART1_RCC_EN RCC_APB1ENR2_LPUART1EN + +#define STM32_USART1_FREQUENCY STM32_PCLK2_FREQUENCY +#define STM32_USART1_RCC_REG STM32_RCC_APB2ENR +#define STM32_USART1_RCC_EN RCC_APB2ENR_USART1EN + +#define STM32_USART2_FREQUENCY STM32_PCLK1_FREQUENCY +#define STM32_USART2_RCC_REG STM32_RCC_APB1ENR1 +#define STM32_USART2_RCC_EN RCC_APB1ENR1_USART2EN + +#define STM32_USART3_FREQUENCY STM32_PCLK1_FREQUENCY +#define STM32_USART3_RCC_REG STM32_RCC_APB1ENR1 +#define STM32_USART3_RCC_EN RCC_APB1ENR1_USART3EN + +#define STM32_UART4_FREQUENCY STM32_PCLK1_FREQUENCY +#define STM32_UART4_RCC_REG STM32_RCC_APB1ENR1 +#define STM32_UART4_RCC_EN RCC_APB1ENR1_UART4EN + +#define STM32_UART5_FREQUENCY STM32_PCLK1_FREQUENCY +#define STM32_UART5_RCC_REG STM32_RCC_APB1ENR1 +#define STM32_UART5_RCC_EN RCC_APB1ENR1_UART5EN + #ifndef __ASSEMBLY__ #undef EXTERN diff --git a/arch/arm/src/stm32l5/stm32l5_lowputc.c b/arch/arm/src/stm32l5/stm32l5_lowputc.c deleted file mode 100644 index c4663a406f2..00000000000 --- a/arch/arm/src/stm32l5/stm32l5_lowputc.c +++ /dev/null @@ -1,415 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32l5/stm32l5_lowputc.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include - -#include "arm_internal.h" -#include "chip.h" - -#include "stm32.h" -#include "stm32_rcc.h" -#include "stm32_gpio.h" -#include "stm32l5_uart.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Select USART parameters for the selected console */ - -#ifdef HAVE_CONSOLE -# if defined(CONFIG_LPUART1_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_LPUART1_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR2 -# define STM32_CONSOLE_APBEN RCC_APB1ENR2_LPUART1EN -# define STM32_CONSOLE_BAUD CONFIG_LPUART1_BAUD -# define STM32_CONSOLE_BITS CONFIG_LPUART1_BITS -# define STM32_CONSOLE_PARITY CONFIG_LPUART1_PARITY -# define STM32_CONSOLE_2STOP CONFIG_LPUART1_2STOP -# define STM32_CONSOLE_TX GPIO_LPUART1_TX -# define STM32_CONSOLE_RX GPIO_LPUART1_RX -# ifdef CONFIG_LPUART1_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_LPUART1_RS485_DIR -# if (CONFIG_LPUART1_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART1_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART1_BASE -# define STM32_APBCLOCK STM32_PCLK2_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB2ENR -# define STM32_CONSOLE_APBEN RCC_APB2ENR_USART1EN -# 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 -# define STM32_CONSOLE_TX GPIO_USART1_TX -# define STM32_CONSOLE_RX GPIO_USART1_RX -# ifdef CONFIG_USART1_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART1_RS485_DIR -# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART2_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART2_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 -# define STM32_CONSOLE_APBEN RCC_APB1ENR1_USART2EN -# 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 -# define STM32_CONSOLE_TX GPIO_USART2_TX -# define STM32_CONSOLE_RX GPIO_USART2_RX -# ifdef CONFIG_USART2_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART2_RS485_DIR -# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_USART3_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_USART3_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 -# define STM32_CONSOLE_APBEN RCC_APB1ENR1_USART3EN -# define STM32_CONSOLE_BAUD CONFIG_USART3_BAUD -# define STM32_CONSOLE_BITS CONFIG_USART3_BITS -# define STM32_CONSOLE_PARITY CONFIG_USART3_PARITY -# define STM32_CONSOLE_2STOP CONFIG_USART3_2STOP -# define STM32_CONSOLE_TX GPIO_USART3_TX -# define STM32_CONSOLE_RX GPIO_USART3_RX -# ifdef CONFIG_USART3_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_USART3_RS485_DIR -# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART4_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART4_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 -# define STM32_CONSOLE_APBEN RCC_APB1ENR1_UART4EN -# define STM32_CONSOLE_BAUD CONFIG_UART4_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART4_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART4_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART4_2STOP -# define STM32_CONSOLE_TX GPIO_UART4_TX -# define STM32_CONSOLE_RX GPIO_UART4_RX -# ifdef CONFIG_UART4_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART4_RS485_DIR -# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# elif defined(CONFIG_UART5_SERIAL_CONSOLE) -# define STM32_CONSOLE_BASE STM32_UART5_BASE -# define STM32_APBCLOCK STM32_PCLK1_FREQUENCY -# define STM32_CONSOLE_APBREG STM32_RCC_APB1ENR1 -# define STM32_CONSOLE_APBEN RCC_APB1ENR1_UART5EN -# define STM32_CONSOLE_BAUD CONFIG_UART5_BAUD -# define STM32_CONSOLE_BITS CONFIG_UART5_BITS -# define STM32_CONSOLE_PARITY CONFIG_UART5_PARITY -# define STM32_CONSOLE_2STOP CONFIG_UART5_2STOP -# define STM32_CONSOLE_TX GPIO_UART5_TX -# define STM32_CONSOLE_RX GPIO_UART5_RX -# ifdef CONFIG_UART5_RS485 -# define STM32_CONSOLE_RS485_DIR GPIO_UART5_RS485_DIR -# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) -# define STM32_CONSOLE_RS485_DIR_POLARITY false -# else -# define STM32_CONSOLE_RS485_DIR_POLARITY true -# endif -# endif -# endif - - /* CR1 settings */ - -# if STM32_CONSOLE_BITS == 9 -# define USART_CR1_M0_VALUE USART_CR1_M0 -# define USART_CR1_M1_VALUE 0 -# elif STM32_CONSOLE_BITS == 7 -# define USART_CR1_M0_VALUE 0 -# define USART_CR1_M1_VALUE USART_CR1_M1 -# else /* 8 bits */ -# define USART_CR1_M0_VALUE 0 -# define USART_CR1_M1_VALUE 0 -# endif - -# if STM32_CONSOLE_PARITY == 1 /* odd parity */ -# define USART_CR1_PARITY_VALUE (USART_CR1_PCE|USART_CR1_PS) -# elif STM32_CONSOLE_PARITY == 2 /* even parity */ -# define USART_CR1_PARITY_VALUE USART_CR1_PCE -# else /* no parity */ -# define USART_CR1_PARITY_VALUE 0 -# endif - -# define USART_CR1_CLRBITS \ - (USART_CR1_UE | USART_CR1_UESM | USART_CR1_RE | USART_CR1_TE | USART_CR1_PS | \ - USART_CR1_PCE | USART_CR1_WAKE | USART_CR1_M0 | USART_CR1_M1 | \ - USART_CR1_MME | USART_CR1_OVER8 | USART_CR1_DEDT_MASK | \ - USART_CR1_DEAT_MASK | USART_CR1_ALLINTS) - -# define USART_CR1_SETBITS (USART_CR1_M0_VALUE|USART_CR1_M1_VALUE|USART_CR1_PARITY_VALUE) - - /* CR2 settings */ - -# if STM32_CONSOLE_2STOP != 0 -# define USART_CR2_STOP2_VALUE USART_CR2_STOP2 -# else -# define USART_CR2_STOP2_VALUE 0 -# endif - -# define USART_CR2_CLRBITS \ - (USART_CR2_ADDM7 | USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \ - USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_STOP_MASK | \ - USART_CR2_LINEN | USART_CR2_SWAP | USART_CR2_RXINV | USART_CR2_TXINV | \ - USART_CR2_DATAINV | USART_CR2_MSBFIRST | USART_CR2_ABREN | \ - USART_CR2_ABRMOD_MASK | USART_CR2_RTOEN | USART_CR2_ADD_MASK) - -# define USART_CR2_SETBITS USART_CR2_STOP2_VALUE - - /* CR3 settings */ - -# define USART_CR3_CLRBITS \ - (USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | USART_CR3_HDSEL | \ - USART_CR3_NACK | USART_CR3_SCEN | USART_CR3_DMAR | USART_CR3_DMAT | \ - USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \ - USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | USART_CR3_DEP | \ - USART_CR3_SCARCNT2_MASK | USART_CR3_WUS_MASK | USART_CR3_WUFIE) - -# define USART_CR3_SETBITS 0 - -# undef USE_OVER8 - - /* Calculate USART BAUD rate divider */ - -# if defined(CONFIG_LPUART1_SERIAL_CONSOLE) - - /* Baud rate for LPUART: - * - * baud = 256 * fCK / LPUARTDIV - * LPUARTDIV = 256 * fCK / baud - * - * LPUARTDIV must be in range [0x300, 0xFFFFF]. - */ - -# define STM32_BRR_VALUE \ - ((((uint64_t)STM32_APBCLOCK << 8) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) - -# else - - /* Baud rate for standard USART (SPI mode included): - * - * In case of oversampling by 16, the equation is: - * baud = fCK / UARTDIV - * UARTDIV = fCK / baud - * - * In case of oversampling by 8, the equation is: - * - * baud = 2 * fCK / UARTDIV - * UARTDIV = 2 * fCK / baud - */ - -# define STM32_USARTDIV8 \ - (((STM32_APBCLOCK << 1) + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) -# define STM32_USARTDIV16 \ - ((STM32_APBCLOCK + (STM32_CONSOLE_BAUD >> 1)) / STM32_CONSOLE_BAUD) - - /* Use oversamply by 8 only if the divisor is small. But what is small? */ - -# if STM32_USARTDIV8 > 2000 -# define STM32_BRR_VALUE STM32_USARTDIV16 -# else -# define USE_OVER8 1 -# define STM32_BRR_VALUE \ - ((STM32_USARTDIV8 & 0xfff0) | ((STM32_USARTDIV8 & 0x000f) >> 1)) -# endif - -# endif /* CONFIG_LPUART1_SERIAL_CONSOLE */ - -#endif /* HAVE_CONSOLE */ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: arm_lowputc - * - * Description: - * Output one byte on the serial console - * - ****************************************************************************/ - -void arm_lowputc(char ch) -{ -#ifdef HAVE_CONSOLE - /* Wait until the TX data register is empty */ - - while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & - USART_ISR_TXE) == 0); -#ifdef STM32_CONSOLE_RS485_DIR - stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, - STM32_CONSOLE_RS485_DIR_POLARITY); -#endif - - /* Then send the character */ - - putreg32((uint32_t)ch, STM32_CONSOLE_BASE + STM32_USART_TDR_OFFSET); - -#ifdef STM32_CONSOLE_RS485_DIR - while ((getreg32(STM32_CONSOLE_BASE + STM32_USART_ISR_OFFSET) & - USART_ISR_TC) == 0); - stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, - !STM32_CONSOLE_RS485_DIR_POLARITY); -#endif - -#endif /* HAVE_CONSOLE */ -} - -/**************************************************************************** - * Name: stm32_lowsetup - * - * Description: - * This performs basic initialization of the USART used for the serial - * console. Its purpose is to get the console output available as soon - * as possible. - * - ****************************************************************************/ - -void stm32_lowsetup(void) -{ -#if defined(HAVE_UART) -#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) - uint32_t cr; -#endif - -#if defined(HAVE_CONSOLE) - /* Enable USART APB1/2 clock */ - - modifyreg32(STM32_CONSOLE_APBREG, 0, STM32_CONSOLE_APBEN); -#endif - - /* Enable the console USART and configure GPIO pins needed for rx/tx. - * - * NOTE: Clocking for selected U[S]ARTs was already provided in - * stm32_rcc.c - */ - -#ifdef STM32_CONSOLE_TX - stm32_configgpio(STM32_CONSOLE_TX); -#endif -#ifdef STM32_CONSOLE_RX - stm32_configgpio(STM32_CONSOLE_RX); -#endif - -#ifdef STM32_CONSOLE_RS485_DIR - stm32_configgpio(STM32_CONSOLE_RS485_DIR); - stm32_gpiowrite(STM32_CONSOLE_RS485_DIR, - !STM32_CONSOLE_RS485_DIR_POLARITY); -#endif - - /* Enable and configure the selected console device */ - -#if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) - /* Configure CR2 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); - cr &= ~USART_CR2_CLRBITS; - cr |= USART_CR2_SETBITS; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); - - /* Configure CR1 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); - cr &= ~USART_CR1_CLRBITS; - cr |= USART_CR1_SETBITS; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); - - /* Configure CR3 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); - cr &= ~USART_CR3_CLRBITS; - cr |= USART_CR3_SETBITS; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); - - /* Configure the USART Baud Rate */ - - putreg32(STM32_BRR_VALUE, - STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); - - /* Select oversampling by 8 */ - - cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); -#ifdef USE_OVER8 - cr |= USART_CR1_OVER8; - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); -#endif - - /* Enable Rx, Tx, and the USART */ - - cr |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); - putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); - -#endif /* HAVE_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ -#endif /* HAVE_UART */ -} diff --git a/arch/arm/src/stm32l5/stm32l5_lowputc.h b/arch/arm/src/stm32l5/stm32l5_lowputc.h deleted file mode 100644 index c3e60eb22ae..00000000000 --- a/arch/arm/src/stm32l5/stm32l5_lowputc.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32l5/stm32l5_lowputc.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32L5_STM32L5_LOWPUTC_H -#define __ARCH_ARM_SRC_STM32L5_STM32L5_LOWPUTC_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "chip.h" - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Name: stm32_lowsetup - * - * Description: - * Called at the very beginning of _start. Performs low level - * initialization of serial console. - * - ****************************************************************************/ - -void stm32_lowsetup(void); - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_STM32L5_STM32L5_LOWPUTC_H */ diff --git a/arch/arm/src/stm32l5/stm32l5_serial.c b/arch/arm/src/stm32l5/stm32l5_serial.c deleted file mode 100644 index e1b8155b2be..00000000000 --- a/arch/arm/src/stm32l5/stm32l5_serial.c +++ /dev/null @@ -1,3246 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32l5/stm32l5_serial.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_SERIAL_TERMIOS -# include -#endif - -#include - -#include "chip.h" -#include "stm32_gpio.h" -#include "stm32l5_uart.h" -#ifdef SERIAL_HAVE_DMA -# include "stm32l5_dma.h" -#endif -#include "stm32_rcc.h" -#include "arm_internal.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Some sanity checks *******************************************************/ - -/* DMA configuration */ - -/* If DMA is enabled on any USART, then very that other pre-requisites - * have also been selected. - * UART DMA1 DMA2 - * 1 X X - * 2 X - * 3 X - * 4 X - * 5 X - */ - -#ifdef SERIAL_HAVE_DMA - -/* Verify that DMA has been enabled and the DMA channel has been defined. - */ - -# if defined(CONFIG_USART2_RXDMA) || defined(CONFIG_USART3_RXDMA) -# if !defined(CONFIG_STM32_DMA1) && !defined(CONFIG_STM32_DMAMUX) -# error STM32L5 USART2/3 receive DMA requires CONFIG_STM32_DMA1 -# endif -# endif - -# if defined(CONFIG_UART4_RXDMA) || defined(CONFIG_UART5_RXDMA) -# if !defined(CONFIG_STM32_DMA2) && !defined(CONFIG_STM32_DMAMUX) -# error STM32L5 UART4/5 receive DMA requires CONFIG_STM32_DMA2 -# endif -# endif - -/* Currently RS-485 support cannot be enabled when RXDMA is in use due to - * lack of testing - RS-485 support was developed on STM32F1x - */ - -# if (defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_RS485)) || \ - (defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_RS485)) || \ - (defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_RS485)) || \ - (defined(CONFIG_UART4_RXDMA) && defined(CONFIG_UART4_RS485)) || \ - (defined(CONFIG_UART5_RXDMA) && defined(CONFIG_UART5_RS485)) -# error "RXDMA and RS-485 cannot be enabled at the same time for the same U[S]ART" -# endif - -/* For the L4, there are alternate DMA channels for USART1. - * Logic in the board.h file make the DMA channel selection by defining - * the following in the board.h file. - */ - -# if defined(CONFIG_USART1_RXDMA) && !defined(DMAMAP_USART1_RX) -# error "USART1 DMA channel not defined (DMAMAP_USART1_RX)" -# endif - -/* UART2-5 have no alternate channels without DMAMUX */ - -# ifndef CONFIG_STM32_HAVE_DMAMUX -# define DMAMAP_USART2_RX DMACHAN_USART2_RX -# define DMAMAP_USART3_RX DMACHAN_USART3_RX -# define DMAMAP_UART4_RX DMACHAN_UART4_RX -# define DMAMAP_UART5_RX DMACHAN_UART5_RX -# endif - -# if defined(CONFIG_USART2_RXDMA) && !defined(DMAMAP_USART2_RX) -# error "USART2 DMA channel not defined (DMAMAP_USART2_RX)" -# endif - -# if defined(CONFIG_USART3_RXDMA) && !defined(DMAMAP_USART3_RX) -# error "USART3 DMA channel not defined (DMAMAP_USART3_RX)" -# endif - -# if defined(CONFIG_UART4_RXDMA) && !defined(DMAMAP_UART4_RX) -# error "UART4 DMA channel not defined (DMAMAP_UART4_RX)" -# endif - -# if defined(CONFIG_UART5_RXDMA) && !defined(DMAMAP_UART5_RX) -# error "UART5 DMA channel not defined (DMAMAP_UART5_RX)" -# endif - -/* The DMA buffer size when using RX DMA to emulate a FIFO. - * - * When streaming data, the generic serial layer will be called - * every time the FIFO receives half this number of bytes. - * - * If there ever is a STM32L5 with D-cache, the buffer size - * should be an even multiple of ARMV7M_DCACHE_LINESIZE, so that it - * can be individually invalidated. - */ - -# if !defined(CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE) || \ - CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE == 0 -# define RXDMA_BUFFER_SIZE 32 -# else -# define RXDMA_BUFFER_SIZE ((CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE + 31) & ~31) -# endif - -/* DMA priority */ - -# ifndef CONFIG_USART_DMAPRIO -# define CONFIG_USART_DMAPRIO DMA_CCR_PRIMED -# endif -# if (CONFIG_USART_DMAPRIO & ~DMA_CCR_PL_MASK) != 0 -# error "Illegal value for CONFIG_USART_DMAPRIO" -# endif - -/* DMA control words */ - -# define SERIAL_DMA_CONTROL_WORD \ - (DMA_CCR_CIRC | \ - DMA_CCR_MINC | \ - DMA_CCR_PSIZE_8BITS | \ - DMA_CCR_MSIZE_8BITS | \ - CONFIG_USART_DMAPRIO) -# ifdef CONFIG_SERIAL_IFLOWCONTROL -# define SERIAL_DMA_IFLOW_CONTROL_WORD \ - (DMA_CCR_MINC | \ - DMA_CCR_PSIZE_8BITS | \ - DMA_CCR_MSIZE_8BITS | \ - CONFIG_USART_DMAPRIO) -# endif - -#endif - -/* Power management definitions */ - -#if defined(CONFIG_PM) && !defined(CONFIG_STM32_PM_SERIAL_ACTIVITY) -# define CONFIG_STM32_PM_SERIAL_ACTIVITY 10 -#endif - -/* Keep track if a Break was set - * - * Note: - * - * 1) This value is set in the priv->ie but never written to the control - * register. It must not collide with USART_CR1_USED_INTS or USART_CR3_EIE - * 2) USART_CR3_EIE is also carried in the up_dev_s ie member. - * - * See stm32l5serial_restoreusartint where the masking is done. - */ - -#ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT -# define USART_CR1_IE_BREAK_INPROGRESS_SHFTS 15 -# define USART_CR1_IE_BREAK_INPROGRESS (1 << USART_CR1_IE_BREAK_INPROGRESS_SHFTS) -#endif - -#ifdef USE_SERIALDRIVER -#ifdef HAVE_UART - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct stm32_serial_s -{ - struct uart_dev_s dev; /* Generic UART device */ - uint16_t ie; /* Saved interrupt mask bits value */ - uint16_t sr; /* Saved status bits */ - - /* Has been initialized and HW is setup. */ - - bool initialized; - -#ifdef CONFIG_PM - bool suspended; /* UART device has been suspended. */ - - /* Interrupt mask value stored before suspending for stop mode. */ - - uint16_t suspended_ie; -#endif - - /* If termios are supported, then the following fields may vary at - * runtime. - */ - -#ifdef CONFIG_SERIAL_TERMIOS - uint8_t parity; /* 0=none, 1=odd, 2=even */ - uint8_t bits; /* Number of bits (7 or 8) */ - bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - bool iflow; /* input flow control (RTS) enabled */ -#endif -#ifdef CONFIG_SERIAL_OFLOWCONTROL - bool oflow; /* output flow control (CTS) enabled */ -#endif - uint32_t baud; /* Configured baud */ -#else - const uint8_t parity; /* 0=none, 1=odd, 2=even */ - const uint8_t bits; /* Number of bits (7 or 8) */ - const bool stopbits2; /* True: Configure with 2 stop bits instead of 1 */ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - const bool iflow; /* input flow control (RTS) enabled */ -#endif -#ifdef CONFIG_SERIAL_OFLOWCONTROL - const bool oflow; /* output flow control (CTS) enabled */ -#endif - const uint32_t baud; /* Configured baud */ -#endif - - const uint8_t irq; /* IRQ associated with this USART */ - const uint32_t apbclock; /* PCLK 1 or 2 frequency */ - const uint32_t usartbase; /* Base address of USART registers */ - const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ - const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ -#endif -#ifdef CONFIG_SERIAL_OFLOWCONTROL - const uint32_t cts_gpio; /* U[S]ART CTS GPIO pin configuration */ -#endif - -#ifdef SERIAL_HAVE_DMA - const unsigned int rxdma_channel; /* DMA channel assigned */ -#endif - - /* RX DMA state */ - -#ifdef SERIAL_HAVE_DMA - DMA_HANDLE rxdma; /* currently-open receive DMA stream */ - bool rxenable; /* DMA-based reception en/disable */ -#ifdef CONFIG_PM - bool rxdmasusp; /* Rx DMA suspended */ -#endif - uint32_t rxdmanext; /* Next byte in the DMA buffer to be read */ - char *const rxfifo; /* Receive DMA buffer */ -#endif - -#ifdef HAVE_RS485 - const uint32_t rs485_dir_gpio; /* U[S]ART RS-485 DIR GPIO pin configuration */ - const bool rs485_dir_polarity; /* U[S]ART RS-485 DIR pin state for TX enabled */ -#endif - spinlock_t lock; -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_UART_CONFIG -static void stm32l5serial_setformat(struct uart_dev_s *dev); -#endif -static int stm32l5serial_setup(struct uart_dev_s *dev); -static void stm32l5serial_shutdown(struct uart_dev_s *dev); -static int stm32l5serial_attach(struct uart_dev_s *dev); -static void stm32l5serial_detach(struct uart_dev_s *dev); -static int stm32l5serial_interrupt(int irq, void *context, - void *arg); -static int stm32l5serial_ioctl(struct file *filep, int cmd, - unsigned long arg); -#ifndef SERIAL_HAVE_ONLY_DMA -static int stm32l5serial_receive(struct uart_dev_s *dev, - unsigned int *status); -static void stm32l5serial_rxint(struct uart_dev_s *dev, bool enable); -static bool stm32l5serial_rxavailable(struct uart_dev_s *dev); -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool stm32l5serial_rxflowcontrol(struct uart_dev_s *dev, - unsigned int nbuffered, bool upper); -#endif -static void stm32l5serial_send(struct uart_dev_s *dev, int ch); -static void stm32l5serial_txint(struct uart_dev_s *dev, bool enable); -static bool stm32l5serial_txready(struct uart_dev_s *dev); - -#ifdef SERIAL_HAVE_DMA -static int stm32l5serial_dmasetup(struct uart_dev_s *dev); -static void stm32l5serial_dmashutdown(struct uart_dev_s *dev); -static int stm32l5serial_dmareceive(struct uart_dev_s *dev, - unsigned int *status); -static void stm32l5serial_dmareenable(struct stm32_serial_s *priv); -#ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool stm32l5serial_dmaiflowrestart(struct stm32_serial_s *priv); -#endif -static void stm32l5serial_dmarxint(struct uart_dev_s *dev, bool enable); -static bool stm32l5serial_dmarxavailable(struct uart_dev_s *dev); - -static void stm32l5serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, - void *arg); -#endif - -#ifdef CONFIG_PM -static void stm32l5serial_setsuspend(struct uart_dev_s *dev, bool suspend); -static void stm32l5serial_pm_setsuspend(bool suspend); -static void stm32l5serial_pmnotify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); -static int stm32l5serial_pmprepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); -#endif - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static const struct uart_ops_s g_uart_ops = -{ - .setup = stm32l5serial_setup, - .shutdown = stm32l5serial_shutdown, - .attach = stm32l5serial_attach, - .detach = stm32l5serial_detach, - .ioctl = stm32l5serial_ioctl, - .receive = stm32l5serial_receive, - .rxint = stm32l5serial_rxint, - .rxavailable = stm32l5serial_rxavailable, -# ifdef CONFIG_SERIAL_IFLOWCONTROL - .rxflowcontrol = stm32l5serial_rxflowcontrol, -# endif - .send = stm32l5serial_send, - .txint = stm32l5serial_txint, - .txready = stm32l5serial_txready, - .txempty = stm32l5serial_txready, -}; -#endif - -#ifdef SERIAL_HAVE_DMA -static const struct uart_ops_s g_uart_dma_ops = -{ - .setup = stm32l5serial_dmasetup, - .shutdown = stm32l5serial_dmashutdown, - .attach = stm32l5serial_attach, - .detach = stm32l5serial_detach, - .ioctl = stm32l5serial_ioctl, - .receive = stm32l5serial_dmareceive, - .rxint = stm32l5serial_dmarxint, - .rxavailable = stm32l5serial_dmarxavailable, -# ifdef CONFIG_SERIAL_IFLOWCONTROL - .rxflowcontrol = stm32l5serial_rxflowcontrol, -# endif - .send = stm32l5serial_send, - .txint = stm32l5serial_txint, - .txready = stm32l5serial_txready, - .txempty = stm32l5serial_txready, -}; -#endif - -/* I/O buffers */ - -#ifdef CONFIG_STM32_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_STM32_USART1_SERIALDRIVER -static char g_usart1rxbuffer[CONFIG_USART1_RXBUFSIZE]; -static char g_usart1txbuffer[CONFIG_USART1_TXBUFSIZE]; -# ifdef CONFIG_USART1_RXDMA -static char g_usart1rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART2_SERIALDRIVER -static char g_usart2rxbuffer[CONFIG_USART2_RXBUFSIZE]; -static char g_usart2txbuffer[CONFIG_USART2_TXBUFSIZE]; -# ifdef CONFIG_USART2_RXDMA -static char g_usart2rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_USART3_SERIALDRIVER -static char g_usart3rxbuffer[CONFIG_USART3_RXBUFSIZE]; -static char g_usart3txbuffer[CONFIG_USART3_TXBUFSIZE]; -# ifdef CONFIG_USART3_RXDMA -static char g_usart3rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART4_SERIALDRIVER -static char g_uart4rxbuffer[CONFIG_UART4_RXBUFSIZE]; -static char g_uart4txbuffer[CONFIG_UART4_TXBUFSIZE]; -# ifdef CONFIG_UART4_RXDMA -static char g_uart4rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -#ifdef CONFIG_STM32_UART5_SERIALDRIVER -static char g_uart5rxbuffer[CONFIG_UART5_RXBUFSIZE]; -static char g_uart5txbuffer[CONFIG_UART5_TXBUFSIZE]; -# ifdef CONFIG_UART5_RXDMA -static char g_uart5rxfifo[RXDMA_BUFFER_SIZE]; -# endif -#endif - -/* This describes the state of the STM32 USART1 ports. */ - -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER -static struct stm32_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 = STM32_IRQ_LPUART1, - .parity = CONFIG_LPUART1_PARITY, - .bits = CONFIG_LPUART1_BITS, - .stopbits2 = CONFIG_LPUART1_2STOP, - .baud = CONFIG_LPUART1_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, - .usartbase = STM32_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_LPUSART_RX, - .rxfifo = g_lpuart1rxfifo, -# endif - -# ifdef CONFIG_USART1_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 - .lock = SP_UNLOCKED, -}; -#endif - -#ifdef CONFIG_STM32_USART1_SERIALDRIVER -static struct stm32_serial_s g_usart1priv = -{ - .dev = - { -# if CONSOLE_UART == 2 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART1_RXBUFSIZE, - .buffer = g_usart1rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART1_TXBUFSIZE, - .buffer = g_usart1txbuffer, - }, -# ifdef CONFIG_USART1_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart1priv, - }, - - .irq = STM32_IRQ_USART1, - .parity = CONFIG_USART1_PARITY, - .bits = CONFIG_USART1_BITS, - .stopbits2 = CONFIG_USART1_2STOP, - .baud = CONFIG_USART1_BAUD, - .apbclock = STM32_PCLK2_FREQUENCY, - .usartbase = STM32_USART1_BASE, - .tx_gpio = GPIO_USART1_TX, - .rx_gpio = GPIO_USART1_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART1_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART1_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART1_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART1_RTS, -# endif -# ifdef CONFIG_USART1_RXDMA - .rxdma_channel = DMAMAP_USART1_RX, - .rxfifo = g_usart1rxfifo, -# endif - -# ifdef CONFIG_USART1_RS485 - .rs485_dir_gpio = GPIO_USART1_RS485_DIR, -# if (CONFIG_USART1_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -# endif - .lock = SP_UNLOCKED, -}; -#endif - -/* This describes the state of the STM32 USART2 port. */ - -#ifdef CONFIG_STM32_USART2_SERIALDRIVER -static struct stm32_serial_s g_usart2priv = -{ - .dev = - { -# if CONSOLE_UART == 3 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART2_RXBUFSIZE, - .buffer = g_usart2rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART2_TXBUFSIZE, - .buffer = g_usart2txbuffer, - }, -# ifdef CONFIG_USART2_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart2priv, - }, - - .irq = STM32_IRQ_USART2, - .parity = CONFIG_USART2_PARITY, - .bits = CONFIG_USART2_BITS, - .stopbits2 = CONFIG_USART2_2STOP, - .baud = CONFIG_USART2_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, - .usartbase = STM32_USART2_BASE, - .tx_gpio = GPIO_USART2_TX, - .rx_gpio = GPIO_USART2_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART2_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART2_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART2_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART2_RTS, -# endif -# ifdef CONFIG_USART2_RXDMA - .rxdma_channel = DMAMAP_USART2_RX, - .rxfifo = g_usart2rxfifo, -# endif - -# ifdef CONFIG_USART2_RS485 - .rs485_dir_gpio = GPIO_USART2_RS485_DIR, -# if (CONFIG_USART2_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -# endif - .lock = SP_UNLOCKED, -}; -#endif - -/* This describes the state of the STM32 USART3 port. */ - -#ifdef CONFIG_STM32_USART3_SERIALDRIVER -static struct stm32_serial_s g_usart3priv = -{ - .dev = - { -# if CONSOLE_UART == 4 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_USART3_RXBUFSIZE, - .buffer = g_usart3rxbuffer, - }, - .xmit = - { - .size = CONFIG_USART3_TXBUFSIZE, - .buffer = g_usart3txbuffer, - }, -# ifdef CONFIG_USART3_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_usart3priv, - }, - - .irq = STM32_IRQ_USART3, - .parity = CONFIG_USART3_PARITY, - .bits = CONFIG_USART3_BITS, - .stopbits2 = CONFIG_USART3_2STOP, - .baud = CONFIG_USART3_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, - .usartbase = STM32_USART3_BASE, - .tx_gpio = GPIO_USART3_TX, - .rx_gpio = GPIO_USART3_RX, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART3_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_USART3_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART3_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_USART3_RTS, -# endif -# ifdef CONFIG_USART3_RXDMA - .rxdma_channel = DMAMAP_USART3_RX, - .rxfifo = g_usart3rxfifo, -# endif - -# ifdef CONFIG_USART3_RS485 - .rs485_dir_gpio = GPIO_USART3_RS485_DIR, -# if (CONFIG_USART3_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -# endif - .lock = SP_UNLOCKED, -}; -#endif - -/* This describes the state of the STM32 UART4 port. */ - -#ifdef CONFIG_STM32_UART4_SERIALDRIVER -static struct stm32_serial_s g_uart4priv = -{ - .dev = - { -# if CONSOLE_UART == 5 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART4_RXBUFSIZE, - .buffer = g_uart4rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART4_TXBUFSIZE, - .buffer = g_uart4txbuffer, - }, -# ifdef CONFIG_UART4_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart4priv, - }, - - .irq = STM32_IRQ_UART4, - .parity = CONFIG_UART4_PARITY, - .bits = CONFIG_UART4_BITS, - .stopbits2 = CONFIG_UART4_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART4_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART4_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART4_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART4_RTS, -# endif - .baud = CONFIG_UART4_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, - .usartbase = STM32_UART4_BASE, - .tx_gpio = GPIO_UART4_TX, - .rx_gpio = GPIO_UART4_RX, -# ifdef CONFIG_UART4_RXDMA - .rxdma_channel = DMAMAP_UART4_RX, - .rxfifo = g_uart4rxfifo, -# endif - -# ifdef CONFIG_UART4_RS485 - .rs485_dir_gpio = GPIO_UART4_RS485_DIR, -# if (CONFIG_UART4_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -# endif - .lock = SP_UNLOCKED, -}; -#endif - -/* This describes the state of the STM32 UART5 port. */ - -#ifdef CONFIG_STM32_UART5_SERIALDRIVER -static struct stm32_serial_s g_uart5priv = -{ - .dev = - { -# if CONSOLE_UART == 6 - .isconsole = true, -# endif - .recv = - { - .size = CONFIG_UART5_RXBUFSIZE, - .buffer = g_uart5rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART5_TXBUFSIZE, - .buffer = g_uart5txbuffer, - }, -# ifdef CONFIG_UART5_RXDMA - .ops = &g_uart_dma_ops, -# else - .ops = &g_uart_ops, -# endif - .priv = &g_uart5priv, - }, - - .irq = STM32_IRQ_UART5, - .parity = CONFIG_UART5_PARITY, - .bits = CONFIG_UART5_BITS, - .stopbits2 = CONFIG_UART5_2STOP, -# if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART5_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART5_CTS, -# endif -# if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART5_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART5_RTS, -# endif - .baud = CONFIG_UART5_BAUD, - .apbclock = STM32_PCLK1_FREQUENCY, - .usartbase = STM32_UART5_BASE, - .tx_gpio = GPIO_UART5_TX, - .rx_gpio = GPIO_UART5_RX, -# ifdef CONFIG_UART5_RXDMA - .rxdma_channel = DMAMAP_UART5_RX, - .rxfifo = g_uart5rxfifo, -# endif - -# ifdef CONFIG_UART5_RS485 - .rs485_dir_gpio = GPIO_UART5_RS485_DIR, -# if (CONFIG_UART5_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -# endif - .lock = SP_UNLOCKED, -}; -#endif - -/* This table lets us iterate over the configured USARTs */ - -static struct stm32_serial_s * const - g_uart_devs[STM32_NLPUART + STM32_NUSART + STM32_NUART] = -{ -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER - [0] = &g_lpuart1priv, -#endif -#ifdef CONFIG_STM32_USART1_SERIALDRIVER - [1] = &g_usart1priv, -#endif -#ifdef CONFIG_STM32_USART2_SERIALDRIVER - [2] = &g_usart2priv, -#endif -#ifdef CONFIG_STM32_USART3_SERIALDRIVER - [3] = &g_usart3priv, -#endif -#ifdef CONFIG_STM32_UART4_SERIALDRIVER - [4] = &g_uart4priv, -#endif -#ifdef CONFIG_STM32_UART5_SERIALDRIVER - [5] = &g_uart5priv, -#endif -}; - -#ifdef CONFIG_PM -struct serialpm_s -{ - struct pm_callback_s pm_cb; - bool serial_suspended; -}; - -static struct serialpm_s g_serialpm = -{ - .pm_cb.notify = stm32l5serial_pmnotify, - .pm_cb.prepare = stm32l5serial_pmprepare, - .serial_suspended = false -}; -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32l5serial_getreg - ****************************************************************************/ - -static inline -uint32_t stm32l5serial_getreg(struct stm32_serial_s *priv, int offset) -{ - return getreg32(priv->usartbase + offset); -} - -/**************************************************************************** - * Name: stm32l5serial_putreg - ****************************************************************************/ - -static inline -void stm32l5serial_putreg(struct stm32_serial_s *priv, - int offset, uint32_t value) -{ - putreg32(value, priv->usartbase + offset); -} - -/**************************************************************************** - * Name: stm32l5serial_setusartint - ****************************************************************************/ - -static inline -void stm32l5serial_setusartint(struct stm32_serial_s *priv, - uint16_t ie) -{ - uint32_t cr; - - /* Save the interrupt mask */ - - priv->ie = ie; - - /* And restore the interrupt state (see the interrupt enable/usage table - * above) - */ - - cr = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr &= ~(USART_CR1_USED_INTS); - cr |= (ie & (USART_CR1_USED_INTS)); - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr); - - cr = stm32l5serial_getreg(priv, STM32_USART_CR3_OFFSET); - cr &= ~USART_CR3_EIE; - cr |= (ie & USART_CR3_EIE); - stm32l5serial_putreg(priv, STM32_USART_CR3_OFFSET, cr); -} - -/**************************************************************************** - * Name: up_restoreusartint - ****************************************************************************/ - -static void stm32l5serial_restoreusartint(struct stm32_serial_s *priv, - uint16_t ie) -{ - irqstate_t flags; - - flags = spin_lock_irqsave(&priv->lock); - - stm32l5serial_setusartint(priv, ie); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/**************************************************************************** - * Name: stm32l5serial_disableusartint - ****************************************************************************/ - -static void stm32l5serial_disableusartint(struct stm32_serial_s *priv, - uint16_t *ie) -{ - irqstate_t flags; - - flags = spin_lock_irqsave(&priv->lock); - - if (ie) - { - uint32_t cr1; - uint32_t cr3; - - /* USART interrupts: - * - * Enable Status Meaning Usage - * ---------------- -------------- ---------------------- ------------- - * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) - * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to - * be Read - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only RS-485) - * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register - * Empty - * USART_CR1_PEIE USART_ISR_PE Parity Error - * - * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) - * USART_CR3_EIE USART_ISR_FE Framing Error - * " " USART_ISR_NF Noise Flag - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) - */ - - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr3 = stm32l5serial_getreg(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_USED_INTS)) | (cr3 & USART_CR3_EIE); - } - - /* Disable all interrupts */ - - stm32l5serial_setusartint(priv, 0); - - spin_unlock_irqrestore(&priv->lock, flags); -} - -/**************************************************************************** - * Name: stm32l5serial_dmanextrx - * - * Description: - * Returns the index into the RX FIFO where the DMA will place the next - * byte that it receives. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static int stm32l5serial_dmanextrx(struct stm32_serial_s *priv) -{ - size_t dmaresidual; - - dmaresidual = stm32_dmaresidual(priv->rxdma); - - return (RXDMA_BUFFER_SIZE - (int)dmaresidual); -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_setformat - * - * Description: - * Set the serial line format and speed. - * - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_UART_CONFIG -static void stm32l5serial_setformat(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t regval; - - /* This first implementation is for U[S]ARTs that support oversampling - * by 8 in additional to the standard oversampling by 16. - */ - - uint32_t usartdiv8; - uint32_t cr1; - uint32_t brr; - -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER - if (priv->usartbase == STM32_LPUART1_BASE) - { - /* LPUART BRR = 256 * fCK / baud */ - - brr = (((uint64_t)priv->apbclock << 8) + - (priv->baud >> 1)) / priv->baud; - stm32l5serial_putreg(priv, STM32_USART_BRR_OFFSET, brr); - } - else -#endif - { - usartdiv8 = ((priv->apbclock << 1) + (priv->baud >> 1)) / priv->baud; - - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - if (usartdiv8 > 2000) - { - brr = (usartdiv8 + 1) >> 1; - cr1 &= ~USART_CR1_OVER8; - } - else - { - DEBUGASSERT(usartdiv8 >= 8); - brr = ((usartdiv8 & 0xfff0) | ((usartdiv8 & 0x000f) >> 1)); - cr1 |= USART_CR1_OVER8; - } - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - stm32l5serial_putreg(priv, STM32_USART_BRR_OFFSET, brr); - } - - /* Configure parity mode */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0 | USART_CR1_M1); - - if (priv->parity == 1) /* Odd parity */ - { - regval |= (USART_CR1_PCE | USART_CR1_PS); - } - else if (priv->parity == 2) /* Even parity */ - { - regval |= USART_CR1_PCE; - } - - /* Configure word length (parity uses one of configured bits) - * - * Default: 1 start, 8 data (no parity), n stop, OR - * 1 start, 7 data + parity, n stop - */ - - if (priv->bits == 9 || (priv->bits == 8 && priv->parity != 0)) - { - /* Select: 1 start, 8 data + parity, n stop, OR - * 1 start, 9 data (no parity), n stop. - */ - - regval |= USART_CR1_M0; - } - else if (priv->bits == 7 && priv->parity == 0) - { - /* Select: 1 start, 7 data (no parity), n stop, OR - */ - - regval |= USART_CR1_M1; - } - - /* Else Select: 1 start, 7 data + parity, n stop, OR - * 1 start, 8 data (no parity), n stop. - */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - - /* Configure STOP bits */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR2_OFFSET); - regval &= ~(USART_CR2_STOP_MASK); - - if (priv->stopbits2) - { - regval |= USART_CR2_STOP2; - } - - stm32l5serial_putreg(priv, STM32_USART_CR2_OFFSET, regval); - - /* Configure hardware flow control */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR3_OFFSET); - regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); - -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && !defined(CONFIG_STM32_FLOWCONTROL_BROKEN) - if (priv->iflow && (priv->rts_gpio != 0)) - { - regval |= USART_CR3_RTSE; - } -#endif - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->oflow && (priv->cts_gpio != 0)) - { - regval |= USART_CR3_CTSE; - } -#endif - - stm32l5serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); -} -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ - -/**************************************************************************** - * Name: stm32l5serial_setsuspend - * - * Description: - * Suspend or resume serial peripheral. - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void stm32l5serial_setsuspend(struct uart_dev_s *dev, bool suspend) -{ - struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; -#ifdef SERIAL_HAVE_DMA - bool dmarestored = false; -#endif - - if (priv->suspended == suspend) - { - return; - } - - priv->suspended = suspend; - - if (suspend) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Force RTS high to prevent further Rx. */ - - stm32_configgpio((priv->rts_gpio & ~GPIO_MODE_MASK) - | (GPIO_OUTPUT | GPIO_OUTPUT_SET)); - } -#endif - - /* Disable interrupts to prevent Tx. */ - - stm32l5serial_disableusartint(priv, &priv->suspended_ie); - - /* Wait last Tx to complete. */ - - while ((stm32l5serial_getreg(priv, STM32_USART_ISR_OFFSET) & - USART_ISR_TC) == 0); - -#ifdef SERIAL_HAVE_DMA - if (priv->dev.ops == &g_uart_dma_ops && !priv->rxdmasusp) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow && priv->rxdmanext == RXDMA_BUFFER_SIZE) - { - /* Rx DMA in non-circular iflow mode and already stopped - * at end of DMA buffer. No need to suspend. - */ - } - else -#endif - { - /* Suspend Rx DMA. */ - - stm32_dmastop(priv->rxdma); - priv->rxdmasusp = true; - } - } -#endif - } - else - { -#ifdef SERIAL_HAVE_DMA - if (priv->dev.ops == &g_uart_dma_ops && priv->rxdmasusp) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - stm32l5serial_dmaiflowrestart(priv); - } - else -#endif - { - /* This USART does not have HW flow-control. Unconditionally - * re-enable DMA (might loss unprocessed bytes received - * to DMA buffer before suspending). - */ - - stm32l5serial_dmareenable(priv); - priv->rxdmasusp = false; - } - - dmarestored = true; - } -#endif - - /* Re-enable interrupts to resume Tx. */ - - stm32l5serial_restoreusartint(priv, priv->suspended_ie); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Restore peripheral RTS control. */ - - stm32_configgpio(priv->rts_gpio); - } -#endif - } - -#ifdef SERIAL_HAVE_DMA - if (dmarestored) - { - irqstate_t flags; - - flags = enter_critical_section(); - - /* Perform initial Rx DMA buffer fetch to wake-up serial device - * activity. - */ - - if (priv->rxdma != NULL) - { - stm32l5serial_dmarxcallback(priv->rxdma, 0, priv); - } - - leave_critical_section(flags); - } -#endif -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_pm_setsuspend - * - * Description: - * Suspend or resume serial peripherals for/from deep-sleep/stop modes. - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void stm32l5serial_pm_setsuspend(bool suspend) -{ - int n; - - /* Already in desired state? */ - - if (suspend == g_serialpm.serial_suspended) - return; - - g_serialpm.serial_suspended = suspend; - - for (n = 0; n < STM32_NLPUART + STM32_NUSART + STM32_NUART; n++) - { - struct stm32_serial_s *priv = g_uart_devs[n]; - - if (!priv || !priv->initialized) - { - continue; - } - - stm32l5serial_setsuspend(&priv->dev, suspend); - } -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_setapbclock - * - * Description: - * Enable or disable APB clock for the USART peripheral - * - * Input Parameters: - * dev - A reference to the UART driver state structure - * on - Enable clock if 'on' is 'true' and disable if 'false' - * - ****************************************************************************/ - -static void stm32l5serial_setapbclock(struct uart_dev_s *dev, bool on) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t rcc_en; - uint32_t regaddr; - - /* Determine which USART to configure */ - - switch (priv->usartbase) - { - default: - return; -#ifdef CONFIG_STM32_LPUART1_SERIALDRIVER - case STM32_LPUART1_BASE: - rcc_en = RCC_APB1ENR2_LPUART1EN; - regaddr = STM32_RCC_APB1ENR2; - break; -#endif -#ifdef CONFIG_STM32_USART1_SERIALDRIVER - case STM32_USART1_BASE: - rcc_en = RCC_APB2ENR_USART1EN; - regaddr = STM32_RCC_APB2ENR; - break; -#endif -#ifdef CONFIG_STM32_USART2_SERIALDRIVER - case STM32_USART2_BASE: - rcc_en = RCC_APB1ENR1_USART2EN; - regaddr = STM32_RCC_APB1ENR1; - break; -#endif -#ifdef CONFIG_STM32_USART3_SERIALDRIVER - case STM32_USART3_BASE: - rcc_en = RCC_APB1ENR1_USART3EN; - regaddr = STM32_RCC_APB1ENR1; - break; -#endif -#ifdef CONFIG_STM32_UART4_SERIALDRIVER - case STM32_UART4_BASE: - rcc_en = RCC_APB1ENR1_UART4EN; - regaddr = STM32_RCC_APB1ENR1; - break; -#endif -#ifdef CONFIG_STM32_UART5_SERIALDRIVER - case STM32_UART5_BASE: - rcc_en = RCC_APB1ENR1_UART5EN; - regaddr = STM32_RCC_APB1ENR1; - break; -#endif - } - - /* Enable/disable APB 1/2 clock for USART */ - - if (on) - { - modifyreg32(regaddr, 0, rcc_en); - } - else - { - modifyreg32(regaddr, rcc_en, 0); - } -} - -/**************************************************************************** - * Name: stm32l5serial_setup - * - * Description: - * Configure the USART baud, bits, parity, etc. This method is called the - * first time that the serial port is opened. - * - ****************************************************************************/ - -static int stm32l5serial_setup(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - -#ifndef CONFIG_SUPPRESS_UART_CONFIG - uint32_t regval; - - /* Note: The logic here depends on the fact that that the USART module - * was enabled in stm32_lowsetup(). - */ - - /* Enable USART APB1/2 clock */ - - stm32l5serial_setapbclock(dev, true); - - /* Configure pins for USART use */ - - if (priv->tx_gpio != 0) - { - stm32_configgpio(priv->tx_gpio); - } - - if (priv->rx_gpio != 0) - { - stm32_configgpio(priv->rx_gpio); - } - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->cts_gpio != 0) - { - stm32_configgpio(priv->cts_gpio); - } -#endif - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->rts_gpio != 0) - { - uint32_t config = priv->rts_gpio; - -#ifdef CONFIG_STM32_FLOWCONTROL_BROKEN - /* Instead of letting hw manage this pin, we will bitbang */ - - config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; -#endif - stm32_configgpio(config); - } -#endif - -#ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) - { - stm32_configgpio(priv->rs485_dir_gpio); - stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); - } -#endif - - /* Configure CR2 */ - - /* Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits */ - - regval = stm32l5serial_getreg(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; - } - - stm32l5serial_putreg(priv, STM32_USART_CR2_OFFSET, regval); - - /* Configure CR1 */ - - /* Clear TE, REm and all interrupt enable bits */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_ALLINTS); - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - - /* Configure CR3 */ - - /* Clear CTSE, RTSE, and all interrupt enable bits */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR3_OFFSET); - regval &= ~(USART_CR3_CTSIE | USART_CR3_CTSE | USART_CR3_RTSE | - USART_CR3_EIE); - - stm32l5serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); - - /* Configure the USART line format and speed. */ - - stm32l5serial_setformat(dev); - - /* Enable Rx, Tx, and the USART */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ - - /* Set up the cached interrupt enables value */ - - priv->ie = 0; - - /* Mark device as initialized. */ - - priv->initialized = true; - - return OK; -} - -/**************************************************************************** - * Name: stm32l5serial_dmasetup - * - * Description: - * Configure the USART baud, bits, parity, etc. This method is called the - * first time that the serial port is opened. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static int stm32l5serial_dmasetup(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - int result; - uint32_t regval; - - /* Do the basic UART setup first, unless we are the console */ - - if (!dev->isconsole) - { - result = stm32l5serial_setup(dev); - if (result != OK) - { - return result; - } - } - - /* Acquire the DMA channel. This should always succeed. */ - - priv->rxdma = stm32_dmachannel(priv->rxdma_channel); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Configure for non-circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_IFLOW_CONTROL_WORD); - } - else -#endif - { - /* Configure for circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_CONTROL_WORD); - } - - /* Reset our DMA shadow pointer to match the address just - * programmed above. - */ - - priv->rxdmanext = 0; - - /* Enable receive DMA for the UART */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR3_OFFSET); - regval |= USART_CR3_DMAR; - stm32l5serial_putreg(priv, STM32_USART_CR3_OFFSET, regval); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Start the DMA channel, and arrange for callbacks at the full point - * in the FIFO. After buffer gets full, hardware flow-control kicks - * in and DMA transfer is stopped. - */ - - stm32_dmastart(priv->rxdma, stm32l5serial_dmarxcallback, - (void *)priv, false); - } - else -#endif - { - /* Start the DMA channel, and arrange for callbacks at the half and - * full points in the FIFO. This ensures that we have half a FIFO - * worth of time to claim bytes before they are overwritten. - */ - - stm32_dmastart(priv->rxdma, stm32l5serial_dmarxcallback, - (void *)priv, true); - } - - return OK; -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_shutdown - * - * Description: - * Disable the USART. This method is called when the serial - * port is closed - * - ****************************************************************************/ - -static void stm32l5serial_shutdown(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t regval; - - /* Mark device as uninitialized. */ - - priv->initialized = false; - - /* Disable all interrupts */ - - stm32l5serial_disableusartint(priv, NULL); - - /* Disable USART APB1/2 clock */ - - stm32l5serial_setapbclock(dev, false); - - /* Disable Rx, Tx, and the UART */ - - regval = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - regval &= ~(USART_CR1_UE | USART_CR1_TE | USART_CR1_RE); - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, regval); - - /* Release pins. "If the serial-attached device is powered down, the TX - * pin causes back-powering, potentially confusing the device to the point - * of complete lock-up." - * - * REVISIT: Is unconfiguring the pins appropriate for all device? If not, - * then this may need to be a configuration option. - */ - - if (priv->tx_gpio != 0) - { - stm32_unconfiggpio(priv->tx_gpio); - } - - if (priv->rx_gpio != 0) - { - stm32_unconfiggpio(priv->rx_gpio); - } - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->cts_gpio != 0) - { - stm32_unconfiggpio(priv->cts_gpio); - } -#endif - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->rts_gpio != 0) - { - stm32_unconfiggpio(priv->rts_gpio); - } -#endif - -#ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) - { - stm32_unconfiggpio(priv->rs485_dir_gpio); - } -#endif -} - -/**************************************************************************** - * Name: stm32l5serial_dmashutdown - * - * Description: - * Disable the USART. This method is called when the serial - * port is closed - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static void stm32l5serial_dmashutdown(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - /* Perform the normal UART shutdown */ - - stm32l5serial_shutdown(dev); - - /* Stop the DMA channel */ - - stm32_dmastop(priv->rxdma); - - /* Release the DMA channel */ - - stm32_dmafree(priv->rxdma); - priv->rxdma = NULL; -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_attach - * - * Description: - * Configure the USART to operation in interrupt driven mode. This method - * is called when the serial port is opened. Normally, this is just after - * the setup() method is called, however, the serial console may operate in - * a non-interrupt driven mode during the boot phase. - * - * RX and TX interrupts are not enabled when by the attach method (unless - * the hardware supports multiple levels of interrupt enabling). The RX - * and TX interrupts are not enabled until the txint() and rxint() methods - * are called. - * - ****************************************************************************/ - -static int stm32l5serial_attach(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - int ret; - - /* Attach and enable the IRQ */ - - ret = irq_attach(priv->irq, stm32l5serial_interrupt, priv); - - if (ret == OK) - { - /* Enable the interrupt (RX and TX interrupts are still disabled - * in the USART - */ - - up_enable_irq(priv->irq); - } - - return ret; -} - -/**************************************************************************** - * Name: stm32l5serial_detach - * - * Description: - * Detach USART interrupts. This method is called when the serial port is - * closed normally just before the shutdown method is called. The - * exception is the serial console which is never shutdown. - * - ****************************************************************************/ - -static void stm32l5serial_detach(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - up_disable_irq(priv->irq); - irq_detach(priv->irq); -} - -/**************************************************************************** - * Name: stm32l5serial_interrupt - * - * Description: - * This is the USART interrupt handler. It will be invoked when an - * interrupt is received on the 'irq'. It should call uart_xmitchars or - * uart_recvchars to perform the appropriate data transfers. The - * interrupt handling logic must be able to map the 'arg' to the - * appropriate uart_dev_s structure in order to call these functions. - * - ****************************************************************************/ - -static int stm32l5serial_interrupt(int irq, void *context, void *arg) -{ - struct stm32_serial_s *priv = (struct stm32_serial_s *)arg; - int passes; - bool handled; - - DEBUGASSERT(priv != NULL); - - /* Report serial activity to the power management logic */ - -#if defined(CONFIG_PM) && CONFIG_STM32_PM_SERIAL_ACTIVITY > 0 - pm_activity(PM_IDLE_DOMAIN, CONFIG_STM32_PM_SERIAL_ACTIVITY); -#endif - - /* Loop until there are no characters to be transferred or, - * until we have been looping for a long time. - */ - - handled = true; - for (passes = 0; passes < 256 && handled; passes++) - { - handled = false; - - /* Get the masked USART status word. */ - - priv->sr = stm32l5serial_getreg(priv, STM32_USART_ISR_OFFSET); - - /* USART interrupts: - * - * Enable Status Meaning Usage - * ---------------- -------------- ---------------------- ------------- - * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) - * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready to - * be Read - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only RS-485) - * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register - * Empty - * USART_CR1_PEIE USART_ISR_PE Parity Error - * - * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) - * USART_CR3_EIE USART_ISR_FE Framing Error - * " " USART_ISR_NE Noise Error - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) - * - * NOTE: Some of these status bits must be cleared by explicitly - * writing one to the ICR register: USART_ICR_CTSCF, USART_ICR_LBDCF. - * None of those are currently being used. - */ - -#ifdef HAVE_RS485 - /* Transmission of whole buffer is over - TC is set, TXEIE is cleared. - * Note - this should be first, to have the most recent TC bit value - * from SR register - sending data affects TC, but without refresh we - * will not know that... - */ - - if ((priv->sr & USART_ISR_TC) != 0 && - (priv->ie & USART_CR1_TCIE) != 0 && - (priv->ie & USART_CR1_TXEIE) == 0) - { - stm32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); - stm32l5serial_restoreusartint(priv, priv->ie & ~USART_CR1_TCIE); - } -#endif - - /* Handle incoming, receive bytes. */ - - if ((priv->sr & USART_ISR_RXNE) != 0 && - (priv->ie & USART_CR1_RXNEIE) != 0) - { - /* Received data ready... process incoming bytes. NOTE the check - * for RXNEIE: We cannot call uart_recvchards of RX interrupts are - * disabled. - */ - - uart_recvchars(&priv->dev); - handled = true; - } - - /* We may still have to read from the DR register to clear any pending - * error conditions. - */ - - else if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) - != 0) - { - /* These errors are cleared by writing the corresponding bit to the - * interrupt clear register (ICR). - */ - - stm32l5serial_putreg(priv, STM32_USART_ICR_OFFSET, - (USART_ICR_NCF | USART_ICR_ORECF | - USART_ICR_FECF)); - } - - /* Handle outgoing, transmit bytes */ - - if ((priv->sr & USART_ISR_TXE) != 0 && - (priv->ie & USART_CR1_TXEIE) != 0) - { - /* Transmit data register empty ... process outgoing bytes */ - - uart_xmitchars(&priv->dev); - handled = true; - } - } - - return OK; -} - -/**************************************************************************** - * Name: stm32l5serial_ioctl - * - * Description: - * All ioctl calls will be routed through this method - * - ****************************************************************************/ - -static int stm32l5serial_ioctl(struct file *filep, int cmd, - unsigned long arg) -{ - struct inode *inode = filep->f_inode; - struct uart_dev_s *dev = inode->i_private; - struct stm32_serial_s *priv = (struct stm32_serial_s *)dev->priv; - int ret = OK; - - UNUSED(inode); - UNUSED(dev); - UNUSED(priv); - - switch (cmd) - { -#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT - case TIOCSERGSTRUCT: - { - struct stm32_serial_s *user; - - user = (struct stm32_serial_s *)arg; - - if (!user) - { - ret = -EINVAL; - } - else - { - memcpy(user, dev, sizeof(struct stm32_serial_s)); - } - } - break; -#endif - -#ifdef CONFIG_STM32_USART_SINGLEWIRE - case TIOCSSINGLEWIRE: - { - uint32_t cr1; - uint32_t cr1_ue; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE, HDSEL can only be written when UE=0 */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Change the TX port to be open-drain/push-pull and enable/disable - * half-duplex mode. - */ - - uint32_t cr = stm32l5serial_getreg(priv, STM32_USART_CR3_OFFSET); - - if ((arg & SER_SINGLEWIRE_ENABLED) != 0) - { - uint32_t gpio_val = GPIO_OPENDRAIN; - - if ((arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLUP) - { - gpio_val |= GPIO_PULLUP; - } - else - { - gpio_val |= GPIO_FLOAT; - } - - if ((arg & SER_SINGLEWIRE_PULL_MASK) == SER_SINGLEWIRE_PULLDOWN) - { - gpio_val |= GPIO_PULLDOWN; - } - else - { - gpio_val |= GPIO_FLOAT; - } - - if (priv->tx_gpio != 0) - { - stm32_configgpio((priv->tx_gpio & - ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | - gpio_val); - } - - cr |= USART_CR3_HDSEL; - } - else - { - if (priv->tx_gpio != 0) - { - stm32_configgpio((priv->tx_gpio & - ~(GPIO_PUPD_MASK | GPIO_OPENDRAIN)) | - GPIO_PUSHPULL); - } - - cr &= ~USART_CR3_HDSEL; - } - - stm32l5serial_putreg(priv, STM32_USART_CR3_OFFSET, cr); - - /* Re-enable UE if appropriate */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); - } - break; -#endif - -#ifdef CONFIG_STM32_USART_INVERT - case TIOCSINVERT: - { - uint32_t cr1; - uint32_t cr1_ue; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE, {R,T}XINV can only be written when UE=0 */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Enable/disable signal inversion. */ - - uint32_t cr = stm32l5serial_getreg(priv, STM32_USART_CR2_OFFSET); - - if (arg & SER_INVERT_ENABLED_RX) - { - cr |= USART_CR2_RXINV; - } - else - { - cr &= ~USART_CR2_RXINV; - } - - if (arg & SER_INVERT_ENABLED_TX) - { - cr |= USART_CR2_TXINV; - } - else - { - cr &= ~USART_CR2_TXINV; - } - - stm32l5serial_putreg(priv, STM32_USART_CR2_OFFSET, cr); - - /* Re-enable UE if appropriate */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); - } - break; -#endif - -#ifdef CONFIG_STM32_USART_SWAP - case TIOCSSWAP: - { - uint32_t cr1; - uint32_t cr1_ue; - irqstate_t flags; - - flags = enter_critical_section(); - - /* Get the original state of UE */ - - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - cr1_ue = cr1 & USART_CR1_UE; - cr1 &= ~USART_CR1_UE; - - /* Disable UE, SWAP can only be written when UE=0 */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1); - - /* Enable/disable Swap mode. */ - - uint32_t cr = stm32l5serial_getreg(priv, STM32_USART_CR2_OFFSET); - - if (arg == SER_SWAP_ENABLED) - { - cr |= USART_CR2_SWAP; - } - else - { - cr &= ~USART_CR2_SWAP; - } - - stm32l5serial_putreg(priv, STM32_USART_CR2_OFFSET, cr); - - /* Re-enable UE if appropriate */ - - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, cr1 | cr1_ue); - leave_critical_section(flags); - } - break; -#endif - -#ifdef CONFIG_SERIAL_TERMIOS - case TCGETS: - { - struct termios *termiosp = (struct termios *)arg; - - if (!termiosp) - { - ret = -EINVAL; - break; - } - - cfsetispeed(termiosp, priv->baud); - - /* Note that since we only support 8/9 bit modes and - * there is no way to report 9-bit mode, we always claim 8. - */ - - termiosp->c_cflag = - ((priv->parity != 0) ? PARENB : 0) | - ((priv->parity == 1) ? PARODD : 0) | - ((priv->stopbits2) ? CSTOPB : 0) | -#ifdef CONFIG_SERIAL_OFLOWCONTROL - ((priv->oflow) ? CCTS_OFLOW : 0) | -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL - ((priv->iflow) ? CRTS_IFLOW : 0) | -#endif - CS8; - - /* TODO: CRTS_IFLOW, CCTS_OFLOW */ - } - break; - - case TCSETS: - { - struct termios *termiosp = (struct termios *)arg; - - if (!termiosp) - { - ret = -EINVAL; - break; - } - - /* Perform some sanity checks before accepting any changes */ - - if (((termiosp->c_cflag & CSIZE) != CS8) -#ifdef CONFIG_SERIAL_OFLOWCONTROL - || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0)) -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL - || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0)) -#endif - ) - { - ret = -EINVAL; - break; - } - - if (termiosp->c_cflag & PARENB) - { - priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; - } - else - { - priv->parity = 0; - } - - priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; -#ifdef CONFIG_SERIAL_OFLOWCONTROL - priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0; -#endif -#ifdef CONFIG_SERIAL_IFLOWCONTROL - priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0; -#endif - - /* Note that since there is no way to request 9-bit mode - * and no way to support 5/6/7-bit modes, we ignore them - * all here. - */ - - /* Note that only cfgetispeed is used because we have knowledge - * that only one speed is supported. - */ - - priv->baud = cfgetispeed(termiosp); - - /* Effect the changes immediately - note that we do not implement - * TCSADRAIN / TCSAFLUSH - */ - - stm32l5serial_setformat(dev); - } - break; -#endif /* CONFIG_SERIAL_TERMIOS */ - -#ifdef CONFIG_STM32_USART_BREAKS -# ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT - case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ - { - irqstate_t flags; - - flags = enter_critical_section(); - - /* Disable any further tx activity */ - - priv->ie |= USART_CR1_IE_BREAK_INPROGRESS; - - stm32l5serial_txint(dev, false); - - /* Configure TX as a GPIO output pin and Send a break signal */ - - if (priv->tx_gpio != 0) - { - uint32_t tx_break = GPIO_OUTPUT | - (~(GPIO_MODE_MASK | GPIO_OUTPUT_SET) & priv->tx_gpio); - stm32_configgpio(tx_break); - } - - leave_critical_section(flags); - } - break; - - case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ - { - irqstate_t flags; - - flags = enter_critical_section(); - - /* Configure TX back to U(S)ART */ - - if (priv->tx_gpio != 0) - { - stm32_configgpio(priv->tx_gpio); - } - - priv->ie &= ~USART_CR1_IE_BREAK_INPROGRESS; - - /* Enable further tx activity */ - - stm32l5serial_txint(dev, true); - - leave_critical_section(flags); - } - break; -# else - case TIOCSBRK: /* No BSD compatibility: Turn break on for M bit times */ - { - uint32_t cr1; - irqstate_t flags; - - flags = enter_critical_section(); - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, - cr1 | USART_CR1_SBK); - leave_critical_section(flags); - } - break; - - case TIOCCBRK: /* No BSD compatibility: May turn off break too soon */ - { - uint32_t cr1; - irqstate_t flags; - - flags = enter_critical_section(); - cr1 = stm32l5serial_getreg(priv, STM32_USART_CR1_OFFSET); - stm32l5serial_putreg(priv, STM32_USART_CR1_OFFSET, - cr1 & ~USART_CR1_SBK); - leave_critical_section(flags); - } - break; -# endif -#endif - - default: - ret = -ENOTTY; - break; - } - - return ret; -} - -/**************************************************************************** - * Name: stm32l5serial_receive - * - * Description: - * Called (usually) from the interrupt level to receive one - * character from the USART. Error bits associated with the - * receipt are provided in the return 'status'. - * - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static int stm32l5serial_receive(struct uart_dev_s *dev, - unsigned int *status) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - uint32_t rdr; - - /* Get the Rx byte */ - - rdr = stm32l5serial_getreg(priv, STM32_USART_RDR_OFFSET); - - /* Get the Rx byte plux error information. Return those in status */ - - *status = priv->sr << 16 | rdr; - priv->sr = 0; - - /* Then return the actual received byte */ - - return rdr & 0xff; -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_rxint - * - * Description: - * Call to enable or disable RX interrupts - * - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static void stm32l5serial_rxint(struct uart_dev_s *dev, bool enable) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - irqstate_t flags; - uint16_t ie; - - /* USART receive interrupts: - * - * Enable Status Meaning Usage - * ---------------- -------------- ---------------------- ---------- - * USART_CR1_IDLEIE USART_ISR_IDLE Idle Line Detected (not used) - * USART_CR1_RXNEIE USART_ISR_RXNE Received Data Ready - * to be Read - * " " USART_ISR_ORE Overrun Error Detected - * USART_CR1_PEIE USART_ISR_PE Parity Error - * - * USART_CR2_LBDIE USART_ISR_LBD Break Flag (not used) - * USART_CR3_EIE USART_ISR_FE Framing Error - * " " USART_ISR_NF Noise Flag - * " " USART_ISR_ORE Overrun Error Detected - */ - - flags = enter_critical_section(); - ie = priv->ie; - if (enable) - { - /* Receive an interrupt when their is anything in the Rx data - * register (or an Rx timeout occurs). - */ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -#ifdef CONFIG_USART_ERRINTS - ie |= (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); -#else - ie |= USART_CR1_RXNEIE; -#endif -#endif - } - else - { - ie &= ~(USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR3_EIE); - } - - /* Then set the new interrupt state */ - - stm32l5serial_restoreusartint(priv, ie); - leave_critical_section(flags); -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_rxavailable - * - * Description: - * Return true if the receive register is not empty - * - ****************************************************************************/ - -#ifndef SERIAL_HAVE_ONLY_DMA -static bool stm32l5serial_rxavailable(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - return ((stm32l5serial_getreg(priv, STM32_USART_ISR_OFFSET) & - USART_ISR_RXNE) != 0); -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_rxflowcontrol - * - * Description: - * Called when Rx buffer is full (or exceeds configured watermark levels - * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined). - * Return true if UART activated RX flow control to block more incoming - * data - * - * Input Parameters: - * dev - UART device instance - * nbuffered - the number of characters currently buffered - * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is - * not defined the value will be 0 for an empty buffer or the - * defined buffer size for a full buffer) - * upper - true indicates the upper watermark was crossed where - * false indicates the lower watermark has been crossed - * - * Returned Value: - * true if RX flow control activated. - * - ****************************************************************************/ - -#ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool stm32l5serial_rxflowcontrol(struct uart_dev_s *dev, - unsigned int nbuffered, bool upper) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - -#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS) && \ - defined(CONFIG_STM32_FLOWCONTROL_BROKEN) - if (priv->iflow && (priv->rts_gpio != 0)) - { - /* Assert/de-assert nRTS set it high resume/stop sending */ - - stm32_gpiowrite(priv->rts_gpio, upper); - - if (upper) - { - /* With heavy Rx traffic, RXNE might be set and data pending. - * Returning 'true' in such case would cause RXNE left unhandled - * and causing interrupt storm. Sending end might be also be slow - * to react on nRTS, and returning 'true' here would prevent - * processing that data. - * - * Therefore, return 'false' so input data is still being processed - * until sending end reacts on nRTS signal and stops sending more. - */ - - return false; - } - - return upper; - } - -#else - if (priv->iflow) - { - /* Is the RX buffer full? */ - - if (upper) - { - /* Disable Rx interrupt to prevent more data being from - * peripheral. When hardware RTS is enabled, this will - * prevent more data from coming in. - * - * This function is only called when UART recv buffer is full, - * that is: "dev->recv.head + 1 == dev->recv.tail". - * - * Logic in "uart_read" will automatically toggle Rx interrupts - * when buffer is read empty and thus we do not have to re- - * enable Rx interrupts. - */ - - uart_disablerxint(dev); - return true; - } - - /* No.. The RX buffer is empty */ - - else - { - /* We might leave Rx interrupt disabled if full recv buffer was - * read empty. Enable Rx interrupt to make sure that more input is - * received. - */ - - uart_enablerxint(dev); - } - } -#endif - - return false; -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_dmareceive - * - * Description: - * Called (usually) from the interrupt level to receive one - * character from the USART. Error bits associated with the - * receipt are provided in the return 'status'. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static int stm32l5serial_dmareceive(struct uart_dev_s *dev, - unsigned int *status) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - int c = 0; - - if (stm32l5serial_dmanextrx(priv) != priv->rxdmanext) - { - c = priv->rxfifo[priv->rxdmanext]; - - priv->rxdmanext++; - if (priv->rxdmanext == RXDMA_BUFFER_SIZE) - { -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* RX DMA buffer full. RX paused, RTS line pulled up to prevent - * more input data from other end. - */ - } - else -#endif - { - priv->rxdmanext = 0; - } - } - } - - return c; -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_dmareenable - * - * Description: - * Call to re-enable RX DMA. - * - ****************************************************************************/ - -#if defined(SERIAL_HAVE_DMA) -static void stm32l5serial_dmareenable(struct stm32_serial_s *priv) -{ -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Configure for non-circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_IFLOW_CONTROL_WORD); - } - else -#endif - { - /* Configure for circular DMA reception into the RX FIFO */ - - stm32_dmasetup(priv->rxdma, - priv->usartbase + STM32_USART_RDR_OFFSET, - (uint32_t)priv->rxfifo, - RXDMA_BUFFER_SIZE, - SERIAL_DMA_CONTROL_WORD); - } - - /* Reset our DMA shadow pointer to match the address just - * programmed above. - */ - - priv->rxdmanext = 0; - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Start the DMA channel, and arrange for callbacks at the full point - * in the FIFO. After buffer gets full, hardware flow-control kicks - * in and DMA transfer is stopped. - */ - - stm32_dmastart(priv->rxdma, stm32l5serial_dmarxcallback, - (void *)priv, false); - } - else -#endif - { - /* Start the DMA channel, and arrange for callbacks at the half and - * full points in the FIFO. This ensures that we have half a FIFO - * worth of time to claim bytes before they are overwritten. - */ - - stm32_dmastart(priv->rxdma, stm32l5serial_dmarxcallback, - (void *)priv, true); - } - -#ifdef CONFIG_PM - /* Clear DMA suspended flag. */ - - priv->rxdmasusp = false; -#endif -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_dmaiflowrestart - * - * Description: - * Call to restart RX DMA for input flow-controlled USART - * - ****************************************************************************/ - -#if defined(SERIAL_HAVE_DMA) && defined(CONFIG_SERIAL_IFLOWCONTROL) -static bool stm32l5serial_dmaiflowrestart(struct stm32_serial_s *priv) -{ - if (!priv->rxenable) - { - /* Rx not enabled by upper layer. */ - - return false; - } - - if (priv->rxdmanext != RXDMA_BUFFER_SIZE) - { -#ifdef CONFIG_PM - if (priv->rxdmasusp) - { - /* Rx DMA in suspended state. */ - - if (stm32l5serial_dmarxavailable(&priv->dev)) - { - /* DMA buffer has unprocessed data, do not re-enable yet. */ - - return false; - } - } - else -#endif - { - return false; - } - } - - /* DMA is stopped or suspended and DMA buffer does not have pending data, - * re-enabling without data loss is now safe. - */ - - stm32l5serial_dmareenable(priv); - - return true; -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_dmarxint - * - * Description: - * Call to enable or disable RX interrupts - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static void stm32l5serial_dmarxint(struct uart_dev_s *dev, bool enable) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - /* En/disable DMA reception. - * - * Note that it is not safe to check for available bytes and immediately - * pass them to uart_recvchars as that could potentially recurse back - * to us again. Instead, bytes must wait until the next up_dma_poll or - * DMA event. - */ - - priv->rxenable = enable; - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Re-enable RX DMA. */ - - stm32l5serial_dmaiflowrestart(priv); - } -#endif -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_dmarxavailable - * - * Description: - * Return true if the receive register is not empty - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static bool stm32l5serial_dmarxavailable(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - /* Compare our receive pointer to the current DMA pointer, if they - * do not match, then there are bytes to be received. - */ - - return (stm32l5serial_dmanextrx(priv) != priv->rxdmanext); -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_send - * - * Description: - * This method will send one byte on the USART - * - ****************************************************************************/ - -static void stm32l5serial_send(struct uart_dev_s *dev, int ch) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - -#ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) - { - stm32_gpiowrite(priv->rs485_dir_gpio, priv->rs485_dir_polarity); - } -#endif - - stm32l5serial_putreg(priv, STM32_USART_TDR_OFFSET, (uint32_t)ch); -} - -/**************************************************************************** - * Name: stm32l5serial_txint - * - * Description: - * Call to enable or disable TX interrupts - * - ****************************************************************************/ - -static void stm32l5serial_txint(struct uart_dev_s *dev, bool enable) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - irqstate_t flags; - - /* USART transmit interrupts: - * - * Enable Status Meaning Usage - * --------------- ------------- ---------------------------- ------------- - * USART_CR1_TCIE USART_ISR_TC Transmission Complete (only RS-485) - * USART_CR1_TXEIE USART_ISR_TXE Transmit Data Register Empty - * USART_CR3_CTSIE USART_ISR_CTS CTS flag (not used) - */ - - flags = enter_critical_section(); - if (enable) - { - /* Set to receive an interrupt when the TX data register is empty */ - -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - uint16_t ie = priv->ie | USART_CR1_TXEIE; - - /* If RS-485 is supported on this U[S]ART, then also enable the - * transmission complete interrupt. - */ - -# ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) - { - ie |= USART_CR1_TCIE; - } -# endif - -# ifdef CONFIG_STM32_SERIALBRK_BSDCOMPAT - if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS) - { - leave_critical_section(flags); - return; - } -# endif - - stm32l5serial_restoreusartint(priv, ie); - - /* Fake a TX interrupt here by just calling uart_xmitchars() with - * interrupts disabled (note this may recurse). - */ - - uart_xmitchars(dev); -#endif - } - else - { - /* Disable the TX interrupt */ - - stm32l5serial_restoreusartint(priv, priv->ie & ~USART_CR1_TXEIE); - } - - leave_critical_section(flags); -} - -/**************************************************************************** - * Name: stm32l5serial_txready - * - * Description: - * Return true if the transmit data register is empty - * - ****************************************************************************/ - -static bool stm32l5serial_txready(struct uart_dev_s *dev) -{ - struct stm32_serial_s *priv = - (struct stm32_serial_s *)dev->priv; - - return ((stm32l5serial_getreg(priv, STM32_USART_ISR_OFFSET) & - USART_ISR_TXE) != 0); -} - -/**************************************************************************** - * Name: stm32l5serial_dmarxcallback - * - * Description: - * This function checks the current DMA state and calls the generic - * serial stack when bytes appear to be available. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -static void stm32l5serial_dmarxcallback(DMA_HANDLE handle, uint8_t status, - void *arg) -{ - struct stm32_serial_s *priv = (struct stm32_serial_s *)arg; - - if (priv->rxenable && stm32l5serial_dmarxavailable(&priv->dev)) - { - uart_recvchars(&priv->dev); - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->iflow) - { - /* Re-enable RX DMA. */ - - stm32l5serial_dmaiflowrestart(priv); - } -#endif - } - - /* Get the masked USART status word to check and clear error flags. - * - * When wake-up from low power mode was not fast enough, UART is resumed - * too late and sometimes exactly when character was coming over UART, - * resulting to frame error. - * If error flag is not cleared, Rx DMA will be stuck. Clearing errors - * will release Rx DMA. - */ - - priv->sr = stm32l5serial_getreg(priv, STM32_USART_ISR_OFFSET); - - if ((priv->sr & (USART_ISR_ORE | USART_ISR_NF | USART_ISR_FE)) != 0) - { - stm32l5serial_putreg(priv, STM32_USART_ICR_OFFSET, - (USART_ICR_NCF | USART_ICR_ORECF | - USART_ICR_FECF)); - } -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_pmnotify - * - * Description: - * Notify the driver of new power state. This callback is called after - * all drivers have had the opportunity to prepare for the new power state. - * - * Input Parameters: - * - * cb - Returned to the driver. The driver version of the callback - * structure may include additional, driver-specific state data at - * the end of the structure. - * - * pmstate - Identifies the new PM state - * - * Returned Value: - * None - The driver already agreed to transition to the low power - * consumption state when when it returned OK to the prepare() call. - * - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void stm32l5serial_pmnotify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) -{ - switch (pmstate) - { - case PM_NORMAL: - { - stm32l5serial_pm_setsuspend(false); - } - break; - - case PM_IDLE: - { - stm32l5serial_pm_setsuspend(false); - } - break; - - case PM_STANDBY: - { - /* TODO: Alternative configuration and logic for enabling serial in - * Stop 1 mode with HSI16 missing. Current logic allows - * suspending serial peripherals for Stop 0/1/2 when serial - * Rx/Tx buffers are empty (checked in pmprepare). - */ - - stm32l5serial_pm_setsuspend(true); - } - break; - - case PM_SLEEP: - { - stm32l5serial_pm_setsuspend(true); - } - break; - - default: - - /* Should not get here */ - - break; - } -} -#endif - -/**************************************************************************** - * Name: stm32l5serial_pmprepare - * - * Description: - * Request the driver to prepare for a new power state. This is a warning - * that the system is about to enter into a new power state. The driver - * should begin whatever operations that may be required to enter power - * state. The driver may abort the state change mode by returning a - * non-zero value from the callback function. - * - * Input Parameters: - * - * cb - Returned to the driver. The driver version of the callback - * structure may include additional, driver-specific state data at - * the end of the structure. - * - * pmstate - Identifies the new PM state - * - * Returned Value: - * Zero - (OK) means the event was successfully processed and that the - * driver is prepared for the PM state change. - * - * Non-zero - means that the driver is not prepared to perform the tasks - * needed achieve this power setting and will cause the state - * change to be aborted. NOTE: The prepare() method will also - * be called when reverting from lower back to higher power - * consumption modes (say because another driver refused a - * lower power state change). Drivers are not permitted to - * return non-zero values when reverting back to higher power - * consumption modes! - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static int stm32l5serial_pmprepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) -{ - int n; - - /* Logic to prepare for a reduced power state goes here. */ - - switch (pmstate) - { - case PM_NORMAL: - case PM_IDLE: - break; - - case PM_STANDBY: - case PM_SLEEP: - -#ifdef SERIAL_HAVE_DMA - /* Flush Rx DMA buffers before checking state of serial device - * buffers. - */ - - stm32_serial_dma_poll(); -#endif - - /* Check if any of the active ports have data pending on Tx/Rx - * buffers. - */ - - for (n = 0; n < STM32_NLPUART + STM32_NUSART + STM32_NUART; n++) - { - struct stm32_serial_s *priv = g_uart_devs[n]; - - if (!priv || !priv->initialized) - { - /* Not active, skip. */ - - continue; - } - - if (priv->suspended) - { - /* Port already suspended, skip. */ - - continue; - } - - /* Check if port has data pending (Rx & Tx). */ - - if (priv->dev.xmit.head != priv->dev.xmit.tail) - { - return ERROR; - } - - if (priv->dev.recv.head != priv->dev.recv.tail) - { - return ERROR; - } - } - break; - - default: - - /* Should not get here */ - - break; - } - - return OK; -} -#endif - -#endif /* HAVE_UART */ -#endif /* USE_SERIALDRIVER */ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -#ifdef USE_SERIALDRIVER - -/**************************************************************************** - * Name: arm_earlyserialinit - * - * Description: - * Performs the low level USART initialization early in debug so that the - * serial console will be available during boot up. This must be called - * before arm_serialinit. - * - ****************************************************************************/ - -#ifdef USE_EARLYSERIALINIT -void arm_earlyserialinit(void) -{ -#ifdef HAVE_UART - unsigned i; - - /* Disable all USART interrupts */ - - for (i = 0; i < STM32_NLPUART + STM32_NUSART + STM32_NUART; i++) - { - if (g_uart_devs[i]) - { - stm32l5serial_disableusartint(g_uart_devs[i], NULL); - } - } - - /* Configure whichever one is the console */ - -#if CONSOLE_UART > 0 - stm32l5serial_setup(&g_uart_devs[CONSOLE_UART - 1]->dev); -#endif -#endif /* HAVE UART */ -} -#endif /* USE_EARLYSERIALINIT */ - -/**************************************************************************** - * Name: arm_serialinit - * - * Description: - * Register serial console and serial ports. This assumes - * that arm_earlyserialinit was called previously. - * - ****************************************************************************/ - -void arm_serialinit(void) -{ -#ifdef HAVE_UART - char devname[16]; - unsigned i; - unsigned minor = 0; -#ifdef CONFIG_PM - int ret; -#endif - - /* Register to receive power management callbacks */ - -#ifdef CONFIG_PM - ret = pm_register(&g_serialpm.pm_cb); - DEBUGASSERT(ret == OK); - UNUSED(ret); -#endif - - /* Register the console */ - -#if CONSOLE_UART > 0 - uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); - -#ifndef CONFIG_STM32_SERIAL_DISABLE_REORDERING - /* If not disabled, register the console UART to ttyS0 and exclude - * it from initializing it further down - */ - - uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); - minor = 1; -#endif - -#ifdef SERIAL_HAVE_CONSOLE_DMA - /* If we need to re-initialise the console to enable DMA do that here. */ - - stm32l5serial_dmasetup(&g_uart_devs[CONSOLE_UART - 1]->dev); -#endif -#endif /* CONSOLE_UART > 0 */ - - /* Register all remaining USARTs */ - - strlcpy(devname, "/dev/ttySx", sizeof(devname)); - - for (i = 0; i < STM32_NLPUART + STM32_NUSART + STM32_NUART; i++) - { - /* Don't create a device for non-configured ports. */ - - if (g_uart_devs[i] == 0) - { - continue; - } - -#ifndef CONFIG_STM32_SERIAL_DISABLE_REORDERING - /* Don't create a device for the console - we did that above */ - - if (g_uart_devs[i]->dev.isconsole) - { - continue; - } -#endif - - /* Register USARTs as devices in increasing order */ - - devname[9] = '0' + minor++; - uart_register(devname, &g_uart_devs[i]->dev); - } -#endif /* HAVE UART */ -} - -/**************************************************************************** - * Name: stm32_serial_dma_poll - * - * Description: - * Checks receive DMA buffers for received bytes that have not accumulated - * to the point where the DMA half/full interrupt has triggered. - * - * This function should be called from a timer or other periodic context. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -void stm32_serial_dma_poll(void) -{ - irqstate_t flags; - - flags = enter_critical_section(); - -#ifdef CONFIG_LPUART1_RXDMA - if (g_lpuart1priv.rxdma != NULL) - { - stm32l5serial_dmarxcallback(g_lpuart1priv.rxdma, 0, &g_lpuart1priv); - } -#endif - -#ifdef CONFIG_USART1_RXDMA - if (g_usart1priv.rxdma != NULL) - { - stm32l5serial_dmarxcallback(g_usart1priv.rxdma, 0, &g_usart1priv); - } -#endif - -#ifdef CONFIG_USART2_RXDMA - if (g_usart2priv.rxdma != NULL) - { - stm32l5serial_dmarxcallback(g_usart2priv.rxdma, 0, &g_usart2priv); - } -#endif - -#ifdef CONFIG_USART3_RXDMA - if (g_usart3priv.rxdma != NULL) - { - stm32l5serial_dmarxcallback(g_usart3priv.rxdma, 0, &g_usart3priv); - } -#endif - -#ifdef CONFIG_UART4_RXDMA - if (g_uart4priv.rxdma != NULL) - { - stm32l5serial_dmarxcallback(g_uart4priv.rxdma, 0, &g_uart4priv); - } -#endif - -#ifdef CONFIG_UART5_RXDMA - if (g_uart5priv.rxdma != NULL) - { - stm32l5serial_dmarxcallback(g_uart5priv.rxdma, 0, &g_uart5priv); - } -#endif - - leave_critical_section(flags); -} -#endif - -/**************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug writes - * - ****************************************************************************/ - -void up_putc(int ch) -{ -#if CONSOLE_UART > 0 - struct stm32_serial_s *priv = g_uart_devs[CONSOLE_UART - 1]; - uint16_t ie; - - stm32l5serial_disableusartint(priv, &ie); - arm_lowputc(ch); - stm32l5serial_restoreusartint(priv, ie); -#endif -} - -#else /* USE_SERIALDRIVER */ - -/**************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug writes - * - ****************************************************************************/ - -void up_putc(int ch) -{ -#if CONSOLE_UART > 0 - arm_lowputc(ch); -#endif -} - -#endif /* USE_SERIALDRIVER */ diff --git a/arch/arm/src/stm32l5/stm32l5_uart.h b/arch/arm/src/stm32l5/stm32l5_uart.h deleted file mode 100644 index 3afcb99c656..00000000000 --- a/arch/arm/src/stm32l5/stm32l5_uart.h +++ /dev/null @@ -1,300 +0,0 @@ -/**************************************************************************** - * arch/arm/src/stm32l5/stm32l5_uart.h - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_STC_STM32L5_STM32L5_UART_H -#define __ARCH_ARM_STC_STM32L5_STM32L5_UART_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -#include "chip.h" - -#if defined(CONFIG_STM32_STM32L562XX) -# include "hardware/stm32l5_uart.h" -#else -# error "Unsupported STM32L5 chip" -#endif - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Make sure that we have not enabled more U[S]ARTs than are supported by the - * device. - */ - -#if !defined(CONFIG_STM32_HAVE_UART5) -# undef CONFIG_STM32_UART5 -#endif -#if !defined(CONFIG_STM32_HAVE_UART4) -# undef CONFIG_STM32_UART4 -#endif -#if !defined(CONFIG_STM32_HAVE_USART3) -# undef CONFIG_STM32_USART3 -#endif -#if !defined(CONFIG_STM32_HAVE_USART2) -# undef CONFIG_STM32_USART2 -#endif -#if !defined(CONFIG_STM32_HAVE_USART1) -# undef CONFIG_STM32_USART1 -#endif -#if !defined(CONFIG_STM32_HAVE_LPUART1) -# undef CONFIG_STM32_LPUART1 -#endif - -/* Sanity checks */ - -#if !defined(CONFIG_STM32_LPUART1) -# undef CONFIG_STM32_LPUART1_SERIALDRIVER -# undef CONFIG_STM32_LPUART1_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART1) -# undef CONFIG_STM32_USART1_SERIALDRIVER -# undef CONFIG_STM32_USART1_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART2) -# undef CONFIG_STM32_USART2_SERIALDRIVER -# undef CONFIG_STM32_USART2_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_USART3) -# undef CONFIG_STM32_USART3_SERIALDRIVER -# undef CONFIG_STM32_USART3_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART4) -# undef CONFIG_STM32_UART4_SERIALDRIVER -# undef CONFIG_STM32_UART4_1WIREDRIVER -#endif -#if !defined(CONFIG_STM32_UART5) -# undef CONFIG_STM32_UART5_SERIALDRIVER -# undef CONFIG_STM32_UART5_1WIREDRIVER -#endif - -/* Is there a USART enabled? */ - -#if defined(CONFIG_STM32_LPUART1) || defined(CONFIG_STM32_USART1) || \ - defined(CONFIG_STM32_USART2) || defined(CONFIG_STM32_USART3) || \ - defined(CONFIG_STM32_UART4) || defined(CONFIG_STM32_UART5) -# define HAVE_UART 1 -#endif - -/* Is there a serial console? */ - -#if defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_STM32_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_USART1_SERIAL_CONSOLE) && defined(CONFIG_STM32_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_USART2_SERIAL_CONSOLE) && defined(CONFIG_STM32_USART2_SERIALDRIVER) -# undef CONFIG_USART1_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_STM32_USART3_SERIALDRIVER) -# 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_STM32_UART4_SERIALDRIVER) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART5_SERIAL_CONSOLE -# define CONSOLE_UART 5 -# define HAVE_CONSOLE 1 -#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_STM32_UART5_SERIALDRIVER) -# undef CONFIG_USART1_SERIAL_CONSOLE -# undef CONFIG_USART2_SERIAL_CONSOLE -# undef CONFIG_USART3_SERIAL_CONSOLE -# undef CONFIG_UART4_SERIAL_CONSOLE -# define CONSOLE_UART 6 -# define HAVE_CONSOLE 1 -#else -# 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 0 -# undef HAVE_CONSOLE -#endif - -/* DMA support is only provided if CONFIG_ARCH_DMA is in the NuttX - * configuration - */ - -#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA) -# undef CONFIG_USART1_RXDMA -# undef CONFIG_USART2_RXDMA -# undef CONFIG_USART3_RXDMA -# undef CONFIG_UART4_RXDMA -# undef CONFIG_UART5_RXDMA -#endif - -/* Disable the DMA configuration on all unused USARTs */ - -#ifndef CONFIG_STM32_LPUART1_SERIALDRIVER -# undef CONFIG_LPUART1_RXDMA -#endif - -#ifndef CONFIG_STM32_USART1_SERIALDRIVER -# undef CONFIG_USART1_RXDMA -#endif - -#ifndef CONFIG_STM32_USART2_SERIALDRIVER -# undef CONFIG_USART2_RXDMA -#endif - -#ifndef CONFIG_STM32_USART3_SERIALDRIVER -# undef CONFIG_USART3_RXDMA -#endif - -#ifndef CONFIG_STM32_UART4_SERIALDRIVER -# undef CONFIG_UART4_RXDMA -#endif - -#ifndef CONFIG_STM32_UART5_SERIALDRIVER -# undef CONFIG_UART5_RXDMA -#endif - -/* Is DMA available on any (enabled) USART? */ - -#undef SERIAL_HAVE_DMA -#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_DMA 1 -#endif - -/* Is DMA used on the console UART? */ - -#undef SERIAL_HAVE_CONSOLE_DMA -#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 -#elif defined(CONFIG_USART3_SERIAL_CONSOLE) && defined(CONFIG_USART3_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_UART4_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_UART5_RXDMA) -# define SERIAL_HAVE_CONSOLE_DMA 1 -#endif - -/* Is DMA used on all (enabled) USARTs */ - -#define SERIAL_HAVE_ONLY_DMA 1 -#if defined(CONFIG_STM32_LPUART1_SERIALDRIVER) && !defined(CONFIG_LPUART1_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART1_SERIALDRIVER) && !defined(CONFIG_USART1_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART2_SERIALDRIVER) && !defined(CONFIG_USART2_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_USART3_SERIALDRIVER) && !defined(CONFIG_USART3_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART4_SERIALDRIVER) && !defined(CONFIG_UART4_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#elif defined(CONFIG_STM32_UART5_SERIALDRIVER) && !defined(CONFIG_UART5_RXDMA) -# undef SERIAL_HAVE_ONLY_DMA -#endif - -/* Is RS-485 used? */ - -#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 - -#ifdef HAVE_RS485 -# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE | USART_CR1_TCIE) -#else -# define USART_CR1_USED_INTS (USART_CR1_RXNEIE | USART_CR1_TXEIE | USART_CR1_PEIE) -#endif - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: stm32_serial_dma_poll - * - * Description: - * Must be called periodically if any STM32 UART is configured for DMA. - * The DMA callback is triggered for each fifo size/2 bytes, but this can - * result in some bytes being transferred but not collected if the incoming - * data is not a whole multiple of half the FIFO size. - * - * May be safely called from either interrupt or thread context. - * - ****************************************************************************/ - -#ifdef SERIAL_HAVE_DMA -void stm32_serial_dma_poll(void); -#endif - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_STC_STM32L5_STM32L5_UART_H */