From what I understand there are two methods for multi-subnode SPI - Regular Method and Daisy Chain Mode [1]. In the regular method, each slave device is designated a separate CS (chip select) pin on the master device which is driven low when the master wants to communicate with the slave.

Since the CS pin behaves like a GPIO pin, I would think the number of devices on an ESP32's SPI bus would be limited by the number of GPIO pins available. However, according to the Espressif's documentation Overview of ESP32’s SPI peripherals:

SPI2 and SPI3 are general purpose SPI controllers, sometimes referred to as HSPI and VSPI, respectively. They are open to users. SPI2 and SPI3 have independent signal buses with the same respective names. Each bus has three CS lines to drive up to three SPI slaves.

Is it not an option to put more than three slaves on the VSPI/HSPI bus by designating more GPIO as CS pins?

[1]: Introduction to SPI Interface.


1 Answer 1


The ESP32 Technical Reference Manual has the following in the Overview of the SPI Controller section:

Controllers SPI2 and SPI3 can be configured as either a master or a slave. When used as a master, each SPI controller can drive multiple CS signals (CS0~CS2) to activate multiple slaves.

I.e. the SPI peripheral can control up to three CS lines which matches the maximum number of SPI slaves mentioned in the question.

The description of the spics_io_num field in the spi_device_interface_config_t structure of the ESP32 SPI Master Driver has the following description which means the SPI driver can be told that a CS pin is not to be driven by the SPI peripheral:

CS GPIO pin for this device, or -1 if not used.

W.r.t. this part of the question:

Is it not an option to put more than three slaves on the VSPI/HSPI bus by designating more GPIO as CS pins?

From looking at the ESP32 documentation, the SPI Master Driver doesn't directly support more than three slave per bus. An alternative scheme could be to:

  1. Configure the SPI driver with spics_io_num set to -1 so the SPI peripheral doesn't automatically control the CS pin.
  2. In the application use GPIO to control the CS pin. I.e. each transfer with a SPI slave would involve:
    • Setting the GPIO CS pin for one slave active.
    • Call the SPI driver to perform a transfer.
    • Once the transfer has completed on the SPI bus, set the GPIO CS pin for the slave inactive.

The downside of the above approach is more timing overhead per SPI transfer, as the application has to control the GPIO CS pin timing, rather than being done by the SPI peripheral. The question doesn't seem to specify the data rate required for multiple SPI slaves, to be able to determine if the above suggestion will meet the requirements.

  • \$\begingroup\$ So would I not be able to simply use vspi.begin() or hspi.begin() from Arduino's 'SPI.h' header to initialize more than 3 devices on a single SPI channel? Only being able to hook up 3 slaves to a SPI master seems rather limiting. One of many reasons I'm thinking about leveling up to a big boy MCU (currently evaluating STM32F4). \$\endgroup\$
    – jskooba
    Jan 9 at 23:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.