ESP32-S3 Fast GPIO using GPIO.out_w1ts

username
Posts: 530
Joined: Thu May 03, 2018 1:18 pm

ESP32-S3 Fast GPIO using GPIO.out_w1ts

Postby username » Mon May 23, 2022 2:42 pm

I need to toggle a GPIO pin as fast as I can.
Using gpio_set_level() is just to slow. I ran across the following, and wanted to try it but the GPIO pin I want to use is 46.
How do yo do the following on the S3 higher than 31 ?

//This can only be used when the IO_PIN_Number is 0-31
//Use GPIO.out_w1ts = ((uint32_t)1 << IO_PIN_Number); to set the pin high
//Use GPIO.out_w1ts = ((uint32_t)1 << IO_PIN_Number); to set the pin low

ESP_igrr
Posts: 2071
Joined: Tue Dec 01, 2015 8:37 am

Re: ESP32-S3 Fast GPIO using GPIO.out_w1ts

Postby ESP_igrr » Mon May 23, 2022 8:42 pm

I think you need something like

GPIO.out1_w1ts = (1U << (pin - 32));

("out" contains the lower 32 pins, "out1" contains the pins starting from 32)

username
Posts: 530
Joined: Thu May 03, 2018 1:18 pm

Re: ESP32-S3 Fast GPIO using GPIO.out_w1ts

Postby username » Tue May 24, 2022 1:42 am

Close, its actually GPIO.out1_w1ts.val , there is no GPIO.out1_w1ts

Just wanted to add clarity for others that may need to twiddle pins faster.
The code below credit comes from this page here.
https://gitlab.cba.mit.edu/erik/strands ... ect_gpio.h

Code: Select all

static inline __attribute__((always_inline))
void directWriteLow(IO_REG_TYPE pin)
{
    if ( pin < 32 )
        GPIO.out_w1tc = ((uint32_t)1 << pin);
    else if ( pin < 34 )
        GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
}

static inline __attribute__((always_inline))
void directWriteHigh(IO_REG_TYPE pin)
{
    if ( pin < 32 )
        GPIO.out_w1ts = ((uint32_t)1 << pin);
    else if ( pin < 34 )
        GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
}

technatur
Posts: 1
Joined: Tue May 31, 2022 2:27 am

Re: ESP32-S3 Fast GPIO using GPIO.out_w1ts

Postby technatur » Tue May 31, 2022 2:55 am

Hey I was running into the same issue recently with the S3 but found dedicated IO bundles and the following assembly inlines to be the fastest:

Code: Select all

static inline __attribute__((always_inline))
void IRAM_ATTR directWriteHigh(const uint8_t dedic_io_num) {
  __asm__ __volatile__ ("ee.set_bit_gpio_out %0" : : "I"(dedic_io_num) : );
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
}

static inline __attribute__((always_inline))
void IRAM_ATTR directWriteLow(const uint8_t dedic_io_num) {
  __asm__ __volatile__ ("ee.clr_bit_gpio_out %0" : : "I"(dedic_io_num) : );
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
}
To use it, you first have to create a dedicated GPIO bundle as described here:
https://docs.espressif.com/projects/esp ... _gpio.html
The dedic_io_num param must be a mask of the pins in the bundle, IE, if your bundle has pins {15,12,14} and you want to write to pin 12 then dedic_io_num should be 0x2 or for pin 14 dedic_io_num should be 0x4 (1 << index_of_pin_in_bundle).

You can also decrease the nops if needed, but I haven't gotten it to work with any less than 2 so far.

username
Posts: 530
Joined: Thu May 03, 2018 1:18 pm

Re: ESP32-S3 Fast GPIO using GPIO.out_w1ts

Postby username » Tue May 31, 2022 10:34 am

Thanks for the info!

srjasz
Posts: 46
Joined: Wed Apr 03, 2024 4:29 pm

Re: ESP32-S3 Fast GPIO using GPIO.out_w1ts

Postby srjasz » Fri May 31, 2024 2:13 pm

I have also gone down the Dedicated GPIO path using Bundles and was able to collect some data.

The API takes 420ns to change an IO pin, whereas using a Dedicated GPIO and assembly code it only takes 12ns. That's 35 times faster. 12ns corresponds to 80mhz and it is possible to create an 80mhz square wave.

I did not find the nops to be necessary but others may know something I don't. Each nop adds another 12ns.

I had previously been using IO Mux/GPIO Matrix without Bundle and writing directly to the wts/wtc registers in C and was getting 60ns.
If the nops are added to the Deticated/Bundle technich it will also be 60ns.

Thanks for the info posted above, it was very helpful.

Who is online

Users browsing this forum: MicroController and 113 guests