diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2012-02-02 23:44:30 +0000 |
---|---|---|
committer | Vincent Palatin <vpalatin@chromium.org> | 2012-02-03 02:00:27 +0000 |
commit | 54f36995a4b626280b868f1efe6049591f3fc53c (patch) | |
tree | f97716aa89d2eb812de3efd8104930f75080663b /chip | |
parent | b2b6eb46b32826386e8ab16ed623a6927df043da (diff) | |
download | chrome-ec-54f36995a4b626280b868f1efe6049591f3fc53c.tar.gz |
stm32l: basic GPIO support
No interrupt support yet.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=None
TEST=on Discovery EC console, using "gpioget" and "gpioset" commands
check we can switch the LED and read the button state.
Change-Id: I01294643d3df070a535dab5a6be02c296487fca5
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32l/build.mk | 2 | ||||
-rw-r--r-- | chip/stm32l/gpio.c | 69 | ||||
-rw-r--r-- | chip/stm32l/registers.h | 18 | ||||
-rw-r--r-- | chip/stm32l/watchdog.c | 6 |
4 files changed, 90 insertions, 5 deletions
diff --git a/chip/stm32l/build.mk b/chip/stm32l/build.mk index bb354c2f92..6f7c8bcda1 100644 --- a/chip/stm32l/build.mk +++ b/chip/stm32l/build.mk @@ -8,5 +8,5 @@ # STM32L15xx SoC family has a Cortex-M3 ARM core CORE:=cortex-m -chip-y=uart.o clock.o hwtimer.o system.o +chip-y=uart.o clock.o hwtimer.o system.o gpio.o chip-$(CONFIG_TASK_WATCHDOG)+=watchdog.o diff --git a/chip/stm32l/gpio.c b/chip/stm32l/gpio.c new file mode 100644 index 0000000000..56d22abf62 --- /dev/null +++ b/chip/stm32l/gpio.c @@ -0,0 +1,69 @@ +/* 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 "gpio.h" +#include "registers.h" +#include "task.h" + +/* Signal information from board.c. Must match order from enum gpio_signal. */ +extern const struct gpio_info gpio_list[GPIO_COUNT]; + + +int gpio_pre_init(void) +{ + const struct gpio_info *g = gpio_list; + int i; + + /* Enable all GPIOs clocks + * TODO: more fine-grained enabling for power saving + */ + STM32L_RCC_AHBENR |= 0x3f; + + /* Set all GPIOs to defaults */ + for (i = 0; i < GPIO_COUNT; i++, g++) { + /* bitmask for registers with 2 bits per GPIO pin */ + uint32_t mask2 = (g->mask * g->mask) | (g->mask * g->mask * 2); + + if (g->flags & GPIO_OUTPUT) { + /* Set pin level */ + gpio_set_level(i, g->flags & GPIO_HIGH); + /* General purpose output : MODE = 01 */ + STM32L_GPIO_MODER_OFF(g->port) |= 0x55555555 & mask2; + } else { + /* Input */ + STM32L_GPIO_MODER_OFF(g->port) &= ~mask2; + if (g->flags & GPIO_PULL) { + /* With pull up/down */ + if (g->flags & GPIO_HIGH) /* Pull Up = 01 */ + STM32L_GPIO_PUPDR_OFF(g->port) |= + 0x55555555 & mask2; + else /* Pull Down = 10 */ + STM32L_GPIO_PUPDR_OFF(g->port) |= + 0xaaaaaaaa & mask2; + } + } + } + + return EC_SUCCESS; +} + + +int gpio_get_level(enum gpio_signal signal) +{ + return !!(STM32L_GPIO_IDR_OFF(gpio_list[signal].port) & + gpio_list[signal].mask); +} + + +int gpio_set_level(enum gpio_signal signal, int value) +{ + STM32L_GPIO_BSRR_OFF(gpio_list[signal].port) = + gpio_list[signal].mask << (value ? 0 : 16); + + return EC_SUCCESS; +} diff --git a/chip/stm32l/registers.h b/chip/stm32l/registers.h index 6e9fc9e0c5..23bad85a44 100644 --- a/chip/stm32l/registers.h +++ b/chip/stm32l/registers.h @@ -125,6 +125,13 @@ #define STM32L_GPIOE_BASE 0x40021000 #define STM32L_GPIOH_BASE 0x40021400 +#define GPIO_A STM32L_GPIOA_BASE +#define GPIO_B STM32L_GPIOB_BASE +#define GPIO_C STM32L_GPIOC_BASE +#define GPIO_D STM32L_GPIOD_BASE +#define GPIO_E STM32L_GPIOE_BASE +#define GPIO_H STM32L_GPIOH_BASE + #define STM32L_GPIO_REG32(l, offset) \ REG32(STM32L_CAT(STM32L_GPIO, l, _BASE) + (offset)) #define STM32L_GPIO_REG16(l, offset) \ @@ -141,6 +148,17 @@ #define STM32L_GPIO_AFRL(l) STM32L_GPIO_REG32(l, 0x20) #define STM32L_GPIO_AFRH(l) STM32L_GPIO_REG32(l, 0x24) +#define STM32L_GPIO_MODER_OFF(b) REG32((b) + 0x00) +#define STM32L_GPIO_OTYPER_OFF(b) REG16((b) + 0x04) +#define STM32L_GPIO_OSPEEDR_OFF(b) REG32((b) + 0x08) +#define STM32L_GPIO_PUPDR_OFF(b) REG32((b) + 0x0C) +#define STM32L_GPIO_IDR_OFF(b) REG16((b) + 0x10) +#define STM32L_GPIO_ODR_OFF(b) REG16((b) + 0x14) +#define STM32L_GPIO_BSRR_OFF(b) REG32((b) + 0x18) +#define STM32L_GPIO_LCKR_OFF(b) REG32((b) + 0x1C) +#define STM32L_GPIO_AFRL_OFF(b) REG32((b) + 0x20) +#define STM32L_GPIO_AFRH_OFF(b) REG32((b) + 0x24) + /* --- I2C --- */ #define STM32L_I2C1_BASE 0x40005400 #define STM32L_I2C2_BASE 0x40005800 diff --git a/chip/stm32l/watchdog.c b/chip/stm32l/watchdog.c index 114c3e9211..4a1cd7f6d2 100644 --- a/chip/stm32l/watchdog.c +++ b/chip/stm32l/watchdog.c @@ -60,14 +60,12 @@ void watchdog_task(void) { while (1) { #ifdef BOARD_discovery - /* TODO use GPIO API: gpio_set_level(GPIO_GREEN_LED, 1); */ - STM32L_GPIO_ODR(B) |= (1 << 7) ; + gpio_set_level(GPIO_GREEN_LED, 1); #endif usleep(500000); watchdog_reload(); #ifdef BOARD_discovery - /* TODO use GPIO API: gpio_set_level(GPIO_GREEN_LED, 0); */ - STM32L_GPIO_ODR(B) &= ~(1 << 7) ; + gpio_set_level(GPIO_GREEN_LED, 0); #endif usleep(500000); watchdog_reload(); |