Page 1 of 1
only three slave can be attached in SPI ?
Posted: Tue Mar 21, 2017 3:01 am
by chopin1998
i have layouted a PCB, esp32 connect 5 spi slave, share same CLK/ MISO/ MOSI and 5 independent nCS to every device.
but when I use spi_bus_add_device() 5 times, it said:
E (199) spi_master: spi_bus_add_device(326): no free cs pins for host
E (199) spi_master: spi_bus_add_device(326): no free cs pins for host
how can I use 5(or more) spi slave device?
Re: only three slave can be attached in SPI ?
Posted: Tue Mar 21, 2017 3:08 am
by chopin1998
maybe i call spi_bus_add_device once, with a dummy CS pin number, and select CS via GPIO manually?
why the API has this limit?
Re: only three slave can be attached in SPI ?
Posted: Tue Mar 21, 2017 6:47 am
by ESP_Sprite
Because the hardware only supports three SPI slaves. In theory, the driver could be expanded to allow for an infinite amount of software CS pins (which would have less strictly defined timings, however), but at the moment no one wrote any code for this yet.
Re: only three slave can be attached in SPI ?
Posted: Tue Mar 21, 2017 8:26 am
by loboris
chopin1998 wrote:maybe i call spi_bus_add_device once, with a dummy CS pin number, and select CS via GPIO manually?
why the API has this limit?
You can set the divice configuration not to use CS (
spics_io_num = -1) in
spi_device_interface_config_t structure
Code: Select all
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
and then activate/deactivate CS pip manually.
Re: only three slave can be attached in SPI ?
Posted: Tue Mar 21, 2017 9:01 am
by chopin1998
yeah, i did this and use .pre_cb and .post_cb to tgl CS pin
thank you!
Re: only three slave can be attached in SPI ?
Posted: Wed Mar 22, 2017 6:53 am
by chopin1998
loboris wrote:chopin1998 wrote:maybe i call spi_bus_add_device once, with a dummy CS pin number, and select CS via GPIO manually?
why the API has this limit?
You can set the divice configuration not to use CS (
spics_io_num = -1) in
spi_device_interface_config_t structure
Code: Select all
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
and then activate/deactivate CS pip manually.
Ooops....
I can set spics_io_num = -1, but when I call spi_bus_add_device > 3 times, driver still said
E (199) spi_master: spi_bus_add_device(326): no free cs pins for host
....
Re: only three slave can be attached in SPI ?
Posted: Wed Mar 22, 2017 8:27 am
by loboris
chopin1998 wrote:
Ooops....
I can set spics_io_num = -1, but when I call spi_bus_add_device > 3 times, driver still said
E (199) spi_master: spi_bus_add_device(326): no free cs pins for host
....
If you wan to use more than 3 devices, you have to modify spi_bus_add_device() function, something like this:
Code: Select all
#define NO_CS 3 // Number of CS pins per SPI host
// ##### ADDED ----------------------------------------------------------
#define NO_DEV 6 // Number of allowed spi devices per SPI host
// ----------------------------------------------------------------------
....
....
static esp_err_t spi_bus_add_device(spi_host_device_t host, spi_device_interface_config_t *dev_config, spi_bus_config_t *bus_config, spi_device_handle_t *handle)
{
int freecs, maxdev;
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(spihost[host]!=NULL, "host not initialized", ESP_ERR_INVALID_STATE);
//##### CHANGED --------------------------------------------------------------------------------------------
if (dev_config->spics_io_num >= 0) {
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num), "spics pin invalid", ESP_ERR_INVALID_ARG);
}
SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);
if (dev_config->spics_io_num > 0) maxdev=NO_CS;
else maxdev=NO_DEV;
for (freecs=0; freecs<maxdev; freecs++) {
//See if this slot is free; reserve if it is by putting a dummy pointer in the slot.
//We use an atomic compare&swap to make this thread-safe.
if (__sync_bool_compare_and_swap(&spihost[host]->device[freecs], NULL, (spi_device_t *)1)) break;
}
SPI_CHECK(freecs!=maxdev, "no free devices for host", ESP_ERR_NOT_FOUND);
//---------------------------------------------------------------------------------------------------------
//The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
//duplex mode does absolutely nothing on the ESP32.
SPI_CHECK(dev_config->cs_ena_pretrans==0 || (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "cs pretrans delay incompatible with full-duplex", ESP_ERR_INVALID_ARG);
....
....
Re: only three slave can be attached in SPI ?
Posted: Thu Mar 23, 2017 3:58 am
by chopin1998
loboris wrote:chopin1998 wrote:
Ooops....
I can set spics_io_num = -1, but when I call spi_bus_add_device > 3 times, driver still said
E (199) spi_master: spi_bus_add_device(326): no free cs pins for host
....
If you wan to use more than 3 devices, you have to modify spi_bus_add_device() function, something like this:
Code: Select all
#define NO_CS 3 // Number of CS pins per SPI host
// ##### ADDED ----------------------------------------------------------
#define NO_DEV 6 // Number of allowed spi devices per SPI host
// ----------------------------------------------------------------------
....
....
static esp_err_t spi_bus_add_device(spi_host_device_t host, spi_device_interface_config_t *dev_config, spi_bus_config_t *bus_config, spi_device_handle_t *handle)
{
int freecs, maxdev;
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK(spihost[host]!=NULL, "host not initialized", ESP_ERR_INVALID_STATE);
//##### CHANGED --------------------------------------------------------------------------------------------
if (dev_config->spics_io_num >= 0) {
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num), "spics pin invalid", ESP_ERR_INVALID_ARG);
}
SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);
if (dev_config->spics_io_num > 0) maxdev=NO_CS;
else maxdev=NO_DEV;
for (freecs=0; freecs<maxdev; freecs++) {
//See if this slot is free; reserve if it is by putting a dummy pointer in the slot.
//We use an atomic compare&swap to make this thread-safe.
if (__sync_bool_compare_and_swap(&spihost[host]->device[freecs], NULL, (spi_device_t *)1)) break;
}
SPI_CHECK(freecs!=maxdev, "no free devices for host", ESP_ERR_NOT_FOUND);
//---------------------------------------------------------------------------------------------------------
//The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
//duplex mode does absolutely nothing on the ESP32.
SPI_CHECK(dev_config->cs_ena_pretrans==0 || (dev_config->flags & SPI_DEVICE_HALFDUPLEX), "cs pretrans delay incompatible with full-duplex", ESP_ERR_INVALID_ARG);
....
....
yes, I have change #define NO_DEV 5.
thank you!
Re: only three slave can be attached in SPI ?
Posted: Sat Dec 14, 2019 2:44 pm
by SinglWolf
Hello!
I have the same problem. I am using framework-espidf 3.30300.190916 (3.3.0) and the proposed fixes cannot be applied in any way.
When using espressif-arduino-esp32, 4 SPI devices (tft display, (VS1053 uses 2 bus) and touchscreen) work normally.
Please, help.