espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.71k stars 7.3k forks source link

ESP32S3 SPI problem in master mode (IDFGH-11405) #12543

Open 393877719 opened 1 year ago

393877719 commented 1 year ago

Answers checklist.

IDF version.

esp-idf-v5.1.1

Espressif SoC revision.

ESP32-S3

Operating System used.

Windows

How did you build your project?

VS Code IDE

If you are using Windows, please specify command line type.

CMD

Development Kit.

ESP32-S3-12k-Kit

Power Supply used.

USB

What is the expected behavior?

I expected the sclk signal to stay at high level after setting spi mode=3. And the first frame message does not make an error after starting SPI sending.

What is the actual behavior?

The first frame data is always wrong after power-on, and the next frame is fine. when esp_rom_gpio_connect_out_signal(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_out, false, false) function was called, the sclk signal will pull down, even if spi mode set to 3(mode=3). ESP32S3_SPI Master mode issue

Steps to reproduce.

  1. Use attachment code, compile and upload.
  2. connecte the SPI2‘s MOSI,MISO,SCLK and CS signals to the logic analyzer respectively.
  3. Reset the device and monitor signals `#include

    include "freertos/FreeRTOS.h"

    include "freertos/task.h"

    include "driver/gpio.h"

    include "driver/spi_master.h"

    void CSLOW(void) { gpio_set_level(48, 0); } void CSHIGH(void) { gpio_set_level(48, 1); }

void app_main(void) { spi_device_handle_t spi; char buf[] = {1, 2, 3, 4, 5, 6, 7, 8}; gpio_config_t ioconfig = { .mode = GPIO_MODE_OUTPUT, .intr_type = GPIO_INTR_DISABLE, .pull_up_en = GPIO_PULLUP_ENABLE, .pin_bit_mask = (1ULL << 48)|(1ULL<<33), }; gpio_config(&ioconfig); spi_bus_config_t busconfig = { .mosi_io_num = 19, .miso_io_num = 20, .sclk_io_num = 21, .quadhd_io_num = -1, .quadwp_io_num = -1, }; spi_bus_initialize(SPI2_HOST, &busconfig, SPI_DMA_CH_AUTO); spi_device_interface_config_t devconfig = { .spics_io_num = -1, .clock_speed_hz = 1000000, .mode = 3, .queue_size = 3, }; spi_bus_add_device(SPI2_HOST, &devconfig, &spi); spi_transaction_t t = { .length = 8 * 8, .tx_buffer = buf, .rx_buffer = NULL, }; // pull Channel 4 down and up to indicate the start trans event gpio_set_level(33,0); // pull Channel 4 down vTaskDelay(pdMS_TO_TICKS(2000)); // delay 2s gpio_set_level(33,1); // pull Channel 4 up while (1) { vTaskDelay(pdMS_TO_TICKS(3000)); // Send a frame of data every 3s CSLOW(); spi_device_transmit(spi, &t); CSHIGH(); } vTaskDelete(NULL); } `

Debug Logs.

N/A

More Information.

I also ran the same test on the esp32-wroom module. I also used arduino IDE to perform SPI master mode tests on ESP32S3 and ESP32 module, and got the same experimental effect. There is always a problem with the first spi message sent using the test code, sclk is pulled down after the esp_rom_gpio_connect_out_signal(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_out, false, false) function is called, even if the spi mode=3 ESP32S3_SPI Master mode issue `#include

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "driver/gpio.h"

include "driver/spi_master.h"

void CSLOW(void) { gpio_set_level(48, 0); } void CSHIGH(void) { gpio_set_level(48, 1); }

void app_main(void) { spi_device_handle_t spi; char buf[] = {1, 2, 3, 4, 5, 6, 7, 8}; gpio_config_t ioconfig = { .mode = GPIO_MODE_OUTPUT, .intr_type = GPIO_INTR_DISABLE, .pull_up_en = GPIO_PULLUP_ENABLE, .pin_bit_mask = (1ULL << 48)|(1ULL<<33), }; gpio_config(&ioconfig); spi_bus_config_t busconfig = { .mosi_io_num = 19, .miso_io_num = 20, .sclk_io_num = 21, .quadhd_io_num = -1, .quadwp_io_num = -1, }; spi_bus_initialize(SPI2_HOST, &busconfig, SPI_DMA_CH_AUTO); spi_device_interface_config_t devconfig = { .spics_io_num = -1, .clock_speed_hz = 1000000, .mode = 3, .queue_size = 3, }; spi_bus_add_device(SPI2_HOST, &devconfig, &spi); spi_transaction_t t = { .length = 8 * 8, .tx_buffer = buf, .rx_buffer = NULL, }; // pull Channel 4 down and up to indicate the start trans event gpio_set_level(33,0); // pull Channel 4 down vTaskDelay(pdMS_TO_TICKS(2000)); // delay 2s gpio_set_level(33,1); // pull Channel 4 up while (1) { vTaskDelay(pdMS_TO_TICKS(3000)); // Send a frame of data every 3s CSLOW(); spi_device_transmit(spi, &t); CSHIGH(); } vTaskDelete(NULL); } `

wanckl commented 1 year ago

@393877719 Hi, Maybe your issue is ,,,,a delusion, let see

In your picture, CLK line is low before first transmission, which against mode 3, But did you find the first clock duration is also not follow 1M you set, and the rise edge is one more than 8*8 bits,,,

OK, real reason is, the spi hardware haven't worked yet before first transmission, now the CLK line statue is controlled by hardware but the default level,

When hardware start, it refresh configures, right now the CLK line is high, then output the clock sequence to start a transmission.

So why you see your figure, you control CS line by software, which is slower than hardware, you pull down CS, then need "long time" to trigger a real transmission, which time is longer than hardware prepare and start flow, so in your transmission there are some timing not belong to actually spi hardware.

If you just remove your CSHIGH & CSLOW and set .spics_io_num = 48,, let hardware control your CS line automatically, you can see right timing on first trans like this
2023-11-08_12-01

BTW, If you can't adjust any timing adopt your device, I can try to help you adjust the hardware status of first trans, PLS tap me at the moment, thank you.

Best wishes!!

393877719 commented 1 year ago

@393877719 Hi, Maybe your issue is ,,,,a delusion, let see

In your picture, CLK line is low before first transmission, which against mode 3, But did you find the first clock duration is also not follow 1M you set, and the rise edge is one more than 8*8 bits,,,

OK, real reason is, the spi hardware haven't worked yet before first transmission, now the CLK line statue is controlled by hardware but the default level,

When hardware start, it refresh configures, right now the CLK line is high, then output the clock sequence to start a transmission.

So why you see your figure, you control CS line by software, which is slower than hardware, you pull down CS, then need "long time" to trigger a real transmission, which time is longer than hardware prepare and start flow, so in your transmission there are some timing not belong to actually spi hardware.

If you just remove your CSHIGH & CSLOW and set .spics_io_num = 48,, let hardware control your CS line automatically, you can see right timing on first trans like this 2023-11-08_12-01

BTW, If you can't adjust any timing adopt your device, I can try to help you adjust the hardware status of first trans, PLS tap me at the moment, thank you.

Best wishes!!

Thank you for your reply. I have done the test according to the method you provided, and it seems that the curve is correct, but logic2 cannot decode the frame, I don't know whether it is a software problem. image If I have to control CS manually, How do I configure the device to prevent errors in the first frame of data?

wanckl commented 1 year ago

@393877719 Hardware works very quickly, So in this way, CS line may active very close to clock output, it may lead some slave device can't react in time, or lose some data, may your logic2 don't think it is a valid timing :rofl: , you can increase the config cs_ena_pretrans and cs_ena_posttrans to adjust CS active time befor/after clock output.

If I have to control CS manually, How do I configure the device to prevent errors in the first frame of data?

I need some time to have a try, will let you know later then, thank you!