PaulStoffregen / SD

70 stars 41 forks source link

Allow Sketch to specify SPI clock divisor SD.begin #3

Open Defragster opened 8 years ago

Defragster commented 8 years ago

Would this added (optional) parameter conflict with any general SD usage?

SD.begin(10, SPI_QUARTER_SPEED)

When using the SPI overclock in the sketch with AUDIO tutorial hardware and ILI9341 this allows the SD card with SPI OC adjustment to work at 72MHz to 120MHz with no apparent issues (at least reading songs for the Part_3_02 tutorial sample I modified for the ILI9361C thread. On the large ILI9341 it still falls behind - but performance is 12% higher on average doing 83 .vs. 74 FPS on the dual FFT data bars for the first sample song. And the slowest update is 67 FPS .vs. 50.

SPI OC is this: https://forum.pjrc.com/threads/34406-Teensy-3-2-SPI-Clock-over-30-MHz?p=104104&viewfull=1#post104104

At 140MHz the SPI OC results in audio BUZZ and loss of TFT – It seems the TFT can’t handle SPI at that speed as it fails without Audio hardware.

At 48MHz SPI OC works - but the millis() and elapsedMillis runs wrong.

Same millis() issue at 24MHz - however there the SPI OC works to play the Audio at the right speed, without SPI OC the song plays slow.

If I read the (solder on SOIC) RAM clock speed specs this SPI OC will break that over 24MHz?, but it should work on a FLASH that is 80MHz or over?

Defragster commented 8 years ago

Here is the 'instrumented' source I used to test. Part_3_02_Fourier_Transform_TFT_instrum.zip

Forum post: https://forum.pjrc.com/threads/34663-Paul-s-taking-a-5-day-vacation?p=105559&viewfull=1#post105559

If you run this code as is, it shows the FPS of FFT display as each sample song completes. Where MIN is the min number of FFT's shown per second, CNT is the number of sample seconds (song length) and AVG shows the number of FFT's or FPS updated for the song - each of the four in turn.

F_CPU MHz: 96, SPI_OVERCLOCK MIN: ,67, CNT: ,94, AVG: ,83 MIN: ,53, CNT: ,92, AVG: ,72 MIN: ,66, CNT: ,77, AVG: ,86 MIN: ,74, CNT: ,96, AVG: ,82

changing this line: //#define SPI_OVERCLOCK // Doing this will break SD usage if not slowed down :: SD.begin(10, SPI_QUARTER_SPEED)

results in: F_CPU MHz: 96, NORMAL SPI MIN: ,50, CNT: ,94, AVG: ,73 MIN: ,37, CNT: ,92, AVG: ,60 MIN: ,57, CNT: ,77, AVG: ,82 MIN: ,57, CNT: ,96, AVG: ,72

Defragster commented 8 years ago

opps - didn't mean to close. Some further refinement to the Graph code and the improvement is good - but not compared to the SPI overclock:

F_CPU MHz: 96, SPI_OVERCLOCK MIN: ,74, CNT: ,94, AVG: ,84 MIN: ,58, CNT: ,92, AVG: ,75 MIN: ,69, CNT: ,77, AVG: ,86 MIN: ,77, CNT: ,96, AVG: ,83

F_CPU MHz: 96, NORMAL SPI MIN: ,54, CNT: ,94, AVG: ,75 MIN: ,44, CNT: ,92, AVG: ,64 MIN: ,60, CNT: ,77, AVG: ,83 MIN: ,57, CNT: ,96, AVG: ,74

Defragster commented 8 years ago

Forum post : https://forum.pjrc.com/threads/34696-SD-Read-Throughput-Worse-on-Sandisk-Ultra?p=105758&viewfull=1#post105758

Led me to looking at SD_t3.h leading to init_t3.cpp - it of course won't work the same using: define SD_SPI_SPEED SPISettings(25000000, MSBFIRST, SPI_MODE0)

PaulStoffregen commented 8 years ago

Any idea if this affects performance (when using 24 Mbit/sec), and by how much?

File > Examples > Audio > HardwareTesting > SdCardTest might be useful as a quick check.

Defragster commented 8 years ago

Tested:: It is functional, but loses some SD throughput - see attached for output.

Generally in the latter 4 tests: Overall speed = 0.87 Mbyte/sec drops to Overall speed = 0.77 Mbyte/sec

Output shows three runs sd_OCparam.txt

Normal Accelerated SPI breaks SD Accelerated SPI with SD.begin(10, SPI_QUARTER_SPEED)

Defragster commented 8 years ago

Tested example / audio / ReadWrite to WORK with SPI OC on Audio Tutorial hardware.

Serial.print("Initializing SD card..."); // Configure SPI for the audio shield pins SPI.setMOSI(7); // Audio shield has MOSI on pin 7 SPI.setSCK(14); // Audio shield has SCK on pin 14 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0) | SIM_CLKDIV1_OUTDIV4(3); if (!SD.begin(chipSelect, SPI_QUARTER_SPEED)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done.");