Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix ESP32: I2C pin defs used instead of the SPI pin defs (fixes pin remapping for HW SPI on ESP32 platform) #2123

Conversation

kazetsukaimiko
Copy link
Contributor

@kazetsukaimiko kazetsukaimiko commented Mar 1, 2023

Follow-up from:
#377 (comment)

Platform

Arduino / ESP32-S3

Display

OLED SSD1309 (SPI)

Summary

A custom PCB requires non-standard SPI pin assignments for an SSD1309 OLED display driven by an ESP32-S3.
Everything has been tested functional with bit-banged SW_SPI (U8G2_SSD1309_128X64_NONAME2_F_4W_SW_SPI constructor) on the required "custom" SPI pin assignments. However, the display manages a very poor 18-19fps frame rate:

software_bb_20%

It appears in the U8G2 code that there is some proviso for manual pin assignments on the HW_SPI functionality. However, after creating a custom constructor to utilize this functionality, some notable bugs were discovered in the U8G2 HW_SPI setup functions: namely, that the "manual pin assigments" query the I2C pin assignment registers, instead of the SPI pin assignment registers (which only the latter are set by the custom HW_SPI constructor).
This error results in the manual SPI pin assignments being effectively inaccessible from the U8G2 constructors.

After correcting the "I2C pin assignments" to "SPI pin assignments", the U8G2 library can utilize the desired manual pin assignments with the SSD1309 OLED screen, showing a huge marked improvement in framerate to approximately 230fps (more than 10 times faster than SW_SPI), as seen here:

230fps_20%

One further improvement that can be made to HW_SPI is to utilize a relatively unknown SPI function for bulk SPI writes on the ESP32, namely "SPI.writeBytes". (It has been mainstream in Arduino-ESP32 code since at least 2017.) Comments in the U8G2 code indicate that the "SPI.transfer" function has been found to overwrite the input buffer; "SPI.writeBytes" does not overwrite the input buffer (this has been tested).
Switching to "SPI.writeBytes" results in a further improvement in frame rate to 374fps, an easy 35% improvement from the "byte transfer" frame rate, as seen here:

324fps_20%

Use SPI.writeBytes from Espressif if present.
@kazetsukaimiko kazetsukaimiko marked this pull request as ready for review March 1, 2023 02:17
@kazetsukaimiko
Copy link
Contributor Author

Credit / thanks to @WebDust21 for doing the deep dive on this.

@olikraus olikraus added the bug label Mar 5, 2023
@olikraus olikraus added this to the 2.34 milestone Mar 5, 2023
@olikraus olikraus changed the title Potential Bugfix: I2C pin defs used instead of the SPI pin defs Bugfix ESP32: I2C pin defs used instead of the SPI pin defs (fixes pin remapping for HW SPI on ESP32 platform) Mar 5, 2023
@olikraus olikraus merged commit 45e692a into olikraus:master Mar 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants