diff --git a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts index f02b9f3e8e7..b1a53115c70 100644 --- a/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts +++ b/boards/arm/cc1352r1_launchxl/cc1352r1_launchxl.dts @@ -9,7 +9,7 @@ #include #include "boosterpack_connector.dtsi" -#define BTN_GPIO_FLAGS (GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP) +#define BTN_GPIO_FLAGS (GPIO_ACTIVE_LOW | GPIO_PULL_UP) / { model = "TI CC1352R1 LaunchXL"; @@ -32,11 +32,11 @@ leds { compatible = "gpio-leds"; led0: led_0 { - gpios = <&gpio0 7 0>; + gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; label = "Green LED"; }; led1: led_1 { - gpios = <&gpio0 6 0>; + gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; label = "Red LED"; }; }; diff --git a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts index 2c4d86d9c59..21ee3683fd4 100644 --- a/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts +++ b/boards/arm/cc26x2r1_launchxl/cc26x2r1_launchxl.dts @@ -9,7 +9,7 @@ #include #include "boosterpack_connector.dtsi" -#define BTN_GPIO_FLAGS (GPIO_INT_ACTIVE_LOW | GPIO_PUD_PULL_UP) +#define BTN_GPIO_FLAGS (GPIO_ACTIVE_LOW | GPIO_PULL_UP) / { model = "TI CC26x2R1 LaunchXL"; @@ -32,11 +32,11 @@ leds { compatible = "gpio-leds"; led0: led_0 { - gpios = <&gpio0 7 0>; + gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; label = "Green LED"; }; led1: led_1 { - gpios = <&gpio0 6 0>; + gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; label = "Red LED"; }; }; diff --git a/drivers/gpio/gpio_cc13xx_cc26xx.c b/drivers/gpio/gpio_cc13xx_cc26xx.c index 63656e3cda2..7a40642e90c 100644 --- a/drivers/gpio/gpio_cc13xx_cc26xx.c +++ b/drivers/gpio/gpio_cc13xx_cc26xx.c @@ -17,6 +17,12 @@ #include "gpio_utils.h" +/* bits 16-18 in iocfg registers correspond to interrupt settings */ +#define IOCFG_INT_MASK 0x00070000 + +/* the rest are for general (non-interrupt) config */ +#define IOCFG_GEN_MASK (~IOCFG_INT_MASK) + struct gpio_cc13xx_cc26xx_data { /* gpio_driver_data needs to be first */ struct gpio_driver_data common; @@ -26,10 +32,15 @@ struct gpio_cc13xx_cc26xx_data { static struct gpio_cc13xx_cc26xx_data gpio_cc13xx_cc26xx_data_0; +static int gpio_cc13xx_cc26xx_port_set_bits_raw(struct device *port, + u32_t mask); +static int gpio_cc13xx_cc26xx_port_clear_bits_raw(struct device *port, + u32_t mask); + static int gpio_cc13xx_cc26xx_config(struct device *port, int access_op, u32_t pin, int flags) { - u32_t config; + u32_t config = 0; if (access_op != GPIO_ACCESS_BY_PIN) { return -ENOTSUP; @@ -37,37 +48,26 @@ static int gpio_cc13xx_cc26xx_config(struct device *port, int access_op, __ASSERT_NO_MSG(pin < NUM_IO_MAX); - config = IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | IOC_SLEW_DISABLE | - IOC_NO_WAKE_UP; - - if (flags & GPIO_INT) { - __ASSERT_NO_MSG((flags & GPIO_DIR_MASK) == GPIO_DIR_IN); - - config |= IOC_INT_ENABLE | IOC_INPUT_ENABLE; - - if (flags & GPIO_INT_EDGE) { - if (flags & GPIO_INT_DOUBLE_EDGE) { - config |= IOC_BOTH_EDGES; - } else if (flags & GPIO_INT_ACTIVE_HIGH) { - config |= IOC_RISING_EDGE; - } else { /* GPIO_INT_ACTIVE_LOW */ - config |= IOC_FALLING_EDGE; - } - } else { - return -ENOTSUP; - } - - config |= (flags & GPIO_INT_DEBOUNCE) ? IOC_HYST_ENABLE : - IOC_HYST_DISABLE; - } else { - config |= IOC_INT_DISABLE | IOC_NO_EDGE | IOC_HYST_DISABLE; - config |= (flags & GPIO_DIR_MASK) == GPIO_DIR_IN ? - IOC_INPUT_ENABLE : - IOC_INPUT_DISABLE; + switch (flags & (GPIO_INPUT | GPIO_OUTPUT)) { + case GPIO_INPUT: + config = IOC_INPUT_ENABLE; + break; + case GPIO_OUTPUT: + config = IOC_INPUT_DISABLE; + break; + case 0: /* disconnected */ + IOCPortConfigureSet(pin, IOC_PORT_GPIO, IOC_NO_IOPULL); + GPIO_setOutputEnableDio(pin, GPIO_OUTPUT_DISABLE); + return 0; + default: + return -ENOTSUP; } - config |= (flags & GPIO_POL_MASK) == GPIO_POL_INV ? IOC_IOMODE_INV : - IOC_IOMODE_NORMAL; + config |= IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | IOC_SLEW_DISABLE | + IOC_NO_WAKE_UP; + + config |= (flags & GPIO_INT_DEBOUNCE) ? IOC_HYST_ENABLE : + IOC_HYST_DISABLE; switch (flags & GPIO_PUD_MASK) { case GPIO_PUD_NORMAL: @@ -83,12 +83,18 @@ static int gpio_cc13xx_cc26xx_config(struct device *port, int access_op, return -EINVAL; } + config |= IOCPortConfigureGet(pin) & IOCFG_INT_MASK; IOCPortConfigureSet(pin, IOC_PORT_GPIO, config); - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - GPIO_setOutputEnableDio(pin, GPIO_OUTPUT_DISABLE); - } else { + if ((flags & GPIO_OUTPUT) != 0) { + if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) { + gpio_cc13xx_cc26xx_port_set_bits_raw(port, BIT(pin)); + } else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) { + gpio_cc13xx_cc26xx_port_clear_bits_raw(port, BIT(pin)); + } GPIO_setOutputEnableDio(pin, GPIO_OUTPUT_ENABLE); + } else { + GPIO_setOutputEnableDio(pin, GPIO_OUTPUT_DISABLE); } return 0; @@ -140,6 +146,80 @@ static int gpio_cc13xx_cc26xx_read(struct device *port, int access_op, return 0; } +static int gpio_cc13xx_cc26xx_port_get_raw(struct device *port, u32_t *value) +{ + __ASSERT_NO_MSG(value != NULL); + + *value = GPIO_readMultiDio(GPIO_DIO_ALL_MASK); + + return 0; +} + +static int gpio_cc13xx_cc26xx_port_set_masked_raw(struct device *port, + u32_t mask, u32_t value) +{ + GPIO_setMultiDio(mask & value); + GPIO_clearMultiDio(mask & ~value); + + return 0; +} + +static int gpio_cc13xx_cc26xx_port_set_bits_raw(struct device *port, u32_t mask) +{ + GPIO_setMultiDio(mask); + + return 0; +} + +static int gpio_cc13xx_cc26xx_port_clear_bits_raw(struct device *port, + u32_t mask) +{ + GPIO_clearMultiDio(mask); + + return 0; +} + +static int gpio_cc13xx_cc26xx_port_toggle_bits(struct device *port, u32_t mask) +{ + GPIO_toggleMultiDio(mask); + + return 0; +} + +static int gpio_cc13xx_cc26xx_pin_interrupt_configure(struct device *port, + unsigned int pin, enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + struct gpio_cc13xx_cc26xx_data *data = port->driver_data; + u32_t config = 0; + + if (mode != GPIO_INT_MODE_DISABLED) { + if (mode == GPIO_INT_MODE_EDGE) { + if (trig == GPIO_INT_TRIG_BOTH) { + config |= IOC_BOTH_EDGES; + } else if (trig == GPIO_INT_TRIG_HIGH) { + config |= IOC_RISING_EDGE; + } else { /* GPIO_INT_TRIG_LOW */ + config |= IOC_FALLING_EDGE; + } + } else { + return -ENOTSUP; + } + + config |= IOC_INT_ENABLE; + } else { + config |= IOC_INT_DISABLE | IOC_NO_EDGE; + } + + config |= IOCPortConfigureGet(pin) & IOCFG_GEN_MASK; + IOCPortConfigureSet(pin, IOC_PORT_GPIO, config); + + WRITE_BIT(data->pin_callback_enables, pin, + mode != GPIO_INT_MODE_DISABLED); + + return 0; +} + static int gpio_cc13xx_cc26xx_manage_callback(struct device *port, struct gpio_callback *callback, bool set) @@ -247,6 +327,12 @@ static const struct gpio_driver_api gpio_cc13xx_cc26xx_driver_api = { .config = gpio_cc13xx_cc26xx_config, .write = gpio_cc13xx_cc26xx_write, .read = gpio_cc13xx_cc26xx_read, + .port_get_raw = gpio_cc13xx_cc26xx_port_get_raw, + .port_set_masked_raw = gpio_cc13xx_cc26xx_port_set_masked_raw, + .port_set_bits_raw = gpio_cc13xx_cc26xx_port_set_bits_raw, + .port_clear_bits_raw = gpio_cc13xx_cc26xx_port_clear_bits_raw, + .port_toggle_bits = gpio_cc13xx_cc26xx_port_toggle_bits, + .pin_interrupt_configure = gpio_cc13xx_cc26xx_pin_interrupt_configure, .manage_callback = gpio_cc13xx_cc26xx_manage_callback, .enable_callback = gpio_cc13xx_cc26xx_enable_callback, .disable_callback = gpio_cc13xx_cc26xx_disable_callback,