summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2012-05-01 22:23:57 +0000
committerVincent Palatin <vpalatin@chromium.org>2012-05-01 17:13:33 -0700
commitcab258137b41e63c78d765883019a3b7c1540692 (patch)
treeb836929a7ac1af6ecc4c9ca0286673b576ec18e9
parenta9ceb116c7c047bfb076e1c69bcc0587cd79ac2a (diff)
downloadchrome-ec-cab258137b41e63c78d765883019a3b7c1540692.tar.gz
introducing chip variant for stm32 family [3/3]
Add STM32F support. Based on David's changelist. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BUG=chrome-os-partner:9057 TEST=make BOARD=daisy ; make BOARD=adv ; make BOARD=discovery Change-Id: Ide817d11480f0b56f67deaae3c08bc631f605075
-rw-r--r--chip/stm32/build.mk3
-rw-r--r--chip/stm32/clock-stm32f100.c51
-rw-r--r--chip/stm32/clock-stm32l15x.c (renamed from chip/stm32/clock.c)0
-rw-r--r--chip/stm32/config-stm32f100.h26
-rw-r--r--chip/stm32/config.h4
-rw-r--r--chip/stm32/dma.c2
-rw-r--r--chip/stm32/gpio-stm32f100.c237
-rw-r--r--chip/stm32/gpio-stm32l15x.c (renamed from chip/stm32/gpio.c)0
-rw-r--r--chip/stm32/jtag-stm32f100.c16
-rw-r--r--chip/stm32/jtag-stm32l15x.c (renamed from chip/stm32/jtag.c)0
-rw-r--r--chip/stm32/registers.h208
-rw-r--r--chip/stm32/system.c14
-rw-r--r--chip/stm32/uart.c4
13 files changed, 544 insertions, 21 deletions
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index 845e3d3d7e..f499f45079 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -8,7 +8,8 @@
# STM32 SoC family has a Cortex-M3 ARM core
CORE:=cortex-m
-chip-y=clock.o dma.o gpio.o hwtimer.o jtag.o system.o uart.o
+chip-y=dma.o hwtimer.o system.o uart.o
+chip-y+=jtag-$(CHIP_VARIANT).o clock-$(CHIP_VARIANT).o gpio-$(CHIP_VARIANT).o
chip-$(CONFIG_TASK_SPI_WORK)+=spi.o
chip-$(CONFIG_TASK_I2C2_WORK)+=i2c.o
chip-$(CONFIG_TASK_WATCHDOG)+=watchdog.o
diff --git a/chip/stm32/clock-stm32f100.c b/chip/stm32/clock-stm32f100.c
new file mode 100644
index 0000000000..803695b227
--- /dev/null
+++ b/chip/stm32/clock-stm32f100.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 2012 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 <stdint.h>
+
+#include "board.h"
+#include "clock.h"
+#include "common.h"
+#include "registers.h"
+#include "util.h"
+
+int clock_init(void)
+{
+ /*
+ * The initial state :
+ * SYSCLK from HSI (=8MHz), no divider on AHB, APB1, APB2
+ * PLL unlocked, RTC enabled on LSE
+ */
+
+ /* Ensure that HSI is ON */
+ if (!(STM32_RCC_CR & (1 << 1))) {
+ /* Enable HSI */
+ STM32_RCC_CR |= 1 << 0;
+ /* Wait for HSI to be ready */
+ while (!(STM32_RCC_CR & (1 << 1)))
+ ;
+ }
+
+ /*
+ * stays on HSI (8MHz), no prescaler, PLLSRC = HSI/2, PLLMUL = x4
+ * no MCO => PLLCLK = 16 Mhz
+ */
+ BUILD_ASSERT(CPU_CLOCK == 16000000);
+ STM32_RCC_CFGR = 0x00880001;
+ /* Enable the PLL */
+ STM32_RCC_CR |= 1 << 24;
+ /* Wait for the PLL to lock */
+ while (!(STM32_RCC_CR & (1 << 25)))
+ ;
+ /* switch to SYSCLK to the PLL */
+ STM32_RCC_CFGR = 0x00880002;
+ /* wait until the PLL is the clock source */
+ while ((STM32_RCC_CFGR & 0xc) != 0x8)
+ ;
+
+ return EC_SUCCESS;
+}
diff --git a/chip/stm32/clock.c b/chip/stm32/clock-stm32l15x.c
index e9b74f12c4..e9b74f12c4 100644
--- a/chip/stm32/clock.c
+++ b/chip/stm32/clock-stm32l15x.c
diff --git a/chip/stm32/config-stm32f100.h b/chip/stm32/config-stm32f100.h
new file mode 100644
index 0000000000..66e2e733e3
--- /dev/null
+++ b/chip/stm32/config-stm32f100.h
@@ -0,0 +1,26 @@
+/* Copyright (c) 2012 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_BASE 0x08000000
+#define CONFIG_FLASH_SIZE 0x00010000
+#define CONFIG_FLASH_BANK_SIZE 0x1000
+#define CONFIG_RAM_BASE 0x20000000
+#define CONFIG_RAM_SIZE 0x00002000
+
+/* Size of one firmware image in flash */
+#define CONFIG_FW_IMAGE_SIZE (32 * 1024)
+#define CONFIG_FW_RO_OFF 0
+#define CONFIG_FW_A_OFF CONFIG_FW_IMAGE_SIZE
+#define CONFIG_FW_B_OFF (2 * CONFIG_FW_IMAGE_SIZE)
+
+/* Number of IRQ vectors on the NVIC */
+#define CONFIG_IRQ_COUNT 61
+
+/* Debug UART parameters for panic message */
+#define CONFIG_UART_ADDRESS 0x40013800 /* USART1 */
+#define CONFIG_UART_DR_OFFSET 0x04
+#define CONFIG_UART_SR_OFFSET 0x00
+#define CONFIG_UART_SR_TXEMPTY 0x80
diff --git a/chip/stm32/config.h b/chip/stm32/config.h
index 567c03ee0a..0ef887e4f7 100644
--- a/chip/stm32/config.h
+++ b/chip/stm32/config.h
@@ -7,8 +7,10 @@
#define __CROS_EC_CHIP_CONFIG_H
/* use variant specific configuration for flash / UART / IRQ */
-#ifdef CHIP_VARIANT_stm32l15x
+#if defined(CHIP_VARIANT_stm32l15x)
#include "config-stm32l15x.h"
+#elif defined(CHIP_VARIANT_stm32f100)
+#include "config-stm32f100.h"
#else
#error "Unsupported chip variant"
#endif
diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c
index 9b9e138894..5c4787fe0d 100644
--- a/chip/stm32/dma.c
+++ b/chip/stm32/dma.c
@@ -166,5 +166,5 @@ void dma_test(void)
void dma_init(void)
{
/* Enable DMA1, we don't support DMA2 yet */
- STM32_RCC_AHBENR |= 1 << 24;
+ STM32_RCC_AHBENR |= RCC_AHBENR_DMA1EN;
}
diff --git a/chip/stm32/gpio-stm32f100.c b/chip/stm32/gpio-stm32f100.c
new file mode 100644
index 0000000000..db4c918ae2
--- /dev/null
+++ b/chip/stm32/gpio-stm32f100.c
@@ -0,0 +1,237 @@
+/* Copyright (c) 2012 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 "board.h"
+#include "console.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "registers.h"
+#include "task.h"
+#include "util.h"
+
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_GPIO, outstr)
+#define CPRINTF(format, args...) cprintf(CC_GPIO, format, ## args)
+
+/* Signal information from board.c. Must match order from enum gpio_signal. */
+extern const struct gpio_info gpio_list[GPIO_COUNT];
+
+/* For each EXTI bit, record which GPIO entry is using it */
+static const struct gpio_info *exti_events[16];
+
+struct port_config {
+ uint32_t addr;
+ uint32_t mode;
+ uint32_t cnf;
+};
+
+/* helper function for generating bitmasks for STM32 GPIO config registers */
+static void gpio_config_info(const struct gpio_info *g, uint32_t *addr,
+ uint32_t *mode, uint32_t *cnf) {
+ /*
+ * 2-bit config followed by 2-bit mode for each pin, each
+ * successive pin raises the exponent for the lowest bit
+ * set by an order of 4, e.g. 2^0, 2^4, 2^8, etc.
+ */
+ if (g->mask & 0xff) {
+ *addr = g->port; /* GPIOx_CRL */
+ *mode = g->mask;
+ } else {
+ *addr = g->port + 0x04; /* GPIOx_CRH */
+ *mode = g->mask >> 8;
+ }
+ *mode = *mode * *mode * *mode * *mode;
+ *mode |= *mode << 1;
+ *cnf = *mode << 2;
+}
+
+int gpio_pre_init(void)
+{
+ const struct gpio_info *g = gpio_list;
+ int i;
+ uint32_t addr, cnf, mode, mask;
+
+ /* Enable all GPIOs clocks
+ * TODO: more fine-grained enabling for power saving
+ */
+ STM32_RCC_APB2ENR |= 0x1fd;
+
+ /* Set all GPIOs to defaults */
+ for (i = 0; i < GPIO_COUNT; i++, g++) {
+ gpio_config_info(g, &addr, &mode, &cnf);
+ mask = REG32(addr) & ~(cnf | mode);
+
+ /*
+ * For STM32, the port configuration field changes meaning
+ * depending on whether the port is an input, analog input,
+ * output, or alternate function.
+ */
+ if (g->flags & GPIO_OUTPUT) {
+ /* FIXME: This assumes output max speed of 10MHz */
+ mask |= 0x11111111 & mode;
+ if (g->flags & GPIO_OPEN_DRAIN)
+ mask |= 0x44444444 & cnf;
+ } else {
+ /* GPIOx_ODR determines which resistor to activate in
+ * input mode, see Table 16 (datasheet rm0041) */
+ if (g->flags & GPIO_PULL_UP) {
+ mask |= 0x88888888 & cnf;
+ STM32_GPIO_BSRR_OFF(g->port) |= g->mask;
+ gpio_set_level(i, 1);
+ } else if (g->flags & GPIO_PULL_DOWN) {
+ mask |= 0x88888888 & cnf;
+ gpio_set_level(i, 0);
+ } else {
+ mask |= 0x44444444 & cnf;
+ }
+ }
+
+ /*
+ * Set pin level after port has been set up as to avoid
+ * potential damage, e.g. driving an open-drain output
+ * high before it has been configured as such.
+ */
+ if (g->flags & GPIO_OUTPUT) /* General purpose, MODE = 01 */
+ gpio_set_level(i, g->flags & GPIO_HIGH);
+
+ REG32(addr) = mask;
+
+ /* Set up interrupts if necessary */
+ ASSERT(!(g->flags & GPIO_INT_LEVEL));
+ if (g->flags & (GPIO_INT_RISING | GPIO_INT_BOTH))
+ STM32_EXTI_RTSR |= g->mask;
+ if (g->flags & (GPIO_INT_FALLING | GPIO_INT_BOTH))
+ STM32_EXTI_FTSR |= g->mask;
+ /* Interrupt is enabled by gpio_enable_interrupt() */
+ }
+
+ return EC_SUCCESS;
+}
+
+
+int gpio_init(void)
+{
+ /* Enable IRQs now that pins are set up */
+ task_enable_irq(STM32_IRQ_EXTI0);
+ task_enable_irq(STM32_IRQ_EXTI1);
+ task_enable_irq(STM32_IRQ_EXTI2);
+ task_enable_irq(STM32_IRQ_EXTI3);
+ task_enable_irq(STM32_IRQ_EXTI4);
+ task_enable_irq(STM32_IRQ_EXTI9_5);
+ task_enable_irq(STM32_IRQ_EXTI15_10);
+
+ return EC_SUCCESS;
+}
+
+
+void gpio_set_alternate_function(int port, int mask, int func)
+{
+ int i;
+ const struct gpio_info *g = gpio_list;
+ uint32_t addr, cnf, mode, val = 0;
+
+ /*
+ * TODO(dhendrix): STM32 GPIO registers do not have free-form
+ * alternate function setup like the STM32, where each pin can
+ * be configured for any alternate function (though not necessarily
+ * in a valid fashion). Instead, pre-determined sets of pins for a
+ * a given alternate function are chosen via a remapping register.
+ *
+ * Consequently, this function becomes very simple and can (should?)
+ * be merged into gpio_pre_init.
+ */
+ for (i = 0; i < GPIO_COUNT; i++, g++) {
+ if ((g->port != port) || (g->mask != mask))
+ continue;
+
+ gpio_config_info(g, &addr, &mode, &cnf);
+ val = REG32(addr) & ~cnf;
+
+ /* switch from general output to alternate output mode */
+ if (g->flags & GPIO_OUTPUT) {
+ if (g->flags & GPIO_OPEN_DRAIN)
+ val |= 0xcccccccc & cnf;
+ else
+ val |= 0x88888888 & cnf;
+ }
+
+ REG32(addr) = val ;
+ break;
+ }
+}
+
+
+int gpio_get_level(enum gpio_signal signal)
+{
+ return !!(STM32_GPIO_IDR_OFF(gpio_list[signal].port) &
+ gpio_list[signal].mask);
+}
+
+
+int gpio_set_level(enum gpio_signal signal, int value)
+{
+ STM32_GPIO_BSRR_OFF(gpio_list[signal].port) =
+ gpio_list[signal].mask << (value ? 0 : 16);
+
+ return EC_SUCCESS;
+}
+
+int gpio_enable_interrupt(enum gpio_signal signal)
+{
+ const struct gpio_info *g = gpio_list + signal;
+ uint32_t bit, group, shift, bank;
+
+ /* Fail if not implemented or no interrupt handler */
+ if (!g->mask || !g->irq_handler)
+ return EC_ERROR_INVAL;
+
+ bit = 31 - __builtin_clz(g->mask);
+
+#ifdef CONFIG_DEBUG
+ if (exti_events[bit]) {
+ CPRINTF("Overriding %s with %s on EXTI%d\n",
+ exti_events[bit]->name, g->name, bit);
+ }
+#endif
+ exti_events[bit] = g;
+
+ group = bit / 4;
+ shift = (bit % 4) * 4;
+ bank = (g->port - STM32_GPIOA_BASE) / 0x400;
+ STM32_AFIO_EXTICR(group) = (STM32_AFIO_EXTICR(group) &
+ ~(0xF << shift)) | (bank << shift);
+ STM32_EXTI_IMR |= g->mask;
+
+ return EC_SUCCESS;
+}
+
+/*****************************************************************************/
+/* Interrupt handler */
+
+static void gpio_interrupt(void)
+{
+ int bit;
+ const struct gpio_info *g;
+ uint32_t pending = STM32_EXTI_PR;
+
+ STM32_EXTI_PR = pending;
+
+ while (pending) {
+ bit = 31 - __builtin_clz(pending);
+ g = exti_events[bit];
+ if (g && g->irq_handler)
+ g->irq_handler(g - gpio_list);
+ pending &= ~(1 << bit);
+ }
+}
+DECLARE_IRQ(STM32_IRQ_EXTI0, gpio_interrupt, 1);
+DECLARE_IRQ(STM32_IRQ_EXTI1, gpio_interrupt, 1);
+DECLARE_IRQ(STM32_IRQ_EXTI2, gpio_interrupt, 1);
+DECLARE_IRQ(STM32_IRQ_EXTI3, gpio_interrupt, 1);
+DECLARE_IRQ(STM32_IRQ_EXTI4, gpio_interrupt, 1);
+DECLARE_IRQ(STM32_IRQ_EXTI9_5, gpio_interrupt, 1);
+DECLARE_IRQ(STM32_IRQ_EXTI15_10, gpio_interrupt, 1);
diff --git a/chip/stm32/gpio.c b/chip/stm32/gpio-stm32l15x.c
index 55eaa22171..55eaa22171 100644
--- a/chip/stm32/gpio.c
+++ b/chip/stm32/gpio-stm32l15x.c
diff --git a/chip/stm32/jtag-stm32f100.c b/chip/stm32/jtag-stm32f100.c
new file mode 100644
index 0000000000..444d00f016
--- /dev/null
+++ b/chip/stm32/jtag-stm32f100.c
@@ -0,0 +1,16 @@
+/* Copyright (c) 2012 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"
+
+int jtag_pre_init(void)
+{
+ /* stop TIM2, TIM3 and watchdogs when the JTAG stops the CPU */
+ STM32_DBGMCU_CR |= 0x00001b00;
+
+ return EC_SUCCESS;
+}
diff --git a/chip/stm32/jtag.c b/chip/stm32/jtag-stm32l15x.c
index 234e2aa967..234e2aa967 100644
--- a/chip/stm32/jtag.c
+++ b/chip/stm32/jtag-stm32l15x.c
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index b4b9e71983..f169dab72e 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -42,10 +42,14 @@
#define STM32_IRQ_DAC 21
#define STM32_IRQ_COMP 22
#define STM32_IRQ_EXTI9_5 23
-#define STM32_IRQ_LCD 24
-#define STM32_IRQ_TIM9 25
-#define STM32_IRQ_TIM10 26
-#define STM32_IRQ_TIM11 27
+#define STM32_IRQ_LCD 24 /* STM32L15X only */
+#define STM32_IRQ_TIM1_BRK_TIM15 24 /* STM32F100 only */
+#define STM32_IRQ_TIM9 25 /* STM32L15X only */
+#define STM32_IRQ_TIM1_UP_TIM16 25 /* STM32F100 only */
+#define STM32_IRQ_TIM10 26 /* STM32L15X only */
+#define STM32_IRQ_TIM1_TRG_TIM17 26 /* STM32F100 only */
+#define STM32_IRQ_TIM11 27 /* STM32L15X only */
+#define STM32_IRQ_TIM1_CC 27 /* STM32F100 only */
#define STM32_IRQ_TIM2 28
#define STM32_IRQ_TIM3 29
#define STM32_IRQ_TIM4 30
@@ -60,14 +64,35 @@
#define STM32_IRQ_USART3 39
#define STM32_IRQ_EXTI15_10 40
#define STM32_IRQ_RTC_ALARM 41
-#define STM32_IRQ_USB_FS_WAKEUP 42
-#define STM32_IRQ_TIM6 43
-#define STM32_IRQ_TIM7 44
+#define STM32_IRQ_USB_FS_WAKEUP 42 /* STM32L15X only */
+#define STM32_IRQ_TIM6_BASIC 43 /* STM32L15X only */
+#define STM32_IRQ_TIM7_BASIC 44 /* STM32L15X only */
+#define STM32_IRQ_CEC 42 /* STM32F100 only */
+#define STM32_IRQ_TIM12 43 /* STM32F100 only */
+#define STM32_IRQ_TIM13 44 /* STM32F100 only */
+#define STM32_IRQ_TIM14 45 /* STM32F100 only */
+/* positions 46-47 are reserved on STM32 */
+#define STM32_IRQ_FSMC 48 /* STM32F100 only */
+/* position 49 is reserved on STM32 */
+#define STM32_IRQ_TIM5 50 /* STM32F100 only */
+#define STM32_IRQ_SPI3 51 /* STM32F100 only */
+#define STM32_IRQ_UART4 52 /* STM32F100 only */
+#define STM32_IRQ_UART5 53 /* STM32F100 only */
+#define STM32_IRQ_TIM6_DAC 54 /* STM32F100 only */
+#define STM32_IRQ_TIM7 55 /* STM32F100 only */
+#define STM32_IRQ_DMA2_CHANNEL1 56 /* STM32F100 only */
+#define STM32_IRQ_DMA2_CHANNEL2 57 /* STM32F100 only */
+#define STM32_IRQ_DMA2_CHANNEL3 58 /* STM32F100 only */
+#define STM32_IRQ_DMA2_CHANNEL4_5 59 /* STM32F100 only */
+/* if MISC_REMAP bits are set */
+#define STM32_IRQ_DMA2_CHANNEL5 60 /* STM32F100 only */
/* --- USART --- */
#define STM32_USART1_BASE 0x40013800
#define STM32_USART2_BASE 0x40004400
#define STM32_USART3_BASE 0x40004800
+#define STM32_UART4_BASE 0x40004c00 /* STM32F100 only */
+#define STM32_UART5_BASE 0x40005000 /* STM32F100 only */
#define STM32_USART_BASE(n) STM32_CAT(STM32_USART, n, _BASE)
@@ -85,14 +110,22 @@
#define STM32_IRQ_USART(n) STM32_CAT(STM32_IRQ_USART, n, )
/* --- TIMERS --- */
+#define STM32_TIM1_BASE 0x40012c00 /* STM32F100 only */
#define STM32_TIM2_BASE 0x40000000
#define STM32_TIM3_BASE 0x40000400
#define STM32_TIM4_BASE 0x40000800
+#define STM32_TIM5_BASE 0x40000c00 /* STM32F100 only */
#define STM32_TIM6_BASE 0x40001000
#define STM32_TIM7_BASE 0x40001400
-#define STM32_TIM9_BASE 0x40010800
-#define STM32_TIM10_BASE 0x40010C00
-#define STM32_TIM11_BASE 0x40011000
+#define STM32_TIM9_BASE 0x40010800 /* STM32L15X only */
+#define STM32_TIM10_BASE 0x40010C00 /* STM32L15X only */
+#define STM32_TIM11_BASE 0x40011000 /* STM32L15X only */
+#define STM32_TIM12_BASE 0x40001800 /* STM32F100 only */
+#define STM32_TIM13_BASE 0x40001c00 /* STM32F100 only */
+#define STM32_TIM14_BASE 0x40002000 /* STM32F100 only */
+#define STM32_TIM15_BASE 0x40014000 /* STM32F100 only */
+#define STM32_TIM16_BASE 0x40014400 /* STM32F100 only */
+#define STM32_TIM17_BASE 0x40014800 /* STM32F100 only */
#define STM32_TIM_REG(n, offset) \
REG16(STM32_CAT(STM32_TIM, n, _BASE) + (offset))
@@ -118,18 +151,14 @@
#define STM32_TIM_OR(n) STM32_TIM_REG(n, 0x50)
/* --- GPIO --- */
-#define STM32_GPIOA_BASE 0x40020000
-#define STM32_GPIOB_BASE 0x40020400
-#define STM32_GPIOC_BASE 0x40020800
-#define STM32_GPIOD_BASE 0x40020C00
-#define STM32_GPIOE_BASE 0x40021000
-#define STM32_GPIOH_BASE 0x40021400
#define GPIO_A STM32_GPIOA_BASE
#define GPIO_B STM32_GPIOB_BASE
#define GPIO_C STM32_GPIOC_BASE
#define GPIO_D STM32_GPIOD_BASE
#define GPIO_E STM32_GPIOE_BASE
+#define GPIO_F STM32_GPIOF_BASE
+#define GPIO_G STM32_GPIOG_BASE
#define GPIO_H STM32_GPIOH_BASE
#define STM32_GPIO_REG32(l, offset) \
@@ -137,6 +166,14 @@
#define STM32_GPIO_REG16(l, offset) \
REG16(STM32_CAT(STM32_GPIO, l, _BASE) + (offset))
+#if defined(CHIP_VARIANT_stm32l15x)
+#define STM32_GPIOA_BASE 0x40020000
+#define STM32_GPIOB_BASE 0x40020400
+#define STM32_GPIOC_BASE 0x40020800
+#define STM32_GPIOD_BASE 0x40020C00
+#define STM32_GPIOE_BASE 0x40021000
+#define STM32_GPIOH_BASE 0x40021400
+
#define STM32_GPIO_MODER(l) STM32_GPIO_REG32(l, 0x00)
#define STM32_GPIO_OTYPER(l) STM32_GPIO_REG16(l, 0x04)
#define STM32_GPIO_OSPEEDR(l) STM32_GPIO_REG32(l, 0x08)
@@ -171,6 +208,48 @@
#define GPIO_ALT_RI 0xE
#define GPIO_ALT_EVENTOUT 0xF
+#elif defined(CHIP_VARIANT_stm32f100)
+#define STM32_GPIOA_BASE 0x40010800
+#define STM32_GPIOB_BASE 0x40010c00
+#define STM32_GPIOC_BASE 0x40011000
+#define STM32_GPIOD_BASE 0x40011400
+#define STM32_GPIOE_BASE 0x40011800
+#define STM32_GPIOF_BASE 0x4001c000
+#define STM32_GPIOG_BASE 0x40012000
+
+#define STM32_GPIO_CRL(l) STM32_GPIO_REG32(l, 0x00)
+#define STM32_GPIO_CRH(l) STM32_GPIO_REG32(l, 0x04)
+#define STM32_GPIO_IDR(l) STM32_GPIO_REG16(l, 0x08)
+#define STM32_GPIO_ODR(l) STM32_GPIO_REG16(l, 0x0c)
+#define STM32_GPIO_BSRR(l) STM32_GPIO_REG32(l, 0x10)
+#define STM32_GPIO_BRR(l) STM32_GPIO_REG16(l, 0x14)
+#define STM32_GPIO_LCKR(l) STM32_GPIO_REG16(l, 0x18)
+
+#define STM32_GPIO_CRL_OFF(b) REG32((b) + 0x00)
+#define STM32_GPIO_CRH_OFF(b) REG32((b) + 0x04)
+#define STM32_GPIO_IDR_OFF(b) REG16((b) + 0x08)
+#define STM32_GPIO_ODR_OFF(b) REG16((b) + 0x0c)
+#define STM32_GPIO_BSRR_OFF(b) REG32((b) + 0x10)
+#define STM32_GPIO_BRR_OFF(b) REG32((b) + 0x14)
+#define STM32_GPIO_LCKR_OFF(b) REG32((b) + 0x18)
+
+#define STM32_AFIO_BASE 0x40010000
+#define STM32_AFIO_EXTICR(n) REG32(STM32_AFIO_BASE + 8 + 4 * (n))
+#define STM32_GPIO_AFIO_EVCR_OFF(b) REG16((b) + 0x00)
+#define STM32_GPIO_AFIO_MAPR_OFF(b) REG32((b) + 0x04)
+#define STM32_GPIO_AFIO_EXTICR1(b) REG16((b) + 0x08)
+#define STM32_GPIO_AFIO_EXTICR2(b) REG16((b) + 0x0c)
+#define STM32_GPIO_AFIO_EXTICR3(b) REG16((b) + 0x10)
+#define STM32_GPIO_AFIO_EXTICR4(b) REG16((b) + 0x14)
+#define STM32_GPIO_AFIO_MAPR2(b) REG16((b) + 0x1c)
+
+#else
+#error Unsupported chip variant
+#endif
+
+
+
+
/* --- I2C --- */
#define STM32_I2C1_BASE 0x40005400
#define STM32_I2C2_BASE 0x40005800
@@ -199,6 +278,7 @@ static inline uint16_t *stm32_i2c_reg(int port, int offset)
#define STM32_PWR_CR REG32(STM32_PWR_BASE + 0x00)
#define STM32_PWR_CSR REG32(STM32_PWR_BASE + 0x04)
+#if defined(CHIP_VARIANT_stm32l15x)
#define STM32_RCC_BASE 0x40023800
#define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x00)
@@ -216,12 +296,35 @@ static inline uint16_t *stm32_i2c_reg(int port, int offset)
#define STM32_RCC_APB1LPENR REG32(STM32_RCC_BASE + 0x30)
#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x34)
+#define RCC_AHBENR_DMA1EN (1 << 24)
+
#define STM32_SYSCFG_BASE 0x40010000
#define STM32_SYSCFG_MEMRMP REG32(STM32_SYSCFG_BASE + 0x00)
#define STM32_SYSCFG_PMC REG32(STM32_SYSCFG_BASE + 0x04)
#define STM32_SYSCFG_EXTICR(n) REG32(STM32_SYSCFG_BASE + 8 + 4 * (n))
+#elif defined(CHIP_VARIANT_stm32f100)
+#define STM32_RCC_BASE 0x40021000
+
+#define STM32_RCC_CR REG32(STM32_RCC_BASE + 0x00)
+#define STM32_RCC_CFGR REG32(STM32_RCC_BASE + 0x04)
+#define STM32_RCC_CIR REG32(STM32_RCC_BASE + 0x08)
+#define STM32_RCC_APB2RSTR REG32(STM32_RCC_BASE + 0x0c)
+#define STM32_RCC_APB1RSTR REG32(STM32_RCC_BASE + 0x10)
+#define STM32_RCC_AHBENR REG32(STM32_RCC_BASE + 0x14)
+#define STM32_RCC_APB2ENR REG32(STM32_RCC_BASE + 0x18)
+#define STM32_RCC_APB1ENR REG32(STM32_RCC_BASE + 0x1c)
+#define STM32_RCC_BDCR REG32(STM32_RCC_BASE + 0x20)
+#define STM32_RCC_CSR REG32(STM32_RCC_BASE + 0x24)
+#define STM32_RCC_CFGR2 REG32(STM32_RCC_BASE + 0x2c)
+
+#define RCC_AHBENR_DMA1EN (1 << 0)
+
+#else
+#error Unsupported chip variant
+#endif
+
/* --- Watchdogs --- */
#define STM32_WWDG_BASE 0x40002C00
@@ -241,6 +344,7 @@ static inline uint16_t *stm32_i2c_reg(int port, int offset)
#define STM32_RTC_BASE 0x40002800
+#if defined(CHIP_VARIANT_stm32l15x)
#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)
@@ -256,9 +360,35 @@ static inline uint16_t *stm32_i2c_reg(int port, int offset)
#define STM32_RTC_TAFCR REG32(STM32_RTC_BASE + 0x40)
#define STM32_RTC_BACKUP(n) REG32(STM32_RTC_BASE + 0x50 + 4 * (n))
+#elif defined(CHIP_VARIANT_stm32f100)
+#define STM32_RTC_CRH REG32(STM32_RTC_BASE + 0x00)
+#define STM32_RTC_CRL REG32(STM32_RTC_BASE + 0x04)
+#define STM32_RTC_PRLH REG32(STM32_RTC_BASE + 0x08)
+#define STM32_RTC_PRLL REG16(STM32_RTC_BASE + 0x0c)
+#define STM32_RTC_DIVH REG16(STM32_RTC_BASE + 0x10)
+#define STM32_RTC_DIVL REG16(STM32_RTC_BASE + 0x14)
+#define STM32_RTC_CNTH REG16(STM32_RTC_BASE + 0x18)
+#define STM32_RTC_CNTL REG16(STM32_RTC_BASE + 0x1c)
+#define STM32_RTC_ALRH REG16(STM32_RTC_BASE + 0x20)
+#define STM32_RTC_ALRL REG16(STM32_RTC_BASE + 0x24)
+
+/* --- Backup Registers --- */
+#define STM32_BKP_BASE 0x40006c00
+#define STM32_BKP_DATA(n) REG16(STM32_BKP_BASE + 2 + 4 * (n))
+#define STM32_BKP_RTCCR REG16(STm32F_BKP_BASE + 0x02)
+#define STM32_BKP_CR REG16(STm32F_BKP_BASE + 0x30)
+#define STM32_BKP_CSR REG16(STm32F_BKP_BASE + 0x34)
+
+#define STM32_RTC_BACKUP(n) STM32_BKP_DATA(n)
+
+#else
+#error Unsupported chip variant
+#endif
+
/* --- SPI --- */
#define STM32_SPI1_BASE 0x40013000
#define STM32_SPI2_BASE 0x40003800
+#define STM32_SPI3_BASE 0x40003c00 /* STM32F100 only */
#define STM32_SPI1_PORT 0
#define STM32_SPI2_PORT 1
@@ -295,9 +425,43 @@ static inline uint16_t *stm32_i2c_reg(int port, int offset)
/* --- Flash --- */
+#if defined(CHIP_VARIANT_stm32l15x)
#define STM32_FLASH_REGS_BASE 0x40023c00
#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00)
+#define STM32_FLASH_PECR REG32(STM32_FLASH_REGS_BASE + 0x04)
+#define STM32_FLASH_PDKEYR REG32(STM32_FLASH_REGS_BASE + 0x08)
+#define STM32_FLASH_PEKEYR REG32(STM32_FLASH_REGS_BASE + 0x0c)
+#define STM32_FLASH_PRGKEYR REG32(STM32_FLASH_REGS_BASE + 0x10)
+#define STM32_FLASH_OPTKEYR REG32(STM32_FLASH_REGS_BASE + 0x14)
+#define STM32_FLASH_SR REG32(STM32_FLASH_REGS_BASE + 0x18)
+#define STM32_FLASH_OBR REG32(STM32_FLASH_REGS_BASE + 0x1c)
+#define STM32_FLASH_WRPR REG32(STM32_FLASH_REGS_BASE + 0x20)
+
+#define STM32_OPTB_BASE 0x1FF80000
+
+#define STM32_OPTB_RDP REG32(STM32_OPTB_BASE + 0x00)
+#define STM32_OPTB_USER REG32(STM32_OPTB_BASE + 0x04)
+#define STM32_OPTB_WRP01 REG32(STM32_OPTB_BASE + 0x08)
+#define STM32_OPTB_WRP23 REG32(STM32_OPTB_BASE + 0x0c)
+
+#elif defined(CHIP_VARIANT_stm32f100)
+#define STM32_FLASH_REGS_BASE 0x40022000
+
+#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00)
+#define STM32_FLASH_KEYR REG32(STM32_FLASH_REGS_BASE + 0x04)
+#define STM32_FLASH_OPTKEYR REG32(STM32_FLASH_REGS_BASE + 0x08)
+#define STM32_FLASH_SR REG32(STM32_FLASH_REGS_BASE + 0x0c)
+#define STM32_FLASH_CR REG32(STM32_FLASH_REGS_BASE + 0x10)
+#define STM32_FLASH_AR REG32(STM32_FLASH_REGS_BASE + 0x14)
+#define STM32_FLASH_OBR REG32(STM32_FLASH_REGS_BASE + 0x1c)
+#define STM32_FLASH_WRPR REG32(STM32_FLASH_REGS_BASE + 0x20)
+
+#define STM32_OPTB_BASE 0x1FFFF800
+
+#else
+#error Unsupported chip variant
+#endif
/* --- External Interrupts --- */
#define STM32_EXTI_BASE 0x40010400
@@ -313,12 +477,22 @@ static inline uint16_t *stm32_i2c_reg(int port, int offset)
#define STM32_RI_BASE 0x40007C04
#define STM32_ADC1_BASE 0x40012400
-#define STM32_ADC_BASE 0x40012700
+#define STM32_ADC_BASE 0x40012700 /* STM32L15X only */
#define STM32_COMP_BASE 0x40007C00
+#define STM32_CEC_BASE 0x40007800 /* STM32F100 only */
#define STM32_DAC_BASE 0x40007400
#define STM32_CRC_BASE 0x40023000
#define STM32_LCD_BASE 0x40002400
+#if defined(CHIP_VARIANT_stm32l15x)
#define STM32_DMA1_BASE 0x40026000
#define STM32_DMA2_BASE 0x40026400
+#elif defined(CHIP_VARIANT_stm32f100)
+#define STM32_DMA1_BASE 0x40020000
+/* FIXME: DMA2 is only available on high-density devices, but is used as part
+ * of a sanity check in dma.c */
+#define STM32_DMA2_BASE 0x40020400
+#else
+#error Unsupported chip variant
+#endif
#endif /* __STM32_REGISTERS */
diff --git a/chip/stm32/system.c b/chip/stm32/system.c
index e5e9c7759d..8515a4bff3 100644
--- a/chip/stm32/system.c
+++ b/chip/stm32/system.c
@@ -8,6 +8,7 @@
#include "cpu.h"
#include "registers.h"
#include "system.h"
+#include "version.h"
static void check_reset_cause(void)
@@ -62,12 +63,23 @@ int system_pre_init(void)
while (!(STM32_RCC_CSR & (1 << 1)))
;
/* re-configure RTC if needed */
+#if defined(CHIP_VARIANT_stm32l15x)
if ((STM32_RCC_CSR & 0x00C30000) != 0x00420000) {
/* the RTC settings are bad, we need to reset it */
STM32_RCC_CSR |= 0x00800000;
/* Enable RTC and use LSI as clock source */
STM32_RCC_CSR = (STM32_RCC_CSR & ~0x00C30000) | 0x00420000;
}
+#elif defined(CHIP_VARIANT_stm32f100)
+ if ((STM32_RCC_BDCR & 0x00018300) != 0x00008200) {
+ /* the RTC settings are bad, we need to reset it */
+ STM32_RCC_BDCR |= 0x00010000;
+ /* Enable RTC and use LSI as clock source */
+ STM32_RCC_BDCR = (STM32_RCC_BDCR & ~0x00018300) | 0x00008200;
+ }
+#else
+#error "Unsupported chip variant"
+#endif
check_reset_cause();
@@ -112,7 +124,7 @@ const char *system_get_chip_vendor(void)
const char *system_get_chip_name(void)
{
- return "stm32l151r8";
+ return STRINGIFY(CHIP_VARIANT);
}
const char *system_get_chip_revision(void)
diff --git a/chip/stm32/uart.c b/chip/stm32/uart.c
index 48532474fe..82460888c9 100644
--- a/chip/stm32/uart.c
+++ b/chip/stm32/uart.c
@@ -124,6 +124,10 @@ int uart_init(void)
STM32_RCC_APB1ENR |= 1 << 17; /* USART2 */
else if (UARTN == 3)
STM32_RCC_APB1ENR |= 1 << 18; /* USART3 */
+ else if (UARTN == 4)
+ STM32_RCC_APB1ENR |= 1 << 19; /* USART4 */
+ else if (UARTN == 5)
+ STM32_RCC_APB1ENR |= 1 << 20; /* USART5 */
/* UART enabled, 8 Data bits, oversampling x16, no parity,
* RXNE interrupt, TX and RX enabled.