From dd5bea954bd67770a80ef66ed16602da23412adc Mon Sep 17 00:00:00 2001 From: Daisuke Nojiri Date: Wed, 20 Apr 2016 16:51:08 -0700 Subject: STM32: Support LPUART console This patch adds support for console on LPUART (low power UART). It is wired to the USB type B port on the board, which is also one of the power sources. So, using LPUART simplifies the set up. BUG=none BRANCH=tot TEST=Verified console works on stm32l476g-eval. make buildall Change-Id: Iccf697cfabdcb7e1362d8453708eb79610d2e0cb Signed-off-by: Daisuke Nojiri Reviewed-on: https://chromium-review.googlesource.com/340101 Reviewed-by: Vincent Palatin --- board/stm32l476g-eval/board.h | 12 +++++++++--- board/stm32l476g-eval/gpio.inc | 1 + chip/stm32/dma.c | 2 +- chip/stm32/registers.h | 20 +++++++++++++++++++- chip/stm32/system.c | 4 ++++ chip/stm32/uart.c | 8 ++++++++ 6 files changed, 42 insertions(+), 5 deletions(-) diff --git a/board/stm32l476g-eval/board.h b/board/stm32l476g-eval/board.h index b4972a63cb..d6f9eb73b2 100644 --- a/board/stm32l476g-eval/board.h +++ b/board/stm32l476g-eval/board.h @@ -12,13 +12,19 @@ #undef CONFIG_WATCHDOG_HELP #undef CONFIG_LID_SWITCH -/* the UART console is on USART1 (PB6/7) */ +/* Console is on LPUART (PG7/8). Undef it to use USART1 (PB6/7). */ +#define STM32L476G_EVAL_USE_LPUART_CONSOLE #undef CONFIG_UART_CONSOLE -#define CONFIG_UART_CONSOLE 1 -/* Use USART1 for DMA TX */ +#ifdef STM32L476G_EVAL_USE_LPUART_CONSOLE +#define CONFIG_UART_CONSOLE 9 +#define CONFIG_UART_TX_DMA_CH STM32_DMAC_CH14 +#define CONFIG_UART_TX_DMA_PH 4 +#else +#define CONFIG_UART_CONSOLE 1 #define CONFIG_UART_TX_DMA_CH STM32_DMAC_USART1_TX #define CONFIG_UART_TX_DMA_PH 2 +#endif /* Optional features */ #define CONFIG_STM_HWTIMER32 diff --git a/board/stm32l476g-eval/gpio.inc b/board/stm32l476g-eval/gpio.inc index 3028956ad4..f0599365aa 100644 --- a/board/stm32l476g-eval/gpio.inc +++ b/board/stm32l476g-eval/gpio.inc @@ -17,3 +17,4 @@ UNIMPLEMENTED(ENTERING_RW) UNIMPLEMENTED(WP_L) ALTERNATE(PIN_MASK(B, 0xC0), GPIO_ALT_F7, MODULE_UART, 0) /* USART1: PB6/7 */ +ALTERNATE(PIN_MASK(G, 0x0180), GPIO_ALT_F8, MODULE_UART, 0) /* LPUART: PG7/8 */ \ No newline at end of file diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c index 3b45544190..a3cc6d6de4 100644 --- a/chip/stm32/dma.c +++ b/chip/stm32/dma.c @@ -231,7 +231,7 @@ void dma_test(enum dma_channel channel) void dma_init(void) { #ifdef CHIP_FAMILY_STM32L4 - STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_DMA1EN; + STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_DMA1EN|STM32_RCC_AHB1ENR_DMA2EN; #else STM32_RCC_AHBENR |= STM32_RCC_HB_DMA1; #endif diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 33b2d9faeb..4a15c20d2d 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -132,6 +132,10 @@ #define STM32_IRQ_SDADC1 61 /* STM32F373 only */ #define STM32_IRQ_SDADC2 62 /* STM32F373 only */ #define STM32_IRQ_SDADC3 63 /* STM32F373 only */ +#define STM32_IRQ_DMA2_CHANNEL6 68 /* STM32L4 only */ +#define STM32_IRQ_DMA2_CHANNEL7 69 /* STM32L4 only */ +#define STM32_IRQ_LPUART 70 /* STM32L4 only */ +#define STM32_IRQ_USART9 70 /* STM32L4 only */ #define STM32_IRQ_USB_WAKEUP 76 /* STM32F373 only */ #define STM32_IRQ_TIM19 78 /* STM32F373 only */ #define STM32_IRQ_FPU 81 /* STM32F373 only */ @@ -139,6 +143,8 @@ /* To simplify code generation, define DMA channel 9..10 */ #define STM32_IRQ_DMA_CHANNEL_9 STM32_IRQ_DMA2_CHANNEL1 #define STM32_IRQ_DMA_CHANNEL_10 STM32_IRQ_DMA2_CHANNEL2 +#define STM32_IRQ_DMA_CHANNEL_13 STM32_IRQ_DMA2_CHANNEL6 +#define STM32_IRQ_DMA_CHANNEL_14 STM32_IRQ_DMA2_CHANNEL7 /* aliases for easier code sharing */ #define STM32_IRQ_I2C1 STM32_IRQ_I2C1_EV @@ -152,6 +158,7 @@ #define STM32_USART2_BASE 0x40004400 #define STM32_USART3_BASE 0x40004800 #define STM32_USART4_BASE 0x40004c00 +#define STM32_USART9_BASE 0x40008000 /* LPUART */ #define STM32_USART_BASE(n) CONCAT3(STM32_USART, n, _BASE) #define STM32_USART_REG(base, offset) REG32((base) + (offset)) @@ -493,7 +500,12 @@ typedef volatile struct timer_ctlr timer_ctlr_t; #define STM32_PWR_CR REG32(STM32_PWR_BASE + 0x00) #define STM32_PWR_CR_LPSDSR (1 << 0) +#if defined(CHIP_FAMILY_STM32L4) +#define STM32_PWR_CR2 REG32(STM32_PWR_BASE + 0x04) +#define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x10) +#else #define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x04) +#endif #if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) #define STM32_PWR_CSR_EWUP1 (1 << 8) #define STM32_PWR_CSR_EWUP2 (1 << 9) @@ -1229,6 +1241,10 @@ enum dma_channel { */ STM32_DMAC_CH9 = 8, STM32_DMAC_CH10 = 9, + STM32_DMAC_CH11 = 10, + STM32_DMAC_CH12 = 11, + STM32_DMAC_CH13 = 12, + STM32_DMAC_CH14 = 13, /* Channel functions */ STM32_DMAC_ADC = STM32_DMAC_CH1, @@ -1247,7 +1263,9 @@ enum dma_channel { STM32_DMAC_I2C1_RX = STM32_DMAC_CH7, STM32_DMAC_PMSE_ROW = STM32_DMAC_CH6, STM32_DMAC_PMSE_COL = STM32_DMAC_CH7, -#ifdef CHIP_VARIANT_STM32F373 +#ifdef CHIP_FAMILY_STM32L4 + STM32_DMAC_COUNT = 14, +#elif defined(CHIP_VARIANT_STM32F373) STM32_DMAC_SPI2_RX = STM32_DMAC_CH4, STM32_DMAC_SPI2_TX = STM32_DMAC_CH5, STM32_DMAC_SPI3_RX = STM32_DMAC_CH9, diff --git a/chip/stm32/system.c b/chip/stm32/system.c index 90a248eafa..e906234f19 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -193,6 +193,10 @@ void system_pre_init(void) clock_wait_bus_cycles(BUS_APB, 1); /* Enable access to RCC CSR register and RTC backup registers */ STM32_PWR_CR |= 1 << 8; +#ifdef CHIP_FAMILY_STM32L4 + /* Enable Vddio2 */ + STM32_PWR_CR2 |= 1 << 9; +#endif /* switch on LSI */ STM32_RCC_CSR |= 1 << 0; diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c index 69dc7d26d2..2804b3153a 100644 --- a/chip/stm32/uart.c +++ b/chip/stm32/uart.c @@ -236,7 +236,12 @@ static void uart_freq_change(void) /* UART clocked from the main clock */ freq = clock_get_freq(); #endif + +#if (UARTN == 9) /* LPUART */ + div = DIV_ROUND_NEAREST(freq, CONFIG_UART_BAUD_RATE) * 256; +#else div = DIV_ROUND_NEAREST(freq, CONFIG_UART_BAUD_RATE); +#endif #if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \ defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4) @@ -274,11 +279,14 @@ void uart_init(void) #endif /* UARTN */ #elif defined(CHIP_FAMILY_STM32L4) STM32_RCC_CCIPR |= (0x2 << STM32_RCC_CCIPR_USART1SEL_SHIFT); + STM32_RCC_CCIPR |= (0x2 << STM32_RCC_CCIPR_LPUART1SEL_SHIFT); #endif /* CHIP_FAMILY_STM32F0 || CHIP_FAMILY_STM32F3 */ /* Enable USART clock */ #if (UARTN == 1) STM32_RCC_APB2ENR |= STM32_RCC_PB2_USART1; +#elif (UARTN == 9) + STM32_RCC_APB1ENR2 |= STM32_RCC_APB1ENR2_LPUART1EN; #else STM32_RCC_APB1ENR |= CONCAT2(STM32_RCC_PB1_USART, UARTN); #endif -- cgit v1.2.1