Skip to content

Commit 6f52efd

Browse files
author
blue-2357
committed
Optimize GPIO and account for micros overflow in delayMicroseconds
1 parent d081d7f commit 6f52efd

File tree

3 files changed

+86
-69
lines changed

3 files changed

+86
-69
lines changed

Diff for: cores/esp32/esp32-hal-gpio.c

+72-63
Original file line numberDiff line numberDiff line change
@@ -22,70 +22,85 @@
2222
#include "soc/gpio_reg.h"
2323
#include "soc/io_mux_reg.h"
2424
#include "soc/gpio_struct.h"
25-
#include "driver/gpio.h"
25+
#include "soc/rtc_io_reg.h"
2626

2727
#define ETS_GPIO_INUM 4
2828

29-
const uint8_t esp32_gpioToFn[40] = {
30-
0x44,//0
31-
0x88,//1
32-
0x40,//2
33-
0x84,//3
34-
0x48,//4
35-
0x6c,//5
36-
0x60,//6
37-
0x64,//7
38-
0x68,//8
39-
0x54,//9
40-
0x58,//10
41-
0x5c,//11
42-
0x34,//12
43-
0x38,//13
44-
0x30,//14
45-
0x3c,//15
46-
0x4c,//16
47-
0x50,//17
48-
0x70,//18
49-
0x74,//19
50-
0x78,//20
51-
0x7c,//21
52-
0x80,//22
53-
0x8c,//23
54-
0xFF,//N/A
55-
0x24,//25
56-
0x28,//26
57-
0x2c,//27
58-
0xFF,//N/A
59-
0xFF,//N/A
60-
0xFF,//N/A
61-
0xFF,//N/A
62-
0x1c,//32
63-
0x20,//33
64-
0x14,//34
65-
0x18,//35
66-
0x04,//36
67-
0x08,//37
68-
0x0c,//38
69-
0x10 //39
29+
typedef struct {
30+
uint32_t mux; /*!< Register to modify various pin settings */
31+
uint32_t pud; /*!< Register to modify to enable or disable pullups or pulldowns */
32+
uint32_t pu; /*!< Bit to set or clear in the above register to enable or disable the pullup, respectively */
33+
uint32_t pd; /*!< Bit to set or clear in the above register to enable or disable the pulldown, respectively */
34+
} esp32_gpioMux_t;
35+
36+
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
37+
{DR_REG_IO_MUX_BASE + 0x44, RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M},
38+
{DR_REG_IO_MUX_BASE + 0x88, 0, 0, 0},
39+
{DR_REG_IO_MUX_BASE + 0x40, RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M},
40+
{DR_REG_IO_MUX_BASE + 0x84, 0, 0, 0},
41+
{DR_REG_IO_MUX_BASE + 0x48, RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M},
42+
{DR_REG_IO_MUX_BASE + 0x6c, 0, 0, 0},
43+
{DR_REG_IO_MUX_BASE + 0x60, 0, 0, 0},
44+
{DR_REG_IO_MUX_BASE + 0x64, 0, 0, 0},
45+
{DR_REG_IO_MUX_BASE + 0x68, 0, 0, 0},
46+
{DR_REG_IO_MUX_BASE + 0x54, 0, 0, 0},
47+
{DR_REG_IO_MUX_BASE + 0x58, 0, 0, 0},
48+
{DR_REG_IO_MUX_BASE + 0x5c, 0, 0, 0},
49+
{DR_REG_IO_MUX_BASE + 0x34, RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M},
50+
{DR_REG_IO_MUX_BASE + 0x38, RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M},
51+
{DR_REG_IO_MUX_BASE + 0x30, RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M},
52+
{DR_REG_IO_MUX_BASE + 0x3c, RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M},
53+
{DR_REG_IO_MUX_BASE + 0x4c, 0, 0, 0},
54+
{DR_REG_IO_MUX_BASE + 0x50, 0, 0, 0},
55+
{DR_REG_IO_MUX_BASE + 0x70, 0, 0, 0},
56+
{DR_REG_IO_MUX_BASE + 0x74, 0, 0, 0},
57+
{DR_REG_IO_MUX_BASE + 0x78, 0, 0, 0},
58+
{DR_REG_IO_MUX_BASE + 0x7c, 0, 0, 0},
59+
{DR_REG_IO_MUX_BASE + 0x80, 0, 0, 0},
60+
{DR_REG_IO_MUX_BASE + 0x8c, 0, 0, 0},
61+
{0, 0, 0, 0},
62+
{DR_REG_IO_MUX_BASE + 0x24, RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M},
63+
{DR_REG_IO_MUX_BASE + 0x28, RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M},
64+
{DR_REG_IO_MUX_BASE + 0x2c, RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M},
65+
{0, 0, 0, 0},
66+
{0, 0, 0, 0},
67+
{0, 0, 0, 0},
68+
{0, 0, 0, 0},
69+
{DR_REG_IO_MUX_BASE + 0x1c, RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M},
70+
{DR_REG_IO_MUX_BASE + 0x20, RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M},
71+
{DR_REG_IO_MUX_BASE + 0x14, 0, 0, 0},
72+
{DR_REG_IO_MUX_BASE + 0x18, 0, 0, 0},
73+
{DR_REG_IO_MUX_BASE + 0x04, 0, 0, 0},
74+
{DR_REG_IO_MUX_BASE + 0x08, 0, 0, 0},
75+
{DR_REG_IO_MUX_BASE + 0x0c, 0, 0, 0},
76+
{DR_REG_IO_MUX_BASE + 0x10, 0, 0, 0}
7077
};
7178

7279
typedef void (*voidFuncPtr)(void);
7380
static voidFuncPtr __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
7481

7582
extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
7683
{
77-
uint32_t pinFunction = 0, pinControl = 0;
7884

79-
if(pin > 39 || esp32_gpioToFn[pin] == 0xFF) {
85+
if(pin > 39 || !esp32_gpioMux[pin].mux) {
8086
return;
8187
}
8288

89+
uint32_t pinFunction = 0, pinControl = 0;
90+
const esp32_gpioMux_t * mux = &esp32_gpioMux[pin];
91+
8392
if(mode & INPUT) {
8493
if(pin < 32) {
8594
GPIO.enable_w1tc = ((uint32_t)1 << pin);
8695
} else {
8796
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
8897
}
98+
99+
if(mode & PULLUP) {
100+
pinFunction |= FUN_PU;
101+
} else if(mode & PULLDOWN) {
102+
pinFunction |= FUN_PD;
103+
}
89104
} else if(mode & OUTPUT) {
90105
if(pin < 32) {
91106
GPIO.enable_w1ts = ((uint32_t)1 << pin);
@@ -105,19 +120,18 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
105120
pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S);
106121
}
107122

108-
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioToFn[pin]) = pinFunction;
123+
ESP_REG(mux->mux) = pinFunction;
109124

110-
if((mode & INPUT) && (mode & (PULLUP|PULLDOWN))) {
111-
if(mode & PULLUP) {
112-
gpio_pullup_en(pin);
113-
gpio_pulldown_dis(pin);
125+
if(mux->pud){
126+
if((mode & INPUT) && (mode & (PULLUP|PULLDOWN))) {
127+
if(mode & PULLUP) {
128+
ESP_REG(mux->pud) = (ESP_REG(mux->pud) | mux->pu) & ~(mux->pd);
129+
} else {
130+
ESP_REG(mux->pud) = (ESP_REG(mux->pud) | mux->pd) & ~(mux->pu);
131+
}
114132
} else {
115-
gpio_pulldown_en(pin);
116-
gpio_pullup_dis(pin);
133+
ESP_REG(mux->pud) = ESP_REG(mux->pud) & ~(mux->pu | mux->pd);
117134
}
118-
} else {
119-
gpio_pullup_dis(pin);
120-
gpio_pulldown_dis(pin);
121135
}
122136

123137
if(mode & OPEN_DRAIN) {
@@ -129,34 +143,29 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
129143

130144
extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val)
131145
{
132-
if(pin > 39) {
133-
return;
134-
}
135146
if(val) {
136147
if(pin < 32) {
137148
GPIO.out_w1ts = ((uint32_t)1 << pin);
138-
} else {
149+
} else if(pin < 35) {
139150
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
140151
}
141152
} else {
142153
if(pin < 32) {
143154
GPIO.out_w1tc = ((uint32_t)1 << pin);
144-
} else {
155+
} else if(pin < 35) {
145156
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
146157
}
147158
}
148159
}
149160

150161
extern int IRAM_ATTR __digitalRead(uint8_t pin)
151162
{
152-
if(pin > 39) {
153-
return 0;
154-
}
155163
if(pin < 32) {
156164
return (GPIO.in >> pin) & 0x1;
157-
} else {
165+
} else if(pin < 40) {
158166
return (GPIO.in1.val >> (pin - 32)) & 0x1;
159167
}
168+
return 0;
160169
}
161170

162171

Diff for: cores/esp32/esp32-hal-misc.c

+10-6
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ uint32_t IRAM_ATTR micros()
6868
uint32_t ccount;
6969
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
7070
return ccount / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
71-
//return system_get_time();
7271
}
7372

7473
uint32_t IRAM_ATTR millis()
@@ -81,12 +80,17 @@ void delay(uint32_t ms)
8180
vTaskDelay(ms / portTICK_PERIOD_MS);
8281
}
8382

84-
void delayMicroseconds(uint32_t us)
83+
void IRAM_ATTR delayMicroseconds(uint32_t us)
8584
{
86-
if(us) {
87-
unsigned long endat = micros();
88-
endat += us;
89-
while(micros() < endat) {
85+
uint32_t m = micros();
86+
if(us){
87+
uint32_t e = (m + us) % ((0xFFFFFFFF / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) + 1);
88+
if(m > e){ //overflow
89+
while(micros() > e){
90+
NOP();
91+
}
92+
}
93+
while(micros() < e){
9094
NOP();
9195
}
9296
}

Diff for: cores/esp32/esp32-hal.h

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ extern "C" {
3434
#include <math.h>
3535
#include "sdkconfig.h"
3636

37+
#ifndef F_CPU
38+
#define F_CPU (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000U)
39+
#endif
40+
3741
#ifndef CONFIG_DISABLE_HAL_LOCKS
3842
#define CONFIG_DISABLE_HAL_LOCKS 0
3943
#endif

0 commit comments

Comments
 (0)