Hi,
so I have this shiny new 4.1 and want to play with the onboard SD.
Installed the latest TeensyDuino 1.52b6 on Arduino IDE 1.8.12.
I tried to rebuild an old test of mine, for T3.6, which was based upon Bill's SdFat; but the "regular" SdFat (latest from GitHub) is not happy about "SdFatSdioEx" type when selecting T4.1 (builds OK for T3.6).
I suppose Bill did not add T4.1 to the regular SdFat yet?
Is my only option to install the new "SdFat Beta"? Pity since it's not compatible with my existing codebase.
Just for completeness, this is my source code:
Error:
so I have this shiny new 4.1 and want to play with the onboard SD.
Installed the latest TeensyDuino 1.52b6 on Arduino IDE 1.8.12.
I tried to rebuild an old test of mine, for T3.6, which was based upon Bill's SdFat; but the "regular" SdFat (latest from GitHub) is not happy about "SdFatSdioEx" type when selecting T4.1 (builds OK for T3.6).
I suppose Bill did not add T4.1 to the regular SdFat yet?
Is my only option to install the new "SdFat Beta"? Pity since it's not compatible with my existing codebase.
Just for completeness, this is my source code:
Code:
// SdFatSdioEx simple write latency test for Teensy 3.5/3.6 onboard uSD
// Last Modified FC aka xfer 20181115
// IMPORTANT NOTE: DO NOT use "LTO" as build option, or it will not run!
#include <SdFat.h>
#define MIN(a,b) ((a<b)?a:b)
#define SERIAL_SPEED 115200
#define BLOCK_DIM 512
// Check SD free space!
#define PREALLOCATED_BLOCKS 512000UL // 256 MB; compromise between meaningful statistics and total benchmark time
#define BUF_DIM (256 * BLOCK_DIM) // 128 KiB: will comfortably fit T3.5/3.6
#define FILE_SIZE (PREALLOCATED_BLOCKS * BLOCK_DIM)
SdFatSdioEX sdEx;
File file;
uint8_t buf[BUF_DIM];
//-----------------------------------------------------------------------------
bool sdBusy() {
return sdEx.card()->isBusy();
}
//-----------------------------------------------------------------------------
void errorHalt(const char* msg)
{
sdEx.errorHalt(msg);
}
//------------------------------------------------------------------------------
uint32_t kHzSdClk() {
return sdEx.card()->kHzSdClk();
}
// Replace "weak" system yield() function
// Usually it checks for serial data etc.; we don't need it
void yield()
{
}
////////////
// RUNTEST
////////////
void runTest(const bool contiguousFile = true, const bool preEraseFile = true)
{
const char filename[] = "T3sdioex.bin";
uint32_t first_sector, last_sector; // 1 sector = 512 bytes
uint32_t first_erase_sector;
const size_t erase_count = 2048; // number of sectors to erase at once. 2048*512 = 1 MiB
const float fMiBs = PREALLOCATED_BLOCKS / 2000.0f;
// Fill buffer with dummy data
memset(buf, 128, BUF_DIM);
// Zero Stats
uint32_t singleWriteMicros = 0;
uint32_t maxSingleWriteMicros = 0;
sdEx.remove(filename);
Serial.print("Preallocating "); Serial.print(fMiBs, 1); Serial.println(" MiB file");
if (!file.createContiguous(sdEx.vwd(), filename, FILE_SIZE))
{
Serial.println("Error from file.createContiguous");
exit(1);
}
if (!file.contiguousRange(&first_sector, &last_sector))
{
Serial.println("Error from contiguousRange. Exiting...");
exit(1);
}
first_erase_sector = first_sector;
Serial.println("Pre-erasing file: please wait...");
while (first_erase_sector <= last_sector)
{
if (!sdEx.card()->erase(first_erase_sector, MIN(first_erase_sector + erase_count, last_sector)))
{
Serial.print("Error from erase; start sector = "); Serial.println(first_erase_sector);
file.close();
exit(1);
}
first_erase_sector += erase_count;
}
file.flush();
file.rewind();
Serial.println("\nStarting write benchmark. First writes are quite slow: please be patient");
delay(200);
Serial.println("\nTransfer size\tWrite speed\tAvg write time\tMax write time");
Serial.println("bytes\t\tKB/s\t\tus\t\tus\n");
for (size_t nb = BLOCK_DIM; nb <= BUF_DIM; nb *= 2) // Loop for growing write sizes (nb)
{
maxSingleWriteMicros = 0;
uint32_t nRdWr = FILE_SIZE/nb;
Serial.print(nb);
Serial.print("\t\t");
uint32_t t = micros();
for (uint32_t n = 0; n < nRdWr; n++) // Number of writes to fill the file, with current write size
{
singleWriteMicros = micros();
if (nb != file.write(buf, nb))
{
errorHalt("write failed");
}
singleWriteMicros = micros() - singleWriteMicros;
if (singleWriteMicros > maxSingleWriteMicros)
maxSingleWriteMicros = singleWriteMicros;
}
t = micros() - t;
// Write speed
Serial.print(1000.0f*FILE_SIZE/t, 1);
Serial.print("\t\t");
// Avg write time (us)
Serial.print(t / nRdWr);
Serial.print("\t\t");
// Max write time (us)
Serial.println(maxSingleWriteMicros);
file.rewind(); // Ready for next write size
t = micros();
}
file.close();
Serial.print("\n SD clock speed (kHzSdClk): ");
Serial.print(kHzSdClk());
Serial.println(" KHz");
}
//-----------------------------------------------------------------------------
//////////
//
// SETUP
//
//////////
void setup()
{
Serial.begin(SERIAL_SPEED);
while (!Serial);
Serial.println("Teensy 3.5/3.6 SdFatSdioEx write latency benchmark\n");
if (!sdEx.begin())
{
sdEx.initErrorHalt("SdFatSdioEX begin() failed");
}
// make sdEx the current volume.
sdEx.chvol();
runTest();
Serial.println("\n*** End of test ***");
}
//-----------------------------------------------------------------------------
/////////
//
// LOOP
//
/////////
void loop()
{
}
Error:
Code:
TeensySdioLatencyBench_fc:16: error: 'SdFatSdioEX' does not name a type
SdFatSdioEX sdEx;