diff options
author | Nick Sanders <nsanders@chromium.org> | 2016-04-13 22:15:02 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-27 14:04:07 -0700 |
commit | 4e52ae607c569e9d240e3ce3363659c840f1aa87 (patch) | |
tree | 6824faac11c4b35ebce8599f41e39c28351eb816 /chip/stm32/gpio-f0-l.c | |
parent | d18cb0e81f2ba3c71349d17c7d84e7e10066711e (diff) | |
download | chrome-ec-4e52ae607c569e9d240e3ce3363659c840f1aa87.tar.gz |
servo_micro: add gpio mode get and set
GPIO console commands currently only show input voltage level,
and can only set level on predefined outputs.
This change allows GPIOs to be cycled between output, input,
and alternate function, as well as displaying the mode and
asserted level (if any) in gpioget.
This change creates CONFIG_CMD_GPIO_EXTENDED
as the internal gpio interface needs to be changed to support
this, and I can't test the other architectures. It may be
worthwhile to add this for all, or not.
This change is also necessary also for servo micro JTAG and PD
UART support, as several pins are tied together on the flex
and stm32 outputs need to be variously active or in high-z
depending on mode.
BUG=chromium:571477
TEST=gpioget <0|1|IN|A|ALT>; gpioget;
BRANCH=None
Change-Id: Iba32992db6244ee1e654db840d1c9c11dd2a0993
Signed-off-by: Nick Sanders <nsanders@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/338885
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'chip/stm32/gpio-f0-l.c')
-rw-r--r-- | chip/stm32/gpio-f0-l.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/chip/stm32/gpio-f0-l.c b/chip/stm32/gpio-f0-l.c index df45c15aa5..4c026cc767 100644 --- a/chip/stm32/gpio-f0-l.c +++ b/chip/stm32/gpio-f0-l.c @@ -24,6 +24,53 @@ static uint32_t expand_to_2bit_mask(uint32_t mask) return mask_out; } +int gpio_get_flags_by_mask(uint32_t port, uint32_t mask) +{ + uint32_t flags = 0; + uint32_t val = 0; + const uint32_t mask2 = expand_to_2bit_mask(mask); + + /* Only one bit must be set. */ + if ((mask != (mask & -mask)) || (mask == 0)) + return 0; + + /* Check output type. */ + val = STM32_GPIO_PUPDR(port) & mask2; + if (val == (0x55555555 & mask2)) + flags |= GPIO_PULL_UP; + if (val == (0xaaaaaaaa & mask2)) + flags |= GPIO_PULL_DOWN; + + if (STM32_GPIO_OTYPER(port) & mask) + flags |= GPIO_OPEN_DRAIN; + + /* Check mode. */ + val = STM32_GPIO_MODER(port) & mask2; + if (val == (0x55555555 & mask2)) + flags |= GPIO_OUTPUT; + if (val == (0xFFFFFFFF & mask2)) + flags |= GPIO_ANALOG; + if (val == (0x0 & mask2)) + flags |= GPIO_INPUT; + if (val == (0xaaaaaaaa & mask2)) + flags |= GPIO_ALTERNATE; + + if (flags & GPIO_OUTPUT) { + if (STM32_GPIO_ODR(port) & mask) + flags |= GPIO_HIGH; + else + flags |= GPIO_LOW; + } + + + if (STM32_EXTI_RTSR & mask) + flags |= GPIO_INT_F_RISING; + if (STM32_EXTI_RTSR & mask) + flags |= GPIO_INT_F_RISING; + + return flags; +} + void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) { /* Bitmask for registers with 2 bits per GPIO pin */ @@ -70,6 +117,10 @@ void gpio_set_flags_by_mask(uint32_t port, uint32_t mask, uint32_t flags) } else if (flags & GPIO_INPUT) { /* Input, MODE=00 */ STM32_GPIO_MODER(port) = val; + } else if (flags & GPIO_ALTERNATE) { + /* Alternate, MODE=10 */ + val |= 0xaaaaaaaa & mask2; + STM32_GPIO_MODER(port) = val; } /* Set up interrupts if necessary */ |