ESP32S3 - Fast GPIO / GPIO_OUT_W1TS/C race
Posted: Sun Jan 07, 2024 9:29 pm
I drive a display with ESP32S3, and to send data I need to clear a WR gpio, then output 8 data bits over gpio, and then set back the WR gpio.
When I do it all using GPIO_OUT_W1TS/C registers it works well.
I wanted to speed this up a bit and use the Fast GPIO (dedicated Gpio) of the ESP32S3. It should both be faster and also allow less outs because I can do both clearing and setting of data in a single command (which I can't with GPIO_OUT_W1TS/C).
Because I'm limited to 8 bits there I used the fast gpio for the data only and left the WR signal for GPIO_OUT_W1TS/C.
I got the fast gpio working, but the entire sequence did not function well.
After experimenting a lot, I found out that I need to place some delay after the clear of the WR gpio, otherwise things work inconsistently, sending partially garbaged data to the screen, and behavior isn't consistent. I did it by sending the clear WR command 5 times, less than that wasn't enough.
It seems like the fast gpio command, though comes after the gpio_out_w1tc to clear the WR signal, beats it to the actual pins and so the data is picked by the display before the WR signal is cleared.
1. Is that indeed the behavior of those commands? Don't the command finish executing only after the data is really out on the physical pins?
2. Is there a way to wait for the data to be surely out so to avoid this race?
3. Any other ideas how to speed up the sequence I need to achieve? (w/o resorting to lcd_cam at this point)?
When I do it all using GPIO_OUT_W1TS/C registers it works well.
I wanted to speed this up a bit and use the Fast GPIO (dedicated Gpio) of the ESP32S3. It should both be faster and also allow less outs because I can do both clearing and setting of data in a single command (which I can't with GPIO_OUT_W1TS/C).
Because I'm limited to 8 bits there I used the fast gpio for the data only and left the WR signal for GPIO_OUT_W1TS/C.
I got the fast gpio working, but the entire sequence did not function well.
After experimenting a lot, I found out that I need to place some delay after the clear of the WR gpio, otherwise things work inconsistently, sending partially garbaged data to the screen, and behavior isn't consistent. I did it by sending the clear WR command 5 times, less than that wasn't enough.
It seems like the fast gpio command, though comes after the gpio_out_w1tc to clear the WR signal, beats it to the actual pins and so the data is picked by the display before the WR signal is cleared.
1. Is that indeed the behavior of those commands? Don't the command finish executing only after the data is really out on the physical pins?
2. Is there a way to wait for the data to be surely out so to avoid this race?
3. Any other ideas how to speed up the sequence I need to achieve? (w/o resorting to lcd_cam at this point)?