Created
January 13, 2020 05:06
-
-
Save igrr/1515d369310479bbaf9239afeed4aac5 to your computer and use it in GitHub Desktop.
ESP32-S2 (beta) dedicated GPIO example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ESP32-S2 (beta) "dedicated GPIO" peripheral example */ | |
#include <stdio.h> | |
#include "sdkconfig.h" | |
#include "soc/system_reg.h" | |
#include "esp32s2beta/rom/gpio.h" | |
#include "soc/gpio_sig_map.h" | |
#include "driver/gpio.h" | |
/* The header file is not yet in IDF; however this is the only register we need. */ | |
#define DEDICATED_GPIO_OUT_CPU_EN_REG (DR_REG_DEDICATED_GPIO_BASE + 0x10) | |
void IRAM_ATTR app_main(void) | |
{ | |
/* enable the peripheral */ | |
REG_SET_BIT(DPORT_CPU_PERI_CLK_EN_REG, DPORT_CLK_EN_DEDICATED_GPIO); | |
REG_CLR_BIT(DPORT_CPU_PERI_RST_EN_REG, DPORT_RST_EN_DEDICATED_GPIO); | |
/* get the values of dedicated GPIO from the CPU, not peripheral registers */ | |
REG_WRITE(DEDICATED_GPIO_OUT_CPU_EN_REG, 0xff); | |
/* configure GPIOs as outputs and route "dedicated GPIO" signals to them */ | |
const int gpio_nums[] = {0, 1, 2, 3, 4, 5, 6, 7}; | |
int n_gpios = sizeof(gpio_nums)/sizeof(gpio_nums[0]); | |
for (int i = 0; i < n_gpios; ++i) { | |
int gpio_num = gpio_nums[i]; | |
gpio_config_t io_conf={ | |
.mode=GPIO_MODE_OUTPUT, | |
.pin_bit_mask=(1ULL<<gpio_num) | |
}; | |
ESP_ERROR_CHECK(gpio_config(&io_conf)); | |
gpio_matrix_out(gpio_num, PRO_ALONEGPIO_OUT0_IDX + i, false, false); | |
} | |
uint32_t val = 0; | |
const uint32_t mask = 0xff; | |
const uint32_t zero = 0; | |
while(true) { | |
/* Set individual bits */ | |
__asm__ __volatile__ ("set_bit_gpio_out 0x1"); | |
__asm__ __volatile__ ("set_bit_gpio_out 0x2"); | |
__asm__ __volatile__ ("set_bit_gpio_out 0x4"); | |
__asm__ __volatile__ ("set_bit_gpio_out 0x8"); | |
__asm__ __volatile__ ("clr_bit_gpio_out 0x1"); | |
__asm__ __volatile__ ("clr_bit_gpio_out 0x2"); | |
__asm__ __volatile__ ("clr_bit_gpio_out 0x4"); | |
__asm__ __volatile__ ("clr_bit_gpio_out 0x8"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
/* write from a register with mask */ | |
__asm__ __volatile__ ("wr_mask_gpio_out %0, %1" : : "r"(val), "r"(mask)); | |
__asm__ __volatile__ ("wr_mask_gpio_out %0, %1" : : "r"(zero), "r"(mask)); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
/* can also set all the 8 bits (without masking) */ | |
__asm__ __volatile__ ("wur.gpio_out %0" : : "r"(val)); | |
__asm__ __volatile__ ("wur.gpio_out %0" : : "r"(zero)); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
__asm__ __volatile__ ("nop"); | |
val++; | |
} | |
} |
I found this screenshot of a logic analyzer trace produced by this example:
the pictured delay of 12.5 ns (1/80 MHz) corresponds to lines 43 and 44 of this code.
For the latest docs about this feature (on ESP32-S2), please check https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/dedic_gpio.html#manipulate-gpios-by-writing-assembly-code.
Thanks, that is good news!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is the maximum GPIO toggle speed you can achieve this way? I need 20 MHz and the ESP32 can only achieve 10 MHz. Considering switching to an ESP32-S2 if this one can do it.