From e03e2c9c1114a5bfe24cd59b098eaba8648c120a Mon Sep 17 00:00:00 2001 From: Antoine van Gelder Date: Wed, 18 Oct 2023 13:42:05 +0200 Subject: [PATCH] firmware: add support for configuring all gpio pin modes --- firmware/include/drivers/gpio.h | 7 ++++ firmware/platform/lpc43xx/drivers/gpio.c | 35 ++++++++++++++++++- .../lpc43xx/include/drivers/platform_gpio.h | 2 ++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/firmware/include/drivers/gpio.h b/firmware/include/drivers/gpio.h index 95ab041..d59a54d 100644 --- a/firmware/include/drivers/gpio.h +++ b/firmware/include/drivers/gpio.h @@ -27,6 +27,13 @@ int gpio_configure_pinmux(gpio_pin_t pin); int gpio_configure_pinmux_and_resistors(gpio_pin_t pin, gpio_resistor_configuration_t resistor_mode); +/** + * Configures the system's pinmux to route the given GPIO pin to a physical pin + * and apply the given pin configuration. + */ +int gpio_configure_pinmux_and_pin(gpio_pin_t pin, gpio_pin_configuration_t pin_configuration); + + /** * Configures the system's pinmux to route all possible GPIO * pins for a given port. diff --git a/firmware/platform/lpc43xx/drivers/gpio.c b/firmware/platform/lpc43xx/drivers/gpio.c index 9b91cd4..2d050f7 100644 --- a/firmware/platform/lpc43xx/drivers/gpio.c +++ b/firmware/platform/lpc43xx/drivers/gpio.c @@ -460,6 +460,39 @@ int gpio_configure_pinmux_and_resistors(gpio_pin_t pin, gpio_resistor_configurat } +/** + * Configures the system's pinmux to route the given GPIO pin to a physical pin + * and apply the given pin configuration. + * + * Note that any provided function in the pin configuration will be overridden by + * the GPIO function. + */ +int gpio_configure_pinmux_and_pin(gpio_pin_t pin, gpio_pin_configuration_t pin_configuration) +{ + uint8_t scu_group, scu_pin; + + if (validate_port_and_pin(pin)) { + return EINVAL; + } + + // Get the SCU group/pin so we can pinmux. + scu_group = gpio_get_group_number(pin); + scu_pin = gpio_get_pin_number(pin); + + // If this port/pin doesn't correspond to a valid physical pin, + // fail out. + if ((scu_group == 0xff) || (scu_pin == 0xff)) { + return EINVAL; + } + + // Select the pinmux function to apply. + pin_configuration.function = (pin.port == 5) ? 4 : 0; + + // Finally, configure the SCU. + platform_scu_configure_pin(scu_group, scu_pin, pin_configuration); + return 0; +} + /** * Configures the system's pinmux to route the given GPIO @@ -467,7 +500,7 @@ int gpio_configure_pinmux_and_resistors(gpio_pin_t pin, gpio_resistor_configurat */ int gpio_configure_pinmux(gpio_pin_t pin) { - gpio_configure_pinmux_and_resistors(pin, SCU_NO_PULL); + return gpio_configure_pinmux_and_resistors(pin, SCU_NO_PULL); } diff --git a/firmware/platform/lpc43xx/include/drivers/platform_gpio.h b/firmware/platform/lpc43xx/include/drivers/platform_gpio.h index 451b463..76bf939 100644 --- a/firmware/platform/lpc43xx/include/drivers/platform_gpio.h +++ b/firmware/platform/lpc43xx/include/drivers/platform_gpio.h @@ -16,6 +16,8 @@ // For LPCxx devices, use the SCU resistor configuration as the GPIO resistor configuration. typedef scu_resistor_configuration_t gpio_resistor_configuration_t; +// For LPCxx devices, use the SCU pin register block as the GPIO pin configuration. +typedef platform_scu_pin_register_t gpio_pin_configuration_t; // Describe the chip's GPIO capabilities. #define GPIO_MAX_PORTS 6