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

How do I connect more than 3 SPI devices (IDFGH-1225) #3527

Closed
amoghskulkarni opened this issue May 23, 2019 · 5 comments
Closed

How do I connect more than 3 SPI devices (IDFGH-1225) #3527

amoghskulkarni opened this issue May 23, 2019 · 5 comments
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally

Comments

@amoghskulkarni
Copy link

amoghskulkarni commented May 23, 2019

spi_master.c driver is implemented in such a way that there is a hard limit on the maximum number of SPI devices that can be communicated with (as shown here). I have two questions regarding this issue -

  1. Why this hard limit?
  2. Is there a work around for connecting more than 3 SPI devices?

P.S. - I tried to manually change the macro value to more than 3, but it didn't change anything (besides not giving the error). I found a reddit thread that discusses this issue and a possible workaround, but I didn't understand how to use the workaround in my code.

@github-actions github-actions bot changed the title How do I connect more than 3 SPI devices How do I connect more than 3 SPI devices (IDFGH-1225) May 23, 2019
@nopnop2002
Copy link

nopnop2002 commented May 27, 2019

Hello.
This is my idea, and I have not tried.

spi_device_interface_config_t devcfg;
memset( &devcfg, 0, sizeof( spi_device_interface_config_t ) );
devcfg.clock_speed_hz = SPI_Frequency;
devcfg.spics_io_num = -1; // CS GPIO pin is not use.
devcfg.queue_size = 1;
spi_device_handle_t handle;
ret = spi_bus_add_device( HSPI_HOST, &devcfg, &handle);

CS of SPI device #1 is GPIO_XX
CS of SPI device #2 is GPIO_YY
CS of SPI device #3 is GPIO_ZZ

You set GPIO_XX GPIO_YY GPIO_ZZ manualy.

@ginkgm
Copy link
Collaborator

ginkgm commented May 30, 2019

Hi all,
The hardware only has three CS signals, so that we set the limit to 3 in the early version.
If you want to support more chips, you can set NO_CS definition to greater value. And use software cs (controlled by gpio_set_level functions) in the pretrans and posttrans callbacks to activate corresponding slave.

Please take care of all cases where 3 or NO_CS are used in spi_master.c yourself. For example, you have to forbid the cs initialization when the device is 4 or larger:
spi_master.c:433

    //Set CS pin, CS options
    if (dev_config->spics_io_num >= 0) {
        spicommon_cs_initialize(host, dev_config->spics_io_num, freecs, !(spihost[host]->flags&SPICOMMON_BUSFLAG_NATIVE_PINS));
    }

BTW, kindly notice: more slaves connected to the same SPI bus will cause the timing to be worse. The delay of all lines will be greater, which will limit your working frequency.

@amoghskulkarni
Copy link
Author

@ginkgm Thank you for the explanation. I am currently trying to get the software CS working for more than 3 devices, will be dropping any new development update/question on this issue. Please feel free to close the issue.

@amoghskulkarni
Copy link
Author

amoghskulkarni commented Jun 2, 2019

If you want to support more chips, you can set NO_CS definition to greater value. And use software cs (controlled by gpio_set_level functions) in the pretrans and posttrans callbacks to activate corresponding slave.

@ginkgm I tried this and my 4th SPI device still wouldn't respond. My setup looks something like this -

void swcs_pre_cb (spi_transaction_t *trans){
    // reset the pin
    gpio_set_level(CS_PIN, 0);
    return;
}

void swcs_post_cb (spi_transaction_t *trans) {
    // set the pin
    gpio_set_level(CS_PIN, 1);
    return;
}

...
extern "C" void app_main(void)
{
...
    spi_device_interface_config_t dev_config;

    dev_config.command_bits = 0;
    dev_config.address_bits = 8;
    dev_config.dummy_bits = 0;
    dev_config.mode = 0;
    dev_config.duty_cycle_pos = 128;  // default 128 = 50%/50% duty
    dev_config.cs_ena_pretrans = 0;  // 0 not used
    dev_config.cs_ena_posttrans = 0;  // 0 not used
    dev_config.clock_speed_hz = 1000000;
    dev_config.spics_io_num = -1; // SW cs 
    dev_config.flags = 0;  // 0 not used
    dev_config.queue_size = 1;
    dev_config.pre_cb = swcs_pre_cb;
    dev_config.post_cb = swcs_post_cb;

    hspi.addDevice(&dev_config, &spi_handle);

   gpio_set_direction(CS_PIN, GPIO_MODE_INPUT_OUTPUT);
   PIN_FUNC_SELECT(CS_PIN, PIN_FUNC_GPIO);
...
}

The exact same configuration works for the first 3 devices with NULL callbacks and different spics_io_num values, which brings me to the following comment of yours -

Please take care of all cases where 3 or NO_CS are used in spi_master.c yourself. For example, you have to forbid the cs initialization when the device is 4 or larger:
spi_master.c:433

I could not determine which parts in spi_master.c need changes, because wherever NO_CS is being used, it is used in the bus acquiring logic which my 4th device needs anyway.

P.S. For my 4th device, I am taking care that the CS pins don't get initialized within spi_master.c driver functions by providing -1 to spics_io_num variable of the config object.

0xFEEDC0DE64 pushed a commit to 0xFEEDC0DE64/esp-idf that referenced this issue May 5, 2021
* Utilize prepoc symbols for SPI pins
* Adjusts for GPIO pins when ALTERNATE_PINS is set
@o-marshmallow
Copy link
Collaborator

Closing this issue, if you are still countering this issue, please open a new ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

5 participants