I am working on a rather large Teensy 4.0 project (it's a portable music tracker / sequencer that will be open source) and hit a minor snag with reading across multiple files.
Occasionally and seemingly randomly it takes about 8x longer to update a buffer from a file.
I made a simple example sketch to highlight my issue:
It outputs the buffer index, time it took in microseconds, data position, and length when the time took is over 1 millisecond.
This hiccup takes around 3.2 milliseconds from the usual 300~400 microseconds.
It occurs with both the stock SD library and SDFatBeta using FIFO_SDIO or DMA_SDIO using the latest Teensyduino. I have not tested older versions.
Breaking up a read into smaller chunks consecutively seems to help mitigate the issue but it shows itself again if I try to get more than 512 bytes from a single file at a time.
Usually I'd blame this on SD being SD but the fact that it's non-repeatable on the same file sections or even random reads (doing a seek each pass) has the exact same behavior.
Disabling IRQ seems to help as well but I have no idea why so any insight into how I can do a deeper dive would be helpful.
If you're interested in my project you can check out a video on YT I posted a week or so ago.
https://www.youtube.com/watch?v=DCFJ-3QfqZA
Thanks!
Occasionally and seemingly randomly it takes about 8x longer to update a buffer from a file.
I made a simple example sketch to highlight my issue:
Code:
#include <SdFat.h>
#define NUM_FILES 8
#define BUFFER_SIZE 512
SdFs sd;
FsFile file[NUM_FILES];
bool isOpen[NUM_FILES];
uint8_t buffer[NUM_FILES][BUFFER_SIZE];
uint32_t pos[NUM_FILES];
static const char * filename = "test.wav";
void setup() {
Serial.begin(9600);
while(!Serial);
if(sd.begin(SdioConfig(FIFO_SDIO))) {
Serial.println("Card Init");
} else {
Serial.println("Card Init Failed!");
while(1) ;
}
for(uint8_t i=0;i<NUM_FILES;i++) {
pos[i] = 0;
if(file[i] = sd.open(filename, O_READ)) {
isOpen[i] = true;
Serial.print("File Open: ");
Serial.print(filename);
Serial.print(" on index: ");
Serial.println(i);
}
}
delay(1000);
}
void loop() {
for(uint8_t i=0;i<NUM_FILES;i++) {
if(!isOpen[i]) continue;
uint32_t t = micros();
file[i].seek(pos[i]);
uint32_t len = file[i].read((uint8_t *) &buffer[i][0], BUFFER_SIZE);
pos[i] = len;
if(len == 0) {
pos[i] = 0;
}
t = micros() - t;
if(t > 1000) {
Serial.print("Index: ");
Serial.print(i);
Serial.print("\tTime: ");
Serial.print(t);
Serial.print("\tPosition: ");
Serial.print(pos[i]);
Serial.print("\tLength: ");
Serial.print(len);
Serial.println();
}
}
delay(1);
}
It outputs the buffer index, time it took in microseconds, data position, and length when the time took is over 1 millisecond.
This hiccup takes around 3.2 milliseconds from the usual 300~400 microseconds.
It occurs with both the stock SD library and SDFatBeta using FIFO_SDIO or DMA_SDIO using the latest Teensyduino. I have not tested older versions.
Breaking up a read into smaller chunks consecutively seems to help mitigate the issue but it shows itself again if I try to get more than 512 bytes from a single file at a time.
Usually I'd blame this on SD being SD but the fact that it's non-repeatable on the same file sections or even random reads (doing a seek each pass) has the exact same behavior.
Disabling IRQ seems to help as well but I have no idea why so any insight into how I can do a deeper dive would be helpful.
If you're interested in my project you can check out a video on YT I posted a week or so ago.
https://www.youtube.com/watch?v=DCFJ-3QfqZA
Thanks!