From c36feab84564a898483a9e431fb58b20f3d380de Mon Sep 17 00:00:00 2001 From: Alex Stewart Date: Sun, 21 Feb 2016 18:34:11 -0800 Subject: [PATCH] Separate pullup config out of `gpio_enable()` Created `gpio_set_pullup` to configure pullups independently of direction. Removed GPIO_INPUT_PULLUP direction type. Added misc other helper functions in iomux.h --- core/esp_gpio.c | 42 +++++++++++++++++++++------------------- core/include/esp/gpio.h | 26 ++++++++++++++++++++++--- core/include/esp/iomux.h | 38 +++++++++++++++++++++++++----------- core/include/esp/types.h | 1 + 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/core/esp_gpio.c b/core/esp_gpio.c index 23ddf22..8d12be1 100644 --- a/core/esp_gpio.c +++ b/core/esp_gpio.c @@ -8,32 +8,34 @@ void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction) { - uint32_t iomux_flags; - - switch(direction) { + switch (direction) { case GPIO_INPUT: - iomux_flags = 0; + GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num); + iomux_set_gpio_function(gpio_num, false); break; case GPIO_OUTPUT: - iomux_flags = IOMUX_PIN_OUTPUT_ENABLE; + GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN; + GPIO.ENABLE_OUT_SET = BIT(gpio_num); + iomux_set_gpio_function(gpio_num, true); break; case GPIO_OUT_OPEN_DRAIN: - iomux_flags = IOMUX_PIN_OUTPUT_ENABLE; - break; - case GPIO_INPUT_PULLUP: - iomux_flags = IOMUX_PIN_PULLUP; - break; - default: - return; /* Invalid direction flag */ - } - iomux_set_gpio_function(gpio_num, iomux_flags); - if(direction == GPIO_OUT_OPEN_DRAIN) GPIO.CONF[gpio_num] |= GPIO_CONF_OPEN_DRAIN; - else - GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN; - if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE) GPIO.ENABLE_OUT_SET = BIT(gpio_num); - else - GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num); + iomux_set_gpio_function(gpio_num, true); + break; + } +} + +void gpio_set_pullup(uint8_t gpio_num, bool enabled, bool enabled_during_sleep) +{ + uint32_t flags = 0; + + if (enabled) { + flags |= IOMUX_PIN_PULLUP; + } + if (enabled_during_sleep) { + flags |= IOMUX_PIN_PULLUP_SLEEP; + } + iomux_set_pullup_flags(gpio_to_iomux(gpio_num), flags); } diff --git a/core/include/esp/gpio.h b/core/include/esp/gpio.h index b5efcaf..95b3c31 100644 --- a/core/include/esp/gpio.h +++ b/core/include/esp/gpio.h @@ -17,14 +17,21 @@ typedef enum { GPIO_INPUT, GPIO_OUTPUT, /* "Standard" push-pull output */ GPIO_OUT_OPEN_DRAIN, /* Open drain output */ - GPIO_INPUT_PULLUP, } gpio_direction_t; -/* Enable GPIO on the specified pin, and set it to input/output/ with - * pullup as needed +/* Enable GPIO on the specified pin, and set it to input or output mode */ void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction); +/* Enable/disable internal pullup resistor for a particular GPIO + * + * Note: According to Espressif, pullup resistor values are between 30K and + * 100K ohms (see http://bbs.espressif.com/viewtopic.php?t=1079#p4097) + * However, measured values suggest that the actual value is likely to be close + * to 47K in reality. + */ +void gpio_set_pullup(uint8_t gpio_num, bool enabled, bool enabled_during_sleep); + /* Disable GPIO on the specified pin, and set it Hi-Z. * * If later muxing this pin to a different function, make sure to set @@ -36,6 +43,19 @@ static inline void gpio_disable(const uint8_t gpio_num) *gpio_iomux_reg(gpio_num) &= ~IOMUX_PIN_OUTPUT_ENABLE; } +/* Set whether the specified pin continues to drive its output when the ESP8266 + * goes into sleep mode. Note that this setting is reset to off whenever + * gpio_enable is called, so this must be called after calling that function. + */ +static inline void gpio_set_output_on_sleep(const uint8_t gpio_num, bool enabled) +{ + if (enabled) { + IOMUX.PIN[gpio_to_iomux(gpio_num)] |= IOMUX_PIN_OUTPUT_ENABLE_SLEEP; + } else { + IOMUX.PIN[gpio_to_iomux(gpio_num)] &= ~IOMUX_PIN_OUTPUT_ENABLE_SLEEP; + } +} + /* Set output of a pin high or low. * * Only works if pin has been set to GPIO_OUTPUT via gpio_enable() diff --git a/core/include/esp/iomux.h b/core/include/esp/iomux.h index 214c9e8..9948784 100644 --- a/core/include/esp/iomux.h +++ b/core/include/esp/iomux.h @@ -43,25 +43,41 @@ inline static esp_reg_t gpio_iomux_reg(const uint8_t gpio_number) return &(IOMUX.PIN[gpio_to_iomux(gpio_number)]); } +inline static void iomux_set_function(uint8_t iomux_num, uint32_t func) +{ + uint32_t prev = IOMUX.PIN[iomux_num] & ~IOMUX_PIN_FUNC_MASK; + IOMUX.PIN[iomux_num] = IOMUX_FUNC(func) | prev; +} + +inline static void iomux_set_direction_flags(uint8_t iomux_num, uint32_t dir_flags) +{ + uint32_t mask = IOMUX_PIN_OUTPUT_ENABLE | IOMUX_PIN_OUTPUT_ENABLE_SLEEP; + uint32_t prev = IOMUX.PIN[iomux_num] & ~mask; + IOMUX.PIN[iomux_num] = dir_flags | prev; +} + +inline static void iomux_set_pullup_flags(uint8_t iomux_num, uint32_t pullup_flags) +{ + uint32_t mask = IOMUX_PIN_PULLUP | IOMUX_PIN_PULLDOWN | IOMUX_PIN_PULLUP_SLEEP | IOMUX_PIN_PULLDOWN_SLEEP; + uint32_t prev = IOMUX.PIN[iomux_num] & ~mask; + IOMUX.PIN[iomux_num] = pullup_flags | prev; +} + /** * Set a pin to the GPIO function. * * This allows you to set pins to GPIO without knowing in advance the * exact register masks to use. * - * flags can be any of IOMUX_PIN_OUTPUT_ENABLE, IOMUX_PIN_PULLUP, IOMUX_PIN_PULLDOWN, etc. Any other flags will be cleared. - * - * Equivalent to a direct register operation if gpio_number is known at compile time. - * ie the following are equivalent: - * - * iomux_set_gpio_function(12, IOMUX_PIN_OUTPUT_ENABLE); - * IOMUX_GPIO12 = IOMUX_GPIO12_FUNC_GPIO | IOMUX_PIN_OUTPUT_ENABLE; + * Sets the function and direction, but leaves the pullup configuration the + * same as before. */ -inline static void iomux_set_gpio_function(const uint8_t gpio_number, const uint32_t flags) +inline static void iomux_set_gpio_function(uint8_t gpio_number, bool output_enable) { - const uint8_t reg_idx = gpio_to_iomux(gpio_number); - const uint32_t func = (reg_idx > 11 ? IOMUX_FUNC(0) : IOMUX_FUNC(3)) | flags; - IOMUX.PIN[reg_idx] = func | flags; + const uint8_t iomux_num = gpio_to_iomux(gpio_number); + const uint32_t func = iomux_num > 11 ? 0 : 3; + iomux_set_function(iomux_num, func); + iomux_set_direction_flags(iomux_num, output_enable ? IOMUX_PIN_OUTPUT_ENABLE : 0); } #ifdef __cplusplus diff --git a/core/include/esp/types.h b/core/include/esp/types.h index 3f0560a..cb816da 100644 --- a/core/include/esp/types.h +++ b/core/include/esp/types.h @@ -2,6 +2,7 @@ #define _ESP_TYPES_H #include +#include typedef volatile uint32_t *esp_reg_t;