Skip to content

hardware SPI is slower than software SPI by maybe a factor of 3 #149

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

Closed
marcmerlin opened this issue Jan 27, 2017 · 9 comments
Closed

hardware SPI is slower than software SPI by maybe a factor of 3 #149

marcmerlin opened this issue Jan 27, 2017 · 9 comments
Labels
Status: To be implemented Selected for Development Type: Feature request Feature request for Arduino ESP32

Comments

@marcmerlin
Copy link
Contributor

I've used this
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
and with the same exact code, it's about 3 times slower (probably 2Mhz at most) than using the software SPI emulation in that library by having it talk to the pins by itself.
Sadly my project uses multiple SPI devices and if I use software SPI for the tft lib, the other hardware SPI only drivers will not work.
@projectgus mentioned to me that there is an inefficiency issue between how the arduino libraries work for hw SPI and how ESP32 expects bigger buffers and takes more time to set things up for a single byte transmit, causing hw SPI to be slower than software emulation if bytes are sent one by one.

Is there a possible fix for this performance issue?

@Dennis650
Copy link

Hi,

i have the same issue with the hardware SPI and ILI9341.

Greetings
Dennis

@me-no-dev
Copy link
Member

me-no-dev commented Jan 27, 2017

Here is the thing about SPI and all other drivers running on ESP32:

  • We have 2 cores, so there is the possibility that hardware could be accessed from both cores at the same time
  • In order to prevent that, we use mutexes
  • Locking and unlocking mutexes takes time :(

Now the ESP32 on other hand can transfer lots of data with just one lock/unlock, but that is not something that Arduino has on lower platforms (AVR), so libraries use the byte-by-byte approach to communicate, which in turn means lock/unlock every byte. And that is what causes the slowdown you see.

There are generally two ways to speed things up:

  • Update all libraries to use proper multi-byte api on ESP32 (Espressif is rolling out own ILI9341 driver based on Adafruit's API)
  • Disable hardware locking by adding #define CONFIG_DISABLE_HAL_LOCKS 1 to esp32-hal.h

@Dennis650
Copy link

Hi,

i tried the second option and it is much faster! Thanks.

esp32-hal.h add
#define CONFIG_DISABLE_HAL_LOCKS 1

Greetings
Dennis

@mobier
Copy link

mobier commented Jan 30, 2017

C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp: In member function 'void Adafruit_ILI9341::spiwrite(uint8_t)':
C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp:113:3: error: 'mosiport' was not declared in this scope

*mosiport |= mosipinmask;

^
C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp:113:16: error: 'mosipinmask' was not declared in this scope

*mosiport |= mosipinmask;

        ^

C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp:116:3: error: 'mosiport' was not declared in this scope

*mosiport &= ~mosipinmask;

^

C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp:116:16: error: 'mosipinmask' was not declared in this scope

*mosiport &= ~mosipinmask;

        ^

C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp:119:8: error: 'clkport' was not declared in this scope

*clkport |= clkpinmask;

^

C:\Users\skaz\Documents\Arduino\libraries\Adafruit_ILI9341\Adafruit_ILI9341.cpp:119:20: error: 'clkpinmask' was not declared in this scope

*clkport |= clkpinmask;

            ^`

This is what the problem?

@me-no-dev
Copy link
Member

@mobier the lib you show above is not made to work with esp32 so it thinks it's avr arduino.

@marcmerlin
Copy link
Contributor Author

@mobier this has been fixed in git already
adafruit/Adafruit_ILI9341@51934bd
download the latest version

@me-no-dev me-no-dev added Type: Feature request Feature request for Arduino ESP32 Status: To be implemented Selected for Development labels Feb 23, 2017
@me-no-dev
Copy link
Member

https://github.com/espressif/Adafruit-GFX-Library
https://github.com/espressif/Adafruit_ILI9341
screen shot 2017-02-16 at 2 48 44 pm

@me-no-dev
Copy link
Member

When @ladyada merges it, you'll be able to use the standard libraries. Closing this now as it is no longer relevant.

@gojimmypi
Copy link

reviving this years-old issue... wondering if the comment above by @me-no-dev still applies today regarding mutexes slowing down hardware SPI calls on the multi-core ESP32?

If not, what are the risks of disabling hardware locks if there's only 1 SPI device in use? Are there other hidden "system" hardware issues such as WiFi that might have unexpected / undesired results?

Disable hardware locking by adding #define CONFIG_DISABLE_HAL_LOCKS 1 to esp32-hal.h

I ask, as I'm looking into poor performance on emard/ulx3s#8 for the SSD1331 - not specific to the ULX3S, as I see the same results on a stand-alone WROOM-32.

brentru pushed a commit to adafruit/arduino-esp32 that referenced this issue Oct 22, 2024
…niton

move all_platforms to its own file
darkxst pushed a commit to darkxst/arduino-esp32 that referenced this issue Dec 5, 2024
* Add c2 (espressif#70)

* Adjust components and build strategy

* enable rev 2 chips (preview)

---------

Co-authored-by: me-no-dev <[email protected]>
Co-authored-by: Jan Prochazka <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: To be implemented Selected for Development Type: Feature request Feature request for Arduino ESP32
Projects
None yet
Development

No branches or pull requests

5 participants