ESP32-S3 Fast GPIO using GPIO.out_w1ts

username
Posts: 477
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: 2067
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: 477
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: 477
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!

Who is online

Users browsing this forum: No registered users and 117 guests