From ed85ff76233ff6c770f655382c0baec4de619c6c Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Tue, 4 Dec 2018 18:39:55 -0600 Subject: [PATCH 1/7] drivers: gpio: fix misuse of u8_t where bool is intended GPIO configuration flags will move and some that used to be in the low 8 bits are now higher, resulting in implicit constant conversion overflows. Use a boolean data type to hold boolean values. Signed-off-by: Peter A. Bigot --- drivers/gpio/gpio_dw.c | 2 +- drivers/gpio/gpio_qmsi.c | 2 +- drivers/gpio/gpio_qmsi_ss.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio_dw.c b/drivers/gpio/gpio_dw.c index 2706b399d72ee..5cb33818d44ef 100644 --- a/drivers/gpio/gpio_dw.c +++ b/drivers/gpio/gpio_dw.c @@ -154,7 +154,7 @@ static inline void dw_interrupt_config(struct device *port, int access_op, struct gpio_dw_runtime *context = port->driver_data; const struct gpio_dw_config *config = port->config->config_info; u32_t base_addr = dw_base_to_block_base(context->base_addr); - u8_t flag_is_set; + bool flag_is_set; ARG_UNUSED(access_op); diff --git a/drivers/gpio/gpio_qmsi.c b/drivers/gpio/gpio_qmsi.c index 1db10b9ad498f..f8213d890ff01 100644 --- a/drivers/gpio/gpio_qmsi.c +++ b/drivers/gpio/gpio_qmsi.c @@ -171,7 +171,7 @@ static void gpio_qmsi_callback(void *data, u32_t status) } } -static void qmsi_write_bit(u32_t *target, u8_t bit, u8_t value) +static void qmsi_write_bit(u32_t *target, u8_t bit, bool value) { if (value) { sys_set_bit((uintptr_t) target, bit); diff --git a/drivers/gpio/gpio_qmsi_ss.c b/drivers/gpio/gpio_qmsi_ss.c index f17588603756e..61d81d81a833b 100644 --- a/drivers/gpio/gpio_qmsi_ss.c +++ b/drivers/gpio/gpio_qmsi_ss.c @@ -143,7 +143,7 @@ static void ss_gpio_qmsi_callback(void *data, uint32_t status) } } -static void ss_qmsi_write_bit(u32_t *target, u8_t bit, u8_t value) +static void ss_qmsi_write_bit(u32_t *target, u8_t bit, bool value) { if (value) { sys_set_bit((uintptr_t) target, bit); From c3d89364aa3e45eca9f499cce4eb9f9442c137e4 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Wed, 5 Dec 2018 06:47:19 -0600 Subject: [PATCH 2/7] dt-bindings: gpio: revise flags to support more complete control Updated GPIO constants to provide more meaningful names and more complete functionality. The intent is that the presence and interpretation of existing flags remains unchanged, although their bitwise representations has. Added signal type and direction flags matching Linux device tree bindings, allowing open drain and open source to be distinguished from push-pull signals. Extended GPIO_DIR to support bidirectional configuration and setting an initial value for outputs. Extended GPIO_INT to more clearly identify level and edge configurations. Some redundancy is required to continue supporting the existing single-bit GPIO_INT_DOUBLE_EDGE flag. GPIO_INT_ACTIVE_foo renamed to GPIO_ACTIVE_foo since active level is meaningful for non-interrupt inputs and output signals (e.g. RESETn is an active low output). GPIO_INT_DEBOUNCE similarly renamed to GPIO_DEBOUNCE as debounce applies to non-interrupt inputs. The legacy macros are retained with their original values to avoid the need for a global substitution change. Other flags have changed bit representations but not interpretation. Closes #10339 Signed-off-by: Peter A. Bigot --- include/dt-bindings/gpio/gpio.h | 398 ++++++++++++++++++++++++++------ 1 file changed, 333 insertions(+), 65 deletions(-) diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index c365d449e347b..febe49924b6c7 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -1,112 +1,325 @@ /* * Copyright (c) 2018 Linaro Limited + * Copyright (c) 2018 Peter Bigot Consulting, LLC * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ - /** - * @name GPIO direction flags - * The `GPIO_DIR_*` flags are used with `gpio_pin_configure` or `gpio_port_configure`, - * to specify whether a GPIO pin will be used for input or output. + * @name GPIO active level indicator. + * + * The `GPIO_ACTIVE_*` flags indicate the level at which a + * corresponding gpio is considered active, e.g. whether an LED is lit + * with a low or high output, or a button is pressed with a low or + * high input. + * * @{ */ -/** GPIO pin to be input. */ -#define GPIO_DIR_IN (0 << 0) +/** @cond INTERNAL_HIDDEN */ +#define GPIO_ACTIVE_SHIFT 0 +#define GPIO_ACTIVE_MASK (1 << GPIO_ACTIVE_SHIFT) +/** @endcond */ -/** GPIO pin to be output. */ -#define GPIO_DIR_OUT (1 << 0) +/** GPIO pin indicates active in high state. */ +#define GPIO_ACTIVE_HIGH (0 << GPIO_ACTIVE_SHIFT) +/** GPIO pin indicates active in low state. */ +#define GPIO_ACTIVE_LOW (1 << GPIO_ACTIVE_SHIFT) + +/** + * @name GPIO signaling method and line role. + * + * These flags are components used to distinguish `GPIO_OPEN_DRAIN`, + * `GPIO_OPEN_SOURCE`, and `GPIO_PUSH_PULL`. + * + * @{ + */ /** @cond INTERNAL_HIDDEN */ -#define GPIO_DIR_MASK 0x1 +#define GPIO_OPEN_SHIFT 1 +#define GPIO_SIGNALING_SHIFT GPIO_OPEN_SHIFT +#define GPIO_SIGNALING_MASK (1 << GPIO_SIGNALING_SHIFT) +#define GPIO_LINE_SHIFT (GPIO_OPEN_SHIFT + 1) +#define GPIO_LINE_MASK (1 << GPIO_LINE_SHIFT) +#define GPIO_OPEN_MASK (GPIO_SIGNALING_MASK | GPIO_LINE_MASK) /** @endcond */ + +/** GPIO uses differential signaling. */ +#define GPIO_PUSH_PULL (0 << GPIO_SIGNALING_SHIFT) + +/** GPIO uses single-ended signaling. */ +#define GPIO_SINGLE_ENDED (1 << GPIO_SIGNALING_SHIFT) + +/** GPIO is source for signal. */ +#define GPIO_LINE_SOURCE (0 << GPIO_LINE_SHIFT) + +/** GPIO is drain for signal. */ +#define GPIO_LINE_DRAIN (1 << GPIO_LINE_SHIFT) + +/** GPIO is an open-source/emitter. */ +#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_SOURCE) + +/** GPIO is an open-drain/collector. */ +#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_DRAIN) + /** @} */ +/** + * @name GPIO pull flags + * The `GPIO_PUD_*` flags are used with `gpio_pin_configure` or + * `gpio_port_configure`, to specify the pull-up or pull-down + * electrical configuration of a GPIO pin. + * + * @{ + */ +/** @cond INTERNAL_HIDDEN */ +#define GPIO_PUD_SHIFT 3 +#define GPIO_PUD_MASK (3 << GPIO_PUD_SHIFT) +/** @endcond */ + +/** Pin is neither pull-up nor pull-down. */ +#define GPIO_PUD_NORMAL (0 << GPIO_PUD_SHIFT) + +/** Enable GPIO pin pull-up. */ +#define GPIO_PUD_PULL_UP (1 << GPIO_PUD_SHIFT) + +/** Enable GPIO pin pull-down. */ +#define GPIO_PUD_PULL_DOWN (2 << GPIO_PUD_SHIFT) + +/** @} */ /** - * @name GPIO interrupt flags - * The `GPIO_INT_*` flags are used with `gpio_pin_configure` or `gpio_port_configure`, - * to specify how input GPIO pins will trigger interrupts. + * @name GPIO input/output configuration. + * The `GPIO_IO_*` flags are used with `gpio_pin_configure` or + * `gpio_port_configure`, to specify whether a GPIO pin will be used + * for input and/or output and the initial state for output. + * + * The `GPIO_DIR_*` values derived from these flags may be more + * convenient. + * * @{ */ -/** GPIO pin to trigger interrupt. */ -#define GPIO_INT (1 << 1) +/** @cond INTERNAL_HIDDEN */ +#define GPIO_IO_SHIFT 5 +#define GPIO_IO_MASK (0x0F << GPIO_IO_SHIFT) +/** @endcond */ -/** GPIO pin trigger on level low or falling edge. */ -#define GPIO_INT_ACTIVE_LOW (0 << 2) +/** + * Mask to isolate the `GPIO_IO_IN_ENABLED` and `GPIO_IO_OUT_ENABLED` + * flags. + */ +#define GPIO_DIR_MASK (0x03 << GPIO_IO_SHIFT) -/** GPIO pin trigger on level high or rising edge. */ -#define GPIO_INT_ACTIVE_HIGH (1 << 2) +/** + * Mask to isolate the `GPIO_IO_INIT_LOW` and `GPIO_IO_INIT_HIGH` + * flags. + */ +#define GPIO_IO_INIT_MASK (1 << (GPIO_IO_SHIFT + 3)) -/** Enable GPIO pin debounce. */ -#define GPIO_INT_DEBOUNCE (1 << 4) +/** GPIO pin input is connected (i.e. read should work). */ +#define GPIO_IO_IN_ENABLED (1 << GPIO_IO_SHIFT) -/** Do Level trigger. */ -#define GPIO_INT_LEVEL (0 << 5) +/** GPIO pin output is enabled (i.e. write should work). */ +#define GPIO_IO_OUT_ENABLED (1 << (GPIO_IO_SHIFT + 1)) -/** Do Edge trigger. */ -#define GPIO_INT_EDGE (1 << 5) +/** + * GPIO pin output is to be initialized simultaneous with + * configuration. + */ +#define GPIO_IO_INIT_ENABLED (1 << (GPIO_IO_SHIFT + 2)) -/** Interrupt triggers on both rising and falling edge. - * Must be combined with GPIO_INT_EDGE. +/** + * GPIO pin output is driven low at configuration. + * + * Flag is applied only if `GPIO_IO_INIT_ENABLED` is set. + */ +#define GPIO_IO_INIT_LOW (0 << (GPIO_IO_SHIFT + 3)) + +/** + * GPIO pin output is driven high at configuration. + * + * Flag is applied only if `GPIO_IO_INIT_ENABLED` is set. + */ +#define GPIO_IO_INIT_HIGH (1 << (GPIO_IO_SHIFT + 3)) + +/** GPIO pin configured as input only. */ +#define GPIO_DIR_IN GPIO_IO_IN_ENABLED + +/** GPIO pin configured as output with no change to output state. */ +#define GPIO_DIR_OUT GPIO_IO_OUT_ENABLED + +/** GPIO pin configured as output low. + * + * Where configuration is not atomic the output value should be set + * before the pin is configured to drive the output. */ -#define GPIO_INT_DOUBLE_EDGE (1 << 6) +#define GPIO_DIR_OUT_LOW (GPIO_IO_OUT_ENABLED \ + | GPIO_IO_INIT_ENABLED \ + | GPIO_IO_INIT_LOW) + +/** GPIO pin configured as output high. + * + * Where configuration is not atomic the output value should be set + * before the pin is configured to drive the output. + */ +#define GPIO_DIR_OUT_HIGH (GPIO_IO_OUT_ENABLED \ + | GPIO_IO_INIT_ENABLED \ + | GPIO_IO_INIT_HIGH) /** @} */ /** - * @name GPIO polarity flags - * The `GPIO_POL_*` flags are used with `gpio_pin_configure` or `gpio_port_configure`, - * to specify the polarity of a GPIO pin. + * @name GPIO interrupt flags + * + * The `GPIO_INT_*` flags are used with `gpio_pin_configure` or + * `gpio_port_configure`, to specify how input GPIO pins will trigger + * interrupts. + * * @{ */ /** @cond INTERNAL_HIDDEN */ -#define GPIO_POL_POS 7 +#define GPIO_INT_SHIFT 9 +#define GPIO_INT_MASK (0x1F << GPIO_INT_SHIFT) /** @endcond */ -/** GPIO pin polarity is normal. */ -#define GPIO_POL_NORMAL (0 << GPIO_POL_POS) +/** Mask to isolate the `GPIO_INT_LEVEL` and `GPIO_INT_EDGE` flags. */ +#define GPIO_INT_TRIGGER_MASK (0x01 << (GPIO_INT_SHIFT + 1)) -/** GPIO pin polarity is inverted. */ -#define GPIO_POL_INV (1 << GPIO_POL_POS) +/** Mask to isolate the `GPIO_INT_LOW` and `GPIO_INT_HIGH` flags. */ +#define GPIO_INT_DIR_MASK (0x03 << (GPIO_INT_SHIFT + 2)) -/** @cond INTERNAL_HIDDEN */ -#define GPIO_POL_MASK (1 << GPIO_POL_POS) -/** @endcond */ -/** @} */ +/** GPIO pin causes interrupt. + * + * This is a component flag that should be combined with other + * `GPIO_INT_*` flags to produce a meaningful configuration. + */ +#define GPIO_INT_ENABLE (1 << GPIO_INT_SHIFT) +/** Trigger detection when signal is observed to be at a particular + * level. + * + * This is a component flag that should be combined with other + * `GPIO_INT_*` flags to produce a meaningful configuration. Isolate + * using `GPIO_INT_TRIGGER_MASK`. + */ +#define GPIO_INT_LEVEL (0 << (GPIO_INT_SHIFT + 1)) + +/** Trigger detection when a signal is observed to change level. + * + * This is a component flag that should be combined with other + * `GPIO_INT_*` flags to produce a meaningful configuration. Isolate + * using `GPIO_INT_TRIGGER_MASK`. + */ +#define GPIO_INT_EDGE (1 << (GPIO_INT_SHIFT + 1)) + +/** Trigger detection when input state is (or transitions to) low. + * + * This is a component flag that should be combined with other + * `GPIO_INT_*` flags to produce a meaningful configuration. Isolate + * using `GPIO_INT_DIR_MASK`. + * + * This bit may be combined `GPIO_INT_HIGH` to sense both states + * (generally with `GPIO_INT_EDGE`). + */ +#define GPIO_INT_LOW (1 << (GPIO_INT_SHIFT + 2)) + +/** Trigger detection on input state is (or transitions to) high. + * + * This is a component flag that should be combined with other + * `GPIO_INT_*` flags to produce a meaningful configuration. Isolate + * using `GPIO_INT_DIR_MASK`. + * + * This bit may be combined `GPIO_INT_LOW` to sense both states + * (generally with `GPIO_INT_EDGE`). + */ +#define GPIO_INT_HIGH (1 << (GPIO_INT_SHIFT + 3)) + +/** Interrupt triggers on both rising and falling edge. + * + * This is a component flag that should be combined with other + * `GPIO_INT_*` flags to produce a meaningful configuration. + * + * For compatibility with old code this should be combined with + * `GPIO_INT_EDGE`. + * + * For compatibility with new code this should be combined with both + * `GPIO_INT_LOW` and `GPIO_INT_HIGH`. Updated driver code should + * prefer to check the individual flags. + * + * @deprecated Replace tests with a check that flags masked by + * `GPIO_INT_DIR_MASK` is equal to `GPIO_INT_LOW | GPIO_INT_HIGH`. + */ +#define GPIO_INT_DOUBLE_EDGE (1 << (GPIO_INT_SHIFT + 4)) + +/** GPIO pin trigger on rising edge. */ +#define GPIO_INT_EDGE_RISING (GPIO_INT_ENABLE \ + | GPIO_INT_EDGE \ + | GPIO_INT_HIGH) + +/** GPIO pin trigger on rising edge. */ +#define GPIO_INT_EDGE_FALLING (GPIO_INT_ENABLE \ + | GPIO_INT_EDGE \ + | GPIO_INT_LOW) + +/** GPIO pin trigger on rising or falling edge. */ +#define GPIO_INT_EDGE_BOTH (GPIO_INT_ENABLE \ + | GPIO_INT_EDGE \ + | GPIO_INT_LOW \ + | GPIO_INT_HIGH \ + | GPIO_INT_DOUBLE_EDGE) + +/** GPIO pin trigger on level low. */ +#define GPIO_INT_LEVEL_LOW (GPIO_INT_ENABLE \ + | GPIO_INT_LEVEL \ + | GPIO_INT_LOW) + +/** GPIO pin trigger on level high. */ +#define GPIO_INT_LEVEL_HIGH (GPIO_INT_ENABLE \ + | GPIO_INT_LEVEL \ + | GPIO_INT_HIGH) + +/** @} */ /** - * @name GPIO pull flags - * The `GPIO_PUD_*` flags are used with `gpio_pin_configure` or `gpio_port_configure`, - * to specify the pull-up or pull-down electrical configuration of a GPIO pin. + * @name GPIO polarity flags + * + * The `GPIO_POL_*` flags are used with `gpio_pin_configure` or + * `gpio_port_configure`, to specify the polarity of a GPIO pin. + * + * Note that not all GPIO drivers may support configuring pin + * polarity, and the effect of such configuration may also be + * driver-specific. + * * @{ */ /** @cond INTERNAL_HIDDEN */ -#define GPIO_PUD_POS 8 +#define GPIO_POL_SHIFT 14 +#define GPIO_POL_MASK (1 << GPIO_POL_SHIFT) /** @endcond */ -/** Pin is neither pull-up nor pull-down. */ -#define GPIO_PUD_NORMAL (0 << GPIO_PUD_POS) +/** GPIO pin polarity is normal. */ +#define GPIO_POL_NORMAL (0 << GPIO_POL_SHIFT) -/** Enable GPIO pin pull-up. */ -#define GPIO_PUD_PULL_UP (1 << GPIO_PUD_POS) +/** GPIO pin polarity is inverted. */ +#define GPIO_POL_INV (1 << GPIO_POL_SHIFT) -/** Enable GPIO pin pull-down. */ -#define GPIO_PUD_PULL_DOWN (2 << GPIO_PUD_POS) +/** @} */ /** @cond INTERNAL_HIDDEN */ -#define GPIO_PUD_MASK (3 << GPIO_PUD_POS) +#define GPIO_DEBOUNCE_SHIFT 15 +#define GPIO_DEBOUNCE_MASK (1 << GPIO_DEBOUNCE_SHIFT) /** @endcond */ -/** @} */ +/** Enable GPIO pin debounce. */ +#define GPIO_DEBOUNCE (1 << GPIO_DEBOUNCE_SHIFT) /** * @name GPIO drive strength flags - * The `GPIO_DS_*` flags are used with `gpio_pin_configure` or `gpio_port_configure`, - * to specify the drive strength configuration of a GPIO pin. + * + * The `GPIO_DS_*` flags are used with `gpio_pin_configure` or + * `gpio_port_configure`, to specify the drive strength configuration + * of a GPIO pin. * * The drive strength of individual pins can be configured * independently for when the pin output is low and high. @@ -130,51 +343,106 @@ * * On hardware that does not support a disconnect mode, `DISCONNECT` * will behave the same as `DFLT`. + * * @{ */ /** @cond INTERNAL_HIDDEN */ -#define GPIO_DS_LOW_POS 12 -#define GPIO_DS_LOW_MASK (0x3 << GPIO_DS_LOW_POS) +#define GPIO_DS_LOW_POS 16 +#define GPIO_DS_LOW_MASK (3 << GPIO_DS_LOW_POS) /** @endcond */ /** Default drive strength standard when GPIO pin output is low. */ -#define GPIO_DS_DFLT_LOW (0x0 << GPIO_DS_LOW_POS) +#define GPIO_DS_DFLT_LOW (0 << GPIO_DS_LOW_POS) /** Alternative drive strength when GPIO pin output is low. * For hardware that does not support configurable drive strength * use the default drive strength. */ -#define GPIO_DS_ALT_LOW (0x1 << GPIO_DS_LOW_POS) +#define GPIO_DS_ALT_LOW (1 << GPIO_DS_LOW_POS) /** Disconnect pin when GPIO pin output is low. * For hardware that does not support disconnect use the default * drive strength. */ -#define GPIO_DS_DISCONNECT_LOW (0x3 << GPIO_DS_LOW_POS) +#define GPIO_DS_DISCONNECT_LOW (3 << GPIO_DS_LOW_POS) /** @cond INTERNAL_HIDDEN */ -#define GPIO_DS_HIGH_POS 14 -#define GPIO_DS_HIGH_MASK (0x3 << GPIO_DS_HIGH_POS) +#define GPIO_DS_HIGH_POS 18 +#define GPIO_DS_HIGH_MASK (3 << GPIO_DS_HIGH_POS) /** @endcond */ -/** Default drive strength when GPIO pin output is high. - */ -#define GPIO_DS_DFLT_HIGH (0x0 << GPIO_DS_HIGH_POS) +/** Default drive strength when GPIO pin output is high. */ +#define GPIO_DS_DFLT_HIGH (0 << GPIO_DS_HIGH_POS) /** Alternative drive strength when GPIO pin output is high. * For hardware that does not support configurable drive strengths * use the default drive strength. */ -#define GPIO_DS_ALT_HIGH (0x1 << GPIO_DS_HIGH_POS) +#define GPIO_DS_ALT_HIGH (1 << GPIO_DS_HIGH_POS) /** Disconnect pin when GPIO pin output is high. * For hardware that does not support disconnect use the default * drive strength. */ -#define GPIO_DS_DISCONNECT_HIGH (0x3 << GPIO_DS_HIGH_POS) +#define GPIO_DS_DISCONNECT_HIGH (3 << GPIO_DS_HIGH_POS) + /** @} */ +/** @name Deprecated Flags + * + * These flags were defined at a time when the characteristic they + * identified was assumed to be relevant only for interrupts. The + * features are also useful for non-interrupt inputs and in some cases + * for outputs. + * + * @{ + */ + +/** Legacy flag setting indicating signal or interrupt active level. + * + * This flag was used both to indicate a signal's active level, and to + * indicate the level associated with an interrupt on a signal. As + * active level is also relevant to output signals the two + * intepretations have been separated. The legacy value supports + * testing for interrupt level as this is the most common use in + * existing code. + * + * @deprecated Replace with `GPIO_ACTIVE_LOW` or `GPIO_INT_LOW` + * depending on intent. + */ +#define GPIO_INT_ACTIVE_LOW GPIO_INT_LOW + +/** Legacy flag setting indicating signal or interrupt active level. + * + * This flag was used both to indicate a signal's active level, and to + * indicate the level associated with an interrupt on a signal. As + * active level is also relevant to output signals the two + * intepretations have been separated. The legacy value supports + * testing for interrupt level as this is the most common use in + * existing code. + * + * @deprecated Replace with `GPIO_ACTIVE_HIGH` or `GPIO_INT_HIGH` + * depending on intent. + */ +#define GPIO_INT_ACTIVE_HIGH GPIO_INT_HIGH + +/** Legacy flag indicating a desire to debounce the signal. + * + * Although debouncing is useful for interrupts it is not specific to + * interrupts. + * + * @deprecated Replace with `GPIO_DEBOUNCE` + */ +#define GPIO_INT_DEBOUNCE GPIO_DEBOUNCE + +/** Legacy alias indicating that interrupts should be enabled on the + * GPIO. + * + * @deprecated Replace with `GPIO_INT_ENABLE` + */ +#define GPIO_INT GPIO_INT_ENABLE +/** @} */ #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ */ From c85f776cc82814fbca1e4677990230e68a706666 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Tue, 11 Dec 2018 09:14:44 -0600 Subject: [PATCH 3/7] dt-bindings: gpio: revise drive strength flags for generality The documentation and design for drive strength was based on Nordic GPIO capabilities, and presumed that the default state was standard while the alternate state was high. The Semtech SX15088/SX1509B GPIO extender went the other way, with default being high and alternate being low. Rework the flags so that low and high are distinct from default. Update the two in-tree GPIO implementations that currently support drive strength to make use of these flags. Deprecate the ALT flag but define it to implement the documented selection (high drive) in case it's being used by out-of-tree systems. Signed-off-by: Peter A. Bigot --- drivers/gpio/gpio_cc2650.c | 2 +- drivers/gpio/gpio_nrfx.c | 24 +++++--- include/dt-bindings/gpio/gpio.h | 105 ++++++++++++++++++++++---------- 3 files changed, 89 insertions(+), 42 deletions(-) diff --git a/drivers/gpio/gpio_cc2650.c b/drivers/gpio/gpio_cc2650.c index 7fa676897a84f..44d466a77d0e1 100644 --- a/drivers/gpio/gpio_cc2650.c +++ b/drivers/gpio/gpio_cc2650.c @@ -164,7 +164,7 @@ static int gpio_cc2650_config_pin(int pin, int flags) if (flags & GPIO_DS_DISCONNECT_LOW) { disconnect(pin, &gpio_doe31_0_config, &iocfg_config); } - if (flags & GPIO_DS_ALT_LOW) { + if ((flags & GPIO_DS_LOW_MASK) == GPIO_DS_HI_LOW) { iocfg_config |= CC2650_IOC_MAX_DRIVE_STRENGTH; } else { iocfg_config |= CC2650_IOC_MIN_DRIVE_STRENGTH; diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 3460ac27844da..5047809081a10 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -134,31 +134,39 @@ static int gpio_nrfx_config(struct device *port, int access_op, u8_t from_pin; u8_t to_pin; + /* Map default selections to Nordic standard (low) */ + if ((flags & GPIO_DS_LOW_MASK) == GPIO_DS_DFLT_LOW) { + flags |= GPIO_DS_LO_LOW; + } + if ((flags & GPIO_DS_HIGH_MASK) == GPIO_DS_DFLT_HIGH) { + flags |= GPIO_DS_LO_HIGH; + } + switch (flags & (GPIO_DS_LOW_MASK | GPIO_DS_HIGH_MASK)) { - case GPIO_DS_DFLT_LOW | GPIO_DS_DFLT_HIGH: + case GPIO_DS_LO_LOW | GPIO_DS_LO_HIGH: drive = NRF_GPIO_PIN_S0S1; break; - case GPIO_DS_DFLT_LOW | GPIO_DS_ALT_HIGH: + case GPIO_DS_LO_LOW | GPIO_DS_HI_HIGH: drive = NRF_GPIO_PIN_S0H1; break; - case GPIO_DS_DFLT_LOW | GPIO_DS_DISCONNECT_HIGH: + case GPIO_DS_LO_LOW | GPIO_DS_DISCONNECT_HIGH: drive = NRF_GPIO_PIN_S0D1; break; - case GPIO_DS_ALT_LOW | GPIO_DS_DFLT_HIGH: + case GPIO_DS_HI_LOW | GPIO_DS_LO_HIGH: drive = NRF_GPIO_PIN_H0S1; break; - case GPIO_DS_ALT_LOW | GPIO_DS_ALT_HIGH: + case GPIO_DS_HI_LOW | GPIO_DS_HI_HIGH: drive = NRF_GPIO_PIN_H0H1; break; - case GPIO_DS_ALT_LOW | GPIO_DS_DISCONNECT_HIGH: + case GPIO_DS_HI_LOW | GPIO_DS_DISCONNECT_HIGH: drive = NRF_GPIO_PIN_H0D1; break; - case GPIO_DS_DISCONNECT_LOW | GPIO_DS_DFLT_HIGH: + case GPIO_DS_DISCONNECT_LOW | GPIO_DS_LO_HIGH: drive = NRF_GPIO_PIN_D0S1; break; - case GPIO_DS_DISCONNECT_LOW | GPIO_DS_ALT_HIGH: + case GPIO_DS_DISCONNECT_LOW | GPIO_DS_HI_HIGH: drive = NRF_GPIO_PIN_D0H1; break; diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index febe49924b6c7..9ac4c4bc1e079 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -7,6 +7,27 @@ #ifndef ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ #define ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ +/* + * Assigned Bit Positions + * + * @note: This table is intended as a convenience to summarize the bit + * assignments used in the fields defined below. The GPIO_foo_SHIFT + * macros are the canonical definition. + * + * Bit Prefix Variations + * ===== ============== ======================================================= + * 0 GPIO_ACTIVE high or low + * 1 GPIO_SIGNALING single-ended or push-pull + * 2 GPIO_LINE source or drain + * 3-4 GPIO_PUD pull normal/up/down + * 5-8 GPIO_IO in, out, initialize, initial value + * 9-13 GPIO_INT enable, level/edge, low, high, double-edge + * 14 GPIO_POL polarity normal/invert + * 15 GPIO_DEBOUNCE disable/enable + * 16-17 GPIO_DS_LOW drive strength for output low: default/low/high/discon + * 18-19 GPIO_DS_HIGH drive strength for output high: default/low/high/discon + */ + /** * @name GPIO active level indicator. * @@ -324,22 +345,27 @@ * The drive strength of individual pins can be configured * independently for when the pin output is low and high. * - * The `GPIO_DS_*_LOW` enumerations define the drive strength of a pin + * The `GPIO_DS_*_LOW` bits define the drive strength of a pin * when output is low. - - * The `GPIO_DS_*_HIGH` enumerations define the drive strength of a pin + * + * The `GPIO_DS_*_HIGH` bits define the drive strength of a pin * when output is high. * - * The `DISCONNECT` drive strength indicates that the pin is placed in a - * high impedance state and not driven, this option is used to - * configure hardware that supports a open collector drive mode. + * If the device does not distinguish drive strength by signal level, + * the drive strength configuration from `GPIO_DS_*_LOW` shall be + * used. * - * The interface supports two different drive strengths: - * `DFLT` - The lowest drive strength supported by the HW - * `ALT` - The highest drive strength supported by the HW + * The interface supports several drive strengths: + * `LO` - The lowest drive strength supported by the HW + * `HI` - The highest drive strength supported by the HW + * `DISCONNECT` - The pin is placed in a high impedance state and not + * driven (open drain mode) * - * On hardware that supports only one standard drive strength, both - * `DFLT` and `ALT` have the same behavior. + * In addition `DFLT` represents the default drive strength for a + * particular driver, and may be either `LO` or `HI`. + * + * On hardware that supports only one standard drive strength `LO` and + * `HI` have the same behavior. * * On hardware that does not support a disconnect mode, `DISCONNECT` * will behave the same as `DFLT`. @@ -347,45 +373,44 @@ * @{ */ /** @cond INTERNAL_HIDDEN */ -#define GPIO_DS_LOW_POS 16 -#define GPIO_DS_LOW_MASK (3 << GPIO_DS_LOW_POS) +#define GPIO_DS_LOW_SHIFT 16 +#define GPIO_DS_LOW_MASK (3 << GPIO_DS_LOW_SHIFT) /** @endcond */ -/** Default drive strength standard when GPIO pin output is low. - */ -#define GPIO_DS_DFLT_LOW (0 << GPIO_DS_LOW_POS) +/** Use default drive strength when GPIO pin output is low. */ +#define GPIO_DS_DFLT_LOW (0 << GPIO_DS_LOW_SHIFT) -/** Alternative drive strength when GPIO pin output is low. - * For hardware that does not support configurable drive strength - * use the default drive strength. - */ -#define GPIO_DS_ALT_LOW (1 << GPIO_DS_LOW_POS) +/** Use low/reduced drive strength when GPIO pin output is low. */ +#define GPIO_DS_LO_LOW (1 << GPIO_DS_LOW_SHIFT) + +/** Use high/increased drive strength when GPIO pin output is low. */ +#define GPIO_DS_HI_LOW (2 << GPIO_DS_LOW_SHIFT) /** Disconnect pin when GPIO pin output is low. * For hardware that does not support disconnect use the default * drive strength. */ -#define GPIO_DS_DISCONNECT_LOW (3 << GPIO_DS_LOW_POS) +#define GPIO_DS_DISCONNECT_LOW (3 << GPIO_DS_LOW_SHIFT) /** @cond INTERNAL_HIDDEN */ -#define GPIO_DS_HIGH_POS 18 -#define GPIO_DS_HIGH_MASK (3 << GPIO_DS_HIGH_POS) +#define GPIO_DS_HIGH_SHIFT 18 +#define GPIO_DS_HIGH_MASK (3 << GPIO_DS_HIGH_SHIFT) /** @endcond */ -/** Default drive strength when GPIO pin output is high. */ -#define GPIO_DS_DFLT_HIGH (0 << GPIO_DS_HIGH_POS) +/** Use default drive strength when GPIO pin output is low. */ +#define GPIO_DS_DFLT_HIGH (0 << GPIO_DS_HIGH_SHIFT) -/** Alternative drive strength when GPIO pin output is high. - * For hardware that does not support configurable drive strengths - * use the default drive strength. - */ -#define GPIO_DS_ALT_HIGH (1 << GPIO_DS_HIGH_POS) +/** Use low/reduced drive strength when GPIO pin output is low. */ +#define GPIO_DS_LO_HIGH (1 << GPIO_DS_HIGH_SHIFT) + +/** Use high/increased drive strength when GPIO pin output is low. */ +#define GPIO_DS_HI_HIGH (2 << GPIO_DS_HIGH_SHIFT) -/** Disconnect pin when GPIO pin output is high. +/** Disconnect pin when GPIO pin output is low. * For hardware that does not support disconnect use the default * drive strength. */ -#define GPIO_DS_DISCONNECT_HIGH (3 << GPIO_DS_HIGH_POS) +#define GPIO_DS_DISCONNECT_HIGH (3 << GPIO_DS_HIGH_SHIFT) /** @} */ @@ -443,6 +468,20 @@ */ #define GPIO_INT GPIO_INT_ENABLE +/** Legacy alias identifying high drive strength when GPIO output is + * low. + * + * @deprecated Replace with `GPIO_DS_HI_LOW` + */ +#define GPIO_DS_ALT_LOW GPIO_DS_HI_LOW + +/** Legacy alias identifying high drive strength when GPIO output is + * high. + * + * @deprecated Replace with `GPIO_DS_HI_HIGH` + */ +#define GPIO_DS_ALT_HIGH GPIO_DS_HI_HIGH + /** @} */ #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_GPIO_GPIO_H_ */ From d5ade36ca05e94962c2d0b80ed69fd050afd1cea Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Mon, 10 Dec 2018 10:53:53 -0600 Subject: [PATCH 4/7] drivers: gpio: sx1509b: remove ability to configure by port It seems highly unlikely that anybody would want to configure all pins to the same configuration. Remove this feature to simplify the code prior to rework. Retain the ability to read and write all pins simultaneously as that has use cases. Signed-off-by: Peter A. Bigot --- drivers/gpio/gpio_sx1509b.c | 114 ++++++++++++------------------------ 1 file changed, 39 insertions(+), 75 deletions(-) diff --git a/drivers/gpio/gpio_sx1509b.c b/drivers/gpio/gpio_sx1509b.c index fb0270364df5b..ceb3f9b847422 100644 --- a/drivers/gpio/gpio_sx1509b.c +++ b/drivers/gpio/gpio_sx1509b.c @@ -89,12 +89,12 @@ static inline int i2c_reg_write_word_be(struct device *dev, u16_t dev_addr, } /** - * @brief Configure pin or port + * @brief Configure pin (port not supported) * * @param dev Device struct of the SX1509B - * @param access_op Access operation (pin or port) + * @param access_op Access operation (pin only, port not supported) * @param pin The pin number - * @param flags Flags of pin or port + * @param flags Flags of pin * * @return 0 if successful, failed otherwise */ @@ -104,84 +104,48 @@ static int gpio_sx1509b_config(struct device *dev, int access_op, u32_t pin, const struct gpio_sx1509b_config *cfg = dev->config->config_info; struct gpio_sx1509b_drv_data *drv_data = dev->driver_data; struct gpio_sx1509b_pin_state *pins = &drv_data->pin_state; - int ret = 0; + int ret = -ENOTSUP; if (flags & GPIO_INT) { - return -ENOTSUP; + goto out; + } + + if (access_op != GPIO_ACCESS_BY_PIN) { + goto out; } k_sem_take(&drv_data->lock, K_FOREVER); - switch (access_op) { - case GPIO_ACCESS_BY_PIN: - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - pins->dir |= BIT(pin); - pins->input_disable &= ~BIT(pin); - } else { - pins->dir &= ~BIT(pin); - pins->input_disable |= BIT(pin); - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) { - pins->pull_up |= BIT(pin); - } else { - pins->pull_up &= ~BIT(pin); - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) { - pins->pull_down |= BIT(pin); - } else { - pins->pull_down &= ~BIT(pin); - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_NORMAL) { - pins->pull_up &= ~BIT(pin); - pins->pull_down &= ~BIT(pin); - } - if (flags & GPIO_DS_DISCONNECT_HIGH) { - pins->open_drain |= BIT(pin); - } else { - pins->open_drain &= ~BIT(pin); - } - if (flags & GPIO_POL_INV) { - pins->polarity |= BIT(pin); - } else { - pins->polarity &= ~BIT(pin); - } - break; - case GPIO_ACCESS_BY_PORT: - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - pins->dir = 0xffff; - pins->input_disable = 0x0000; - } else { - pins->dir = 0x0000; - pins->input_disable = 0xffff; - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) { - pins->pull_up = 0xffff; - } else { - pins->pull_up = 0x0000; - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) { - pins->pull_down = 0xffff; - } else { - pins->pull_down = 0x0000; - } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_NORMAL) { - pins->pull_up = 0x0000; - pins->pull_down = 0x0000; - } - if (flags & GPIO_DS_DISCONNECT_HIGH) { - pins->open_drain = 0xffff; - } else { - pins->open_drain = 0x0000; - } - if (flags & GPIO_POL_INV) { - pins->polarity = 0xffff; - } else { - pins->polarity = 0x0000; - } - break; - default: - ret = -ENOTSUP; - goto out; + if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { + pins->dir |= BIT(pin); + pins->input_disable &= ~BIT(pin); + } else { + pins->dir &= ~BIT(pin); + pins->input_disable |= BIT(pin); + } + if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) { + pins->pull_up |= BIT(pin); + } else { + pins->pull_up &= ~BIT(pin); + } + if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) { + pins->pull_down |= BIT(pin); + } else { + pins->pull_down &= ~BIT(pin); + } + if ((flags & GPIO_PUD_MASK) == GPIO_PUD_NORMAL) { + pins->pull_up &= ~BIT(pin); + pins->pull_down &= ~BIT(pin); + } + if (flags & GPIO_DS_DISCONNECT_HIGH) { + pins->open_drain |= BIT(pin); + } else { + pins->open_drain &= ~BIT(pin); + } + if (flags & GPIO_POL_INV) { + pins->polarity |= BIT(pin); + } else { + pins->polarity &= ~BIT(pin); } ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, From 13ff5f8cbde0836fbc99e0ba1581e5933838c7b1 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Tue, 11 Dec 2018 10:51:51 -0600 Subject: [PATCH 5/7] drivers: gpio: sx1509b: transition to new GPIO configuration Demonstrates an implementation that takes advantage of the new flexibility in GPIO pin configuration. New features include support for bi-directional GPIO and drive strength. Signed-off-by: Peter A. Bigot --- drivers/gpio/gpio_sx1509b.c | 160 +++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 65 deletions(-) diff --git a/drivers/gpio/gpio_sx1509b.c b/drivers/gpio/gpio_sx1509b.c index ceb3f9b847422..22b7dbdd9bbcd 100644 --- a/drivers/gpio/gpio_sx1509b.c +++ b/drivers/gpio/gpio_sx1509b.c @@ -14,15 +14,17 @@ #include #include -/** Cache of the output configuration and data of the pins */ +/** Cache of the output configuration and data of the pins. */ struct gpio_sx1509b_pin_state { - u16_t input_disable; - u16_t pull_up; - u16_t pull_down; - u16_t open_drain; - u16_t polarity; - u16_t dir; - u16_t data; + u16_t input_disable; /* 0x00 */ + u16_t long_slew; /* 0x02 */ + u16_t low_drive; /* 0x04 */ + u16_t pull_up; /* 0x06 */ + u16_t pull_down; /* 0x08 */ + u16_t open_drain; /* 0x0A */ + u16_t polarity; /* 0x0C */ + u16_t dir; /* 0x0E */ + u16_t data; /* 0x10 */ }; /** Runtime driver data */ @@ -104,76 +106,108 @@ static int gpio_sx1509b_config(struct device *dev, int access_op, u32_t pin, const struct gpio_sx1509b_config *cfg = dev->config->config_info; struct gpio_sx1509b_drv_data *drv_data = dev->driver_data; struct gpio_sx1509b_pin_state *pins = &drv_data->pin_state; - int ret = -ENOTSUP; + struct { + u8_t reg; + struct gpio_sx1509b_pin_state pins; + } __packed outbuf; + int ret = 0; + u16_t bit = BIT(pin); + bool data_first = false; - if (flags & GPIO_INT) { - goto out; + if (access_op != GPIO_ACCESS_BY_PIN) { + return -ENOTSUP; } - if (access_op != GPIO_ACCESS_BY_PIN) { - goto out; + if (flags & GPIO_INT_ENABLE) { + return -ENOTSUP; } k_sem_take(&drv_data->lock, K_FOREVER); - if ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) { - pins->dir |= BIT(pin); - pins->input_disable &= ~BIT(pin); + if ((flags & GPIO_OPEN_MASK) == GPIO_OPEN_DRAIN) { + pins->open_drain |= bit; } else { - pins->dir &= ~BIT(pin); - pins->input_disable |= BIT(pin); + pins->open_drain &= ~bit; } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_UP) { - pins->pull_up |= BIT(pin); - } else { - pins->pull_up &= ~BIT(pin); + + switch (flags & GPIO_PUD_MASK) { + default: + ret = -EINVAL; + goto out; + case GPIO_PUD_NORMAL: + pins->pull_up &= ~bit; + pins->pull_down &= ~bit; + break; + case GPIO_PUD_PULL_UP: + pins->pull_up |= bit; + pins->pull_down &= ~bit; + break; + case GPIO_PUD_PULL_DOWN: + pins->pull_up &= ~bit; + pins->pull_down |= bit; + break; } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_PULL_DOWN) { - pins->pull_down |= BIT(pin); + + if (flags & GPIO_IO_IN_ENABLED) { + pins->input_disable &= ~bit; } else { - pins->pull_down &= ~BIT(pin); + pins->input_disable |= bit; } - if ((flags & GPIO_PUD_MASK) == GPIO_PUD_NORMAL) { - pins->pull_up &= ~BIT(pin); - pins->pull_down &= ~BIT(pin); - } - if (flags & GPIO_DS_DISCONNECT_HIGH) { - pins->open_drain |= BIT(pin); + + if (flags & GPIO_IO_OUT_ENABLED) { + pins->dir &= ~bit; } else { - pins->open_drain &= ~BIT(pin); + pins->dir |= bit; } + + if (flags & GPIO_IO_INIT_ENABLED) { + data_first = true; + if ((flags & GPIO_IO_INIT_MASK) == GPIO_IO_INIT_HIGH) { + pins->data |= bit; + } else { + pins->data &= ~bit; + } + } + if (flags & GPIO_POL_INV) { - pins->polarity |= BIT(pin); + pins->polarity |= bit; } else { - pins->polarity &= ~BIT(pin); + pins->polarity &= ~bit; } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_DIR, pins->dir); - if (ret) - goto out; - - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_INPUT_DISABLE, - pins->input_disable); - if (ret) - goto out; - - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_PULL_UP, - pins->pull_up); - if (ret) - goto out; - - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_PULL_DOWN, - pins->pull_down); - if (ret) - goto out; + if (flags & GPIO_DS_LO_LOW) { + pins->low_drive |= bit; + } else { + pins->low_drive &= ~bit; + } - ret = i2c_reg_write_word_be(drv_data->i2c_master, cfg->i2c_slave_addr, - SX1509B_REG_OPEN_DRAIN, - pins->open_drain); + outbuf.reg = SX1509B_REG_INPUT_DISABLE; + outbuf.pins.input_disable = sys_cpu_to_be16(pins->input_disable); + outbuf.pins.long_slew = sys_cpu_to_be16(pins->long_slew); + outbuf.pins.low_drive = sys_cpu_to_be16(pins->low_drive); + outbuf.pins.pull_up = sys_cpu_to_be16(pins->pull_up); + outbuf.pins.pull_down = sys_cpu_to_be16(pins->pull_down); + outbuf.pins.open_drain = sys_cpu_to_be16(pins->open_drain); + outbuf.pins.polarity = sys_cpu_to_be16(pins->polarity); + outbuf.pins.dir = sys_cpu_to_be16(pins->dir); + outbuf.pins.data = sys_cpu_to_be16(pins->data); + + if (data_first) { + ret = i2c_reg_write_word_be(drv_data->i2c_master, + cfg->i2c_slave_addr, + SX1509B_REG_DATA, pins->data); + if (ret == 0) { + ret = i2c_write(drv_data->i2c_master, + &outbuf.reg, + sizeof(outbuf) - sizeof(pins->data), + cfg->i2c_slave_addr); + } + } else { + ret = i2c_write(drv_data->i2c_master, + &outbuf.reg, + sizeof(outbuf), + cfg->i2c_slave_addr); + } out: k_sem_give(&drv_data->lock); @@ -287,12 +321,8 @@ static int gpio_sx1509b_init(struct device *dev) /* Reset state */ drv_data->pin_state = (struct gpio_sx1509b_pin_state) { - .input_disable = 0x0000, - .pull_up = 0x0000, - .pull_down = 0x0000, - .open_drain = 0x0000, - .dir = 0xffff, - .data = 0xffff, + .dir = -1, + .data = -1, }; ret = i2c_reg_write_byte(drv_data->i2c_master, cfg->i2c_slave_addr, From e0e3d38c74f66a267ecad99be201446d32fec7de Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Sat, 26 Jan 2019 06:27:31 -0600 Subject: [PATCH 6/7] drivers: gpio: esp32: correct constant test for interrupt trigger Interrupts default to trigger on level for historical reasons, so use of GPIO_INT_LEVEL` as a mask results in a zero value. Use a mask macro to isolate the trigger configuration. Signed-off-by: Peter A. Bigot --- drivers/gpio/gpio_esp32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio_esp32.c b/drivers/gpio/gpio_esp32.c index a4a0ead673608..20841cc6dc1cf 100644 --- a/drivers/gpio/gpio_esp32.c +++ b/drivers/gpio/gpio_esp32.c @@ -52,7 +52,7 @@ static int convert_int_type(int flags) return 0; /* Disables interrupt for a pin. */ } - if ((flags & GPIO_INT_EDGE) == GPIO_INT_EDGE) { + if ((flags & GPIO_INT_TRIGGER_MASK) == GPIO_INT_EDGE) { if ((flags & GPIO_INT_ACTIVE_HIGH) == GPIO_INT_ACTIVE_HIGH) { return 1; } @@ -64,7 +64,7 @@ static int convert_int_type(int flags) return 2; /* Defaults to falling edge. */ } - if ((flags & GPIO_INT_LEVEL) == GPIO_INT_LEVEL) { + if ((flags & GPIO_INT_TRIGGER_MASK) == GPIO_INT_LEVEL) { if ((flags & GPIO_INT_ACTIVE_HIGH) == GPIO_INT_ACTIVE_HIGH) { return 5; } From 241f9b4a55468420b7e7da0ef06dc51cb3e3c467 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Sat, 26 Jan 2019 06:28:23 -0600 Subject: [PATCH 7/7] tests: gpio: basic_api: correct constant test for interrupt trigger Interrupts default to trigger on level for historical reasons, so use of GPIO_INT_LEVEL` as a mask results in a zero value. Use a mask macro to isolate the trigger configuration. Signed-off-by: Peter A. Bigot --- tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c b/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c index 70908bae230cf..d775ebd9cdd9b 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c +++ b/tests/drivers/gpio/gpio_basic_api/src/test_callback_trigger.c @@ -93,7 +93,7 @@ static int test_callback(int mode) goto pass_exit; } - if ((mode & GPIO_INT_LEVEL) == GPIO_INT_LEVEL) { + if ((mode & GPIO_INT_TRIGGER_MASK) == GPIO_INT_LEVEL) { if (cb_cnt != MAX_INT_CNT) { TC_ERROR("not trigger callback correctly\n"); goto err_exit;