diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-05-01 22:23:57 +0000 |
---|---|---|
committer | Vincent Palatin <vpalatin@chromium.org> | 2012-05-01 17:13:33 -0700 |
commit | cab258137b41e63c78d765883019a3b7c1540692 (patch) | |
tree | b836929a7ac1af6ecc4c9ca0286673b576ec18e9 | |
parent | a9ceb116c7c047bfb076e1c69bcc0587cd79ac2a (diff) | |
download | chrome-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.mk | 3 | ||||
-rw-r--r-- | chip/stm32/clock-stm32f100.c | 51 | ||||
-rw-r--r-- | chip/stm32/clock-stm32l15x.c (renamed from chip/stm32/clock.c) | 0 | ||||
-rw-r--r-- | chip/stm32/config-stm32f100.h | 26 | ||||
-rw-r--r-- | chip/stm32/config.h | 4 | ||||
-rw-r--r-- | chip/stm32/dma.c | 2 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32f100.c | 237 | ||||
-rw-r--r-- | chip/stm32/gpio-stm32l15x.c (renamed from chip/stm32/gpio.c) | 0 | ||||
-rw-r--r-- | chip/stm32/jtag-stm32f100.c | 16 | ||||
-rw-r--r-- | chip/stm32/jtag-stm32l15x.c (renamed from chip/stm32/jtag.c) | 0 | ||||
-rw-r--r-- | chip/stm32/registers.h | 208 | ||||
-rw-r--r-- | chip/stm32/system.c | 14 | ||||
-rw-r--r-- | chip/stm32/uart.c | 4 |
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. |