From 6db0ee13043166efcc3d603cddfbf2f4507c4ad6 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Fri, 2 Dec 2016 13:03:48 +0200 Subject: [PATCH] Optimize GPIO and account for micros overflow in delayMicroseconds --- cores/esp32/esp32-hal-gpio.c | 135 +++++++++++++++++++---------------- cores/esp32/esp32-hal-misc.c | 16 +++-- cores/esp32/esp32-hal.h | 4 ++ 3 files changed, 86 insertions(+), 69 deletions(-) diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index 7e9dabd6..19f0417a 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -22,51 +22,58 @@ #include "soc/gpio_reg.h" #include "soc/io_mux_reg.h" #include "soc/gpio_struct.h" -#include "driver/gpio.h" +#include "soc/rtc_io_reg.h" #define ETS_GPIO_INUM 4 -const uint8_t esp32_gpioToFn[40] = { - 0x44,//0 - 0x88,//1 - 0x40,//2 - 0x84,//3 - 0x48,//4 - 0x6c,//5 - 0x60,//6 - 0x64,//7 - 0x68,//8 - 0x54,//9 - 0x58,//10 - 0x5c,//11 - 0x34,//12 - 0x38,//13 - 0x30,//14 - 0x3c,//15 - 0x4c,//16 - 0x50,//17 - 0x70,//18 - 0x74,//19 - 0x78,//20 - 0x7c,//21 - 0x80,//22 - 0x8c,//23 - 0xFF,//N/A - 0x24,//25 - 0x28,//26 - 0x2c,//27 - 0xFF,//N/A - 0xFF,//N/A - 0xFF,//N/A - 0xFF,//N/A - 0x1c,//32 - 0x20,//33 - 0x14,//34 - 0x18,//35 - 0x04,//36 - 0x08,//37 - 0x0c,//38 - 0x10 //39 +typedef struct { + uint32_t mux; /*!< Register to modify various pin settings */ + uint32_t pud; /*!< Register to modify to enable or disable pullups or pulldowns */ + uint32_t pu; /*!< Bit to set or clear in the above register to enable or disable the pullup, respectively */ + uint32_t pd; /*!< Bit to set or clear in the above register to enable or disable the pulldown, respectively */ +} esp32_gpioMux_t; + +const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={ + {DR_REG_IO_MUX_BASE + 0x44, RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x88, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x40, RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x84, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x48, RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x6c, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x60, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x64, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x68, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x54, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x58, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x5c, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x34, RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x38, RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x30, RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x3c, RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x4c, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x50, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x70, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x74, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x78, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x7c, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x80, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x8c, 0, 0, 0}, + {0, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x24, RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x28, RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x2c, RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x1c, RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x20, RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M}, + {DR_REG_IO_MUX_BASE + 0x14, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x18, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x04, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x08, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x0c, 0, 0, 0}, + {DR_REG_IO_MUX_BASE + 0x10, 0, 0, 0} }; typedef void (*voidFuncPtr)(void); @@ -74,18 +81,26 @@ static voidFuncPtr __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,}; extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode) { - uint32_t pinFunction = 0, pinControl = 0; - if(pin > 39 || esp32_gpioToFn[pin] == 0xFF) { + if(pin > 39 || !esp32_gpioMux[pin].mux) { return; } + uint32_t pinFunction = 0, pinControl = 0; + const esp32_gpioMux_t * mux = &esp32_gpioMux[pin]; + if(mode & INPUT) { if(pin < 32) { GPIO.enable_w1tc = ((uint32_t)1 << pin); } else { GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32)); } + + if(mode & PULLUP) { + pinFunction |= FUN_PU; + } else if(mode & PULLDOWN) { + pinFunction |= FUN_PD; + } } else if(mode & OUTPUT) { if(pin < 32) { GPIO.enable_w1ts = ((uint32_t)1 << pin); @@ -105,19 +120,18 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode) pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S); } - ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioToFn[pin]) = pinFunction; + ESP_REG(mux->mux) = pinFunction; - if((mode & INPUT) && (mode & (PULLUP|PULLDOWN))) { - if(mode & PULLUP) { - gpio_pullup_en(pin); - gpio_pulldown_dis(pin); + if(mux->pud){ + if((mode & INPUT) && (mode & (PULLUP|PULLDOWN))) { + if(mode & PULLUP) { + ESP_REG(mux->pud) = (ESP_REG(mux->pud) | mux->pu) & ~(mux->pd); + } else { + ESP_REG(mux->pud) = (ESP_REG(mux->pud) | mux->pd) & ~(mux->pu); + } } else { - gpio_pulldown_en(pin); - gpio_pullup_dis(pin); + ESP_REG(mux->pud) = ESP_REG(mux->pud) & ~(mux->pu | mux->pd); } - } else { - gpio_pullup_dis(pin); - gpio_pulldown_dis(pin); } if(mode & OPEN_DRAIN) { @@ -129,19 +143,16 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode) extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) { - if(pin > 39) { - return; - } if(val) { if(pin < 32) { GPIO.out_w1ts = ((uint32_t)1 << pin); - } else { + } else if(pin < 35) { GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32)); } } else { if(pin < 32) { GPIO.out_w1tc = ((uint32_t)1 << pin); - } else { + } else if(pin < 35) { GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32)); } } @@ -149,14 +160,12 @@ extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) extern int IRAM_ATTR __digitalRead(uint8_t pin) { - if(pin > 39) { - return 0; - } if(pin < 32) { return (GPIO.in >> pin) & 0x1; - } else { + } else if(pin < 40) { return (GPIO.in1.val >> (pin - 32)) & 0x1; } + return 0; } diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c index ce9eb552..1fd1d743 100644 --- a/cores/esp32/esp32-hal-misc.c +++ b/cores/esp32/esp32-hal-misc.c @@ -68,7 +68,6 @@ uint32_t IRAM_ATTR micros() uint32_t ccount; __asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); return ccount / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; - //return system_get_time(); } uint32_t IRAM_ATTR millis() @@ -81,12 +80,17 @@ void delay(uint32_t ms) vTaskDelay(ms / portTICK_PERIOD_MS); } -void delayMicroseconds(uint32_t us) +void IRAM_ATTR delayMicroseconds(uint32_t us) { - if(us) { - unsigned long endat = micros(); - endat += us; - while(micros() < endat) { + uint32_t m = micros(); + if(us){ + uint32_t e = (m + us) % ((0xFFFFFFFF / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) + 1); + if(m > e){ //overflow + while(micros() > e){ + NOP(); + } + } + while(micros() < e){ NOP(); } } diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index 3304f6c2..3950bc36 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -34,6 +34,10 @@ extern "C" { #include #include "sdkconfig.h" +#ifndef F_CPU +#define F_CPU (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000U) +#endif + #ifndef CONFIG_DISABLE_HAL_LOCKS #define CONFIG_DISABLE_HAL_LOCKS 0 #endif