Introduction: Faster ESP32
There are two ways to make the ESP32 GPIO stay at 0 or 1. You can call the #digitalwrite function, or you can go straight to the recorder. I’m showing the second option today: how to go straight to the register and write in the memory. This way, the command will instantly change state. Thus, we’ll first learn how to modify multiple GPIOs at once by using bitmasks. In our example today, we used five leds.
Step 1: Demonstration
Step 2: Registers /sdk/include/soc/soc/rtc_io_struct.h
union {
struct { uint32_t reserved0:14; uint32_t w1ts:18; /*GPIO0~17 output value write 1 to set*/ }; uint32_t val; } out_w1ts; union { struct { uint32_t reserved0:14; uint32_t w1tc:18; /*GPIO0~17 output value write 1 to clear*/ }; uint32_t val; } out_w1tc;
Step 3: DigitalWrite ESP32 Code Arduino /cores/esp32/esp32-hal-gpio.c
extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val){ if(val) { if(pin < 32) { GPIO.out_w1ts = ((uint32_t)1 << pin); } else if(pin < 34) { GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32)); } } else { if(pin < 32) { GPIO.out_w1tc = ((uint32_t)1 << pin); } else if(pin < 34) { GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32)); } } }
Step 4: Multiple Pins at Once Ex.1
Setup
void setup()
{ //Configuração dos gpios gpio_config_t io_conf //Colocamos como OUTPUT io_conf.mode = GPIO_MODE_OUTPUT; //Definição dos gpios que fazem parte desta configuração //Da direita para a esquerda, os que tem 1 fazem parte da configuração //Neste exemplo, contando da direita para esquerda (começando do 0) temos o gpio 2 e o gpio 4 //Para facilitar quando temos pinos de valor alto podemos utilizar //deslocamento de bits, por exemplo: (1 << 2) | (1 << 4) io_conf.pin_bit_mask = 0b10100; //Ou poderia ser //io_conf.pin_bit_mask = (1 << 2) | (1 << 4); //Aplica a configuração gpio_config(&io_conf); }
Loop
void loop()
{ //Máscara de bits com os pinos que serão "setados" como ativos GPIO.out_w1ts = 0b10100; //Ou poderia ser //GPIO.out_w1ts = (1 << 2) | (1 << 4); //Delay de 1 segundo delay(1000); //Máscara de bits com os pinos serão desativados (clear) GPIO.out_w1tc = 0b10100; //Ou poderia ser //GPIO.out_w1tc = (1 << 2) | (1 << 4); //Delay de 1 segundo delay(1000); }
Step 5: Multiple Pins at Once Ex.2
Setup
//Máscara com os GPIOs 0, 2 e 4
//Se invertermos esta máscara com "~" teremos 0b01010 //e passamos a ter selecionados os GPIOs 1 e 3 int mask = 0b10101; void setup() { //Configuração dos gpios gpio_config_t io_conf; //Colocamos como OUTPUT io_conf.mode = GPIO_MODE_OUTPUT; //Definição dos gpios que fazem parte desta configuração //Da direita para a esquerda, os que tem 1 fazem parte da conifguração //No caso os GPIOs 0, 1, 2, 3 e 4 io_conf.pin_bit_mask = 0b11111; //Aplica a configuração gpio_config(&io_conf); }
Loop
void loop()
{ //Invertamos os bits da máscara //Os que estavam selecionados são desselecionados e vice-versa mask = ~mask; //Máscara de bits com os pinos que serão "setados" como ativos GPIO.out_w1ts = mask; //Máscara de bits com os pinos que serão desativados (clear) GPIO.out_w1tc = ~mask; //Delay de 1 segundo delay(1000); }
Step 6: Digital Speed TestWrite
void setup()
{ pinMode(4, OUTPUT); } void loop() { digitalWrite(4, HIGH); digitalWrite(4, LOW); }
Step 7: Speed Test Bit Mask
void setup(){ //Configuração dos gpios gpio_config_t io_conf; //Colocamos como OUTPUT io_conf.mode = GPIO_MODE_OUTPUT; //Definição dos gpios que fazem parte desta configuração io_conf.pin_bit_mask = 0b10000; //Aplica a configuração gpio_config(&io_conf); } void loop() { //Máscara de bits com os pinos que serão "setados" como ativos GPIO.out_w1ts = 0b10000; //Máscara de bits com os pinos serão desativados (clear) GPIO.out_w1tc = 0b10000; }