| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 | // Simple performance test for Teensy 3.5/3.6 SDHC.// Demonstrates yield() efficiency.// Warning SdFatSdio and SdFatSdioEX normally should// not both be used in a program.// Each has its own cache and member variables.#include "SdFat.h"#error See Version 2 SDIO example// 32 KiB buffer.const size_t BUF_DIM = 32768;// 8 MiB file.const uint32_t FILE_SIZE = 256UL*BUF_DIM;SdFatSdio sd;SdFatSdioEX sdEx;File file;uint8_t buf[BUF_DIM];// buffer as uint32_tuint32_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;// Control access to the two versions of SdFat.bool useEx = false;//-----------------------------------------------------------------------------bool sdBusy() {  return useEx ? sdEx.card()->isBusy() : sd.card()->isBusy();}//-----------------------------------------------------------------------------void errorHalt(const char* msg) {  if (useEx) {    sdEx.errorHalt(msg);  } else {    sd.errorHalt(msg);  }}//------------------------------------------------------------------------------uint32_t kHzSdClk() {  return useEx ? sdEx.card()->kHzSdClk() : sd.card()->kHzSdClk();}//------------------------------------------------------------------------------// 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) {    file.truncate(0);    uint32_t nRdWr = FILE_SIZE/nb;    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) {  }  Serial.println("SdFatSdioEX uses extended multi-block transfers without DMA.");  Serial.println("SdFatSdio uses a traditional DMA SDIO implementation.");  Serial.println("Note the difference is speed and busy yield time.\n");}//-----------------------------------------------------------------------------void loop() {  do {    delay(10);  } while (Serial.available() && Serial.read());  Serial.println("Type '1' for SdFatSdioEX or '2' for SdFatSdio");  while (!Serial.available()) {  }  char c = Serial.read();  if (c != '1' && c != '2') {    Serial.println("Invalid input");    return;  }  if (c =='1') {    useEx = true;    if (!sdEx.begin()) {      sd.initErrorHalt("SdFatSdioEX begin() failed");    }    // make sdEx the current volume.    sdEx.chvol();  } else {    useEx = false;    if (!sd.begin()) {      sd.initErrorHalt("SdFatSdio begin() failed");    }    // make sd the current volume.    sd.chvol();  }  runTest();}
 |