From 97a49113d937774aacebd2a5c92e2e15d0e39464 Mon Sep 17 00:00:00 2001 From: David Hendricks Date: Fri, 20 Apr 2012 14:02:05 -0700 Subject: [PATCH] stm32l: clear and then set GPIO mode and pull-up/down settings GPIO mode and pull-up/down registers do not all get initialized to zero on reset. This patch ensures that all bits in the those registers are set explicitly. An intermediate variable is used so that changes are made atomically. Note: output speed registers are also not all initialized to zero, but we don't handle that in gpio_pre_init yet. BUG=none TEST=tested on newer daisy boards (which needed this patch to boot) Change-Id: Ice2795197135dcee8f8484e4908dbfcf90fec2c9 Signed-off-by: David Hendricks --- chip/stm32l/gpio.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/chip/stm32l/gpio.c b/chip/stm32l/gpio.c index 0f3e7f44a5..d56efa32d4 100644 --- a/chip/stm32l/gpio.c +++ b/chip/stm32l/gpio.c @@ -29,15 +29,17 @@ int gpio_pre_init(void) */ 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); + uint32_t val; + val = STM32L_GPIO_PUPDR_OFF(g->port) & ~mask2; if (g->flags & GPIO_PULL_UP) /* Pull Up = 01 */ - STM32L_GPIO_PUPDR_OFF(g->port) |= 0x55555555 & mask2; + val |= 0x55555555 & mask2; else if (g->flags & GPIO_PULL_DOWN) /* Pull Down = 10 */ - STM32L_GPIO_PUPDR_OFF(g->port) |= 0xaaaaaaaa & mask2; + val |= 0xaaaaaaaa & mask2; + STM32L_GPIO_PUPDR_OFF(g->port) = val; if (g->flags & GPIO_OPEN_DRAIN) STM32L_GPIO_OTYPER_OFF(g->port) |= g->mask; @@ -47,11 +49,13 @@ int gpio_pre_init(void) * potential damage, e.g. driving an open-drain output * high before it has been configured as such. */ + val = STM32L_GPIO_MODER_OFF(g->port) & ~mask2; if (g->flags & GPIO_OUTPUT) { /* General purpose, MODE = 01 */ - STM32L_GPIO_MODER_OFF(g->port) |= 0x55555555 & mask2; + val |= 0x55555555 & mask2; + STM32L_GPIO_MODER_OFF(g->port) = val; gpio_set_level(i, g->flags & GPIO_HIGH); - } else if (g->flags & GPIO_INPUT) { - STM32L_GPIO_MODER_OFF(g->port) &= ~mask2; + } else if (g->flags & GPIO_INPUT) { /* Input, MODE=00 */ + STM32L_GPIO_MODER_OFF(g->port) = val; } /* Set up interrupts if necessary */