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
This commit is contained in:
		
							parent
							
								
									7c1d7fb43e
								
							
						
					
					
						commit
						c36feab845
					
				
					 4 changed files with 73 additions and 34 deletions
				
			
		|  | @ -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); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| #define _ESP_TYPES_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| typedef volatile uint32_t *esp_reg_t; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue