How to make SD card (in SPI Mode) working with other SPI Devices

User avatar
Gfast2
Posts: 182
Joined: Fri Aug 11, 2017 1:52 am

How to make SD card (in SPI Mode) working with other SPI Devices

Postby Gfast2 » Sat Apr 13, 2019 6:15 am

Hello ESP-IDF,

Recently I decide to make a "gps camera" for myself. It has many parts. but its core is simple:
I read GPS Sentence from UART, If I push that button, I write this info into SD card.

But the problem is, I would like to use a Nokia 5510 Display for some information display. It would share the same SPI bus with SD card. And I believe it shouldn't impossible, because the beauty of SPI / I²C bus is in such cases. ;)

Automagic function "esp_vfs_fat_sdmmc_mount" would help me do the "spi_bus_initialize". But the same thing has been done by my Display driver too. I've tried to comment out the spi_bus_initialize behavier from function "sdspi_host_init_slot" which that automagic function leveradged for SD card initialization. but I still got panic.

The Trace is as follow:

Code: Select all

W (977) Display: Display init task ended
W (977) Display: task 'task_display_info'started
I (977) SD_CARD: Initializing SD card
I (977) SD_CARD: Using SPI peripheral
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x40084065  PS      : 0x00060031  A0      : 0x40082238  A1      : 0x3ffb0c60  
0x40084065: spi_intr at /home/gfast2/esp/esp-idf/components/driver/spi_master.c:764 (discriminator 1)

0x40082238: _xt_lowint1 at /home/gfast2/esp/esp-idf/components/freertos/xtensa_vectors.S:1154

A2      : 0x3ffb3ba4  A3      : 0x00000001  A4      : 0x00000000  A5      : 0x40089968  
0x40089968: _frxt_int_enter at /home/gfast2/esp/esp-idf/components/freertos/portasm.S:119

A6      : 0x0000759b  A7      : 0x00000000  A8      : 0x00000001  A9      : 0x3ffb0c40  
A10     : 0x00000000  A11     : 0x3ffb3bb8  A12     : 0x3ffb0c60  A13     : 0x3ffb3cc0  
A14     : 0x00060021  A15     : 0x00060021  SAR     : 0x00000017  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000005  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Core 1 was running in ISR context:
EPC1    : 0x40084065  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000
0x40084065: spi_intr at /home/gfast2/esp/esp-idf/components/driver/spi_master.c:764 (discriminator 1)


ELF file SHA256: 5a8f59436ee9a81aa30e720e06bffed131da23ba2079517ba184d8e3f13153e9

Backtrace: 0x40084065:0x3ffb0c60 0x40082235:0x3ffb0c90 0x400e60de:0x3ffb9500 0x400e6347:0x3ffb9540 0x400e89d6:0x3ffb9590 0x400e934e:0x3ffb95e0 0x400eb31d:0x3ffb9620 0x400d31fd:0x3ffb9670 0x40087cf9:0x3ffb9770
0x40084065: spi_intr at /home/gfast2/esp/esp-idf/components/driver/spi_master.c:764 (discriminator 1)

0x40082235: _xt_lowint1 at /home/gfast2/esp/esp-idf/components/freertos/xtensa_vectors.S:1154

0x400e60de: spi_cal_clock at /home/gfast2/esp/esp-idf/components/driver/spi_master.c:566

0x400e6347: spi_bus_add_device at /home/gfast2/esp/esp-idf/components/driver/spi_master.c:449 (discriminator 4)

0x400e89d6: init_spi_dev at /home/gfast2/esp/esp-idf/components/driver/sdspi_host.c:220

0x400e934e: sdspi_host_init_slot at /home/gfast2/esp/esp-idf/components/driver/sdspi_host.c:287

0x400eb31d: esp_vfs_fat_sdmmc_mount at /home/gfast2/esp/esp-idf/components/fatfs/src/vfs_fat_sdmmc.c:73

0x400d31fd: sd_card_task(void*) at /home/gfast2/workspace/gpsrecorder/main/sd_card.cpp:93

0x40087cf9: vPortTaskWrapper at /home/gfast2/esp/esp-idf/components/freertos/port.c:403


CPU halted.


I'm very happy with the truth that I can tell you the source code. It's here ;)

A Off-Topic Question:
From SPI [url=https://docs.espressif.com/projects/esp ... aster.html]Master driver Documentation[url] I found this Note:
Half duplex transactions with both read and write phases are not supported when using DMA. See Known Issues for details and workarounds.
Should I watch out this for my application? At least in my trial I can't init SPI Bus correctlly when I try to use DMA when calling "spi_bus_initialize()" (-> '0' has to be set as the value of the last parameter)

Cheers

Gfast2
Attachments
20190413_075130.jpg
20190413_075130.jpg (3.61 MiB) Viewed 844 times


User avatar
Gfast2
Posts: 182
Joined: Fri Aug 11, 2017 1:52 am

Re: How to make SD card (in SPI Mode) working with other SPI Devices

Postby Gfast2 » Sat Apr 13, 2019 4:05 pm

Hi WiFive,

Thank you very much for the Quick reply. I will checkout the possible solution for my setup and may be post a nice little video if both of them works properly.

Cheers

Gfast2

User avatar
Gfast2
Posts: 182
Joined: Fri Aug 11, 2017 1:52 am

Re: How to make SD card (in SPI Mode) working with other SPI Devices

Postby Gfast2 » Sat Apr 20, 2019 6:54 am

Jo, I got this working. There is really no trick or change in esp-idf itself. The solution right now is just unplug the display from SPI bus & deinitialize the SPI bus, reinitialize the same SPI bus for SD Card accessing, mount/plug this card (the two job would be done by those automagic functions in sd_card demo codes) on the SPI bus. After finish data I/O, reverse this crazy process again back as normal.

User avatar
Gfast2
Posts: 182
Joined: Fri Aug 11, 2017 1:52 am

Re: How to make SD card (in SPI Mode) working with other SPI Devices

Postby Gfast2 » Wed May 08, 2019 6:55 am

Hello ESP32,

I'm still fight for stopping & restarting SPI Bus "HSPI_HOST" again.
Now I believe I can stop HSPI_HOST and do the SD Card I/O job as I wished. But I get no luck to reinitialize the SPI for the Nokia 5510 Display again.

The Error Log:

Code: Select all

I (12920) MAIN: long btn press get triggered
I (12920) MAIN: stop_mode_temp
I (12920) DISPLAY: Try to stop Display & its SPI Bus!
I (12920) ADAFRUIT_PCD8544: Try to stop PCD8544 Display
I (12920) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (12930) gpio: GPIO[13]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (12940) gpio: GPIO[14]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (12950) ADAFRUIT_PCD8544: Stop Display to using SPI bus & free SPI bus HSPI_HOST
I (12960) DISPLAY: Display Temperature Task get deleted
I (12970) MAIN: start_mode_gps_detail
I (12970) ADAFRUIT_PCD8544: test abcd: _sclk: 14, _din: 13
I (12980) BME280: bme280 Task get terminated
I (12980) ADAFRUIT_PCD8544: ... Initializing bus.
E (12990) spi_master: spi_bus_initialize(236): intr flag not allowed
ESP_ERROR_CHECK failed: esp_err_t 0x102 (ESP_ERR_INVALID_ARG) at 0x40086244
0x40086244: _esp_error_check_failed at /home/gfast2/esp/esp-idf/components/esp32/panic.c:720

file: "/home/gfast2/workspace/gpsrecorder/components/Adafruit-PCD8544-Nokia-5110-LCD-library/Adafruit_PCD8544.cpp" line 143
func: void Adafruit_PCD8544::begin(uint8_t, uint8_t)
expression: spi_bus_initialize(HSPI_HOST, &bus_config,1)

ELF file SHA256: 0f8fbdbff38015d85a781bf16ec1091ce73cd783ece93287655df73b3a864311

Backtrace: 0x40085ddc:0x3ffba6e0 0x40086247:0x3ffba700 0x400e3f60:0x3ffba720 0x400d35ec:0x3ffba7a0 0x40087d7d:0x3ffba7f0
0x40085ddc: invoke_abort at /home/gfast2/esp/esp-idf/components/esp32/panic.c:715

0x40086247: _esp_error_check_failed at /home/gfast2/esp/esp-idf/components/esp32/panic.c:721

0x400e3f60: Adafruit_PCD8544::begin(unsigned char, unsigned char) at /home/gfast2/workspace/gpsrecorder/components/Adafruit-PCD8544-Nokia-5110-LCD-library/Adafruit_PCD8544.cpp:143 (discriminator 1)

0x400d35ec: task_disp_gps at /home/gfast2/workspace/gpsrecorder/main/test_pcd8544.cpp:141

0x40087d7d: vPortTaskWrapper at /home/gfast2/esp/esp-idf/components/freertos/port.c:403


CPU halted.


What I didn't understand is this one:

Code: Select all

E (12990) spi_master: spi_bus_initialize(236): intr flag not allowed
I know struct "spi_bus_config_t" has attribute "intr_flags", and through the comment in file spi_common.h about this attribute, it configures the Interrupt flag for the bus to set the priority. But it helps me not much. The ported Adafruit_PCD8544 Library for ESP32 did not touch this attribute at all:

Code: Select all

void Adafruit_PCD8544::begin(uint8_t contrast, uint8_t bias) {

	ESP_LOGI(TAG, "test abcd: _sclk: %d, _din: %d", _sclk, _din);
	spi_bus_config_t bus_config;
	bus_config.sclk_io_num   = _sclk; // CLK
	bus_config.mosi_io_num   = _din; // MOSI
	bus_config.miso_io_num   = -1; // MISO
	bus_config.quadwp_io_num = -1; // Not used
	bus_config.quadhd_io_num = -1; // Not used
	ESP_LOGI(TAG, "... Initializing bus.");
	ESP_ERROR_CHECK(spi_bus_initialize(HSPI_HOST, &bus_config,1)); // spi_bus_free() for "remove"
	spi_device_interface_config_t dev_config;
	dev_config.address_bits     = 0;
	dev_config.command_bits     = 0;
	dev_config.dummy_bits       = 0;
	dev_config.mode             = 0;
	dev_config.duty_cycle_pos   = 0;
	dev_config.cs_ena_posttrans = 0;
	dev_config.cs_ena_pretrans  = 0;
	dev_config.clock_speed_hz   = 800000; // 800KHz
	dev_config.spics_io_num     = _cs;
	dev_config.flags            = 0;
	dev_config.queue_size       = 1;
	dev_config.pre_cb           = NULL;
	dev_config.post_cb          = NULL;
	ESP_LOGI(TAG, "... Adding device bus.");
	ESP_ERROR_CHECK(spi_bus_add_device(HSPI_HOST, &dev_config, &spi_handle)); // spi_bus_remove_device() for "remove"

  gpio_set_direction((gpio_num_t)_dc, GPIO_MODE_OUTPUT);
  if (_rst > 0) {
    gpio_set_direction((gpio_num_t)_rst, GPIO_MODE_OUTPUT);
  }

  // toggle RST low to reset
  if (_rst > 0) {
  	gpio_set_level((gpio_num_t)_rst, 0);
  	vTaskDelay(500/portTICK_PERIOD_MS);
  	gpio_set_level((gpio_num_t)_rst, 1);
  }

  // get into the EXTENDED mode!
  command(PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION );

  // LCD bias select (4 is optimal?)
  command(PCD8544_SETBIAS | bias);

  // set VOP
  if (contrast > 0x7f) {
    contrast = 0x7f;
  }

  command( PCD8544_SETVOP | contrast); // Experimentally determined

  // normal mode
  command(PCD8544_FUNCTIONSET);

  // Set display to Normal
  command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL);

  // initial display line
  // set page address
  // set column address
  // write display data

  // set up a bounding box for screen updates

  updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
  // Push out pcd8544_buffer to the Display (will show the AFI logo)
  display();
}
And this initialization works well in its first call (during the initializaiton of the system).
My question is something about how to understand this? Is that means the ported Display driver has some problem? (I've tried to set this flag for SPI bus with no luck) or this is just something impossible (SPI Bus initialize / deinitialize on the fly?)

P.s.:
In the trace log, I'm trying to switching from different "Mode" of the Device. This device is switching from read/display temperature/Humidity to displaying GPS information. The Display & SPI Bus should not / don't have to be deinitialized, but for some other scenario this is not avoidable, so I just generalized this and through function pointer automat all "Mode-Switch". So the log looks some how different. If some one interested in much detailed logic. please contact me, I will try to much my right now status to a separated branch in my Github repo (Because this is still not working, and should not push to mast branch right :->)

Cheers

Su

WiFive
Posts: 2401
Joined: Tue Dec 01, 2015 7:35 am

Re: How to make SD card (in SPI Mode) working with other SPI Devices

Postby WiFive » Wed May 08, 2019 7:18 am

Zero initialize your structs, adafruit

User avatar
Gfast2
Posts: 182
Joined: Fri Aug 11, 2017 1:52 am

Re: How to make SD card (in SPI Mode) working with other SPI Devices

Postby Gfast2 » Wed May 08, 2019 7:56 pm

WiFive wrote:
Wed May 08, 2019 7:18 am
Zero initialize your structs, adafruit
Hi WiFive,

It just works. Thanks really a lot! I never suppose the error is such a simple one! :lol:

Now everything works fine!

Cheers

Gfast2

User avatar
Gfast2
Posts: 182
Joined: Fri Aug 11, 2017 1:52 am

Re: How to make SD card (in SPI Mode) working with other SPI Devices

Postby Gfast2 » Sun May 12, 2019 8:15 am

Hi ESP32,

Today I bring out this Gear to test its functionality in real. It's really a nice peace of gear!
But I suddenly discovered/figured out, that some times when I try to write things to SD Card, the SD Card seems still no ready for that. I got such a log when I go back to my bench & try to reproduce this error:

Code: Select all

E (91473) sdmmc_io: sdmmc_io_reset: unexpected return: 0x103

Error Code "0x103" is "ESP_ERR_INVALID_STATE" according to this docs.

I'm try to scopping / reproducing the same error with other sd card. The detailed log is as follow:

Code: Select all

Name: 00000
Type: SDHC/SDXC
Speed: 20 MHz
Size: 30528MB
I (86013) SD_CARD: Read from file: '2019-5-11T20:8:40:0@52.553509,13.337528'
I (86013) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (86023) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (86033) gpio: GPIO[14]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (86043) SD_CARD: Now Sd card finish its job!
-----------------------------------------------------------------------------------------------
I (86043) MAIN: start_mode_gps_detail
I (86053) ADAFRUIT_PCD8544: test abcd: _sclk: 14, _din: 13
I (86053) ADAFRUIT_PCD8544: ... Initializing bus.
I (86063) ADAFRUIT_PCD8544: ... Adding device bus.
I (86603) DISPLAY: Display Initialization Task All done!
I (86603) DISPLAY: Display GPS information.
-----------------------------------------------------------------------------------------------
I (86753) MAIN: BTN get pressed down.
I (86853) MAIN: BTN get released.
I (86853) MAIN: Triggered a snapshot
I (86853) MAIN: stop_mode_gps_detail
I (87633) ADAFRUIT_PCD8544: Try to stop PCD8544 Display
I (87633) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (87633) gpio: GPIO[13]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (87644) gpio: GPIO[14]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (87653) ADAFRUIT_PCD8544: Stop Display to using SPI bus & free SPI bus HSPI_HOST succeed!
I (87663) DISPLAY: Display GPS information Task terminated.
I (87663) SD_CARD: Initializing SD card
I (87673) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
Name: 00000
Type: SDHC/SDXC
Speed: 20 MHz
Size: 30528MB
I (87753) SD_CARD: Read from file: '2019-5-11T20:8:42:0@52.553661,13.337584'
I (87753) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (87753) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (87763) gpio: GPIO[14]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (87773) SD_CARD: Now Sd card finish its job!
-----------------------------------------------------------------------------------------------
I (87783) MAIN: start_mode_gps_detail
I (87783) ADAFRUIT_PCD8544: test abcd: _sclk: 14, _din: 13
I (87793) ADAFRUIT_PCD8544: ... Initializing bus.
I (87793) ADAFRUIT_PCD8544: ... Adding device bus.
I (88333) DISPLAY: Display Initialization Task All done!
I (88333) DISPLAY: Display GPS information.
I (91083) MAIN: BTN get pressed down.
I (91283) MAIN: BTN get released.
I (91283) MAIN: Triggered a snapshot
I (91283) MAIN: stop_mode_gps_detail
I (91423) ADAFRUIT_PCD8544: Try to stop PCD8544 Display
I (91423) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (91423) gpio: GPIO[13]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (91433) gpio: GPIO[14]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (91443) ADAFRUIT_PCD8544: Stop Display to using SPI bus & free SPI bus HSPI_HOST succeed!
I (91453) DISPLAY: Display GPS information Task terminated.
I (91453) SD_CARD: Initializing SD card
I (91463) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
E (91473) sdmmc_io: sdmmc_io_reset: unexpected return: 0x103
I (91473) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (91483) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (91493) gpio: GPIO[14]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
E (91503) SD_CARD: Failed to initialize the card (ESP_ERR_INVALID_STATE). Make sure SD card lines have pull-up resistors in place.
E (91523) FreeRTOS: FreeRTOS Task "sd_card_tsk" should not return, Aborting now!
abort() was called at PC 0x40087d9b on core 1
0x40087d9b: vPortTaskWrapper at /home/gfast2/esp/esp-idf/components/freertos/port.c:403


ELF file SHA256: 5f0cf5af1da34d1c0d604a2bfbad68fbb7b4ca7717bd18b86e5f6523f5c61388

Backtrace: 0x40085ddc:0x3ffbd060 0x40086029:0x3ffbd080 0x40087d9b:0x3ffbd0a0
0x40085ddc: invoke_abort at /home/gfast2/esp/esp-idf/components/esp32/panic.c:715

0x40086029: abort at /home/gfast2/esp/esp-idf/components/esp32/panic.c:715

0x40087d9b: vPortTaskWrapper at /home/gfast2/esp/esp-idf/components/freertos/port.c:403


CPU halted.



-----------------------------------

BTW: I found this Post describing may be the same issue. Am I right, has this issue resolved eventually?

Cheers

Gfast2

Who is online

Users browsing this forum: Bing [Bot] and 22 guests