Page 1 of 1

SPI does not work

Posted: Sat Jan 27, 2024 3:49 pm
by Energiya
Hello,
I have got XIAO ESP32S3 and ESP32-WROOM32 units. I have got exactly the same problem on both. SPI works on Arduino but it does not on ESP-IDF. I use ESP-IDF 5.1.2.

I setup SPI by using code below. Later I send 4 bytes

  1. //On XIAO I tried
  2.         //gpio_iomux_in(GPIO_NUM_9, SPI3_D_IN_IDX);
  3.         //gpio_iomux_out(GPIO_NUM_8, SPI3_Q_OUT_IDX, false);
  4.         //gpio_iomux_in(GPIO_NUM_7, SPI3_CLK_IN_IDX);
  5.         //gpio_iomux_in(GPIO_NUM_1, SPI3_CS0_IN_IDX);
  6.         // and this
  7.         //gpio_iomux_out(GPIO_NUM_9, SPI3_D_OUT_IDX, false);
  8.         //gpio_iomux_in(GPIO_NUM_8, SPI3_Q_IN_IDX);
  9.         //gpio_iomux_out(GPIO_NUM_7, SPI3_CLK_OUT_IDX, false);
  10.         //gpio_iomux_out(GPIO_NUM_1, SPI3_CS0_IN_IDX,false);
  11.  
  12.         spi_bus_config_t Config;
  13.         Config.mosi_io_num = GPIO_NUM_23;//GPIO_NUM_9;//GPIO_NUM_13;//
  14.         Config.miso_io_num = GPIO_NUM_19;//GPIO_NUM_8;//GPIO_NUM_12;//
  15.         Config.sclk_io_num = GPIO_NUM_18;//GPIO_NUM_7;//GPIO_NUM_14;//;
  16.         //Config.mosi_io_num = GPIO_NUM_9;
  17.         //Config.miso_io_num = GPIO_NUM_8;
  18.         //Config.sclk_io_num = GPIO_NUM_7;
  19.         Config.max_transfer_sz = 0;
  20.         Config.quadwp_io_num = -1;  // -1 not used
  21.         Config.quadhd_io_num = -1;  // -1 not used
  22.         Config.intr_flags = 0;
  23.         Config.data0_io_num = -1;
  24.         Config.data1_io_num = -1;
  25.         Config.data2_io_num = -1;
  26.         Config.data3_io_num = -1;
  27.         Config.data4_io_num = -1;
  28.         Config.data5_io_num = -1;
  29.         Config.data6_io_num = -1;
  30.         Config.data7_io_num = -1;
  31.         //Tried with SPICOMMON_BUSFLAG_NATIVE_PINS, SPICOMMON_BUSFLAG_NATIVE_PINS, SPICOMMON_BUSFLAG_GPIO_PINS
  32.         Config.flags = SPICOMMON_BUSFLAG_MASTER;// | SPICOMMON_BUSFLAG_NATIVE_PINS;// | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI;
  33.         Config.isr_cpu_id = INTR_CPU_ID_0;
  34.         if(ESP_OK == spi_bus_initialize(SPI3_HOST, &Config, SPI_DMA_CH_AUTO))//SPI_DMA_DISABLED);//SPI_DMA_CH_AUTO);
  35.         {
  36.             printf("-----OK-----");
  37.         }  
  38.  
  39.         //spicommon_bus_initialize_io
  40.         spi_device_interface_config_t ConfigInterface;
  41.         ConfigInterface.command_bits = 0;
  42.         ConfigInterface.address_bits = 0;
  43.         ConfigInterface.dummy_bits = 0;
  44.         ConfigInterface.mode = 0;
  45.         ConfigInterface.duty_cycle_pos = 128;  // default 128 = 50%/50% duty
  46.         ConfigInterface.cs_ena_pretrans = 0;  // 0 not used
  47.         ConfigInterface.cs_ena_posttrans = 0;  // 0 not used
  48.         ConfigInterface.clock_speed_hz = 500000;
  49.         ConfigInterface.clock_source = SPI_CLK_SRC_APB; //SPI_CLK_SRC_DEFAULT
  50.         ConfigInterface.spics_io_num = GPIO_NUM_5;
  51.         ConfigInterface.flags = 0;//SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_NO_DUMMY; //| SPI_DEVICE_HALFDUPLEX;
  52.         ConfigInterface.queue_size = 1;
  53.         ConfigInterface.pre_cb = NULL;
  54.         ConfigInterface.post_cb = NULL;
  55.         ConfigInterface.input_delay_ns = 0;
  56.         if(ESP_OK == spi_bus_add_device(SPI3_HOST, &ConfigInterface, &SPIHandle))
  57.         {
  58.             printf("-----OK-----");
  59.         }

I receive wrong data, always the same bytes no matter what 4 bytes are sent. Screenshot from logic analyzer:

ESP-IDF.PNG
ESP-IDF.PNG (81.36 KiB) Viewed 2210 times

When I use Arduino

  1. #include <Arduino.h>
  2. #include <SPI.h>
  3.  
  4. #define VSPI_MISO   19
  5. #define VSPI_MOSI   23
  6. #define VSPI_SCLK   18
  7. #define VSPI_SS     5
  8.  
  9. SPIClass * vspi = NULL;
  10.  
  11. void setup()
  12. {
  13.   printf("Start");
  14.   pinMode(VSPI_SS, OUTPUT);
  15.   vspi = new SPIClass(2);
  16.   vspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS); //SCLK, MISO, MOSI, SS
  17. }
  18.  
  19. void loop()
  20. {
  21.   //uint16_t addressToRead = 0x0740;
  22.   uint16_t addressToRead = 0x08E7;
  23.   vspi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
  24.   delay(10);
  25.   digitalWrite(VSPI_SS, 0);  
  26.   vspi->transfer(0x0D);
  27.   vspi->transfer16(addressToRead);
  28.   vspi->transfer(0x38);  
  29.   digitalWrite(VSPI_SS, 1);  
  30.   vspi->endTransaction();
  31.  
  32. delay(2000);
  33.  
  34.   vspi->beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE0));
  35.   delay(10);
  36.   addressToRead = 0x08E7;
  37.   digitalWrite(VSPI_SS, 0);
  38.   vspi->transfer(0x1D);
  39.   vspi->transfer16(addressToRead);
  40.   vspi->transfer(0x00);  
  41.   uint8_t regValue = vspi->transfer(0x00);  
  42.   digitalWrite(VSPI_SS, 1);  
  43.   vspi->endTransaction();
  44.   printf("Reg %u", regValue);
  45.   delay(2000);
  46.   printf("Stop\n");
  47. }
Everything is correct. I can write and read data without problems. Screenshot from logic analyzer below. Everything is fine.
Arduino.PNG
Arduino.PNG (85 KiB) Viewed 2210 times

When I start program on Arduino later on ESP-IDF you can clearly see differences on logic analyzer

Both.PNG
Both.PNG (71.5 KiB) Viewed 2210 times

Hardware connection is fine because it works on Arduino. It is something wrong with configuration on ESP-IDF (I have spent lots of time trying different configurations). It is something incorrect with PINS or MOSI or CLOCK or ... . Behavior is the same on XIAO ESP32s3 and ESP32 units ( I reconfigure pins of course ). Tried VSPI and HSPI.

Did someone have similar issue?

Re: SPI does not work

Posted: Sun Jan 28, 2024 4:37 pm
by Energiya
Hi,
I have resolved the issue. I have noticed that mosi_io_num and data0_io_num are union. Also miso_io_num and data1_io_num.

union {
int mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
int data0_io_num; ///< GPIO pin for spi data0 signal in quad/octal mode, or -1 if not used.
};
union {
int miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
int data1_io_num; ///< GPIO pin for spi data1 signal in quad/octal mode, or -1 if not used.
};

When these lines are removed everything works fine

Config.data0_io_num = -1;
Config.data1_io_num = -1;