summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-04-20 14:49:56 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-04-25 16:49:02 -0700
commit40c02e3ff2477df1aca7657a92905816e5a13d0c (patch)
tree57f05231828259506bf8bfdd2c494e533715e01f
parentcb0d8108e5a5b630ec05a8d21a824cb601246bf5 (diff)
downloadchrome-ec-40c02e3ff2477df1aca7657a92905816e5a13d0c.tar.gz
Bring up STM32L476G-Eval
This patch adds initial set of files to bring up STM32L476G-Eval board. BUG=none BRANCH=tot TEST=Tested console. make buildall && make tests Change-Id: I0c0f73f31e84099746fced4214c5ed7f45468cef Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/340100 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
l---------board/stm32l476g-eval/Makefile1
-rw-r--r--board/stm32l476g-eval/board.c20
-rw-r--r--board/stm32l476g-eval/board.h42
-rw-r--r--board/stm32l476g-eval/build.mk12
-rw-r--r--board/stm32l476g-eval/ec.tasklist21
-rw-r--r--board/stm32l476g-eval/gpio.inc19
-rw-r--r--board/stm32l476g-eval/openocd-flash.cfg19
-rw-r--r--chip/stm32/build.mk4
-rw-r--r--chip/stm32/clock-stm32l4.c204
-rw-r--r--chip/stm32/config-stm32l476.h20
-rw-r--r--chip/stm32/config_chip.h4
-rw-r--r--chip/stm32/dma.c4
-rw-r--r--chip/stm32/gpio-stm32l4.c26
-rw-r--r--chip/stm32/jtag-stm32l4.c21
-rw-r--r--chip/stm32/registers.h87
-rw-r--r--chip/stm32/system.c6
-rw-r--r--chip/stm32/uart.c11
-rw-r--r--include/config.h3
18 files changed, 508 insertions, 16 deletions
diff --git a/board/stm32l476g-eval/Makefile b/board/stm32l476g-eval/Makefile
new file mode 120000
index 0000000000..94aaae2c4d
--- /dev/null
+++ b/board/stm32l476g-eval/Makefile
@@ -0,0 +1 @@
+../../Makefile \ No newline at end of file
diff --git a/board/stm32l476g-eval/board.c b/board/stm32l476g-eval/board.c
new file mode 100644
index 0000000000..37ff088090
--- /dev/null
+++ b/board/stm32l476g-eval/board.c
@@ -0,0 +1,20 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "common.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "registers.h"
+#include "gpio_list.h"
+
+void tick_event(void)
+{
+ static int count;
+
+ gpio_set_level(GPIO_LED_GREEN, (count & 0x03) == 0);
+
+ count++;
+}
+DECLARE_HOOK(HOOK_TICK, tick_event, HOOK_PRIO_DEFAULT);
diff --git a/board/stm32l476g-eval/board.h b/board/stm32l476g-eval/board.h
new file mode 100644
index 0000000000..b4972a63cb
--- /dev/null
+++ b/board/stm32l476g-eval/board.h
@@ -0,0 +1,42 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* STM32L476G-Eval board configuration */
+
+#ifndef __CROS_EC_BOARD_H
+#define __CROS_EC_BOARD_H
+
+/* Optional features */
+#undef CONFIG_WATCHDOG_HELP
+#undef CONFIG_LID_SWITCH
+
+/* the UART console is on USART1 (PB6/7) */
+#undef CONFIG_UART_CONSOLE
+#define CONFIG_UART_CONSOLE 1
+
+/* Use USART1 for DMA TX */
+#define CONFIG_UART_TX_DMA_CH STM32_DMAC_USART1_TX
+#define CONFIG_UART_TX_DMA_PH 2
+
+/* Optional features */
+#define CONFIG_STM_HWTIMER32
+
+/*
+ * Allow dangerous commands all the time, since we don't have a write protect
+ * switch.
+ */
+#define CONFIG_SYSTEM_UNLOCKED
+
+#ifndef __ASSEMBLER__
+
+#undef CONFIG_FLASH
+
+/* Timer selection */
+#define TIM_CLOCK32 5
+
+#include "gpio_signal.h"
+
+#endif /* !__ASSEMBLER__ */
+#endif /* __CROS_EC_BOARD_H */
diff --git a/board/stm32l476g-eval/build.mk b/board/stm32l476g-eval/build.mk
new file mode 100644
index 0000000000..23c7cd9d38
--- /dev/null
+++ b/board/stm32l476g-eval/build.mk
@@ -0,0 +1,12 @@
+# -*- makefile -*-
+# Copyright 2016 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Board specific files build
+
+CHIP:=stm32
+CHIP_FAMILY:=stm32l4
+CHIP_VARIANT:=stm32l476
+
+board-y=board.o
diff --git a/board/stm32l476g-eval/ec.tasklist b/board/stm32l476g-eval/ec.tasklist
new file mode 100644
index 0000000000..0c19123e58
--- /dev/null
+++ b/board/stm32l476g-eval/ec.tasklist
@@ -0,0 +1,21 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_ALWAYS(n, r, d, s) for base tasks and
+ * TASK_NOTEST(n, r, d, s) for tasks that can be excluded in test binaries,
+ * where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TASK_LIST \
+ TASK_ALWAYS(HOOKS, hook_task, NULL, TASK_STACK_SIZE) \
+ TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE)
diff --git a/board/stm32l476g-eval/gpio.inc b/board/stm32l476g-eval/gpio.inc
new file mode 100644
index 0000000000..3028956ad4
--- /dev/null
+++ b/board/stm32l476g-eval/gpio.inc
@@ -0,0 +1,19 @@
+/* -*- mode:c -*-
+ *
+ * Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Declare symbolic names for all the GPIOs that we care about.
+ * Note: Those with interrupt handlers must be declared first. */
+
+/* Outputs */
+GPIO(LED_GREEN, PIN(B, 2), GPIO_OUT_LOW)
+GPIO(LED_RED, PIN(C, 1), GPIO_OUT_LOW)
+
+/* Unimplemented signals which we need to emulate for now */
+UNIMPLEMENTED(ENTERING_RW)
+UNIMPLEMENTED(WP_L)
+
+ALTERNATE(PIN_MASK(B, 0xC0), GPIO_ALT_F7, MODULE_UART, 0) /* USART1: PB6/7 */
diff --git a/board/stm32l476g-eval/openocd-flash.cfg b/board/stm32l476g-eval/openocd-flash.cfg
new file mode 100644
index 0000000000..a347f88b79
--- /dev/null
+++ b/board/stm32l476g-eval/openocd-flash.cfg
@@ -0,0 +1,19 @@
+# Copyright 2016 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source [find board/stm32l4discovery.cfg]
+
+# For flashing, force the board into reset on connect, this ensures that
+# code running on the core can't interfere with programming.
+reset_config connect_assert_srst
+
+gdb_port 0
+tcl_port 0
+telnet_port 0
+init
+reset init
+flash write_image erase $BUILD_DIR/ec.bin 0x08000000
+reset halt
+resume
+shutdown
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index f7af790555..9d76c03885 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -11,8 +11,8 @@ ifeq ($(CHIP_FAMILY),stm32f0)
CORE:=cortex-m0
# Force ARMv6-M ISA used by the Cortex-M0
CFLAGS_CPU+=-march=armv6-m -mcpu=cortex-m0
-else ifeq ($(CHIP_FAMILY),stm32f3)
-# STM32F3xx sub-family has a Cortex-M4 ARM core
+else ifeq ($(CHIP_FAMILY),$(filter $(CHIP_FAMILY),stm32f3 stm32l4))
+# STM32F3xx and STM32L4xx sub-family has a Cortex-M4 ARM core
CORE:=cortex-m
# Allow the full Cortex-M4 instruction set
CFLAGS_CPU+=-march=armv7e-m -mcpu=cortex-m4
diff --git a/chip/stm32/clock-stm32l4.c b/chip/stm32/clock-stm32l4.c
new file mode 100644
index 0000000000..7cbd098a4d
--- /dev/null
+++ b/chip/stm32/clock-stm32l4.c
@@ -0,0 +1,204 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Clocks and power management settings */
+
+#include "chipset.h"
+#include "clock.h"
+#include "common.h"
+#include "console.h"
+#include "cpu.h"
+#include "hooks.h"
+#include "registers.h"
+#include "util.h"
+
+/* High-speed oscillator is 16 MHz */
+#define HSI_CLOCK 16000000
+/*
+ * MSI is 2 MHz (default) 1 MHz, depending on ICSCR setting. We use 1 MHz
+ * because it's the lowest clock rate we can still run 115200 baud serial
+ * for the debug console.
+ */
+#define MSI_2MHZ_CLOCK (1 << 21)
+#define MSI_1MHZ_CLOCK (1 << 20)
+
+enum clock_osc {
+ OSC_INIT = 0, /* Uninitialized */
+ OSC_HSI, /* High-speed oscillator */
+ OSC_MSI, /* Med-speed oscillator @ 1 MHz */
+};
+
+static int freq;
+static int current_osc;
+
+int clock_get_freq(void)
+{
+ return freq;
+}
+
+void clock_wait_bus_cycles(enum bus_type bus, uint32_t cycles)
+{
+ volatile uint32_t dummy __attribute__((unused));
+
+ if (bus == BUS_AHB) {
+ while (cycles--)
+ dummy = STM32_DMA1_REGS->isr;
+ } else { /* APB */
+ while (cycles--)
+ dummy = STM32_USART_BRR(STM32_USART1_BASE);
+ }
+}
+
+/**
+ * Set which oscillator is used for the clock
+ *
+ * @param osc Oscillator to use
+ */
+static void clock_set_osc(enum clock_osc osc)
+{
+ if (osc == current_osc)
+ return;
+
+ if (current_osc != OSC_INIT)
+ hook_notify(HOOK_PRE_FREQ_CHANGE);
+
+ switch (osc) {
+ case OSC_HSI:
+ /* Ensure that HSI is ON */
+ if (!(STM32_RCC_CR & STM32_RCC_CR_HSIRDY)) {
+ /* Enable HSI */
+ STM32_RCC_CR |= STM32_RCC_CR_HSION;
+ /* Wait for HSI to be ready */
+ while (!(STM32_RCC_CR & STM32_RCC_CR_HSIRDY))
+ ;
+ }
+
+ /* Disable LPSDSR */
+ STM32_PWR_CR &= ~STM32_PWR_CR_LPSDSR;
+
+ /* Switch to HSI */
+ STM32_RCC_CFGR = STM32_RCC_CFGR_SW_HSI;
+ /* RM says to check SWS bits to make sure HSI is the sysclock */
+ while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) !=
+ STM32_RCC_CFGR_SWS_HSI)
+ ;
+
+ /* Disable MSI */
+ STM32_RCC_CR &= ~STM32_RCC_CR_MSION;
+
+ freq = HSI_CLOCK;
+ break;
+
+ case OSC_MSI:
+ /* Switch to MSI @ 1MHz */
+ STM32_RCC_ICSCR =
+ (STM32_RCC_ICSCR & ~STM32_RCC_ICSCR_MSIRANGE_MASK) |
+ STM32_RCC_ICSCR_MSIRANGE_1MHZ;
+ /* Ensure that MSI is ON */
+ if (!(STM32_RCC_CR & STM32_RCC_CR_MSIRDY)) {
+ /* Enable MSI */
+ STM32_RCC_CR |= STM32_RCC_CR_MSION;
+ /* Wait for MSI to be ready */
+ while (!(STM32_RCC_CR & STM32_RCC_CR_MSIRDY))
+ ;
+ }
+
+ /* Switch to MSI */
+ STM32_RCC_CFGR = STM32_RCC_CFGR_SW_MSI;
+ /* RM says to check SWS bits to make sure MSI is the sysclock */
+ while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) !=
+ STM32_RCC_CFGR_SWS_MSI)
+ ;
+
+ /* Disable HSI */
+ STM32_RCC_CR &= ~STM32_RCC_CR_HSION;
+
+ /* Enable LPSDSR */
+ STM32_PWR_CR |= STM32_PWR_CR_LPSDSR;
+
+ freq = MSI_1MHZ_CLOCK;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Notify modules of frequency change unless we're initializing */
+ if (current_osc != OSC_INIT) {
+ current_osc = osc;
+ hook_notify(HOOK_FREQ_CHANGE);
+ } else {
+ current_osc = osc;
+ }
+}
+
+void clock_enable_module(enum module_id module, int enable)
+{
+ static uint32_t clock_mask;
+ int new_mask;
+
+ if (enable)
+ new_mask = clock_mask | (1 << module);
+ else
+ new_mask = clock_mask & ~(1 << module);
+
+ /* Only change clock if needed */
+ if ((!!new_mask) != (!!clock_mask)) {
+
+ /* Flush UART before switching clock speed */
+ cflush();
+
+ clock_set_osc(new_mask ? OSC_HSI : OSC_MSI);
+ }
+
+ clock_mask = new_mask;
+}
+
+void clock_init(void)
+{
+ /*
+ * The initial state :
+ * SYSCLK from MSI (=2MHz), no divider on AHB, APB1, APB2
+ * PLL unlocked, RTC enabled on LSE
+ */
+
+ /* Switch to high-speed oscillator */
+ clock_set_osc(OSC_HSI);
+}
+
+static void clock_chipset_startup(void)
+{
+ /* Return to full speed */
+ clock_enable_module(MODULE_CHIPSET, 1);
+}
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, clock_chipset_startup, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, clock_chipset_startup, HOOK_PRIO_DEFAULT);
+
+static void clock_chipset_shutdown(void)
+{
+ /* Drop to lower clock speed if no other module requires full speed */
+ clock_enable_module(MODULE_CHIPSET, 0);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, clock_chipset_shutdown, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, clock_chipset_shutdown, HOOK_PRIO_DEFAULT);
+
+static int command_clock(int argc, char **argv)
+{
+ if (argc >= 2) {
+ if (!strcasecmp(argv[1], "hsi"))
+ clock_set_osc(OSC_HSI);
+ else if (!strcasecmp(argv[1], "msi"))
+ clock_set_osc(OSC_MSI);
+ else
+ return EC_ERROR_PARAM1;
+ }
+
+ ccprintf("Clock frequency is now %d Hz\n", freq);
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(clock, command_clock,
+ "hsi | msi",
+ "Set clock frequency",
+ NULL);
diff --git a/chip/stm32/config-stm32l476.h b/chip/stm32/config-stm32l476.h
new file mode 100644
index 0000000000..9f6b35b8b1
--- /dev/null
+++ b/chip/stm32/config-stm32l476.h
@@ -0,0 +1,20 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Memory mapping */
+#define CONFIG_FLASH_SIZE 0x00100000 /* 1 MB */
+#define CONFIG_FLASH_BANK_SIZE 0x800 /* 2 kB */
+#define CONFIG_FLASH_ERASE_SIZE 0x800 /* 2 KB */
+#define CONFIG_FLASH_WRITE_SIZE 0x8 /* 64 bits (without 8 bits ECC) */
+
+/* Ideal write size in page-mode */
+#define CONFIG_FLASH_WRITE_IDEAL_SIZE 0x100 /* 256 (32 double words) */
+
+#define CONFIG_RAM_BASE 0x20000000
+/* Only using SRAM1. SRAM2 (32 KB) is ignored. */
+#define CONFIG_RAM_SIZE 0x00018000 /* 96 kB */
+
+/* Number of IRQ vectors on the NVIC */
+#define CONFIG_IRQ_COUNT 82
diff --git a/chip/stm32/config_chip.h b/chip/stm32/config_chip.h
index 87ebd21c09..80415e413a 100644
--- a/chip/stm32/config_chip.h
+++ b/chip/stm32/config_chip.h
@@ -23,7 +23,9 @@
#define CHIP_VARIANT_STM32F03X
#endif
-#if defined(CHIP_VARIANT_STM32L15X)
+#if defined(CHIP_VARIANT_STM32L476)
+#include "config-stm32l476.h"
+#elif defined(CHIP_VARIANT_STM32L15X)
#include "config-stm32l15x.h"
#elif defined(CHIP_VARIANT_STM32L100)
#include "config-stm32l100.h"
diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c
index d169cf7f45..3b45544190 100644
--- a/chip/stm32/dma.c
+++ b/chip/stm32/dma.c
@@ -230,7 +230,11 @@ void dma_test(enum dma_channel channel)
void dma_init(void)
{
+#ifdef CHIP_FAMILY_STM32L4
+ STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_DMA1EN;
+#else
STM32_RCC_AHBENR |= STM32_RCC_HB_DMA1;
+#endif
#ifdef CHIP_FAMILY_STM32F3
STM32_RCC_AHBENR |= STM32_RCC_HB_DMA2;
#endif
diff --git a/chip/stm32/gpio-stm32l4.c b/chip/stm32/gpio-stm32l4.c
new file mode 100644
index 0000000000..67df8ba157
--- /dev/null
+++ b/chip/stm32/gpio-stm32l4.c
@@ -0,0 +1,26 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* GPIO module for Chrome EC */
+
+#include "clock.h"
+#include "common.h"
+#include "registers.h"
+
+void gpio_enable_clocks(void)
+{
+ /*
+ * Enable all GPIOs clocks
+ *
+ * TODO(crosbug.com/p/23770): only enable the banks we need to,
+ * and support disabling some of them in low-power idle.
+ */
+ STM32_RCC_AHB2ENR |= STM32_RCC_AHB2ENR_GPIOMASK;
+
+ /* Delay 1 AHB clock cycle after the clock is enabled */
+ clock_wait_bus_cycles(BUS_AHB, 1);
+}
+
+#include "gpio-f0-l.c"
diff --git a/chip/stm32/jtag-stm32l4.c b/chip/stm32/jtag-stm32l4.c
new file mode 100644
index 0000000000..44fb9972e3
--- /dev/null
+++ b/chip/stm32/jtag-stm32l4.c
@@ -0,0 +1,21 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+/* Settings to enable JTAG debugging */
+
+#include "jtag.h"
+#include "registers.h"
+
+void jtag_pre_init(void)
+{
+ /*
+ * Stop all timers we might use (TIM1-8) and watchdogs when
+ * the JTAG stops the CPU.
+ */
+ STM32_DBGMCU_APB1FZ |=
+ STM32_RCC_PB1_TIM2 | STM32_RCC_PB1_TIM3 | STM32_RCC_PB1_TIM4 |
+ STM32_RCC_PB1_TIM5 | STM32_RCC_PB1_TIM6 | STM32_RCC_PB1_TIM7 |
+ STM32_RCC_PB1_WWDG | STM32_RCC_PB1_IWDG;
+ STM32_DBGMCU_APB2FZ |= STM32_RCC_PB2_TIM1 | STM32_RCC_PB2_TIM8;
+}
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 74eee526cb..33b2d9faeb 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -156,7 +156,8 @@
#define STM32_USART_BASE(n) CONCAT3(STM32_USART, n, _BASE)
#define STM32_USART_REG(base, offset) REG32((base) + (offset))
-#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
+#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
+ defined(CHIP_FAMILY_STM32L4)
#define STM32_USART_CR1(base) STM32_USART_REG(base, 0x00)
#define STM32_USART_CR1_UE (1 << 0)
#define STM32_USART_CR1_UESM (1 << 1)
@@ -352,13 +353,16 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define GPIO_ALT_RI 0xE
#define GPIO_ALT_EVENTOUT 0xF
-#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
+#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
+ defined(CHIP_FAMILY_STM32L4)
#define STM32_GPIOA_BASE 0x48000000
#define STM32_GPIOB_BASE 0x48000400
#define STM32_GPIOC_BASE 0x48000800
#define STM32_GPIOD_BASE 0x48000C00
#define STM32_GPIOE_BASE 0x48001000
#define STM32_GPIOF_BASE 0x48001400
+#define STM32_GPIOG_BASE 0x48001800 /* only for stm32l4 */
+#define STM32_GPIOH_BASE 0x48001C00 /* only for stm32l4 */
#define STM32_GPIO_MODER(b) REG32((b) + 0x00)
#define STM32_GPIO_OTYPER(b) REG16((b) + 0x04)
@@ -371,6 +375,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_GPIO_AFRL(b) REG32((b) + 0x20)
#define STM32_GPIO_AFRH(b) REG32((b) + 0x24)
#define STM32_GPIO_BRR(b) REG32((b) + 0x28)
+#define STM32_GPIO_ASCR(b) REG32((b) + 0x2C) /* only for stm32l4 */
#define GPIO_ALT_F0 0x0
#define GPIO_ALT_F1 0x1
@@ -378,14 +383,21 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define GPIO_ALT_F3 0x3
#define GPIO_ALT_F4 0x4
#define GPIO_ALT_F5 0x5
+#define GPIO_ALT_F6 0x6
+#define GPIO_ALT_F7 0x7
+#define GPIO_ALT_F8 0x8
+#define GPIO_ALT_F9 0x9
+#define GPIO_ALT_FA 0xA
+#define GPIO_ALT_FB 0xB
+#define GPIO_ALT_FC 0xC
+#define GPIO_ALT_FD 0xD
+#define GPIO_ALT_FE 0xE
+#define GPIO_ALT_FF 0xF
#else
#error Unsupported chip variant
#endif
-
-
-
/* --- I2C --- */
#define STM32_I2C1_BASE 0x40005400
#define STM32_I2C2_BASE 0x40005800
@@ -543,6 +555,60 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_SYSCFG_PMC REG32(STM32_SYSCFG_BASE + 0x04)
#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n))
+#elif defined(CHIP_FAMILY_STM32L4)
+#define STM32_RCC_BASE 0x40021000
+
+#define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x00)
+#define STM32_RCC_CR_MSION (1 << 0)
+#define STM32_RCC_CR_MSIRDY (1 << 1)
+#define STM32_RCC_CR_HSION (1 << 8)
+#define STM32_RCC_CR_HSIRDY (1 << 10)
+
+#define STM32_RCC_ICSCR REG32(STM32_RCC_BASE + 0x04)
+#define STM32_RCC_ICSCR_MSIRANGE(n) ((n) << 13)
+#define STM32_RCC_ICSCR_MSIRANGE_1MHZ STM32_RCC_ICSCR_MSIRANGE(4)
+#define STM32_RCC_ICSCR_MSIRANGE_2MHZ STM32_RCC_ICSCR_MSIRANGE(5)
+#define STM32_RCC_ICSCR_MSIRANGE_MASK STM32_RCC_ICSCR_MSIRANGE(7)
+
+#define STM32_RCC_CFGR REG32(STM32_RCC_BASE + 0x08)
+#define STM32_RCC_CFGR_SW_MSI (0 << 0)
+#define STM32_RCC_CFGR_SW_HSI (1 << 0)
+#define STM32_RCC_CFGR_SW_HSE (2 << 0)
+#define STM32_RCC_CFGR_SW_PLL (3 << 0)
+#define STM32_RCC_CFGR_SW_MASK (3 << 0)
+#define STM32_RCC_CFGR_SWS_MSI (0 << 2)
+#define STM32_RCC_CFGR_SWS_HSI (1 << 2)
+#define STM32_RCC_CFGR_SWS_HSE (2 << 2)
+#define STM32_RCC_CFGR_SWS_PLL (3 << 2)
+#define STM32_RCC_CFGR_SWS_MASK (3 << 2)
+
+#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x48)
+#define STM32_RCC_AHB1ENR_DMA1EN (1 << 0)
+#define STM32_RCC_AHB1ENR_DMA2EN (1 << 1)
+
+#define STM32_RCC_AHB2ENR REG32(STM32_RCC_BASE + 0x4C)
+#define STM32_RCC_AHB2ENR_GPIOMASK (0xff << 0)
+
+#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x58)
+#define STM32_RCC_APB1ENR2 REG32(STM32_RCC_BASE + 0x5C)
+#define STM32_RCC_APB1ENR2_LPUART1EN (1 << 0)
+
+#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x60)
+
+#define STM32_RCC_CCIPR REG32(STM32_RCC_BASE + 0x88)
+#define STM32_RCC_CCIPR_LPUART1SEL_SHIFT (10)
+#define STM32_RCC_CCIPR_USART1SEL_SHIFT (0)
+
+#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x90)
+
+#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x94)
+
+#define STM32_RCC_PB2_TIM1 (1 << 11)
+#define STM32_RCC_PB2_TIM8 (1 << 13)
+
+#define STM32_SYSCFG_BASE 0x40010000
+#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n))
+
#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
#define STM32_RCC_BASE 0x40021000
@@ -634,7 +700,7 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RTC_BASE 0x40002800
#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \
- defined(CHIP_FAMILY_STM32F3)
+ defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4)
#define STM32_RTC_TR REG32(STM32_RTC_BASE + 0x00)
#define STM32_RTC_DR REG32(STM32_RTC_BASE + 0x04)
#define STM32_RTC_CR REG32(STM32_RTC_BASE + 0x08)
@@ -780,7 +846,8 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#define STM32_OPTB_WRP3L 0x18
#define STM32_OPTB_WRP3H 0x1c
-#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
+#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
+ defined(CHIP_FAMILY_STM32L4)
#define STM32_FLASH_REGS_BASE 0x40022000
#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00)
@@ -1128,7 +1195,8 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#if defined(CHIP_FAMILY_STM32L)
#define STM32_DMA1_BASE 0x40026000
-#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
+#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
+ defined(CHIP_FAMILY_STM32L4)
#define STM32_DMA1_BASE 0x40020000
#define STM32_DMA2_BASE 0x40020400
#else
@@ -1228,9 +1296,8 @@ typedef volatile struct stm32_dma_regs stm32_dma_regs_t;
#define STM32_DMA1_REGS ((stm32_dma_regs_t *)STM32_DMA1_BASE)
-#ifdef CHIP_FAMILY_STM32F3
+#if defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4)
#define STM32_DMA2_REGS ((stm32_dma_regs_t *)STM32_DMA2_BASE)
-
#define STM32_DMA_REGS(channel) \
((channel) < STM32_DMAC_PER_CTLR ? STM32_DMA1_REGS : STM32_DMA2_REGS)
#define STM32_DMA_CSELR(channel) \
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index 682020b344..90a248eafa 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -207,7 +207,8 @@ void system_pre_init(void)
/* Enable RTC and use LSI as clock source */
STM32_RCC_CSR = (STM32_RCC_CSR & ~0x00C30000) | 0x00420000;
}
-#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
+#elif defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3) || \
+ defined(CHIP_FAMILY_STM32L4)
if ((STM32_RCC_BDCR & 0x00018300) != 0x00008200) {
/* the RTC settings are bad, we need to reset it */
STM32_RCC_BDCR |= 0x00010000;
@@ -396,5 +397,8 @@ int system_is_reboot_warm(void)
return ((STM32_RCC_AHBENR & 0x7e0000) == 0x7e0000);
#elif defined(CHIP_FAMILY_STM32L)
return ((STM32_RCC_AHBENR & 0x3f) == 0x3f);
+#elif defined(CHIP_FAMILY_STM32L4)
+ return ((STM32_RCC_AHB2ENR & STM32_RCC_AHB2ENR_GPIOMASK)
+ == STM32_RCC_AHB2ENR_GPIOMASK);
#endif
}
diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c
index 33ef1064f0..69dc7d26d2 100644
--- a/chip/stm32/uart.c
+++ b/chip/stm32/uart.c
@@ -15,6 +15,7 @@
#include "task.h"
#include "uart.h"
#include "util.h"
+#include "stm32-dma.h"
/* Console USART index */
#define UARTN CONFIG_UART_CONSOLE
@@ -238,7 +239,7 @@ static void uart_freq_change(void)
div = DIV_ROUND_NEAREST(freq, CONFIG_UART_BAUD_RATE);
#if defined(CHIP_FAMILY_STM32L) || defined(CHIP_FAMILY_STM32F0) || \
- defined(CHIP_FAMILY_STM32F3)
+ defined(CHIP_FAMILY_STM32F3) || defined(CHIP_FAMILY_STM32L4)
if (div / 16 > 0) {
/*
* CPU clock is high enough to support x16 oversampling.
@@ -264,15 +265,18 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, uart_freq_change, HOOK_PRIO_DEFAULT);
void uart_init(void)
{
- /* Enable USART clock */
+ /* Select clock source */
#if defined(CHIP_FAMILY_STM32F0) || defined(CHIP_FAMILY_STM32F3)
#if (UARTN == 1)
STM32_RCC_CFGR3 |= 0x0003; /* USART1 clock source from HSI(8MHz) */
#elif (UARTN == 2)
STM32_RCC_CFGR3 |= 0x030000; /* USART2 clock source from HSI(8MHz) */
#endif /* UARTN */
+#elif defined(CHIP_FAMILY_STM32L4)
+ STM32_RCC_CCIPR |= (0x2 << STM32_RCC_CCIPR_USART1SEL_SHIFT);
#endif /* CHIP_FAMILY_STM32F0 || CHIP_FAMILY_STM32F3 */
+ /* Enable USART clock */
#if (UARTN == 1)
STM32_RCC_APB2ENR |= STM32_RCC_PB2_USART1;
#else
@@ -316,6 +320,9 @@ void uart_init(void)
#ifdef CONFIG_UART_TX_DMA
/* Enable DMA transmitter */
STM32_USART_CR3(UARTN_BASE) |= STM32_USART_CR3_DMAT;
+#ifdef CONFIG_UART_TX_DMA_PH
+ dma_select_channel(CONFIG_UART_TX_DMA_CH, CONFIG_UART_TX_DMA_PH);
+#endif
#else
/* DMA disabled, special modes disabled, error interrupt disabled */
STM32_USART_CR3(UARTN_BASE) &= ~STM32_USART_CR3_DMAR &
diff --git a/include/config.h b/include/config.h
index bfbc0b17a2..173db8f3ed 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1765,6 +1765,9 @@
#undef CONFIG_UART_TX_DMA_CH
#undef CONFIG_UART_RX_DMA_CH
+/* The DMA peripheral request signal for UART TX. STM32 only. */
+#undef CONFIG_UART_TX_DMA_PH
+
/*****************************************************************************/
/* USB PD config */