From 24991a4577fb3944a79313ecaed08548d9b6f59d Mon Sep 17 00:00:00 2001 From: Shuopeng Deng Date: Thu, 10 Oct 2019 18:14:30 -0500 Subject: [PATCH] Changed mbed gpio-port api to match gpio api The port configuration api was not correctly setting the port-pins' direction. Changed the port driver to call the gpio driver for configuration (read and write still are optimized for port-level operations) so that the behavior is consistent. --- .../TARGET_Cypress/TARGET_PSOC6/cy_port_api.c | 52 ++++++++++++------- .../TARGET_Cypress/TARGET_PSOC6/gpio_object.h | 4 +- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/cy_port_api.c b/targets/TARGET_Cypress/TARGET_PSOC6/cy_port_api.c index 993a4af62f..3e9bfb7d00 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/cy_port_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/cy_port_api.c @@ -16,7 +16,7 @@ */ #include "port_api.h" -#include "cy_gpio.h" +#include "gpio_api.h" #if DEVICE_PORTIN || DEVICE_PORTOUT @@ -26,47 +26,59 @@ extern "C" { void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { - obj->port = Cy_GPIO_PortToAddr(port); - obj->mask = (uint8_t)mask; - uint32_t driveMode = dir == PIN_INPUT ? CY_GPIO_DM_HIGHZ : CY_GPIO_DM_STRONG; - for (int i = 0; i < 8; i++) { - if (0 != (mask & (1 << i))) { - Cy_GPIO_Pin_FastInit(obj->port, i, driveMode, 0, HSIOM_SEL_GPIO); + gpio_t gpio; + for (uint8_t pin = 0; pin < 8; pin++) { + if ((1 << pin) & mask) { + gpio_init(&gpio, port_pin(port, pin)); + gpio_dir(&gpio, dir); } } + obj->port = port; + obj->mask = mask; + obj->drive_mode = gpio.drive_mode; + obj->direction = gpio.direction; } void port_mode(port_t *obj, PinMode mode) { - for (int i = 0; i < 8; i++) { - if (0 != (obj->mask & (1 << i))) { - uint32_t origMode = Cy_GPIO_GetDrivemode(obj->port, i); - Cy_GPIO_SetDrivemode(obj->port, i, (origMode & CY_GPIO_DM_HIGHZ) | mode); + gpio_t gpio = {.pin = 0, .direction = obj->direction, .drive_mode = obj->drive_mode}; + for (uint8_t pin = 0; pin < 8; pin++) { + if ((1 << pin) & obj->mask) { + gpio.pin = port_pin(obj->port, pin); + gpio_mode(&gpio, mode); } } } void port_dir(port_t *obj, PinDirection dir) { - for (int i = 0; i < 8; i++) { - if (0 != (obj->mask & (1 << i))) { - uint32_t origMode = Cy_GPIO_GetDrivemode(obj->port, i); - Cy_GPIO_SetDrivemode(obj->port, i, origMode == PIN_OUTPUT - ? (origMode & ~CY_GPIO_DM_HIGHZ) - : (origMode | CY_GPIO_DM_HIGHZ)); + gpio_t gpio = {.pin = 0, .direction = obj->direction, .drive_mode = obj->drive_mode}; + for (uint8_t pin = 0; pin < 8; pin++) { + if ((1 << pin) & obj->mask) { + gpio.pin = port_pin(obj->port, pin); + gpio_dir(&gpio, dir); } } } void port_write(port_t *obj, int value) { - obj->port->OUT_SET = value & obj->mask; - obj->port->OUT_CLR = (~value) & obj->mask; + GPIO_PRT_Type *port_type = Cy_GPIO_PortToAddr(obj->port); + if (obj->mask == 0xff) + { + // Optimization for when all pins on the port is used. + port_type->OUT = value; + } + else + { + port_type->OUT_SET = value & obj->mask; + port_type->OUT_CLR = (~value) & obj->mask; + } } int port_read(port_t *obj) { - return obj->port->IN & obj->mask; + return Cy_GPIO_PortToAddr(obj->port)->IN & obj->mask; } #ifdef __cplusplus diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/gpio_object.h b/targets/TARGET_Cypress/TARGET_PSOC6/gpio_object.h index b4fd3be0cd..3bfc4c3b4c 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/gpio_object.h +++ b/targets/TARGET_Cypress/TARGET_PSOC6/gpio_object.h @@ -45,8 +45,10 @@ struct gpio_irq_s { }; struct port_s { - GPIO_PRT_Type *port; + PortName port; uint8_t mask; + cyhal_gpio_direction_t direction; + cyhal_gpio_drive_mode_t drive_mode; }; /** Set the output value