You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MicroDexed/third-party/SdFs/examples/TeensySdioDemo/TeensySdioDemo.ino

196 lines
5.0 KiB

// Simple performance test for Teensy 3.5/3.6 SDHC.
// Demonstrates yield() efficiency for SDIO modes.
// Uses built-in SD for SPI modes.
#include "SdFs.h"
// FILE_SYSTEM = 1 for FAT16/FAT32
// 2 for exFAT,
// 3 for FAT16/FAT32 and exFAT.
#define FILE_SYSTEM 3
// 32 KiB buffer.
const size_t BUF_DIM = 32768;
// 8 MiB file.
const uint32_t FILE_SIZE = 256UL*BUF_DIM;
#if FILE_SYSTEM == 1
SdFat sd;
FatFile file;
#elif FILE_SYSTEM == 2
SdExFat sd;
ExFatFile file;
#elif FILE_SYSTEM == 3
SdFs sd;
FsFile file;
#endif
uint8_t buf[BUF_DIM];
// buffer as uint32_t
uint32_t* buf32 = (uint32_t*)buf;
// Total usec in read/write calls.
uint32_t totalMicros = 0;
// Time in yield() function.
uint32_t yieldMicros = 0;
// Number of yield calls.
uint32_t yieldCalls = 0;
// Max busy time for single yield call.
uint32_t yieldMaxUsec = 0;
//-----------------------------------------------------------------------------
void errorHalt(const char* msg) {
Serial.print("Error: ");
Serial.println(msg);
if (sd.sdErrorCode()) {
if (sd.sdErrorCode() == SD_CARD_ERROR_ACMD41) {
Serial.println("Try power cycling the SD card.");
}
printSdErrorSymbol(&Serial, sd.sdErrorCode());
Serial.print(", ErrorData: 0X");
Serial.println(sd.sdErrorData(), HEX);
}
while (true) {}
}
bool ready = false;
//-----------------------------------------------------------------------------
bool sdBusy() {
return ready ? sd.card()->isBusy() : false;
}
//------------------------------------------------------------------------------
// Replace "weak" system yield() function.
void yield() {
// Only count cardBusy time.
if (!sdBusy()) {
return;
}
uint32_t m = micros();
yieldCalls++;
while (sdBusy()) {
// Do something here.
}
m = micros() - m;
if (m > yieldMaxUsec) {
yieldMaxUsec = m;
}
yieldMicros += m;
}
//-----------------------------------------------------------------------------
void runTest() {
// Zero Stats
totalMicros = 0;
yieldMicros = 0;
yieldCalls = 0;
yieldMaxUsec = 0;
if (!file.open("TeensyDemo.bin", O_RDWR | O_CREAT)) {
errorHalt("open failed");
}
Serial.println("\nsize,write,read");
Serial.println("bytes,KB/sec,KB/sec");
for (size_t nb = 512; nb <= BUF_DIM; nb *= 2) {
uint32_t nRdWr = FILE_SIZE/nb;
if (!file.truncate(0)) {
errorHalt("truncate failed");
}
Serial.print(nb);
Serial.print(',');
uint32_t t = micros();
for (uint32_t n = 0; n < nRdWr; n++) {
// Set start and end of buffer.
buf32[0] = n;
buf32[nb/4 - 1] = n;
if (nb != file.write(buf, nb)) {
errorHalt("write failed");
}
}
t = micros() - t;
totalMicros += t;
Serial.print(1000.0*FILE_SIZE/t);
Serial.print(',');
file.rewind();
t = micros();
for (uint32_t n = 0; n < nRdWr; n++) {
if ((int)nb != file.read(buf, nb)) {
errorHalt("read failed");
}
// crude check of data.
if (buf32[0] != n || buf32[nb/4 - 1] != n) {
errorHalt("data check");
}
}
t = micros() - t;
totalMicros += t;
Serial.println(1000.0*FILE_SIZE/t);
}
file.close();
Serial.print("\ntotalMicros ");
Serial.println(totalMicros);
Serial.print("yieldMicros ");
Serial.println(yieldMicros);
Serial.print("yieldCalls ");
Serial.println(yieldCalls);
Serial.print("yieldMaxUsec ");
Serial.println(yieldMaxUsec);
// Serial.print("kHzSdClk ");
// Serial.println(kHzSdClk());
Serial.println("Done");
}
//-----------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
while (!Serial) {
}
}
//-----------------------------------------------------------------------------
void loop() {
static bool warn = true;
if (warn) {
warn = false;
Serial.println(
"SD cards must be power cycled to leave\n"
"SPI mode so do SDIO tests first.\n"
"\nCycle power on the card if an error occurs.");
}
do {
delay(10);
} while (Serial.available() && Serial.read());
Serial.println(
"\nType '1' for FIFO SDIO"
"\n '2' for DMA SDIO"
"\n '3' for Dedicated SPI"
"\n '4' for Shared SPI");
while (!Serial.available()) {
}
char c = Serial.read();
if (c =='1') {
if (!sd.begin(SdioConfig(FIFO_SDIO))) {
errorHalt("begin failed");
}
Serial.println("\nFIFO SDIO mode.");
} else if (c == '2') {
if (!sd.begin(SdioConfig(DMA_SDIO))) {
errorHalt("begin failed");
}
Serial.println("\nDMA SDIO mode - slow for small transfers.");
} else if (c == '3') {
if (!sd.begin(SdSpiConfig(SDCARD_SS_PIN, DEDICATED_SPI, SD_SCK_MHZ(50)))) {
errorHalt("begin failed");
}
Serial.println("\nDedicated SPI mode.");
} else if (c == '4') {
if (!sd.begin(SdSpiConfig(SDCARD_SS_PIN, SHARED_SPI, SD_SCK_MHZ(50)))) {
errorHalt("begin failed");
}
Serial.println("\nShared SPI mode - slow for small transfers.");
} else {
Serial.println("Invalid input");
return;
}
ready = true;
runTest();
ready = false;
}