#include <SD.h>
#include <SPI.h>
// https://forum.pjrc.com/threads/65851-Problem-reading-from-SD-card-directly-into-PSRAM?p=266951&viewfull=1#post266951
#if defined(ARDUINO_TEENSY41)
#define BUFSIZE (256*1024)
#elif defined(ARDUINO_TEENSY40)
#define BUFSIZE (200*1024)
#endif
#define FILENAME "TESTFILE.BIN"
#define FILENAME2 "TESTFILE.BIN"
File file;
char itcmBuf[BUFSIZE];
EXTMEM char psramBuf[BUFSIZE];
bool runTest(int variant) {
Serial.print("running variant ");
Serial.println(variant);
file = SD.open(FILENAME);
if (!file) {
Serial.println("file open failed");
return false;
}
int total_bytes_read = 0;
uint32_t rTime = micros();
while (file.available()) {
int bytes_read;
if (variant == 1) {
bytes_read = file.read(psramBuf, BUFSIZE);
} else {
bytes_read = file.read(itcmBuf, BUFSIZE);
}
if (bytes_read < 0) {
Serial.print("read failed after ");
Serial.print(total_bytes_read);
Serial.println(" bytes");
file.close();
return false;
} else {
//Serial.println("read ok");
total_bytes_read += bytes_read;
}
if (variant == 3 || variant == 4) {
memcpy(psramBuf, itcmBuf, BUFSIZE);
if (variant == 4) {
arm_dcache_flush_delete(psramBuf, BUFSIZE);
}
}
}
rTime = micros() - rTime;
Serial.printf("reads succeeded %lu bytes in %lu us at %f MB/sec\n", total_bytes_read, rTime, (float)total_bytes_read / rTime );
file.close();
return true;
}
bool writeTest(int variant) {
Serial.print("running Write variant ");
Serial.println(variant);
if (variant == 5) {
file = SD.open(FILENAME2, FILE_WRITE);
}
else {
if (SD.exists(FILENAME2))
SD.remove(FILENAME2);
file = SD.open(FILENAME2, FILE_WRITE);
}
if (!file) {
Serial.println("file open failed");
return false;
}
int total_bytes_written = 0;
int bytes2Write = 5 * 1024 * 1024;
uint32_t rTime = micros();
while (total_bytes_written < bytes2Write) {
int bytes_read;
if (variant == 5) {
bytes_read = file.write(psramBuf, BUFSIZE);
} else {
bytes_read = file.write(itcmBuf, BUFSIZE);
}
if (bytes_read < 0) {
Serial.print("write failed after ");
Serial.print(total_bytes_written);
Serial.println(" bytes");
file.close();
return false;
} else {
//Serial.println("read ok");
total_bytes_written += bytes_read;
}
if (variant == 3 || variant == 4) {
memcpy(psramBuf, itcmBuf, BUFSIZE);
if (variant == 4) {
arm_dcache_flush_delete(psramBuf, BUFSIZE);
}
}
}
rTime = micros() - rTime;
Serial.printf("write succeeded %lu bytes in %lu us at %f MB/sec\n", total_bytes_written, rTime, (float)total_bytes_written / rTime );
file.close();
return true;
}
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
if (!SD.begin(BUILTIN_SDCARD)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
// stress test
#if 0
uint32_t lCnt = 0;
while (runTest(1)) {
lCnt++;
if ( !(lCnt % 10) ) Serial.printf("\t%lu\t", lCnt );
}
#endif
}
void loop() {
int repeats = 1;
// put your main code here, to run repeatedly:
Serial.println("Select test variant ('a#' repeats 10 times)");
Serial.println("1: SD -> PSRAM");
Serial.println("2: SD -> ITCM");
Serial.println("3: SD -> ITCM, ITCM -> PSRAM");
Serial.println("4: SD -> ITCM, ITCM -> PSRAM with cache flush");
Serial.println("5: WRITE PSRAM -> SD");
Serial.println("6: delete> WRITE PSRAM -> SD");
int variant = 0;
while (variant == 0) {
while (!Serial.available());
char c = Serial.read();
if (c == 'a') {
repeats = 10;
}
if (c >= '1' && c <= '6') {
variant = c - '0';
}
}
while ( repeats > 0 ) {
if ( variant <= 4 )
runTest(variant);
else
writeTest(variant);
repeats--;
}
}